From d601d0f25962e46f0d99918307cdda2d81ef26f4 Mon Sep 17 00:00:00 2001 From: dsk-minchulahn Date: Wed, 3 Jan 2024 17:29:11 +0900 Subject: [PATCH] =?UTF-8?q?=EB=94=94=EB=A0=89=ED=86=A0=EB=A6=AC=20?= =?UTF-8?q?=EA=B5=AC=EC=A1=B0=20=EB=B0=8F=20=EA=B0=81=20=EC=84=9C=EB=B9=84?= =?UTF-8?q?=EC=8A=A4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 14 +- docker/README.md | 1 + helm/README.md | 2 + helm/actions-runner-controller/.helmignore | 25 + helm/actions-runner-controller/Chart.yaml | 13 + helm/actions-runner-controller/README.md | 157 + .../ci/ci-values.yaml | 30 + ...rwind.dev_horizontalrunnerautoscalers.yaml | 259 + ...ions.summerwind.dev_runnerdeployments.yaml | 5393 ++++++++ ...ions.summerwind.dev_runnerreplicasets.yaml | 5372 ++++++++ .../crds/actions.summerwind.dev_runners.yaml | 5370 ++++++++ .../actions.summerwind.dev_runnersets.yaml | 4682 +++++++ .../runner-deployment/dsk-agent-group.yaml | 13 + .../runner-deployment/dsk-devops-group.yaml | 13 + .../runner-deployment/dsk-front-group.yaml | 13 + .../templates/NOTES.txt | 22 + .../_actions_metrics_server_helpers.tpl | 60 + .../_github_webhook_server_helpers.tpl | 64 + .../templates/_helpers.tpl | 117 + .../templates/actionsmetrics.deployment.yaml | 168 + .../templates/actionsmetrics.ingress.yaml.yml | 47 + .../templates/actionsmetrics.role.yaml | 90 + .../actionsmetrics.role_binding.yaml | 14 + .../templates/actionsmetrics.secrets.yaml | 28 + .../templates/actionsmetrics.service.yaml | 32 + .../actionsmetrics.serviceaccount.yaml.yml | 15 + .../actionsmetrics.servicemonitor.yaml.yml | 25 + .../templates/auth_proxy_role.yaml | 15 + .../templates/auth_proxy_role_binding.yaml | 14 + .../templates/certificate.yaml | 26 + .../templates/ci-secret.yaml | 14 + .../templates/controller.metrics.service.yaml | 18 + .../controller.metrics.serviceMonitor.yaml | 25 + .../templates/controller.pdb.yaml | 19 + .../templates/deployment.yaml | 213 + .../templates/githubwebhook.deployment.yaml | 178 + .../templates/githubwebhook.ingress.yaml | 47 + .../templates/githubwebhook.pdb.yaml | 19 + .../templates/githubwebhook.role.yaml | 90 + .../templates/githubwebhook.role_binding.yaml | 14 + .../templates/githubwebhook.secrets.yaml | 28 + .../templates/githubwebhook.service.yaml | 32 + .../githubwebhook.serviceMonitor.yaml | 25 + .../githubwebhook.serviceaccount.yaml | 15 + .../templates/leader_election_role.yaml | 33 + .../leader_election_role_binding.yaml | 13 + .../templates/manager_role.yaml | 306 + .../templates/manager_role_binding.yaml | 12 + .../manager_role_binding_secrets.yaml | 21 + .../templates/manager_role_secrets.yaml | 24 + .../templates/manager_secrets.yaml | 32 + .../templates/runner_editor_role.yaml | 26 + .../templates/runner_viewer_role.yaml | 20 + .../templates/serviceaccount.yaml | 13 + .../templates/webhook_configs.yaml | 261 + .../templates/webhook_service.yaml | 20 + helm/actions-runner-controller/values.yaml | 394 + helm/airflow/.gitignore | 9 + helm/airflow/.helmignore | 42 + helm/airflow/Chart.lock | 6 + helm/airflow/Chart.yaml | 137 + helm/airflow/INSTALL | 14 + helm/airflow/LICENSE | 201 + helm/airflow/NOTICE | 17 + helm/airflow/README.md | 63 + helm/airflow/RELEASE_NOTES.rst | 749 ++ helm/airflow/charts/postgresql-12.10.0.tgz | Bin 0 -> 61605 bytes helm/airflow/dockerfiles/README.md | 28 + .../dockerfiles/pgbouncer-exporter/Dockerfile | 57 + .../pgbouncer-exporter/build_and_push.sh | 68 + helm/airflow/dockerfiles/pgbouncer/Dockerfile | 77 + .../dockerfiles/pgbouncer/build_and_push.sh | 69 + .../pod-template-file.kubernetes-helm-yaml | 141 + helm/airflow/files/statsd-mappings.yml | 87 + .../newsfragments/31066.significant.rst | 23 + .../newsfragments/33747.significant.rst | 3 + .../newsfragments/33748.significant.rst | 3 + .../newsfragments/34186.significant.rst | 3 + helm/airflow/newsfragments/config.toml | 50 + helm/airflow/override_values.yaml | 197 + helm/airflow/templates/NOTES.txt | 206 + helm/airflow/templates/_helpers.yaml | 985 ++ helm/airflow/templates/check-values.yaml | 64 + .../templates/cleanup/cleanup-cronjob.yaml | 109 + .../cleanup/cleanup-serviceaccount.yaml | 40 + .../templates/configmaps/configmap.yaml | 74 + .../configmaps/extra-configmaps.yaml | 53 + .../configmaps/statsd-configmap.yaml | 52 + .../configmaps/webserver-configmap.yaml | 44 + .../dag-processor-deployment.yaml | 261 + .../dag-processor-serviceaccount.yaml | 43 + .../dags-persistent-volume-claim.yaml | 52 + .../templates/flower/flower-deployment.yaml | 169 + .../templates/flower/flower-ingress.yaml | 94 + .../flower/flower-networkpolicy.yaml | 60 + .../templates/flower/flower-service.yaml | 61 + .../flower/flower-serviceaccount.yaml | 41 + .../jobs/create-user-job-serviceaccount.yaml | 41 + .../templates/jobs/create-user-job.yaml | 134 + .../migrate-database-job-serviceaccount.yaml | 41 + .../templates/jobs/migrate-database-job.yaml | 135 + helm/airflow/templates/limitrange.yaml | 39 + .../logs-persistent-volume-claim.yaml | 52 + .../pgbouncer/pgbouncer-deployment.yaml | 212 + .../pgbouncer/pgbouncer-networkpolicy.yaml | 77 + .../pgbouncer-poddisruptionbudget.yaml | 44 + .../pgbouncer/pgbouncer-service.yaml | 56 + .../pgbouncer/pgbouncer-serviceaccount.yaml | 41 + .../priorityclasses/priority-classes.yaml | 34 + .../templates/rbac/pod-cleanup-role.yaml | 44 + .../rbac/pod-cleanup-rolebinding.yaml | 44 + .../templates/rbac/pod-launcher-role.yaml | 74 + .../rbac/pod-launcher-rolebinding.yaml | 64 + .../templates/rbac/pod-log-reader-role.yaml | 59 + .../rbac/pod-log-reader-rolebinding.yaml | 62 + ...curity-context-constraint-rolebinding.yaml | 88 + .../templates/redis/redis-networkpolicy.yaml | 65 + .../templates/redis/redis-service.yaml | 48 + .../templates/redis/redis-serviceaccount.yaml | 41 + .../templates/redis/redis-statefulset.yaml | 126 + helm/airflow/templates/resourcequota.yaml | 39 + .../scheduler/scheduler-deployment.yaml | 339 + .../scheduler/scheduler-networkpolicy.yaml | 57 + .../scheduler-poddisruptionbudget.yaml | 44 + .../scheduler/scheduler-service.yaml | 48 + .../scheduler/scheduler-serviceaccount.yaml | 44 + .../secrets/elasticsearch-secret.yaml | 44 + .../templates/secrets/extra-secrets.yaml | 62 + .../templates/secrets/fernetkey-secret.yaml | 44 + .../templates/secrets/flower-secret.yaml | 38 + .../secrets/kerberos-keytab-secret.yaml | 40 + .../secrets/metadata-connection-secret.yaml | 53 + .../pgbouncer-certificates-secret.yaml | 46 + .../secrets/pgbouncer-config-secret.yaml | 41 + .../secrets/pgbouncer-stats-secret.yaml | 40 + .../templates/secrets/redis-secrets.yaml | 83 + .../templates/secrets/registry-secret.yaml | 38 + .../result-backend-connection-secret.yaml | 50 + .../secrets/webserver-secret-key-secret.yaml | 41 + .../templates/statsd/statsd-deployment.yaml | 138 + .../statsd/statsd-networkpolicy.yaml | 59 + .../templates/statsd/statsd-service.yaml | 58 + .../statsd/statsd-serviceaccount.yaml | 41 + .../triggerer/triggerer-deployment.yaml | 312 + .../triggerer/triggerer-kedaautoscaler.yaml | 57 + .../triggerer/triggerer-networkpolicy.yaml | 60 + .../triggerer/triggerer-service.yaml | 51 + .../triggerer/triggerer-serviceaccount.yaml | 43 + .../webserver/webserver-deployment.yaml | 297 + .../webserver/webserver-ingress.yaml | 111 + .../webserver/webserver-networkpolicy.yaml | 57 + .../webserver-poddisruptionbudget.yaml | 44 + .../webserver/webserver-service.yaml | 56 + .../webserver/webserver-serviceaccount.yaml | 41 + .../templates/workers/worker-deployment.yaml | 412 + .../workers/worker-kedaautoscaler.yaml | 59 + .../workers/worker-networkpolicy.yaml | 55 + .../templates/workers/worker-service.yaml | 48 + .../workers/worker-serviceaccount.yaml | 41 + helm/airflow/values.schema.json | 10226 +++++++++++++++ helm/airflow/values.yaml | 2471 ++++ helm/airflow/values_schema.schema.json | 104 + helm/argo-cd/.helmignore | 4 + helm/argo-cd/Chart.lock | 6 + helm/argo-cd/Chart.yaml | 27 + helm/argo-cd/README.md | 1176 ++ helm/argo-cd/README.md.gotmpl | 548 + helm/argo-cd/charts/redis-ha-4.22.4.tgz | Bin 0 -> 30769 bytes helm/argo-cd/ci/default-values.yaml | 3 + helm/argo-cd/ci/external-redis-values.yaml | 12 + helm/argo-cd/ci/ha-autoscaling-values.yaml | 16 + helm/argo-cd/ci/ha-static-values.yaml | 12 + helm/argo-cd/override-values.yaml | 29 + helm/argo-cd/templates/NOTES.txt | 143 + helm/argo-cd/templates/_common.tpl | 122 + helm/argo-cd/templates/_helpers.tpl | 215 + helm/argo-cd/templates/_versions.tpl | 52 + helm/argo-cd/templates/aggregate-roles.yaml | 85 + .../clusterrole.yaml | 24 + .../clusterrolebinding.yaml | 17 + .../metrics.yaml | 25 + .../networkpolicy.yaml | 19 + .../argocd-application-controller/pdb.yaml | 26 + .../prometheusrule.yaml | 26 + .../argocd-application-controller/role.yaml | 36 + .../rolebinding.yaml | 14 + .../serviceaccount.yaml | 18 + .../servicemonitor.yaml | 49 + .../statefulset.yaml | 320 + .../argocd-applicationset/deployment.yaml | 249 + .../argocd-applicationset/metrics.yaml | 25 + .../argocd-applicationset/networkpolicy.yaml | 25 + .../templates/argocd-applicationset/pdb.yaml | 26 + .../templates/argocd-applicationset/role.yaml | 88 + .../argocd-applicationset/rolebinding.yaml | 16 + .../argocd-applicationset/service.yaml | 24 + .../argocd-applicationset/serviceaccount.yaml | 18 + .../argocd-applicationset/servicemonitor.yaml | 51 + .../webhook-ingress.yaml | 72 + .../templates/argocd-configs/argocd-cm.yaml | 16 + .../argocd-configs/argocd-cmd-params-cm.yaml | 14 + .../argocd-configs/argocd-cmp-cm.yaml | 24 + .../argocd-dex-server-tls-secret.yaml | 24 + .../argocd-configs/argocd-gpg-keys-cm.yaml | 16 + .../argocd-notifications-cm.yaml | 27 + .../argocd-notifications-secret.yaml | 19 + .../argocd-configs/argocd-rbac-cm.yaml | 18 + .../argocd-repo-server-tls-secret.yaml | 24 + .../argocd-configs/argocd-secret.yaml | 48 + .../argocd-server-tls-secret.yaml | 21 + .../argocd-ssh-known-hosts-cm.yaml | 22 + .../argocd-configs/argocd-styles-cm.yaml | 11 + .../argocd-configs/argocd-tls-certs-cm.yaml | 22 + .../argocd-configs/cluster-secrets.yaml | 31 + .../argocd-configs/externalredis-secret.yaml | 22 + .../repository-credentials-secret.yaml | 20 + .../argocd-configs/repository-secret.yaml | 20 + .../argocd-notifications/deployment.yaml | 144 + .../argocd-notifications/metrics.yaml | 25 + .../argocd-notifications/networkpolicy.yaml | 19 + .../templates/argocd-notifications/pdb.yaml | 26 + .../templates/argocd-notifications/role.yaml | 44 + .../argocd-notifications/rolebinding.yaml | 16 + .../argocd-notifications/serviceaccount.yaml | 18 + .../argocd-notifications/servicemonitor.yaml | 52 + .../argocd-repo-server/clusterrole.yaml | 24 + .../clusterrolebinding.yaml | 17 + .../argocd-repo-server/deployment.yaml | 363 + .../templates/argocd-repo-server/hpa.yaml | 44 + .../templates/argocd-repo-server/metrics.yaml | 25 + .../argocd-repo-server/networkpolicy.yaml | 41 + .../templates/argocd-repo-server/pdb.yaml | 26 + .../templates/argocd-repo-server/role.yaml | 12 + .../argocd-repo-server/rolebinding.yaml | 16 + .../templates/argocd-repo-server/service.yaml | 23 + .../argocd-repo-server/serviceaccount.yaml | 18 + .../argocd-repo-server/servicemonitor.yaml | 49 + .../templates/argocd-server/aws/service.yaml | 24 + .../templates/argocd-server/certificate.yaml | 32 + .../templates/argocd-server/clusterrole.yaml | 48 + .../argocd-server/clusterrolebinding.yaml | 17 + .../templates/argocd-server/deployment.yaml | 429 + .../argocd-server/gke/backendconfig.yaml | 10 + .../argocd-server/gke/frontendconfig.yaml | 10 + .../argocd-server/gke/managedcertificate.yaml | 11 + helm/argo-cd/templates/argocd-server/hpa.yaml | 44 + .../templates/argocd-server/ingress-grpc.yaml | 72 + .../templates/argocd-server/ingress.yaml | 89 + .../templates/argocd-server/metrics.yaml | 25 + .../argocd-server/networkpolicy.yaml | 16 + .../argocd-server/openshift/route.yaml | 26 + helm/argo-cd/templates/argocd-server/pdb.yaml | 26 + .../argo-cd/templates/argocd-server/role.yaml | 52 + .../templates/argocd-server/rolebinding.yaml | 14 + .../templates/argocd-server/service.yaml | 52 + .../argocd-server/serviceaccount.yaml | 18 + .../argocd-server/servicemonitor.yaml | 49 + .../templates/crds/crd-application.yaml | 4021 ++++++ .../templates/crds/crd-applicationset.yaml | 10775 ++++++++++++++++ .../argo-cd/templates/crds/crd-extension.yaml | 104 + helm/argo-cd/templates/crds/crd-project.yaml | 331 + helm/argo-cd/templates/dex/deployment.yaml | 196 + helm/argo-cd/templates/dex/networkpolicy.yaml | 31 + helm/argo-cd/templates/dex/pdb.yaml | 26 + helm/argo-cd/templates/dex/role.yaml | 18 + helm/argo-cd/templates/dex/rolebinding.yaml | 16 + helm/argo-cd/templates/dex/service.yaml | 35 + .../argo-cd/templates/dex/serviceaccount.yaml | 15 + .../argo-cd/templates/dex/servicemonitor.yaml | 49 + helm/argo-cd/templates/extra-manifests.yaml | 4 + .../templates/networkpolicy-default-deny.yaml | 12 + helm/argo-cd/templates/redis/deployment.yaml | 143 + helm/argo-cd/templates/redis/metrics.yaml | 30 + .../templates/redis/networkpolicy.yaml | 36 + helm/argo-cd/templates/redis/pdb.yaml | 27 + helm/argo-cd/templates/redis/service.yaml | 25 + .../templates/redis/serviceaccount.yaml | 15 + .../templates/redis/servicemonitor.yaml | 50 + helm/argo-cd/values.yaml | 3050 +++++ helm/argo-workflows/.helmignore | 23 + helm/argo-workflows/Chart.yaml | 20 + .../Lab/credentails/aws-secret.yaml | 10 + .../Lab/credentails/git-secret.yaml | 8 + .../Lab/credentails/kubeconfig.yaml | 18 + .../Lab/credentails/my-kubeconfig.yaml | 8 + .../Lab/db-backup/bastion-ssh-key.yaml | 8 + .../Lab/db-backup/db-backup-cron.yaml | 71 + .../Lab/db-backup/db-creds.yaml | 11 + .../Lab/db-backup/test-workflow.yaml | 92 + helm/argo-workflows/Lab/script.sh | 190 + .../steampipe-dashboard/00_Old/test-pod.yaml | 11 + .../00_Old/test-workflow.yaml | 112 + .../cron-steampipe-report.yaml | 143 + .../steampipe_configmap.yaml | 200 + .../steampipe-dsk-iac/00_Old/test-pod.yaml | 11 + .../00_Old/test-workflow.yaml | 112 + .../Lab/steampipe-dsk-iac/cron-steampipe.yaml | 115 + .../steampipe_configmap.yaml | 200 + helm/argo-workflows/Lab/steampipe.yaml | 34 + helm/argo-workflows/Lab/test.sh | 6 + .../Lab/ui-monitoring/cron_ui_monitoring.yaml | 49 + .../ui-monitoring/cron_ui_monitoring.yaml_bak | 37 + .../test/cron_ui_monitoring.yaml | 62 + .../ui_monitoring_configmap.yaml | 16 + helm/argo-workflows/README.md | 376 + helm/argo-workflows/override_values.yaml | 38 + helm/argo-workflows/templates/NOTES.txt | 7 + helm/argo-workflows/templates/_helpers.tpl | 181 + .../artifact-repository-ref-cm.yaml | 19 + .../controller/workflow-aggregate-roles.yaml | 91 + .../workflow-controller-cluster-roles.yaml | 220 + .../workflow-controller-config-map.yaml | 193 + .../controller/workflow-controller-crb.yaml | 45 + .../workflow-controller-deployment-pdb.yaml | 20 + .../workflow-controller-deployment.yaml | 129 + .../controller/workflow-controller-sa.yaml | 16 + .../workflow-controller-service.yaml | 39 + .../workflow-controller-servicemonitor.yaml | 50 + .../templates/controller/workflow-rb.yaml | 24 + .../templates/controller/workflow-role.yaml | 58 + .../templates/controller/workflow-sa.yaml | 25 + .../argoproj.io_clusterworkflowtemplates.yaml | 47 + .../crds/argoproj.io_cronworkflows.yaml | 49 + .../argoproj.io_workflowartifactgctasks.yaml | 50 + .../argoproj.io_workfloweventbindings.yaml | 44 + .../templates/crds/argoproj.io_workflows.yaml | 64 + .../crds/argoproj.io_workflowtaskresults.yaml | 593 + .../crds/argoproj.io_workflowtasksets.yaml | 50 + .../crds/argoproj.io_workflowtemplates.yaml | 44 + .../templates/extra-manifests.yaml | 8 + .../templates/server/gke/backendconfig.yaml | 11 + .../templates/server/gke/frontendconfig.yaml | 11 + .../server/gke/managedcertificate.yaml | 12 + .../server/server-cluster-roles.yaml | 145 + .../templates/server/server-crb.yaml | 45 + .../server/server-deployment-hpa.yaml | 45 + .../server/server-deployment-pdb.yaml | 20 + .../templates/server/server-deployment.yaml | 139 + .../templates/server/server-ingress.yaml | 90 + .../templates/server/server-sa.yaml | 16 + .../templates/server/server-service.yaml | 35 + helm/argo-workflows/values.yaml | 841 ++ helm/awx-operator/.helmignore | 23 + helm/awx-operator/Chart.yaml | 6 + helm/awx-operator/README.md | 67 + ...definition-awxbackups.awx.ansible.com.yaml | 127 + ...efinition-awxrestores.awx.ansible.com.yaml | 127 + ...sourcedefinition-awxs.awx.ansible.com.yaml | 1797 +++ helm/awx-operator/templates/NOTES.txt | 1 + helm/awx-operator/templates/_helpers.tpl | 6 + helm/awx-operator/templates/awx-deploy.yaml | 24 + ...usterrole-awx-operator-metrics-reader.yaml | 11 + .../clusterrole-awx-operator-proxy-role.yaml | 19 + ...inding-awx-operator-proxy-rolebinding.yaml | 14 + ...igmap-awx-operator-awx-manager-config.yaml | 28 + ...yment-awx-operator-controller-manager.yaml | 91 + .../templates/postgres-config.yaml | 18 + .../role-awx-operator-awx-manager-role.yaml | 127 + ...ole-awx-operator-leader-election-role.yaml | 38 + ...-awx-operator-awx-manager-rolebinding.yaml | 14 + ...-operator-leader-election-rolebinding.yaml | 14 + ...or-controller-manager-metrics-service.yaml | 16 + ...count-awx-operator-controller-manager.yaml | 6 + helm/awx-operator/values.yaml | 26 + helm/ghost/.helmignore | 21 + helm/ghost/Chart.lock | 9 + helm/ghost/Chart.yaml | 37 + helm/ghost/README.md | 537 + helm/ghost/charts/common/.helmignore | 22 + helm/ghost/charts/common/Chart.yaml | 23 + helm/ghost/charts/common/README.md | 235 + .../charts/common/templates/_affinities.tpl | 111 + .../charts/common/templates/_capabilities.tpl | 185 + .../ghost/charts/common/templates/_errors.tpl | 28 + .../ghost/charts/common/templates/_images.tpl | 85 + .../charts/common/templates/_ingress.tpl | 73 + .../ghost/charts/common/templates/_labels.tpl | 23 + helm/ghost/charts/common/templates/_names.tpl | 71 + .../charts/common/templates/_secrets.tpl | 172 + .../charts/common/templates/_storage.tpl | 28 + .../charts/common/templates/_tplvalues.tpl | 27 + helm/ghost/charts/common/templates/_utils.tpl | 67 + .../charts/common/templates/_warnings.tpl | 19 + .../templates/validations/_cassandra.tpl | 77 + .../common/templates/validations/_mariadb.tpl | 108 + .../common/templates/validations/_mongodb.tpl | 113 + .../common/templates/validations/_mysql.tpl | 108 + .../templates/validations/_postgresql.tpl | 134 + .../common/templates/validations/_redis.tpl | 81 + .../templates/validations/_validations.tpl | 51 + helm/ghost/charts/common/values.yaml | 8 + helm/ghost/charts/mysql/.helmignore | 21 + helm/ghost/charts/mysql/Chart.lock | 6 + helm/ghost/charts/mysql/Chart.yaml | 28 + helm/ghost/charts/mysql/README.md | 552 + .../charts/mysql/charts/common/.helmignore | 22 + .../charts/mysql/charts/common/Chart.yaml | 23 + .../charts/mysql/charts/common/README.md | 235 + .../charts/common/templates/_affinities.tpl | 111 + .../charts/common/templates/_capabilities.tpl | 185 + .../mysql/charts/common/templates/_errors.tpl | 28 + .../mysql/charts/common/templates/_images.tpl | 85 + .../charts/common/templates/_ingress.tpl | 73 + .../mysql/charts/common/templates/_labels.tpl | 23 + .../mysql/charts/common/templates/_names.tpl | 71 + .../charts/common/templates/_secrets.tpl | 172 + .../charts/common/templates/_storage.tpl | 28 + .../charts/common/templates/_tplvalues.tpl | 27 + .../mysql/charts/common/templates/_utils.tpl | 67 + .../charts/common/templates/_warnings.tpl | 19 + .../templates/validations/_cassandra.tpl | 77 + .../common/templates/validations/_mariadb.tpl | 108 + .../common/templates/validations/_mongodb.tpl | 113 + .../common/templates/validations/_mysql.tpl | 108 + .../templates/validations/_postgresql.tpl | 134 + .../common/templates/validations/_redis.tpl | 81 + .../templates/validations/_validations.tpl | 51 + .../charts/mysql/charts/common/values.yaml | 8 + helm/ghost/charts/mysql/templates/NOTES.txt | 75 + .../ghost/charts/mysql/templates/_helpers.tpl | 166 + .../charts/mysql/templates/extra-list.yaml | 9 + .../charts/mysql/templates/metrics-svc.yaml | 37 + .../charts/mysql/templates/networkpolicy.yaml | 45 + .../mysql/templates/primary/configmap.yaml | 23 + .../primary/initialization-configmap.yaml | 22 + .../charts/mysql/templates/primary/pdb.yaml | 30 + .../mysql/templates/primary/statefulset.yaml | 393 + .../mysql/templates/primary/svc-headless.yaml | 34 + .../charts/mysql/templates/primary/svc.yaml | 57 + .../mysql/templates/prometheusrule.yaml | 27 + helm/ghost/charts/mysql/templates/role.yaml | 29 + .../charts/mysql/templates/rolebinding.yaml | 26 + .../mysql/templates/secondary/configmap.yaml | 23 + .../charts/mysql/templates/secondary/pdb.yaml | 30 + .../templates/secondary/statefulset.yaml | 374 + .../templates/secondary/svc-headless.yaml | 36 + .../charts/mysql/templates/secondary/svc.yaml | 59 + .../ghost/charts/mysql/templates/secrets.yaml | 83 + .../mysql/templates/serviceaccount.yaml | 28 + .../mysql/templates/servicemonitor.yaml | 54 + helm/ghost/charts/mysql/values.schema.json | 195 + helm/ghost/charts/mysql/values.yaml | 1248 ++ helm/ghost/override_values_blog.yaml | 51 + helm/ghost/override_values_docs.yaml | 43 + helm/ghost/templates/NOTES.txt | 149 + helm/ghost/templates/_helpers.tpl | 164 + helm/ghost/templates/deployment.yaml | 302 + helm/ghost/templates/external-db-secrets.yaml | 24 + helm/ghost/templates/extra-list.yaml | 9 + helm/ghost/templates/ingress.yaml | 71 + .../networkpolicy-backend-ingress.yaml | 33 + .../ghost/templates/networkpolicy-egress.yaml | 38 + .../templates/networkpolicy-ingress.yaml | 53 + helm/ghost/templates/pvc.yaml | 39 + helm/ghost/templates/secrets.yaml | 33 + helm/ghost/templates/service-account.yaml | 25 + helm/ghost/templates/svc.yaml | 71 + helm/ghost/templates/tls-secrets.yaml | 50 + helm/ghost/values.schema.json | 186 + helm/ghost/values.yaml | 765 ++ helm/grafana/.helmignore | 23 + helm/grafana/Chart.yaml | 22 + helm/grafana/README.md | 651 + helm/grafana/ci/default-values.yaml | 1 + helm/grafana/ci/with-affinity-values.yaml | 16 + .../ci/with-dashboard-json-values.yaml | 53 + helm/grafana/ci/with-dashboard-values.yaml | 19 + .../ci/with-extraconfigmapmounts-values.yaml | 7 + .../ci/with-image-renderer-values.yaml | 19 + helm/grafana/ci/with-persistence.yaml | 3 + helm/grafana/dashboards/custom-dashboard.json | 1 + helm/grafana/templates/NOTES.txt | 54 + helm/grafana/templates/_helpers.tpl | 201 + helm/grafana/templates/_pod.tpl | 1159 ++ helm/grafana/templates/clusterrole.yaml | 25 + .../grafana/templates/clusterrolebinding.yaml | 24 + .../configmap-dashboard-provider.yaml | 29 + helm/grafana/templates/configmap.yaml | 134 + .../templates/dashboards-json-configmap.yaml | 35 + helm/grafana/templates/deployment.yaml | 50 + helm/grafana/templates/extra-manifests.yaml | 4 + helm/grafana/templates/headless-service.yaml | 22 + helm/grafana/templates/hpa.yaml | 52 + .../templates/image-renderer-deployment.yaml | 125 + .../grafana/templates/image-renderer-hpa.yaml | 47 + .../image-renderer-network-policy.yaml | 79 + .../templates/image-renderer-service.yaml | 31 + .../image-renderer-servicemonitor.yaml | 48 + helm/grafana/templates/ingress.yaml | 78 + helm/grafana/templates/networkpolicy.yaml | 52 + .../templates/poddisruptionbudget.yaml | 22 + helm/grafana/templates/podsecuritypolicy.yaml | 49 + helm/grafana/templates/pvc.yaml | 36 + helm/grafana/templates/role.yaml | 32 + helm/grafana/templates/rolebinding.yaml | 25 + helm/grafana/templates/secret-env.yaml | 14 + helm/grafana/templates/secret.yaml | 26 + helm/grafana/templates/service.yaml | 60 + helm/grafana/templates/serviceaccount.yaml | 17 + helm/grafana/templates/servicemonitor.yaml | 48 + helm/grafana/templates/statefulset.yaml | 55 + .../templates/tests/test-configmap.yaml | 20 + .../tests/test-podsecuritypolicy.yaml | 32 + helm/grafana/templates/tests/test-role.yaml | 17 + .../templates/tests/test-rolebinding.yaml | 20 + .../templates/tests/test-serviceaccount.yaml | 12 + helm/grafana/templates/tests/test.yaml | 49 + helm/grafana/values.yaml | 1223 ++ helm/jenkins/.helmignore | 26 + helm/jenkins/CHANGELOG.md | 2451 ++++ helm/jenkins/Chart.yaml | 38 + helm/jenkins/README.md | 1044 ++ helm/jenkins/Tiltfile | 5 + helm/jenkins/VALUES_SUMMARY.md | 400 + helm/jenkins/ci/default-values.yaml | 5 + helm/jenkins/ci/other-values.yaml | 95 + helm/jenkins/ci/with-secrets-values.yaml | 4 + helm/jenkins/override_values.yaml | 132 + helm/jenkins/templates/NOTES.txt | 68 + helm/jenkins/templates/_helpers.tpl | 448 + .../templates/config-init-scripts.yaml | 18 + helm/jenkins/templates/config.yaml | 86 + helm/jenkins/templates/deprecation.yaml | 115 + helm/jenkins/templates/home-pvc.yaml | 37 + helm/jenkins/templates/jcasc-config.yaml | 45 + helm/jenkins/templates/jenkins-agent-svc.yaml | 43 + .../jenkins-aws-security-group-policies.yaml | 16 + .../templates/jenkins-backup-cronjob.yaml | 168 + .../templates/jenkins-backup-rbac.yaml | 64 + .../jenkins-controller-alerting-rules.yaml | 26 + .../jenkins-controller-backendconfig.yaml | 24 + .../templates/jenkins-controller-ingress.yaml | 77 + .../jenkins-controller-networkpolicy.yaml | 76 + .../templates/jenkins-controller-pdb.yaml | 34 + .../jenkins-controller-podmonitor.yaml | 30 + .../templates/jenkins-controller-route.yaml | 34 + .../jenkins-controller-secondary-ingress.yaml | 56 + .../jenkins-controller-servicemonitor.yaml | 40 + .../jenkins-controller-statefulset.yaml | 436 + .../templates/jenkins-controller-svc.yaml | 56 + helm/jenkins/templates/rbac.yaml | 149 + helm/jenkins/templates/secret-additional.yaml | 21 + helm/jenkins/templates/secret-claims.yaml | 29 + helm/jenkins/templates/secret-https-jks.yaml | 20 + helm/jenkins/templates/secret.yaml | 20 + .../templates/service-account-agent.yaml | 23 + helm/jenkins/templates/service-account.yaml | 23 + .../jenkins/templates/tests/jenkins-test.yaml | 49 + helm/jenkins/templates/tests/test-config.yaml | 14 + ...kins-controller-statefulset-test.yaml.snap | 5 + .../unittests/config-init-scripts-test.yaml | 19 + helm/jenkins/unittests/config-test.yaml | 128 + helm/jenkins/unittests/home-pvc-test.yaml | 94 + helm/jenkins/unittests/jcasc-config-test.yaml | 2636 ++++ .../unittests/jenkins-agent-svc-test.yaml | 130 + .../jenkins-backup-cronjob-test.yaml | 62 + ...enkins-controller-alerting-rules-test.yaml | 79 + .../jenkins-controller-ingress-1.19-test.yaml | 148 + .../jenkins-controller-ingress-test.yaml | 145 + ...jenkins-controller-networkpolicy-test.yaml | 94 + .../jenkins-controller-pdb-1.21-test.yaml | 44 + .../jenkins-controller-pdb-test.yaml | 57 + ...ontroller-secondary-ingress-1.19-test.yaml | 78 + ...ins-controller-secondary-ingress-test.yaml | 76 + ...enkins-controller-servicemonitor_test.yaml | 82 + .../jenkins-controller-statefulset-test.yaml | 700 + .../jenkins-controller-svc-test.yaml | 158 + helm/jenkins/unittests/rbac-test.yaml | 217 + .../unittests/secret-additional-test.yaml | 41 + .../jenkins/unittests/secret-claims-test.yaml | 82 + .../unittests/secret-existing-test.yaml | 52 + helm/jenkins/unittests/secret-test.yaml | 65 + .../unittests/service-account-agent-test.yaml | 83 + .../unittests/service-account-test.yaml | 58 + helm/jenkins/values.yaml | 950 ++ helm/nexus-repository-manager/.helmignore | 24 + helm/nexus-repository-manager/Chart.yaml | 24 + helm/nexus-repository-manager/LICENSE | 13 + helm/nexus-repository-manager/README.md | 236 + .../override-values.yaml | 39 + .../templates/NOTES.txt | 27 + .../templates/_helpers.tpl | 63 + .../templates/configmap-properties.yaml | 17 + .../templates/configmap.yaml | 15 + .../templates/deployment.yaml | 163 + .../templates/ingress.yaml | 85 + .../templates/proxy-route.yaml | 23 + .../templates/pv.yaml | 26 + .../templates/pvc.yaml | 30 + .../templates/route.yaml | 27 + .../templates/secret.yaml | 15 + .../templates/service.yaml | 69 + .../templates/serviceaccount.yaml | 15 + helm/nexus-repository-manager/values.yaml | 184 + helm/nfs-provisioner-nas/Chart.yaml | 13 + helm/nfs-provisioner-nas/README.md | 99 + helm/nfs-provisioner-nas/ci/test-values.yaml | 5 + helm/nfs-provisioner-nas/override-values.yaml | 17 + .../templates/_helpers.tpl | 92 + .../templates/clusterrole.yaml | 30 + .../templates/clusterrolebinding.yaml | 16 + .../templates/deployment.yaml | 83 + .../templates/persistentvolume.yaml | 26 + .../templates/persistentvolumeclaim.yaml | 19 + .../templates/podsecuritypolicy.yaml | 29 + helm/nfs-provisioner-nas/templates/role.yaml | 18 + .../templates/rolebinding.yaml | 16 + .../templates/serviceaccount.yaml | 12 + .../templates/storageclass.yaml | 33 + helm/nfs-provisioner-nas/test/configmap.yaml | 52 + helm/nfs-provisioner-nas/test/deployment.yaml | 42 + helm/nfs-provisioner-nas/test/pvc.yaml | 11 + helm/nfs-provisioner-nas/values.yaml | 110 + helm/openebs/Chart.lock | 27 + helm/openebs/Chart.yaml | 57 + helm/openebs/OWNERS | 6 + helm/openebs/README.md | 204 + helm/openebs/charts/cstor/.helmignore | 23 + helm/openebs/charts/cstor/Chart.lock | 6 + helm/openebs/charts/cstor/Chart.yaml | 29 + helm/openebs/charts/cstor/README.md | 251 + .../cstor/charts/openebs-ndm/Chart.yaml | 23 + .../charts/cstor/charts/openebs-ndm/README.md | 93 + .../charts/openebs-ndm/crds/blockdevice.yaml | 241 + .../openebs-ndm/crds/blockdeviceclaim.yaml | 144 + .../charts/openebs-ndm/templates/NOTES.txt | 8 + .../charts/openebs-ndm/templates/_helpers.tpl | 242 + .../templates/cluster-exporter-service.yaml | 18 + .../templates/cluster-exporter.yaml | 60 + .../openebs-ndm/templates/configmap.yaml | 45 + .../openebs-ndm/templates/daemonset.yaml | 179 + .../openebs-ndm/templates/deployment.yaml | 87 + .../templates/node-exporter-service.yaml | 18 + .../openebs-ndm/templates/node-exporter.yaml | 62 + .../charts/openebs-ndm/templates/rbac.yaml | 44 + .../cstor/charts/openebs-ndm/values.yaml | 156 + .../charts/cstor/crds/cstorbackup.yaml | 87 + .../cstor/crds/cstorcompletedbackup.yaml | 74 + .../charts/cstor/crds/cstorpoolcluster.yaml | 485 + .../charts/cstor/crds/cstorpoolinstance.yaml | 449 + .../charts/cstor/crds/cstorrestore.yaml | 100 + .../charts/cstor/crds/cstorvolume.yaml | 265 + .../cstor/crds/cstorvolumeattachment.yaml | 122 + .../charts/cstor/crds/cstorvolumeconfig.yaml | 758 ++ .../charts/cstor/crds/cstorvolumepolicy.yaml | 536 + .../charts/cstor/crds/cstorvolumereplica.yaml | 210 + .../charts/cstor/crds/migrationtask.yaml | 128 + .../charts/cstor/crds/upgradetask.yaml | 257 + .../charts/cstor/crds/volumesnapshot.yaml | 312 + .../cstor/crds/volumesnapshotclass.yaml | 135 + .../cstor/crds/volumesnapshotcontent.yaml | 402 + helm/openebs/charts/cstor/templates/NOTES.txt | 11 + .../charts/cstor/templates/_helpers.tpl | 217 + .../cstor/templates/admission-server.yaml | 59 + .../cstor/templates/cleanup-webhook.yaml | 39 + .../cstor/templates/csi-controller-rbac.yaml | 196 + .../cstor/templates/csi-controller.yaml | 137 + .../charts/cstor/templates/csi-driver.yaml | 16 + .../cstor/templates/csi-iscsiadm-config.yaml | 18 + .../charts/cstor/templates/csi-node-rbac.yaml | 73 + .../charts/cstor/templates/csi-node.yaml | 143 + .../charts/cstor/templates/cspc-operator.yaml | 90 + .../cstor/templates/cvc-operator-service.yaml | 15 + .../charts/cstor/templates/cvc-operator.yaml | 80 + .../cstor/templates/priority-class.yaml | 19 + helm/openebs/charts/cstor/templates/psp.yaml | 24 + helm/openebs/charts/cstor/templates/rbac.yaml | 117 + .../cstor/templates/snapshot-class.yaml | 14 + helm/openebs/charts/cstor/values.yaml | 256 + helm/openebs/charts/jiva/.helmignore | 23 + helm/openebs/charts/jiva/Chart.lock | 6 + helm/openebs/charts/jiva/Chart.yaml | 29 + helm/openebs/charts/jiva/README.md | 218 + .../charts/localpv-provisioner/.helmignore | 23 + .../charts/localpv-provisioner/Chart.lock | 6 + .../charts/localpv-provisioner/Chart.yaml | 27 + .../jiva/charts/localpv-provisioner/README.md | 160 + .../charts/openebs-ndm/Chart.yaml | 23 + .../charts/openebs-ndm/README.md | 93 + .../charts/openebs-ndm/crds/blockdevice.yaml | 241 + .../openebs-ndm/crds/blockdeviceclaim.yaml | 144 + .../charts/openebs-ndm/templates/NOTES.txt | 8 + .../charts/openebs-ndm/templates/_helpers.tpl | 242 + .../templates/cluster-exporter-service.yaml | 18 + .../templates/cluster-exporter.yaml | 60 + .../openebs-ndm/templates/configmap.yaml | 45 + .../openebs-ndm/templates/daemonset.yaml | 179 + .../openebs-ndm/templates/deployment.yaml | 87 + .../templates/node-exporter-service.yaml | 18 + .../openebs-ndm/templates/node-exporter.yaml | 62 + .../charts/openebs-ndm/templates/rbac.yaml | 44 + .../charts/openebs-ndm/values.yaml | 156 + .../localpv-provisioner/templates/NOTES.txt | 12 + .../templates/_helpers.tpl | 79 + .../templates/deployment.yaml | 120 + .../templates/device-class.yaml | 31 + .../templates/hostpath-class.yaml | 40 + .../localpv-provisioner/templates/psp.yaml | 30 + .../localpv-provisioner/templates/rbac.yaml | 99 + .../charts/localpv-provisioner/values.yaml | 171 + .../charts/jiva/crds/jivavolumepolicy.yaml | 2974 +++++ .../openebs/charts/jiva/crds/jivavolumes.yaml | 3300 +++++ .../openebs/charts/jiva/crds/upgradetask.yaml | 257 + helm/openebs/charts/jiva/templates/NOTES.txt | 8 + .../charts/jiva/templates/_helpers.tpl | 150 + .../jiva/templates/csi-controller-rbac.yaml | 196 + .../charts/jiva/templates/csi-controller.yaml | 134 + .../charts/jiva/templates/csi-driver.yaml | 9 + .../jiva/templates/csi-iscsiadm-config.yaml | 18 + .../charts/jiva/templates/csi-node-rbac.yaml | 43 + .../charts/jiva/templates/csi-node.yaml | 165 + .../charts/jiva/templates/default-policy.yaml | 10 + .../jiva/templates/default-storageclass.yaml | 17 + .../jiva/templates/jiva-operator-rbac.yaml | 103 + .../charts/jiva/templates/jiva-operator.yaml | 74 + .../charts/jiva/templates/priority-class.yaml | 19 + helm/openebs/charts/jiva/templates/psp.yaml | 27 + helm/openebs/charts/jiva/values.yaml | 225 + .../charts/localpv-provisioner/.helmignore | 23 + .../charts/localpv-provisioner/Chart.lock | 6 + .../charts/localpv-provisioner/Chart.yaml | 27 + .../charts/localpv-provisioner/README.md | 160 + .../charts/openebs-ndm/Chart.yaml | 23 + .../charts/openebs-ndm/README.md | 93 + .../charts/openebs-ndm/crds/blockdevice.yaml | 241 + .../openebs-ndm/crds/blockdeviceclaim.yaml | 144 + .../charts/openebs-ndm/templates/NOTES.txt | 8 + .../charts/openebs-ndm/templates/_helpers.tpl | 242 + .../templates/cluster-exporter-service.yaml | 18 + .../templates/cluster-exporter.yaml | 60 + .../openebs-ndm/templates/configmap.yaml | 45 + .../openebs-ndm/templates/daemonset.yaml | 179 + .../openebs-ndm/templates/deployment.yaml | 87 + .../templates/node-exporter-service.yaml | 18 + .../openebs-ndm/templates/node-exporter.yaml | 62 + .../charts/openebs-ndm/templates/rbac.yaml | 44 + .../charts/openebs-ndm/values.yaml | 156 + .../localpv-provisioner/templates/NOTES.txt | 12 + .../templates/_helpers.tpl | 79 + .../templates/deployment.yaml | 120 + .../templates/device-class.yaml | 31 + .../templates/hostpath-class.yaml | 40 + .../localpv-provisioner/templates/psp.yaml | 30 + .../localpv-provisioner/templates/rbac.yaml | 99 + .../charts/localpv-provisioner/values.yaml | 171 + helm/openebs/charts/lvm-localpv/.helmignore | 23 + helm/openebs/charts/lvm-localpv/Chart.yaml | 23 + helm/openebs/charts/lvm-localpv/README.md | 160 + .../charts/lvm-localpv/crds/lvmnode.yaml | 177 + .../charts/lvm-localpv/crds/lvmsnapshot.yaml | 85 + .../charts/lvm-localpv/crds/lvmvolume.yaml | 153 + .../charts/lvm-localpv/templates/NOTES.txt | 5 + .../charts/lvm-localpv/templates/_helpers.tpl | 138 + .../lvm-localpv/templates/csidriver.yaml | 10 + .../lvm-localpv/templates/lvm-controller.yaml | 159 + .../templates/lvm-node-service.yaml | 18 + .../lvm-localpv/templates/lvm-node.yaml | 158 + .../lvm-localpv/templates/priority-class.yaml | 19 + .../charts/lvm-localpv/templates/psp.yaml | 24 + .../charts/lvm-localpv/templates/rbac.yaml | 197 + .../templates/volumesnapshotclasses-crd.yaml | 136 + .../templates/volumesnapshotcontents-crd.yaml | 403 + .../templates/volumesnapshots-crd.yaml | 314 + helm/openebs/charts/lvm-localpv/values.yaml | 188 + helm/openebs/charts/mayastor/.helmignore | 24 + helm/openebs/charts/mayastor/Chart.lock | 18 + helm/openebs/charts/mayastor/Chart.yaml | 26 + helm/openebs/charts/mayastor/README.md.tmpl | 58 + .../charts/mayastor/charts/etcd/.helmignore | 21 + .../charts/mayastor/charts/etcd/Chart.lock | 6 + .../charts/mayastor/charts/etcd/Chart.yaml | 29 + .../charts/mayastor/charts/etcd/README.md | 545 + .../charts/etcd/charts/common/.helmignore | 22 + .../charts/etcd/charts/common/Chart.yaml | 23 + .../charts/etcd/charts/common/README.md | 351 + .../charts/common/templates/_affinities.tpl | 106 + .../charts/common/templates/_capabilities.tpl | 154 + .../etcd/charts/common/templates/_errors.tpl | 23 + .../etcd/charts/common/templates/_images.tpl | 76 + .../etcd/charts/common/templates/_ingress.tpl | 68 + .../etcd/charts/common/templates/_labels.tpl | 18 + .../etcd/charts/common/templates/_names.tpl | 66 + .../etcd/charts/common/templates/_secrets.tpl | 165 + .../etcd/charts/common/templates/_storage.tpl | 23 + .../charts/common/templates/_tplvalues.tpl | 13 + .../etcd/charts/common/templates/_utils.tpl | 62 + .../charts/common/templates/_warnings.tpl | 14 + .../templates/validations/_cassandra.tpl | 72 + .../common/templates/validations/_mariadb.tpl | 103 + .../common/templates/validations/_mongodb.tpl | 108 + .../common/templates/validations/_mysql.tpl | 103 + .../templates/validations/_postgresql.tpl | 129 + .../common/templates/validations/_redis.tpl | 76 + .../templates/validations/_validations.tpl | 46 + .../charts/etcd/charts/common/values.yaml | 5 + .../mayastor/charts/etcd/templates/NOTES.txt | 119 + .../charts/etcd/templates/_helpers.tpl | 205 + .../charts/etcd/templates/configmap.yaml | 17 + .../charts/etcd/templates/cronjob.yaml | 132 + .../charts/etcd/templates/extra-list.yaml | 4 + .../charts/etcd/templates/networkpolicy.yaml | 81 + .../mayastor/charts/etcd/templates/pdb.yaml | 23 + .../charts/etcd/templates/podmonitor.yaml | 42 + .../charts/etcd/templates/prometheusrule.yaml | 26 + .../charts/etcd/templates/secrets.yaml | 21 + .../charts/etcd/templates/serviceaccount.yaml | 24 + .../charts/etcd/templates/snapshot-pvc.yaml | 21 + .../charts/etcd/templates/statefulset.yaml | 419 + .../charts/etcd/templates/svc-headless.yaml | 42 + .../mayastor/charts/etcd/templates/svc.yaml | 62 + .../charts/etcd/templates/token-secrets.yaml | 14 + .../charts/mayastor/charts/etcd/values.yaml | 887 ++ .../charts/jaeger-operator/.helmignore | 21 + .../charts/jaeger-operator/Chart.yaml | 14 + .../mayastor/charts/jaeger-operator/README.md | 128 + .../charts/jaeger-operator/crds/crd.yaml | 34 + .../jaeger-operator/templates/NOTES.txt | 8 + .../jaeger-operator/templates/_helpers.tpl | 49 + .../jaeger-operator/templates/crds.yaml | 6 + .../jaeger-operator/templates/deployment.yaml | 84 + .../jaeger-operator/templates/jaeger.yaml | 11 + .../charts/jaeger-operator/templates/psp.yaml | 36 + .../templates/role-binding.yaml | 17 + .../jaeger-operator/templates/role.yaml | 231 + .../templates/service-account.yaml | 19 + .../jaeger-operator/templates/service.yaml | 24 + .../charts/jaeger-operator/values.yaml | 69 + .../charts/localpv-provisioner/.helmignore | 23 + .../charts/localpv-provisioner/Chart.lock | 6 + .../charts/localpv-provisioner/Chart.yaml | 27 + .../charts/localpv-provisioner/README.md | 160 + .../charts/openebs-ndm/Chart.yaml | 23 + .../charts/openebs-ndm/README.md | 93 + .../charts/openebs-ndm/crds/blockdevice.yaml | 241 + .../openebs-ndm/crds/blockdeviceclaim.yaml | 144 + .../charts/openebs-ndm/templates/NOTES.txt | 8 + .../charts/openebs-ndm/templates/_helpers.tpl | 242 + .../templates/cluster-exporter-service.yaml | 18 + .../templates/cluster-exporter.yaml | 60 + .../openebs-ndm/templates/configmap.yaml | 45 + .../openebs-ndm/templates/daemonset.yaml | 179 + .../openebs-ndm/templates/deployment.yaml | 87 + .../templates/node-exporter-service.yaml | 18 + .../openebs-ndm/templates/node-exporter.yaml | 62 + .../charts/openebs-ndm/templates/rbac.yaml | 44 + .../charts/openebs-ndm/values.yaml | 156 + .../localpv-provisioner/templates/NOTES.txt | 12 + .../templates/_helpers.tpl | 79 + .../templates/deployment.yaml | 120 + .../templates/device-class.yaml | 31 + .../templates/hostpath-class.yaml | 40 + .../localpv-provisioner/templates/psp.yaml | 30 + .../localpv-provisioner/templates/rbac.yaml | 99 + .../charts/localpv-provisioner/values.yaml | 171 + .../mayastor/charts/loki-stack/.helmignore | 22 + .../mayastor/charts/loki-stack/Chart.yaml | 13 + .../mayastor/charts/loki-stack/README.md | 60 + .../loki-stack/charts/filebeat/.helmignore | 2 + .../loki-stack/charts/filebeat/Chart.yaml | 12 + .../loki-stack/charts/filebeat/Makefile | 1 + .../loki-stack/charts/filebeat/README.md | 271 + .../charts/filebeat/examples/default/Makefile | 13 + .../filebeat/examples/default/README.md | 27 + .../filebeat/examples/default/test/goss.yaml | 47 + .../filebeat/examples/deployment/Makefile | 13 + .../filebeat/examples/deployment/README.md | 27 + .../examples/deployment/test/goss.yaml | 6 + .../filebeat/examples/deployment/values.yaml | 16 + .../charts/filebeat/examples/oss/Makefile | 13 + .../charts/filebeat/examples/oss/README.md | 27 + .../filebeat/examples/oss/test/goss.yaml | 22 + .../charts/filebeat/examples/oss/values.yaml | 22 + .../filebeat/examples/security/Makefile | 13 + .../filebeat/examples/security/README.md | 28 + .../filebeat/examples/security/test/goss.yaml | 9 + .../filebeat/examples/security/values.yaml | 37 + .../charts/filebeat/examples/upgrade/Makefile | 16 + .../filebeat/examples/upgrade/README.md | 21 + .../filebeat/examples/upgrade/test/goss.yaml | 45 + .../filebeat/examples/upgrade/values.yaml | 4 + .../charts/filebeat/templates/NOTES.txt | 2 + .../charts/filebeat/templates/_helpers.tpl | 32 + .../filebeat/templates/clusterrole.yaml | 12 + .../templates/clusterrolebinding.yaml | 19 + .../charts/filebeat/templates/configmap.yaml | 53 + .../charts/filebeat/templates/daemonset.yaml | 201 + .../charts/filebeat/templates/deployment.yaml | 157 + .../charts/filebeat/templates/role.yaml | 14 + .../filebeat/templates/rolebinding.yaml | 19 + .../filebeat/templates/serviceaccount.yaml | 15 + .../loki-stack/charts/filebeat/values.yaml | 243 + .../loki-stack/charts/fluent-bit/.helmignore | 22 + .../loki-stack/charts/fluent-bit/Chart.yaml | 15 + .../loki-stack/charts/fluent-bit/README.md | 126 + .../charts/fluent-bit/templates/NOTES.txt | 11 + .../charts/fluent-bit/templates/_helpers.tpl | 66 + .../fluent-bit/templates/clusterrole.yaml | 17 + .../templates/clusterrolebinding.yaml | 19 + .../fluent-bit/templates/configmap.yaml | 75 + .../fluent-bit/templates/daemonset.yaml | 80 + .../templates/podsecuritypolicy.yaml | 34 + .../charts/fluent-bit/templates/role.yaml | 19 + .../fluent-bit/templates/rolebinding.yaml | 19 + .../templates/service-headless.yaml | 22 + .../fluent-bit/templates/serviceaccount.yaml | 12 + .../fluent-bit/templates/servicemonitor.yaml | 35 + .../loki-stack/charts/fluent-bit/values.yaml | 122 + .../loki-stack/charts/grafana/.helmignore | 23 + .../loki-stack/charts/grafana/Chart.yaml | 22 + .../loki-stack/charts/grafana/README.md | 561 + .../charts/grafana/ci/default-values.yaml | 1 + .../ci/with-dashboard-json-values.yaml | 53 + .../grafana/ci/with-dashboard-values.yaml | 19 + .../ci/with-image-renderer-values.yaml | 19 + .../grafana/dashboards/custom-dashboard.json | 1 + .../charts/grafana/templates/NOTES.txt | 54 + .../charts/grafana/templates/_helpers.tpl | 163 + .../charts/grafana/templates/_pod.tpl | 684 + .../charts/grafana/templates/clusterrole.yaml | 25 + .../grafana/templates/clusterrolebinding.yaml | 24 + .../configmap-dashboard-provider.yaml | 29 + .../charts/grafana/templates/configmap.yaml | 82 + .../templates/dashboards-json-configmap.yaml | 35 + .../charts/grafana/templates/deployment.yaml | 50 + .../grafana/templates/extra-manifests.yaml | 4 + .../grafana/templates/headless-service.yaml | 22 + .../charts/grafana/templates/hpa.yaml | 20 + .../templates/image-renderer-deployment.yaml | 119 + .../image-renderer-network-policy.yaml | 76 + .../templates/image-renderer-service.yaml | 30 + .../charts/grafana/templates/ingress.yaml | 78 + .../grafana/templates/networkpolicy.yaml | 37 + .../templates/poddisruptionbudget.yaml | 22 + .../grafana/templates/podsecuritypolicy.yaml | 49 + .../charts/grafana/templates/pvc.yaml | 33 + .../charts/grafana/templates/role.yaml | 32 + .../charts/grafana/templates/rolebinding.yaml | 25 + .../charts/grafana/templates/secret-env.yaml | 14 + .../charts/grafana/templates/secret.yaml | 26 + .../charts/grafana/templates/service.yaml | 51 + .../grafana/templates/serviceaccount.yaml | 13 + .../grafana/templates/servicemonitor.yaml | 42 + .../charts/grafana/templates/statefulset.yaml | 52 + .../templates/tests/test-configmap.yaml | 17 + .../tests/test-podsecuritypolicy.yaml | 29 + .../grafana/templates/tests/test-role.yaml | 14 + .../templates/tests/test-rolebinding.yaml | 17 + .../templates/tests/test-serviceaccount.yaml | 9 + .../charts/grafana/templates/tests/test.yaml | 48 + .../loki-stack/charts/grafana/values.yaml | 846 ++ .../loki-stack/charts/logstash/.helmignore | 2 + .../loki-stack/charts/logstash/Chart.yaml | 12 + .../loki-stack/charts/logstash/Makefile | 1 + .../loki-stack/charts/logstash/README.md | 237 + .../charts/logstash/examples/default/Makefile | 14 + .../logstash/examples/default/README.md | 17 + .../logstash/examples/default/test/goss.yaml | 41 + .../logstash/examples/elasticsearch/Makefile | 15 + .../logstash/examples/elasticsearch/README.md | 28 + .../examples/elasticsearch/test/goss.yaml | 54 + .../examples/elasticsearch/values.yaml | 12 + .../charts/logstash/examples/oss/Makefile | 14 + .../charts/logstash/examples/oss/README.md | 17 + .../logstash/examples/oss/test/goss.yaml | 40 + .../charts/logstash/examples/oss/values.yaml | 2 + .../logstash/examples/security/Makefile | 15 + .../logstash/examples/security/README.md | 28 + .../logstash/examples/security/test/goss.yaml | 62 + .../logstash/examples/security/values.yaml | 40 + .../charts/logstash/examples/upgrade/Makefile | 16 + .../logstash/examples/upgrade/README.md | 19 + .../logstash/examples/upgrade/test/goss.yaml | 41 + .../logstash/examples/upgrade/values.yaml | 1 + .../charts/logstash/templates/NOTES.txt | 2 + .../charts/logstash/templates/_helpers.tpl | 27 + .../logstash/templates/configmap-config.yaml | 17 + .../logstash/templates/configmap-pattern.yaml | 17 + .../templates/configmap-pipeline.yaml | 17 + .../charts/logstash/templates/ingress.yaml | 68 + .../templates/poddisruptionbudget.yaml | 20 + .../logstash/templates/podsecuritypolicy.yaml | 18 + .../charts/logstash/templates/role.yaml | 25 + .../logstash/templates/rolebinding.yaml | 20 + .../charts/logstash/templates/secret.yaml | 27 + .../logstash/templates/service-headless.yaml | 20 + .../charts/logstash/templates/service.yaml | 32 + .../logstash/templates/serviceaccount.yaml | 22 + .../logstash/templates/statefulset.yaml | 237 + .../loki-stack/charts/logstash/values.yaml | 295 + .../charts/loki-stack/charts/loki/.helmignore | 22 + .../charts/loki-stack/charts/loki/Chart.yaml | 13 + .../charts/loki-stack/charts/loki/README.md | 82 + .../charts/loki/templates/NOTES.txt | 3 + .../charts/loki/templates/_helpers.tpl | 75 + .../loki/templates/configmap-alert.yaml | 17 + .../charts/loki/templates/ingress.yaml | 55 + .../charts/loki/templates/networkpolicy.yaml | 26 + .../loki-stack/charts/loki/templates/pdb.yaml | 17 + .../loki/templates/podsecuritypolicy.yaml | 41 + .../charts/loki/templates/prometheusrule.yaml | 23 + .../charts/loki/templates/role.yaml | 20 + .../charts/loki/templates/rolebinding.yaml | 20 + .../charts/loki/templates/secret.yaml | 14 + .../loki/templates/service-headless.yaml | 24 + .../charts/loki/templates/service.yaml | 43 + .../charts/loki/templates/serviceaccount.yaml | 16 + .../charts/loki/templates/servicemonitor.yaml | 38 + .../charts/loki/templates/statefulset.yaml | 154 + .../charts/loki-stack/charts/loki/values.yaml | 324 + .../loki-stack/charts/prometheus/.helmignore | 23 + .../loki-stack/charts/prometheus/Chart.lock | 6 + .../loki-stack/charts/prometheus/Chart.yaml | 30 + .../loki-stack/charts/prometheus/README.md | 226 + .../charts/kube-state-metrics/.helmignore | 21 + .../charts/kube-state-metrics/Chart.yaml | 21 + .../charts/kube-state-metrics/README.md | 68 + .../kube-state-metrics/templates/NOTES.txt | 10 + .../kube-state-metrics/templates/_helpers.tpl | 82 + .../templates/clusterrolebinding.yaml | 20 + .../templates/deployment.yaml | 148 + .../templates/kubeconfig-secret.yaml | 12 + .../kube-state-metrics/templates/pdb.yaml | 14 + .../templates/podsecuritypolicy.yaml | 39 + .../templates/psp-clusterrole.yaml | 19 + .../templates/psp-clusterrolebinding.yaml | 16 + .../kube-state-metrics/templates/role.yaml | 187 + .../templates/rolebinding.yaml | 24 + .../kube-state-metrics/templates/service.yaml | 35 + .../templates/serviceaccount.yaml | 15 + .../templates/servicemonitor.yaml | 66 + .../templates/stsdiscovery-role.yaml | 26 + .../templates/stsdiscovery-rolebinding.yaml | 17 + .../charts/kube-state-metrics/values.yaml | 224 + .../charts/prometheus/templates/NOTES.txt | 112 + .../charts/prometheus/templates/_helpers.tpl | 282 + .../templates/alertmanager/clusterrole.yaml | 21 + .../alertmanager/clusterrolebinding.yaml | 20 + .../prometheus/templates/alertmanager/cm.yaml | 19 + .../templates/alertmanager/deploy.yaml | 204 + .../templates/alertmanager/headless-svc.yaml | 31 + .../templates/alertmanager/ingress.yaml | 57 + .../templates/alertmanager/netpol.yaml | 20 + .../templates/alertmanager/pdb.yaml | 14 + .../templates/alertmanager/psp.yaml | 46 + .../templates/alertmanager/pvc.yaml | 37 + .../templates/alertmanager/role.yaml | 24 + .../templates/alertmanager/rolebinding.yaml | 23 + .../templates/alertmanager/service.yaml | 53 + .../alertmanager/serviceaccount.yaml | 11 + .../templates/alertmanager/sts.yaml | 181 + .../templates/node-exporter/daemonset.yaml | 146 + .../templates/node-exporter/psp.yaml | 55 + .../templates/node-exporter/role.yaml | 17 + .../templates/node-exporter/rolebinding.yaml | 19 + .../node-exporter/serviceaccount.yaml | 11 + .../templates/node-exporter/svc.yaml | 47 + .../templates/pushgateway/clusterrole.yaml | 21 + .../pushgateway/clusterrolebinding.yaml | 16 + .../templates/pushgateway/deploy.yaml | 119 + .../templates/pushgateway/ingress.yaml | 54 + .../templates/pushgateway/netpol.yaml | 20 + .../prometheus/templates/pushgateway/pdb.yaml | 14 + .../prometheus/templates/pushgateway/psp.yaml | 42 + .../prometheus/templates/pushgateway/pvc.yaml | 31 + .../templates/pushgateway/service.yaml | 41 + .../templates/pushgateway/serviceaccount.yaml | 11 + .../prometheus/templates/pushgateway/vpa.yaml | 20 + .../templates/server/clusterrole.yaml | 48 + .../templates/server/clusterrolebinding.yaml | 16 + .../prometheus/templates/server/cm.yaml | 85 + .../prometheus/templates/server/deploy.yaml | 316 + .../templates/server/headless-svc.yaml | 37 + .../prometheus/templates/server/ingress.yaml | 59 + .../prometheus/templates/server/netpol.yaml | 18 + .../prometheus/templates/server/pdb.yaml | 14 + .../prometheus/templates/server/psp.yaml | 51 + .../prometheus/templates/server/pvc.yaml | 39 + .../templates/server/rolebinding.yaml | 20 + .../prometheus/templates/server/service.yaml | 60 + .../templates/server/serviceaccount.yaml | 13 + .../prometheus/templates/server/sts.yaml | 298 + .../prometheus/templates/server/vpa.yaml | 24 + .../loki-stack/charts/prometheus/values.yaml | 1825 +++ .../loki-stack/charts/promtail/.helmignore | 22 + .../loki-stack/charts/promtail/Chart.yaml | 17 + .../loki-stack/charts/promtail/README.md | 257 + .../charts/promtail/README.md.gotmpl | 187 + .../charts/promtail/ci/default-values.yaml | 0 .../charts/promtail/ci/netpol-values.yaml | 53 + .../charts/promtail/ci/service-values.yaml | 34 + .../charts/promtail/templates/NOTES.txt | 10 + .../charts/promtail/templates/_helpers.tpl | 80 + .../promtail/templates/clusterrole.yaml | 21 + .../templates/clusterrolebinding.yaml | 16 + .../charts/promtail/templates/daemonset.yaml | 132 + .../promtail/templates/extra-manifests.yaml | 4 + .../promtail/templates/networkpolicy.yaml | 126 + .../promtail/templates/podsecuritypolicy.yaml | 10 + .../charts/promtail/templates/role.yaml | 18 + .../promtail/templates/rolebinding.yaml | 16 + .../charts/promtail/templates/secret.yaml | 10 + .../promtail/templates/service-extra.yaml | 52 + .../promtail/templates/service-metrics.yaml | 18 + .../promtail/templates/serviceaccount.yaml | 17 + .../promtail/templates/servicemonitor.yaml | 40 + .../loki-stack/charts/promtail/values.yaml | 387 + .../charts/loki-stack/requirements.lock | 24 + .../charts/loki-stack/requirements.yaml | 29 + .../charts/loki-stack/templates/NOTES.txt | 3 + .../charts/loki-stack/templates/_helpers.tpl | 58 + .../loki-stack/templates/datasources.yaml | 35 + .../templates/tests/loki-test-configmap.yaml | 52 + .../templates/tests/loki-test-pod.yaml | 30 + .../mayastor/charts/loki-stack/values.yaml | 74 + .../charts/mayastor/charts/nats/.helmignore | 22 + .../charts/mayastor/charts/nats/Chart.yaml | 16 + .../charts/mayastor/charts/nats/README.md | 918 ++ .../mayastor/charts/nats/templates/NOTES.txt | 26 + .../charts/nats/templates/_helpers.tpl | 256 + .../charts/nats/templates/configmap.yaml | 614 + .../charts/nats/templates/nats-box.yaml | 121 + .../charts/nats/templates/networkpolicy.yaml | 79 + .../mayastor/charts/nats/templates/pdb.yaml | 20 + .../mayastor/charts/nats/templates/rbac.yaml | 39 + .../charts/nats/templates/service.yaml | 74 + .../charts/nats/templates/serviceMonitor.yaml | 36 + .../charts/nats/templates/statefulset.yaml | 650 + .../templates/tests/test-request-reply.yaml | 31 + .../charts/mayastor/charts/nats/values.yaml | 827 ++ .../crds/csi-volume-snapshot-class.yaml | 147 + .../crds/csi-volume-snapshot-content.yaml | 485 + .../mayastor/crds/csi-volume-snapshot.yaml | 387 + helm/openebs/charts/mayastor/crds/jaeger.yaml | 44 + helm/openebs/charts/mayastor/doc.yaml | 19 + helm/openebs/charts/mayastor/product.yaml | 3 + .../charts/mayastor/templates/NOTES.txt | 4 + .../charts/mayastor/templates/_helpers.tpl | 209 + .../etcd/storage/localpv-storageclass.yaml | 16 + .../templates/etcd/storage/localpv.yaml | 22 + .../templates/jaeger-operator/jaeger.yaml | 23 + .../storage/localpv-storageclass.yaml | 16 + .../templates/loki-stack/storage/localpv.yaml | 20 + .../agents/core/agent-core-deployment.yaml | 108 + .../agents/core/agent-core-service.yaml | 17 + .../mayastor/agents/ha/ha-node-daemonset.yaml | 115 + .../mayastor/apis/api-rest-deployment.yaml | 63 + .../mayastor/apis/api-rest-service.yaml | 28 + .../csi/csi-controller-deployment.yaml | 118 + .../mayastor/csi/csi-node-daemonset.yaml | 156 + .../mayastor/io/io-engine-daemonset.yaml | 149 + .../metrics-exporter-pool-service.yaml | 19 + .../mayastor/obs/obs-callhome-deployment.yaml | 80 + .../templates/mayastor/obs/stats-service.yaml | 29 + .../operator-diskpool-deployment.yaml | 64 + .../priority-class/priority-class.yaml | 7 + .../templates/mayastor/rbac/rbac.yaml | 118 + .../mayastor/templates/storageclass.yaml | 9 + helm/openebs/charts/mayastor/values.yaml | 707 + .../openebs/charts/nfs-provisioner/Chart.yaml | 25 + helm/openebs/charts/nfs-provisioner/README.md | 156 + .../nfs-provisioner/templates/NOTES.txt | 9 + .../nfs-provisioner/templates/_helpers.tpl | 77 + .../templates/clusterrole.yaml | 58 + .../templates/clusterrolebinding.yaml | 43 + .../nfs-provisioner/templates/deployment.yaml | 149 + .../templates/kernel-nfs-storageclass.yaml | 57 + .../charts/nfs-provisioner/templates/psp.yaml | 31 + .../templates/serviceaccount.yaml | 10 + .../charts/nfs-provisioner/values.yaml | 142 + helm/openebs/charts/openebs-ndm/Chart.yaml | 23 + helm/openebs/charts/openebs-ndm/README.md | 93 + .../charts/openebs-ndm/crds/blockdevice.yaml | 241 + .../openebs-ndm/crds/blockdeviceclaim.yaml | 144 + .../charts/openebs-ndm/templates/NOTES.txt | 8 + .../charts/openebs-ndm/templates/_helpers.tpl | 242 + .../templates/cluster-exporter-service.yaml | 18 + .../templates/cluster-exporter.yaml | 60 + .../openebs-ndm/templates/configmap.yaml | 45 + .../openebs-ndm/templates/daemonset.yaml | 179 + .../openebs-ndm/templates/deployment.yaml | 87 + .../templates/node-exporter-service.yaml | 18 + .../openebs-ndm/templates/node-exporter.yaml | 62 + .../charts/openebs-ndm/templates/rbac.yaml | 44 + helm/openebs/charts/openebs-ndm/values.yaml | 156 + helm/openebs/charts/zfs-localpv/.helmignore | 23 + helm/openebs/charts/zfs-localpv/Chart.yaml | 24 + helm/openebs/charts/zfs-localpv/README.md | 137 + .../crds/volumesnapshotclasses.yaml | 134 + .../crds/volumesnapshotcontents.yaml | 401 + .../zfs-localpv/crds/volumesnapshots.yaml | 312 + .../charts/zfs-localpv/crds/zfsbackup.yaml | 116 + .../charts/zfs-localpv/crds/zfsnode.yaml | 87 + .../charts/zfs-localpv/crds/zfsrestore.yaml | 238 + .../charts/zfs-localpv/crds/zfssnapshot.yaml | 383 + .../charts/zfs-localpv/crds/zfsvolume.yaml | 449 + .../charts/zfs-localpv/templates/NOTES.txt | 5 + .../charts/zfs-localpv/templates/_helpers.tpl | 138 + .../zfs-localpv/templates/configmap.yaml | 17 + .../zfs-localpv/templates/csidriver.yaml | 10 + .../zfs-localpv/templates/priority-class.yaml | 19 + .../charts/zfs-localpv/templates/psp.yaml | 24 + .../charts/zfs-localpv/templates/rbac.yaml | 200 + .../zfs-localpv/templates/zfs-contoller.yaml | 153 + .../zfs-localpv/templates/zfs-node.yaml | 164 + helm/openebs/charts/zfs-localpv/values.yaml | 172 + helm/openebs/crds/blockdevice.yaml | 241 + helm/openebs/crds/blockdeviceclaim.yaml | 144 + helm/openebs/override_values.yaml | 14 + helm/openebs/templates/NOTES.txt | 53 + helm/openebs/templates/_helpers.tpl | 160 + helm/openebs/templates/clusterrole.yaml | 50 + .../openebs/templates/clusterrolebinding.yaml | 19 + .../templates/kyverno/allow-capabilities.yaml | 30 + .../kyverno/allow-host-namespaces.yaml | 32 + .../templates/kyverno/allow-host-ports.yaml | 31 + .../kyverno/allow-privilege-escalation.yaml | 30 + .../kyverno/allow-privileged-containers.yaml | 30 + .../templates/kyverno/allow-proc-mount.yaml | 31 + .../templates/kyverno/allow-selinux.yaml | 34 + .../kyverno/require-user-groups.yaml | 56 + .../templates/legacy/cleanup-webhook.yaml | 49 + .../legacy/deployment-admission-server.yaml | 84 + .../legacy/deployment-maya-apiserver.yaml | 178 + .../legacy/deployment-maya-provisioner.yaml | 115 + .../deployment-maya-snapshot-operator.yaml | 147 + .../legacy/service-maya-apiserver.yaml | 23 + .../deployment-local-provisioner.yaml | 128 + .../localprovisioner/device-class.yaml | 40 + .../localprovisioner/hostpath-class.yaml | 49 + .../ndm/cluster-exporter-service.yaml | 25 + .../templates/ndm/cluster-exporter.yaml | 53 + .../templates/ndm/cm-node-disk-manager.yaml | 50 + helm/openebs/templates/ndm/daemonset-ndm.yaml | 188 + .../ndm/deployment-ndm-operator.yaml | 93 + .../templates/ndm/node-exporter-service.yaml | 25 + helm/openebs/templates/ndm/node-exporter.yaml | 54 + helm/openebs/templates/psp-clusterrole.yaml | 14 + .../templates/psp-clusterrolebinding.yaml | 17 + helm/openebs/templates/psp.yaml | 28 + helm/openebs/templates/serviceaccount.yaml | 11 + helm/openebs/values.yaml | 980 ++ helm/sonarqube/.helmignore | 23 + helm/sonarqube/CHANGELOG.md | 389 + helm/sonarqube/Chart.lock | 9 + helm/sonarqube/Chart.yaml | 56 + helm/sonarqube/README.md | 528 + .../charts/ingress-nginx/.helmignore | 22 + .../charts/ingress-nginx/CHANGELOG.md | 460 + .../sonarqube/charts/ingress-nginx/Chart.yaml | 25 + helm/sonarqube/charts/ingress-nginx/OWNERS | 10 + helm/sonarqube/charts/ingress-nginx/README.md | 507 + .../charts/ingress-nginx/README.md.gotmpl | 229 + .../charts/ingress-nginx/changelog.md.gotmpl | 9 + .../charts/ingress-nginx/changelog/.gitkeep | 0 .../changelog/Changelog-4.5.2.md | 13 + .../changelog/Changelog-4.6.0.md | 24 + .../changelog/Changelog-4.6.1.md | 11 + .../changelog/Changelog-4.7.0.md | 14 + .../changelog/Changelog-4.7.1.md | 12 + ...ler-admission-tls-cert-manager-values.yaml | 6 + .../controller-custom-ingressclass-flags.yaml | 7 + .../ci/daemonset-customconfig-values.yaml | 14 + .../ci/daemonset-customnodeport-values.yaml | 22 + .../ci/daemonset-extra-modules.yaml | 10 + .../ci/daemonset-headers-values.yaml | 14 + .../ci/daemonset-internal-lb-values.yaml | 14 + .../ci/daemonset-nodeport-values.yaml | 10 + .../ci/daemonset-podannotations-values.yaml | 17 + ...set-tcp-udp-configMapNamespace-values.yaml | 20 + ...emonset-tcp-udp-portNamePrefix-values.yaml | 18 + .../ci/daemonset-tcp-udp-values.yaml | 16 + .../ci/daemonset-tcp-values.yaml | 14 + .../ci/deamonset-default-values.yaml | 10 + .../ci/deamonset-metrics-values.yaml | 12 + .../ci/deamonset-psp-values.yaml | 13 + .../ci/deamonset-webhook-and-psp-values.yaml | 13 + .../ci/deamonset-webhook-values.yaml | 10 + ...eployment-autoscaling-behavior-values.yaml | 14 + .../ci/deployment-autoscaling-values.yaml | 11 + .../ci/deployment-customconfig-values.yaml | 12 + .../ci/deployment-customnodeport-values.yaml | 20 + .../ci/deployment-default-values.yaml | 8 + ...modules-default-container-sec-context.yaml | 12 + ...odules-specific-container-sec-context.yaml | 12 + .../ci/deployment-extra-modules.yaml | 10 + .../ci/deployment-headers-values.yaml | 13 + .../ci/deployment-internal-lb-values.yaml | 19 + .../ci/deployment-metrics-values.yaml | 11 + .../ci/deployment-nodeport-values.yaml | 9 + .../ci/deployment-podannotations-values.yaml | 16 + .../ci/deployment-psp-values.yaml | 10 + ...ent-tcp-udp-configMapNamespace-values.yaml | 19 + ...loyment-tcp-udp-portNamePrefix-values.yaml | 17 + .../ci/deployment-tcp-udp-values.yaml | 15 + .../ci/deployment-tcp-values.yaml | 11 + .../ci/deployment-webhook-and-psp-values.yaml | 12 + .../deployment-webhook-extraEnvs-values.yaml | 12 + .../deployment-webhook-resources-values.yaml | 23 + .../ci/deployment-webhook-values.yaml | 9 + .../charts/ingress-nginx/templates/NOTES.txt | 73 + .../ingress-nginx/templates/_helpers.tpl | 216 + .../ingress-nginx/templates/_params.tpl | 65 + .../admission-webhooks/cert-manager.yaml | 63 + .../job-patch/clusterrole.yaml | 34 + .../job-patch/clusterrolebinding.yaml | 23 + .../job-patch/job-createSecret.yaml | 80 + .../job-patch/job-patchWebhook.yaml | 82 + .../job-patch/networkpolicy.yaml | 26 + .../admission-webhooks/job-patch/psp.yaml | 41 + .../admission-webhooks/job-patch/role.yaml | 24 + .../job-patch/rolebinding.yaml | 24 + .../job-patch/serviceaccount.yaml | 16 + .../validating-webhook.yaml | 53 + .../ingress-nginx/templates/clusterrole.yaml | 102 + .../templates/clusterrolebinding.yaml | 19 + .../controller-configmap-addheaders.yaml | 14 + .../controller-configmap-proxyheaders.yaml | 14 + .../templates/controller-configmap-tcp.yaml | 17 + .../templates/controller-configmap-udp.yaml | 17 + .../templates/controller-configmap.yaml | 28 + .../templates/controller-daemonset.yaml | 239 + .../templates/controller-deployment.yaml | 243 + .../templates/controller-hpa.yaml | 47 + .../templates/controller-ingressclass.yaml | 21 + .../templates/controller-keda.yaml | 47 + .../controller-poddisruptionbudget.yaml | 26 + .../templates/controller-prometheusrules.yaml | 21 + .../templates/controller-psp.yaml | 94 + .../templates/controller-role.yaml | 101 + .../templates/controller-rolebinding.yaml | 21 + .../templates/controller-secret.yaml | 15 + .../controller-service-internal.yaml | 79 + .../templates/controller-service-metrics.yaml | 45 + .../templates/controller-service-webhook.yaml | 40 + .../templates/controller-service.yaml | 104 + .../templates/controller-serviceaccount.yaml | 18 + .../templates/controller-servicemonitor.yaml | 48 + .../controller-webhooks-networkpolicy.yaml | 19 + .../templates/default-backend-deployment.yaml | 123 + .../templates/default-backend-hpa.yaml | 40 + .../default-backend-poddisruptionbudget.yaml | 21 + .../templates/default-backend-psp.yaml | 38 + .../templates/default-backend-role.yaml | 22 + .../default-backend-rolebinding.yaml | 21 + .../templates/default-backend-service.yaml | 41 + .../default-backend-serviceaccount.yaml | 14 + .../charts/ingress-nginx/values.yaml | 904 ++ helm/sonarqube/charts/postgresql/.helmignore | 21 + helm/sonarqube/charts/postgresql/Chart.lock | 6 + helm/sonarqube/charts/postgresql/Chart.yaml | 29 + helm/sonarqube/charts/postgresql/README.md | 816 ++ .../postgresql/charts/common/.helmignore | 22 + .../postgresql/charts/common/Chart.yaml | 23 + .../charts/postgresql/charts/common/README.md | 328 + .../charts/common/templates/_affinities.tpl | 102 + .../charts/common/templates/_capabilities.tpl | 128 + .../charts/common/templates/_errors.tpl | 23 + .../charts/common/templates/_images.tpl | 75 + .../charts/common/templates/_ingress.tpl | 55 + .../charts/common/templates/_labels.tpl | 18 + .../charts/common/templates/_names.tpl | 52 + .../charts/common/templates/_secrets.tpl | 129 + .../charts/common/templates/_storage.tpl | 23 + .../charts/common/templates/_tplvalues.tpl | 13 + .../charts/common/templates/_utils.tpl | 62 + .../charts/common/templates/_warnings.tpl | 14 + .../templates/validations/_cassandra.tpl | 72 + .../common/templates/validations/_mariadb.tpl | 103 + .../common/templates/validations/_mongodb.tpl | 108 + .../templates/validations/_postgresql.tpl | 129 + .../common/templates/validations/_redis.tpl | 76 + .../templates/validations/_validations.tpl | 46 + .../postgresql/charts/common/values.yaml | 5 + .../postgresql/ci/commonAnnotations.yaml | 3 + .../charts/postgresql/ci/default-values.yaml | 1 + .../ci/shmvolume-disabled-values.yaml | 2 + .../charts/postgresql/files/README.md | 1 + .../charts/postgresql/files/conf.d/README.md | 4 + .../docker-entrypoint-initdb.d/README.md | 3 + .../charts/postgresql/templates/NOTES.txt | 89 + .../charts/postgresql/templates/_helpers.tpl | 361 + .../postgresql/templates/configmap.yaml | 34 + .../templates/extended-config-configmap.yaml | 29 + .../postgresql/templates/extra-list.yaml | 4 + .../templates/initialization-configmap.yaml | 26 + .../templates/metrics-configmap.yaml | 17 + .../postgresql/templates/metrics-svc.yaml | 29 + .../postgresql/templates/networkpolicy.yaml | 42 + .../templates/podsecuritypolicy.yaml | 42 + .../postgresql/templates/prometheusrule.yaml | 26 + .../charts/postgresql/templates/role.yaml | 24 + .../postgresql/templates/rolebinding.yaml | 23 + .../charts/postgresql/templates/secrets.yaml | 27 + .../postgresql/templates/serviceaccount.yaml | 15 + .../postgresql/templates/servicemonitor.yaml | 42 + .../templates/statefulset-readreplicas.yaml | 430 + .../postgresql/templates/statefulset.yaml | 636 + .../postgresql/templates/svc-headless.yaml | 31 + .../postgresql/templates/svc-read-set.yaml | 42 + .../charts/postgresql/templates/svc-read.yaml | 47 + .../charts/postgresql/templates/svc.yaml | 45 + .../postgresql/templates/tls-secrets.yaml | 25 + .../charts/postgresql/values.schema.json | 103 + helm/sonarqube/charts/postgresql/values.yaml | 996 ++ helm/sonarqube/override_values.yaml | 27 + helm/sonarqube/templates/NOTES.txt | 22 + helm/sonarqube/templates/_helpers.tpl | 199 + .../templates/change-admin-password-hook.yml | 82 + helm/sonarqube/templates/config.yaml | 20 + helm/sonarqube/templates/deployment.yaml | 482 + helm/sonarqube/templates/ingress.yaml | 43 + helm/sonarqube/templates/init-fs.yaml | 14 + helm/sonarqube/templates/init-sysctl.yaml | 37 + helm/sonarqube/templates/install-plugins.yaml | 18 + helm/sonarqube/templates/jdbc-config.yaml | 16 + helm/sonarqube/templates/networkpolicy.yaml | 114 + .../templates/prometheus-ce-config.yaml | 14 + .../templates/prometheus-config.yaml | 14 + .../templates/prometheus-podmonitor.yaml | 37 + helm/sonarqube/templates/pvc.yaml | 30 + helm/sonarqube/templates/route.yaml | 34 + helm/sonarqube/templates/secret.yaml | 64 + helm/sonarqube/templates/service.yaml | 42 + helm/sonarqube/templates/serviceaccount.yaml | 16 + helm/sonarqube/templates/sonarqube-scc.yaml | 63 + helm/sonarqube/templates/sonarqube-sts.yaml | 531 + .../templates/tests/sonarqube-test.yaml | 40 + helm/sonarqube/values.schema.json | 62 + helm/sonarqube/values.yaml | 542 + helm/teleport-cluster/.lint/acme-off.yaml | 3 + helm/teleport-cluster/.lint/acme-on.yaml | 3 + .../.lint/acme-uri-staging.yaml | 4 + helm/teleport-cluster/.lint/affinity.yaml | 29 + helm/teleport-cluster/.lint/annotations.yaml | 17 + .../.lint/auth-connector-name.yaml | 3 + .../.lint/auth-disable-local.yaml | 5 + .../.lint/auth-locking-mode.yaml | 3 + .../.lint/auth-passwordless.yaml | 4 + .../.lint/auth-type-legacy.yaml | 4 + helm/teleport-cluster/.lint/auth-type.yaml | 3 + .../.lint/auth-webauthn-legacy.yaml | 10 + .../teleport-cluster/.lint/auth-webauthn.yaml | 8 + .../.lint/aws-dynamodb-autoscaling.yaml | 14 + helm/teleport-cluster/.lint/aws-ha-acme.yaml | 14 + .../.lint/aws-ha-antiaffinity.yaml | 12 + helm/teleport-cluster/.lint/aws-ha-log.yaml | 17 + helm/teleport-cluster/.lint/aws-ha.yaml | 11 + helm/teleport-cluster/.lint/aws.yaml | 11 + helm/teleport-cluster/.lint/azure.yaml | 11 + helm/teleport-cluster/.lint/cert-manager.yaml | 15 + helm/teleport-cluster/.lint/cert-secret.yaml | 15 + .../.lint/example-minimal-standalone.yaml | 7 + .../.lint/existing-tls-secret-with-ca.yaml | 4 + .../.lint/existing-tls-secret.yaml | 3 + helm/teleport-cluster/.lint/extra-env.yaml | 4 + helm/teleport-cluster/.lint/gcp-ha-acme.yaml | 14 + .../.lint/gcp-ha-antiaffinity.yaml | 12 + helm/teleport-cluster/.lint/gcp-ha-log.yaml | 17 + .../.lint/gcp-ha-workload.yaml | 12 + helm/teleport-cluster/.lint/gcp-ha.yaml | 11 + helm/teleport-cluster/.lint/gcp.yaml | 11 + .../.lint/imagepullsecrets.yaml | 4 + .../.lint/ingress-publicaddr.yaml | 8 + helm/teleport-cluster/.lint/ingress.yaml | 6 + .../.lint/initcontainers.yaml | 8 + .../.lint/kube-cluster-name.yaml | 2 + helm/teleport-cluster/.lint/log-basic.yaml | 4 + helm/teleport-cluster/.lint/log-extra.yaml | 6 + helm/teleport-cluster/.lint/log-legacy.yaml | 2 + .../teleport-cluster/.lint/node-selector.yaml | 4 + helm/teleport-cluster/.lint/operator.yaml | 4 + helm/teleport-cluster/.lint/pdb.yaml | 12 + .../.lint/persistence-legacy.yaml | 4 + helm/teleport-cluster/.lint/podmonitor.yaml | 6 + .../.lint/priority-class-name.yaml | 4 + .../.lint/probe-timeout-seconds.yaml | 4 + .../.lint/proxy-listener-mode-multiplex.yaml | 2 + .../.lint/proxy-listener-mode-separate.yaml | 2 + .../.lint/public-addresses.yaml | 11 + helm/teleport-cluster/.lint/resources.yaml | 10 + .../.lint/security-context-empty.yaml | 1 + .../.lint/security-context.yaml | 8 + .../.lint/separate-mongo-listener.yaml | 2 + .../.lint/separate-postgres-listener.yaml | 2 + .../.lint/service-account.yaml | 7 + helm/teleport-cluster/.lint/service.yaml | 5 + .../.lint/session-recording.yaml | 2 + .../standalone-custom-storage-class.yaml | 9 + .../.lint/standalone-customsize.yaml | 9 + .../.lint/standalone-existingpvc.yaml | 9 + helm/teleport-cluster/.lint/tolerations.yaml | 18 + .../.lint/version-override.yaml | 5 + helm/teleport-cluster/.lint/volumes.yaml | 8 + helm/teleport-cluster/Chart.yaml | 13 + helm/teleport-cluster/README.md | 64 + .../charts/teleport-operator/Chart.yaml | 8 + ...sources.teleport.dev_githubconnectors.yaml | 168 + .../resources.teleport.dev_loginrules.yaml | 145 + ...resources.teleport.dev_oidcconnectors.yaml | 213 + ...esources.teleport.dev_oktaimportrules.yaml | 183 + ...esources.teleport.dev_provisiontokens.yaml | 353 + .../resources.teleport.dev_roles.yaml | 2386 ++++ ...resources.teleport.dev_samlconnectors.yaml | 210 + .../resources.teleport.dev_users.yaml | 195 + helm/teleport-cluster/override_values.yaml | 45 + helm/teleport-cluster/teleport_svc.yaml | 44 + helm/teleport-cluster/templates/NOTES.txt | 35 + helm/teleport-cluster/templates/_helpers.tpl | 91 + .../templates/auth/_config.aws.tpl | 26 + .../templates/auth/_config.azure.tpl | 38 + .../templates/auth/_config.common.tpl | 65 + .../templates/auth/_config.gcp.tpl | 16 + .../templates/auth/_config.scratch.tpl | 12 + .../templates/auth/_config.standalone.tpl | 3 + .../templates/auth/clusterrole.yaml | 71 + .../templates/auth/clusterrolebinding.yaml | 31 + .../templates/auth/config.yaml | 28 + .../templates/auth/deployment.yaml | 321 + helm/teleport-cluster/templates/auth/pdb.yaml | 17 + .../templates/auth/predeploy_config.yaml | 31 + .../templates/auth/predeploy_job.yaml | 103 + helm/teleport-cluster/templates/auth/pvc.yaml | 24 + .../auth/service-previous-version.yaml | 31 + .../templates/auth/service.yaml | 21 + .../templates/auth/serviceaccount.yaml | 17 + .../templates/podmonitor.yaml | 31 + .../templates/proxy/_config.aws.tpl | 3 + .../templates/proxy/_config.azure.tpl | 3 + .../templates/proxy/_config.common.tpl | 76 + .../templates/proxy/_config.gcp.tpl | 3 + .../templates/proxy/_config.scratch.tpl | 12 + .../templates/proxy/_config.standalone.tpl | 3 + .../templates/proxy/certificate.yaml | 27 + .../templates/proxy/config.yaml | 16 + .../templates/proxy/deployment.yaml | 307 + .../templates/proxy/ingress.yaml | 57 + .../teleport-cluster/templates/proxy/pdb.yaml | 17 + .../templates/proxy/predeploy_config.yaml | 16 + .../templates/proxy/predeploy_job.yaml | 99 + .../templates/proxy/service.yaml | 70 + .../templates/proxy/serviceaccount.yaml | 11 + helm/teleport-cluster/templates/psp.yaml | 68 + helm/teleport-cluster/tests/README.md | 23 + .../auth_clusterrole_test.yaml.snap | 66 + .../__snapshot__/auth_config_test.yaml.snap | 1674 +++ .../auth_deployment_test.yaml.snap | 518 + .../tests/__snapshot__/ingress_test.yaml.snap | 55 + .../__snapshot__/predeploy_test.yaml.snap | 6 + .../proxy_certificate_test.yaml.snap | 16 + .../__snapshot__/proxy_config_test.yaml.snap | 530 + .../proxy_deployment_test.yaml.snap | 495 + .../__snapshot__/proxy_service_test.yaml.snap | 68 + .../tests/__snapshot__/psp_test.yaml.snap | 62 + .../tests/auth_clusterrole_test.yaml | 19 + .../tests/auth_clusterrolebinding_test.yaml | 20 + .../tests/auth_config_test.yaml | 512 + .../tests/auth_deployment_test.yaml | 826 ++ .../teleport-cluster/tests/auth_pdb_test.yaml | 23 + .../teleport-cluster/tests/auth_pvc_test.yaml | 87 + .../tests/auth_serviceaccount_test.yaml | 32 + helm/teleport-cluster/tests/ingress_test.yaml | 538 + .../tests/podmonitor_test.yaml | 40 + .../tests/predeploy_test.yaml | 111 + .../tests/proxy_certificate_test.yaml | 29 + .../tests/proxy_config_test.yaml | 235 + .../tests/proxy_deployment_test.yaml | 899 ++ .../tests/proxy_pdb_test.yaml | 23 + .../tests/proxy_service_test.yaml | 381 + .../tests/proxy_serviceaccount_test.yaml | 22 + helm/teleport-cluster/tests/psp_test.yaml | 35 + helm/teleport-cluster/values.schema.json | 923 ++ helm/teleport-cluster/values.yaml | 638 + helm/vault/.helmignore | 28 + helm/vault/CHANGELOG.md | 484 + helm/vault/CODEOWNERS | 1 + helm/vault/CONTRIBUTING.md | 247 + helm/vault/Chart.yaml | 23 + helm/vault/LICENSE | 355 + helm/vault/Makefile | 101 + helm/vault/README.md | 43 + helm/vault/command/admin-policy.hcl | 3 + helm/vault/command/command.sh | 14 + helm/vault/override_values.yaml | 5 + helm/vault/templates/NOTES.txt | 14 + helm/vault/templates/_helpers.tpl | 996 ++ helm/vault/templates/csi-agent-configmap.yaml | 34 + helm/vault/templates/csi-clusterrole.yaml | 23 + .../templates/csi-clusterrolebinding.yaml | 24 + helm/vault/templates/csi-daemonset.yaml | 157 + helm/vault/templates/csi-role.yaml | 31 + helm/vault/templates/csi-rolebinding.yaml | 24 + helm/vault/templates/csi-serviceaccount.yaml | 21 + .../templates/injector-certs-secret.yaml | 19 + .../vault/templates/injector-clusterrole.yaml | 24 + .../injector-clusterrolebinding.yaml | 24 + helm/vault/templates/injector-deployment.yaml | 179 + .../templates/injector-disruptionbudget.yaml | 25 + .../templates/injector-mutating-webhook.yaml | 44 + .../templates/injector-network-policy.yaml | 29 + helm/vault/templates/injector-psp-role.yaml | 25 + .../templates/injector-psp-rolebinding.yaml | 26 + helm/vault/templates/injector-psp.yaml | 51 + helm/vault/templates/injector-role.yaml | 34 + .../vault/templates/injector-rolebinding.yaml | 27 + helm/vault/templates/injector-service.yaml | 27 + .../templates/injector-serviceaccount.yaml | 18 + .../templates/prometheus-prometheusrules.yaml | 31 + .../templates/prometheus-servicemonitor.yaml | 49 + .../templates/server-clusterrolebinding.yaml | 29 + .../templates/server-config-configmap.yaml | 45 + .../templates/server-discovery-role.yaml | 26 + .../server-discovery-rolebinding.yaml | 34 + .../templates/server-disruptionbudget.yaml | 31 + .../templates/server-ha-active-service.yaml | 55 + .../templates/server-ha-standby-service.yaml | 54 + .../templates/server-headless-service.yaml | 39 + helm/vault/templates/server-ingress.yaml | 69 + .../templates/server-network-policy.yaml | 31 + helm/vault/templates/server-psp-role.yaml | 25 + .../templates/server-psp-rolebinding.yaml | 26 + helm/vault/templates/server-psp.yaml | 54 + helm/vault/templates/server-route.yaml | 39 + helm/vault/templates/server-service.yaml | 51 + .../templates/server-serviceaccount.yaml | 22 + helm/vault/templates/server-statefulset.yaml | 217 + helm/vault/templates/tests/server-test.yaml | 56 + helm/vault/templates/ui-service.yaml | 42 + helm/vault/values.openshift.yaml | 21 + helm/vault/values.schema.json | 1144 ++ helm/vault/values.yaml | 1230 ++ scripts/README.md | 1 + yaml/README.md | 1 + 1632 files changed, 207616 insertions(+), 1 deletion(-) create mode 100644 docker/README.md create mode 100644 helm/README.md create mode 100644 helm/actions-runner-controller/.helmignore create mode 100644 helm/actions-runner-controller/Chart.yaml create mode 100644 helm/actions-runner-controller/README.md create mode 100644 helm/actions-runner-controller/ci/ci-values.yaml create mode 100644 helm/actions-runner-controller/crds/actions.summerwind.dev_horizontalrunnerautoscalers.yaml create mode 100644 helm/actions-runner-controller/crds/actions.summerwind.dev_runnerdeployments.yaml create mode 100644 helm/actions-runner-controller/crds/actions.summerwind.dev_runnerreplicasets.yaml create mode 100644 helm/actions-runner-controller/crds/actions.summerwind.dev_runners.yaml create mode 100644 helm/actions-runner-controller/crds/actions.summerwind.dev_runnersets.yaml create mode 100644 helm/actions-runner-controller/runner-deployment/dsk-agent-group.yaml create mode 100644 helm/actions-runner-controller/runner-deployment/dsk-devops-group.yaml create mode 100644 helm/actions-runner-controller/runner-deployment/dsk-front-group.yaml create mode 100644 helm/actions-runner-controller/templates/NOTES.txt create mode 100644 helm/actions-runner-controller/templates/_actions_metrics_server_helpers.tpl create mode 100644 helm/actions-runner-controller/templates/_github_webhook_server_helpers.tpl create mode 100644 helm/actions-runner-controller/templates/_helpers.tpl create mode 100644 helm/actions-runner-controller/templates/actionsmetrics.deployment.yaml create mode 100644 helm/actions-runner-controller/templates/actionsmetrics.ingress.yaml.yml create mode 100644 helm/actions-runner-controller/templates/actionsmetrics.role.yaml create mode 100644 helm/actions-runner-controller/templates/actionsmetrics.role_binding.yaml create mode 100644 helm/actions-runner-controller/templates/actionsmetrics.secrets.yaml create mode 100644 helm/actions-runner-controller/templates/actionsmetrics.service.yaml create mode 100644 helm/actions-runner-controller/templates/actionsmetrics.serviceaccount.yaml.yml create mode 100644 helm/actions-runner-controller/templates/actionsmetrics.servicemonitor.yaml.yml create mode 100644 helm/actions-runner-controller/templates/auth_proxy_role.yaml create mode 100644 helm/actions-runner-controller/templates/auth_proxy_role_binding.yaml create mode 100644 helm/actions-runner-controller/templates/certificate.yaml create mode 100644 helm/actions-runner-controller/templates/ci-secret.yaml create mode 100644 helm/actions-runner-controller/templates/controller.metrics.service.yaml create mode 100644 helm/actions-runner-controller/templates/controller.metrics.serviceMonitor.yaml create mode 100644 helm/actions-runner-controller/templates/controller.pdb.yaml create mode 100644 helm/actions-runner-controller/templates/deployment.yaml create mode 100644 helm/actions-runner-controller/templates/githubwebhook.deployment.yaml create mode 100644 helm/actions-runner-controller/templates/githubwebhook.ingress.yaml create mode 100644 helm/actions-runner-controller/templates/githubwebhook.pdb.yaml create mode 100644 helm/actions-runner-controller/templates/githubwebhook.role.yaml create mode 100644 helm/actions-runner-controller/templates/githubwebhook.role_binding.yaml create mode 100644 helm/actions-runner-controller/templates/githubwebhook.secrets.yaml create mode 100644 helm/actions-runner-controller/templates/githubwebhook.service.yaml create mode 100644 helm/actions-runner-controller/templates/githubwebhook.serviceMonitor.yaml create mode 100644 helm/actions-runner-controller/templates/githubwebhook.serviceaccount.yaml create mode 100644 helm/actions-runner-controller/templates/leader_election_role.yaml create mode 100644 helm/actions-runner-controller/templates/leader_election_role_binding.yaml create mode 100644 helm/actions-runner-controller/templates/manager_role.yaml create mode 100644 helm/actions-runner-controller/templates/manager_role_binding.yaml create mode 100644 helm/actions-runner-controller/templates/manager_role_binding_secrets.yaml create mode 100644 helm/actions-runner-controller/templates/manager_role_secrets.yaml create mode 100644 helm/actions-runner-controller/templates/manager_secrets.yaml create mode 100644 helm/actions-runner-controller/templates/runner_editor_role.yaml create mode 100644 helm/actions-runner-controller/templates/runner_viewer_role.yaml create mode 100644 helm/actions-runner-controller/templates/serviceaccount.yaml create mode 100644 helm/actions-runner-controller/templates/webhook_configs.yaml create mode 100644 helm/actions-runner-controller/templates/webhook_service.yaml create mode 100644 helm/actions-runner-controller/values.yaml create mode 100644 helm/airflow/.gitignore create mode 100644 helm/airflow/.helmignore create mode 100644 helm/airflow/Chart.lock create mode 100644 helm/airflow/Chart.yaml create mode 100644 helm/airflow/INSTALL create mode 100644 helm/airflow/LICENSE create mode 100644 helm/airflow/NOTICE create mode 100644 helm/airflow/README.md create mode 100644 helm/airflow/RELEASE_NOTES.rst create mode 100644 helm/airflow/charts/postgresql-12.10.0.tgz create mode 100644 helm/airflow/dockerfiles/README.md create mode 100644 helm/airflow/dockerfiles/pgbouncer-exporter/Dockerfile create mode 100755 helm/airflow/dockerfiles/pgbouncer-exporter/build_and_push.sh create mode 100644 helm/airflow/dockerfiles/pgbouncer/Dockerfile create mode 100755 helm/airflow/dockerfiles/pgbouncer/build_and_push.sh create mode 100644 helm/airflow/files/pod-template-file.kubernetes-helm-yaml create mode 100644 helm/airflow/files/statsd-mappings.yml create mode 100644 helm/airflow/newsfragments/31066.significant.rst create mode 100644 helm/airflow/newsfragments/33747.significant.rst create mode 100644 helm/airflow/newsfragments/33748.significant.rst create mode 100644 helm/airflow/newsfragments/34186.significant.rst create mode 100644 helm/airflow/newsfragments/config.toml create mode 100644 helm/airflow/override_values.yaml create mode 100644 helm/airflow/templates/NOTES.txt create mode 100644 helm/airflow/templates/_helpers.yaml create mode 100644 helm/airflow/templates/check-values.yaml create mode 100644 helm/airflow/templates/cleanup/cleanup-cronjob.yaml create mode 100644 helm/airflow/templates/cleanup/cleanup-serviceaccount.yaml create mode 100644 helm/airflow/templates/configmaps/configmap.yaml create mode 100644 helm/airflow/templates/configmaps/extra-configmaps.yaml create mode 100644 helm/airflow/templates/configmaps/statsd-configmap.yaml create mode 100644 helm/airflow/templates/configmaps/webserver-configmap.yaml create mode 100644 helm/airflow/templates/dag-processor/dag-processor-deployment.yaml create mode 100644 helm/airflow/templates/dag-processor/dag-processor-serviceaccount.yaml create mode 100644 helm/airflow/templates/dags-persistent-volume-claim.yaml create mode 100644 helm/airflow/templates/flower/flower-deployment.yaml create mode 100644 helm/airflow/templates/flower/flower-ingress.yaml create mode 100644 helm/airflow/templates/flower/flower-networkpolicy.yaml create mode 100644 helm/airflow/templates/flower/flower-service.yaml create mode 100644 helm/airflow/templates/flower/flower-serviceaccount.yaml create mode 100644 helm/airflow/templates/jobs/create-user-job-serviceaccount.yaml create mode 100644 helm/airflow/templates/jobs/create-user-job.yaml create mode 100644 helm/airflow/templates/jobs/migrate-database-job-serviceaccount.yaml create mode 100644 helm/airflow/templates/jobs/migrate-database-job.yaml create mode 100644 helm/airflow/templates/limitrange.yaml create mode 100644 helm/airflow/templates/logs-persistent-volume-claim.yaml create mode 100644 helm/airflow/templates/pgbouncer/pgbouncer-deployment.yaml create mode 100644 helm/airflow/templates/pgbouncer/pgbouncer-networkpolicy.yaml create mode 100644 helm/airflow/templates/pgbouncer/pgbouncer-poddisruptionbudget.yaml create mode 100644 helm/airflow/templates/pgbouncer/pgbouncer-service.yaml create mode 100644 helm/airflow/templates/pgbouncer/pgbouncer-serviceaccount.yaml create mode 100644 helm/airflow/templates/priorityclasses/priority-classes.yaml create mode 100644 helm/airflow/templates/rbac/pod-cleanup-role.yaml create mode 100644 helm/airflow/templates/rbac/pod-cleanup-rolebinding.yaml create mode 100644 helm/airflow/templates/rbac/pod-launcher-role.yaml create mode 100644 helm/airflow/templates/rbac/pod-launcher-rolebinding.yaml create mode 100644 helm/airflow/templates/rbac/pod-log-reader-role.yaml create mode 100644 helm/airflow/templates/rbac/pod-log-reader-rolebinding.yaml create mode 100644 helm/airflow/templates/rbac/security-context-constraint-rolebinding.yaml create mode 100644 helm/airflow/templates/redis/redis-networkpolicy.yaml create mode 100644 helm/airflow/templates/redis/redis-service.yaml create mode 100644 helm/airflow/templates/redis/redis-serviceaccount.yaml create mode 100644 helm/airflow/templates/redis/redis-statefulset.yaml create mode 100644 helm/airflow/templates/resourcequota.yaml create mode 100644 helm/airflow/templates/scheduler/scheduler-deployment.yaml create mode 100644 helm/airflow/templates/scheduler/scheduler-networkpolicy.yaml create mode 100644 helm/airflow/templates/scheduler/scheduler-poddisruptionbudget.yaml create mode 100644 helm/airflow/templates/scheduler/scheduler-service.yaml create mode 100644 helm/airflow/templates/scheduler/scheduler-serviceaccount.yaml create mode 100644 helm/airflow/templates/secrets/elasticsearch-secret.yaml create mode 100644 helm/airflow/templates/secrets/extra-secrets.yaml create mode 100644 helm/airflow/templates/secrets/fernetkey-secret.yaml create mode 100644 helm/airflow/templates/secrets/flower-secret.yaml create mode 100644 helm/airflow/templates/secrets/kerberos-keytab-secret.yaml create mode 100644 helm/airflow/templates/secrets/metadata-connection-secret.yaml create mode 100644 helm/airflow/templates/secrets/pgbouncer-certificates-secret.yaml create mode 100644 helm/airflow/templates/secrets/pgbouncer-config-secret.yaml create mode 100644 helm/airflow/templates/secrets/pgbouncer-stats-secret.yaml create mode 100644 helm/airflow/templates/secrets/redis-secrets.yaml create mode 100644 helm/airflow/templates/secrets/registry-secret.yaml create mode 100644 helm/airflow/templates/secrets/result-backend-connection-secret.yaml create mode 100644 helm/airflow/templates/secrets/webserver-secret-key-secret.yaml create mode 100644 helm/airflow/templates/statsd/statsd-deployment.yaml create mode 100644 helm/airflow/templates/statsd/statsd-networkpolicy.yaml create mode 100644 helm/airflow/templates/statsd/statsd-service.yaml create mode 100644 helm/airflow/templates/statsd/statsd-serviceaccount.yaml create mode 100644 helm/airflow/templates/triggerer/triggerer-deployment.yaml create mode 100644 helm/airflow/templates/triggerer/triggerer-kedaautoscaler.yaml create mode 100644 helm/airflow/templates/triggerer/triggerer-networkpolicy.yaml create mode 100644 helm/airflow/templates/triggerer/triggerer-service.yaml create mode 100644 helm/airflow/templates/triggerer/triggerer-serviceaccount.yaml create mode 100644 helm/airflow/templates/webserver/webserver-deployment.yaml create mode 100644 helm/airflow/templates/webserver/webserver-ingress.yaml create mode 100644 helm/airflow/templates/webserver/webserver-networkpolicy.yaml create mode 100644 helm/airflow/templates/webserver/webserver-poddisruptionbudget.yaml create mode 100644 helm/airflow/templates/webserver/webserver-service.yaml create mode 100644 helm/airflow/templates/webserver/webserver-serviceaccount.yaml create mode 100644 helm/airflow/templates/workers/worker-deployment.yaml create mode 100644 helm/airflow/templates/workers/worker-kedaautoscaler.yaml create mode 100644 helm/airflow/templates/workers/worker-networkpolicy.yaml create mode 100644 helm/airflow/templates/workers/worker-service.yaml create mode 100644 helm/airflow/templates/workers/worker-serviceaccount.yaml create mode 100644 helm/airflow/values.schema.json create mode 100644 helm/airflow/values.yaml create mode 100644 helm/airflow/values_schema.schema.json create mode 100644 helm/argo-cd/.helmignore create mode 100644 helm/argo-cd/Chart.lock create mode 100644 helm/argo-cd/Chart.yaml create mode 100644 helm/argo-cd/README.md create mode 100644 helm/argo-cd/README.md.gotmpl create mode 100644 helm/argo-cd/charts/redis-ha-4.22.4.tgz create mode 100644 helm/argo-cd/ci/default-values.yaml create mode 100644 helm/argo-cd/ci/external-redis-values.yaml create mode 100644 helm/argo-cd/ci/ha-autoscaling-values.yaml create mode 100644 helm/argo-cd/ci/ha-static-values.yaml create mode 100644 helm/argo-cd/override-values.yaml create mode 100644 helm/argo-cd/templates/NOTES.txt create mode 100644 helm/argo-cd/templates/_common.tpl create mode 100644 helm/argo-cd/templates/_helpers.tpl create mode 100644 helm/argo-cd/templates/_versions.tpl create mode 100644 helm/argo-cd/templates/aggregate-roles.yaml create mode 100644 helm/argo-cd/templates/argocd-application-controller/clusterrole.yaml create mode 100644 helm/argo-cd/templates/argocd-application-controller/clusterrolebinding.yaml create mode 100644 helm/argo-cd/templates/argocd-application-controller/metrics.yaml create mode 100644 helm/argo-cd/templates/argocd-application-controller/networkpolicy.yaml create mode 100644 helm/argo-cd/templates/argocd-application-controller/pdb.yaml create mode 100644 helm/argo-cd/templates/argocd-application-controller/prometheusrule.yaml create mode 100644 helm/argo-cd/templates/argocd-application-controller/role.yaml create mode 100644 helm/argo-cd/templates/argocd-application-controller/rolebinding.yaml create mode 100644 helm/argo-cd/templates/argocd-application-controller/serviceaccount.yaml create mode 100644 helm/argo-cd/templates/argocd-application-controller/servicemonitor.yaml create mode 100644 helm/argo-cd/templates/argocd-application-controller/statefulset.yaml create mode 100644 helm/argo-cd/templates/argocd-applicationset/deployment.yaml create mode 100644 helm/argo-cd/templates/argocd-applicationset/metrics.yaml create mode 100644 helm/argo-cd/templates/argocd-applicationset/networkpolicy.yaml create mode 100644 helm/argo-cd/templates/argocd-applicationset/pdb.yaml create mode 100644 helm/argo-cd/templates/argocd-applicationset/role.yaml create mode 100644 helm/argo-cd/templates/argocd-applicationset/rolebinding.yaml create mode 100644 helm/argo-cd/templates/argocd-applicationset/service.yaml create mode 100644 helm/argo-cd/templates/argocd-applicationset/serviceaccount.yaml create mode 100644 helm/argo-cd/templates/argocd-applicationset/servicemonitor.yaml create mode 100644 helm/argo-cd/templates/argocd-applicationset/webhook-ingress.yaml create mode 100644 helm/argo-cd/templates/argocd-configs/argocd-cm.yaml create mode 100644 helm/argo-cd/templates/argocd-configs/argocd-cmd-params-cm.yaml create mode 100644 helm/argo-cd/templates/argocd-configs/argocd-cmp-cm.yaml create mode 100644 helm/argo-cd/templates/argocd-configs/argocd-dex-server-tls-secret.yaml create mode 100644 helm/argo-cd/templates/argocd-configs/argocd-gpg-keys-cm.yaml create mode 100644 helm/argo-cd/templates/argocd-configs/argocd-notifications-cm.yaml create mode 100644 helm/argo-cd/templates/argocd-configs/argocd-notifications-secret.yaml create mode 100644 helm/argo-cd/templates/argocd-configs/argocd-rbac-cm.yaml create mode 100644 helm/argo-cd/templates/argocd-configs/argocd-repo-server-tls-secret.yaml create mode 100644 helm/argo-cd/templates/argocd-configs/argocd-secret.yaml create mode 100644 helm/argo-cd/templates/argocd-configs/argocd-server-tls-secret.yaml create mode 100644 helm/argo-cd/templates/argocd-configs/argocd-ssh-known-hosts-cm.yaml create mode 100644 helm/argo-cd/templates/argocd-configs/argocd-styles-cm.yaml create mode 100644 helm/argo-cd/templates/argocd-configs/argocd-tls-certs-cm.yaml create mode 100644 helm/argo-cd/templates/argocd-configs/cluster-secrets.yaml create mode 100644 helm/argo-cd/templates/argocd-configs/externalredis-secret.yaml create mode 100644 helm/argo-cd/templates/argocd-configs/repository-credentials-secret.yaml create mode 100644 helm/argo-cd/templates/argocd-configs/repository-secret.yaml create mode 100644 helm/argo-cd/templates/argocd-notifications/deployment.yaml create mode 100644 helm/argo-cd/templates/argocd-notifications/metrics.yaml create mode 100644 helm/argo-cd/templates/argocd-notifications/networkpolicy.yaml create mode 100644 helm/argo-cd/templates/argocd-notifications/pdb.yaml create mode 100644 helm/argo-cd/templates/argocd-notifications/role.yaml create mode 100644 helm/argo-cd/templates/argocd-notifications/rolebinding.yaml create mode 100644 helm/argo-cd/templates/argocd-notifications/serviceaccount.yaml create mode 100644 helm/argo-cd/templates/argocd-notifications/servicemonitor.yaml create mode 100644 helm/argo-cd/templates/argocd-repo-server/clusterrole.yaml create mode 100644 helm/argo-cd/templates/argocd-repo-server/clusterrolebinding.yaml create mode 100755 helm/argo-cd/templates/argocd-repo-server/deployment.yaml create mode 100644 helm/argo-cd/templates/argocd-repo-server/hpa.yaml create mode 100644 helm/argo-cd/templates/argocd-repo-server/metrics.yaml create mode 100644 helm/argo-cd/templates/argocd-repo-server/networkpolicy.yaml create mode 100644 helm/argo-cd/templates/argocd-repo-server/pdb.yaml create mode 100644 helm/argo-cd/templates/argocd-repo-server/role.yaml create mode 100644 helm/argo-cd/templates/argocd-repo-server/rolebinding.yaml create mode 100644 helm/argo-cd/templates/argocd-repo-server/service.yaml create mode 100644 helm/argo-cd/templates/argocd-repo-server/serviceaccount.yaml create mode 100644 helm/argo-cd/templates/argocd-repo-server/servicemonitor.yaml create mode 100644 helm/argo-cd/templates/argocd-server/aws/service.yaml create mode 100644 helm/argo-cd/templates/argocd-server/certificate.yaml create mode 100644 helm/argo-cd/templates/argocd-server/clusterrole.yaml create mode 100644 helm/argo-cd/templates/argocd-server/clusterrolebinding.yaml create mode 100755 helm/argo-cd/templates/argocd-server/deployment.yaml create mode 100644 helm/argo-cd/templates/argocd-server/gke/backendconfig.yaml create mode 100644 helm/argo-cd/templates/argocd-server/gke/frontendconfig.yaml create mode 100644 helm/argo-cd/templates/argocd-server/gke/managedcertificate.yaml create mode 100644 helm/argo-cd/templates/argocd-server/hpa.yaml create mode 100644 helm/argo-cd/templates/argocd-server/ingress-grpc.yaml create mode 100644 helm/argo-cd/templates/argocd-server/ingress.yaml create mode 100644 helm/argo-cd/templates/argocd-server/metrics.yaml create mode 100644 helm/argo-cd/templates/argocd-server/networkpolicy.yaml create mode 100644 helm/argo-cd/templates/argocd-server/openshift/route.yaml create mode 100644 helm/argo-cd/templates/argocd-server/pdb.yaml create mode 100644 helm/argo-cd/templates/argocd-server/role.yaml create mode 100644 helm/argo-cd/templates/argocd-server/rolebinding.yaml create mode 100644 helm/argo-cd/templates/argocd-server/service.yaml create mode 100644 helm/argo-cd/templates/argocd-server/serviceaccount.yaml create mode 100644 helm/argo-cd/templates/argocd-server/servicemonitor.yaml create mode 100644 helm/argo-cd/templates/crds/crd-application.yaml create mode 100644 helm/argo-cd/templates/crds/crd-applicationset.yaml create mode 100644 helm/argo-cd/templates/crds/crd-extension.yaml create mode 100644 helm/argo-cd/templates/crds/crd-project.yaml create mode 100755 helm/argo-cd/templates/dex/deployment.yaml create mode 100644 helm/argo-cd/templates/dex/networkpolicy.yaml create mode 100644 helm/argo-cd/templates/dex/pdb.yaml create mode 100644 helm/argo-cd/templates/dex/role.yaml create mode 100644 helm/argo-cd/templates/dex/rolebinding.yaml create mode 100644 helm/argo-cd/templates/dex/service.yaml create mode 100644 helm/argo-cd/templates/dex/serviceaccount.yaml create mode 100644 helm/argo-cd/templates/dex/servicemonitor.yaml create mode 100644 helm/argo-cd/templates/extra-manifests.yaml create mode 100644 helm/argo-cd/templates/networkpolicy-default-deny.yaml create mode 100755 helm/argo-cd/templates/redis/deployment.yaml create mode 100644 helm/argo-cd/templates/redis/metrics.yaml create mode 100644 helm/argo-cd/templates/redis/networkpolicy.yaml create mode 100644 helm/argo-cd/templates/redis/pdb.yaml create mode 100644 helm/argo-cd/templates/redis/service.yaml create mode 100644 helm/argo-cd/templates/redis/serviceaccount.yaml create mode 100644 helm/argo-cd/templates/redis/servicemonitor.yaml create mode 100755 helm/argo-cd/values.yaml create mode 100644 helm/argo-workflows/.helmignore create mode 100644 helm/argo-workflows/Chart.yaml create mode 100644 helm/argo-workflows/Lab/credentails/aws-secret.yaml create mode 100644 helm/argo-workflows/Lab/credentails/git-secret.yaml create mode 100644 helm/argo-workflows/Lab/credentails/kubeconfig.yaml create mode 100644 helm/argo-workflows/Lab/credentails/my-kubeconfig.yaml create mode 100644 helm/argo-workflows/Lab/db-backup/bastion-ssh-key.yaml create mode 100644 helm/argo-workflows/Lab/db-backup/db-backup-cron.yaml create mode 100644 helm/argo-workflows/Lab/db-backup/db-creds.yaml create mode 100644 helm/argo-workflows/Lab/db-backup/test-workflow.yaml create mode 100644 helm/argo-workflows/Lab/script.sh create mode 100644 helm/argo-workflows/Lab/steampipe-dashboard/00_Old/test-pod.yaml create mode 100644 helm/argo-workflows/Lab/steampipe-dashboard/00_Old/test-workflow.yaml create mode 100644 helm/argo-workflows/Lab/steampipe-dashboard/cron-steampipe-report.yaml create mode 100644 helm/argo-workflows/Lab/steampipe-dashboard/steampipe_configmap.yaml create mode 100644 helm/argo-workflows/Lab/steampipe-dsk-iac/00_Old/test-pod.yaml create mode 100644 helm/argo-workflows/Lab/steampipe-dsk-iac/00_Old/test-workflow.yaml create mode 100644 helm/argo-workflows/Lab/steampipe-dsk-iac/cron-steampipe.yaml create mode 100644 helm/argo-workflows/Lab/steampipe-dsk-iac/steampipe_configmap.yaml create mode 100644 helm/argo-workflows/Lab/steampipe.yaml create mode 100644 helm/argo-workflows/Lab/test.sh create mode 100644 helm/argo-workflows/Lab/ui-monitoring/cron_ui_monitoring.yaml create mode 100644 helm/argo-workflows/Lab/ui-monitoring/cron_ui_monitoring.yaml_bak create mode 100644 helm/argo-workflows/Lab/ui-monitoring/test/cron_ui_monitoring.yaml create mode 100644 helm/argo-workflows/Lab/ui-monitoring/ui_monitoring_configmap.yaml create mode 100644 helm/argo-workflows/README.md create mode 100644 helm/argo-workflows/override_values.yaml create mode 100644 helm/argo-workflows/templates/NOTES.txt create mode 100644 helm/argo-workflows/templates/_helpers.tpl create mode 100644 helm/argo-workflows/templates/controller/artifact-repository-ref-cm.yaml create mode 100644 helm/argo-workflows/templates/controller/workflow-aggregate-roles.yaml create mode 100644 helm/argo-workflows/templates/controller/workflow-controller-cluster-roles.yaml create mode 100644 helm/argo-workflows/templates/controller/workflow-controller-config-map.yaml create mode 100644 helm/argo-workflows/templates/controller/workflow-controller-crb.yaml create mode 100644 helm/argo-workflows/templates/controller/workflow-controller-deployment-pdb.yaml create mode 100644 helm/argo-workflows/templates/controller/workflow-controller-deployment.yaml create mode 100644 helm/argo-workflows/templates/controller/workflow-controller-sa.yaml create mode 100644 helm/argo-workflows/templates/controller/workflow-controller-service.yaml create mode 100644 helm/argo-workflows/templates/controller/workflow-controller-servicemonitor.yaml create mode 100644 helm/argo-workflows/templates/controller/workflow-rb.yaml create mode 100644 helm/argo-workflows/templates/controller/workflow-role.yaml create mode 100644 helm/argo-workflows/templates/controller/workflow-sa.yaml create mode 100644 helm/argo-workflows/templates/crds/argoproj.io_clusterworkflowtemplates.yaml create mode 100644 helm/argo-workflows/templates/crds/argoproj.io_cronworkflows.yaml create mode 100644 helm/argo-workflows/templates/crds/argoproj.io_workflowartifactgctasks.yaml create mode 100644 helm/argo-workflows/templates/crds/argoproj.io_workfloweventbindings.yaml create mode 100644 helm/argo-workflows/templates/crds/argoproj.io_workflows.yaml create mode 100644 helm/argo-workflows/templates/crds/argoproj.io_workflowtaskresults.yaml create mode 100644 helm/argo-workflows/templates/crds/argoproj.io_workflowtasksets.yaml create mode 100644 helm/argo-workflows/templates/crds/argoproj.io_workflowtemplates.yaml create mode 100644 helm/argo-workflows/templates/extra-manifests.yaml create mode 100644 helm/argo-workflows/templates/server/gke/backendconfig.yaml create mode 100644 helm/argo-workflows/templates/server/gke/frontendconfig.yaml create mode 100644 helm/argo-workflows/templates/server/gke/managedcertificate.yaml create mode 100644 helm/argo-workflows/templates/server/server-cluster-roles.yaml create mode 100644 helm/argo-workflows/templates/server/server-crb.yaml create mode 100644 helm/argo-workflows/templates/server/server-deployment-hpa.yaml create mode 100644 helm/argo-workflows/templates/server/server-deployment-pdb.yaml create mode 100644 helm/argo-workflows/templates/server/server-deployment.yaml create mode 100644 helm/argo-workflows/templates/server/server-ingress.yaml create mode 100644 helm/argo-workflows/templates/server/server-sa.yaml create mode 100644 helm/argo-workflows/templates/server/server-service.yaml create mode 100644 helm/argo-workflows/values.yaml create mode 100644 helm/awx-operator/.helmignore create mode 100644 helm/awx-operator/Chart.yaml create mode 100644 helm/awx-operator/README.md create mode 100644 helm/awx-operator/crds/customresourcedefinition-awxbackups.awx.ansible.com.yaml create mode 100644 helm/awx-operator/crds/customresourcedefinition-awxrestores.awx.ansible.com.yaml create mode 100644 helm/awx-operator/crds/customresourcedefinition-awxs.awx.ansible.com.yaml create mode 100644 helm/awx-operator/templates/NOTES.txt create mode 100644 helm/awx-operator/templates/_helpers.tpl create mode 100644 helm/awx-operator/templates/awx-deploy.yaml create mode 100644 helm/awx-operator/templates/clusterrole-awx-operator-metrics-reader.yaml create mode 100644 helm/awx-operator/templates/clusterrole-awx-operator-proxy-role.yaml create mode 100644 helm/awx-operator/templates/clusterrolebinding-awx-operator-proxy-rolebinding.yaml create mode 100644 helm/awx-operator/templates/configmap-awx-operator-awx-manager-config.yaml create mode 100644 helm/awx-operator/templates/deployment-awx-operator-controller-manager.yaml create mode 100644 helm/awx-operator/templates/postgres-config.yaml create mode 100644 helm/awx-operator/templates/role-awx-operator-awx-manager-role.yaml create mode 100644 helm/awx-operator/templates/role-awx-operator-leader-election-role.yaml create mode 100644 helm/awx-operator/templates/rolebinding-awx-operator-awx-manager-rolebinding.yaml create mode 100644 helm/awx-operator/templates/rolebinding-awx-operator-leader-election-rolebinding.yaml create mode 100644 helm/awx-operator/templates/service-awx-operator-controller-manager-metrics-service.yaml create mode 100644 helm/awx-operator/templates/serviceaccount-awx-operator-controller-manager.yaml create mode 100644 helm/awx-operator/values.yaml create mode 100644 helm/ghost/.helmignore create mode 100644 helm/ghost/Chart.lock create mode 100644 helm/ghost/Chart.yaml create mode 100644 helm/ghost/README.md create mode 100644 helm/ghost/charts/common/.helmignore create mode 100644 helm/ghost/charts/common/Chart.yaml create mode 100644 helm/ghost/charts/common/README.md create mode 100644 helm/ghost/charts/common/templates/_affinities.tpl create mode 100644 helm/ghost/charts/common/templates/_capabilities.tpl create mode 100644 helm/ghost/charts/common/templates/_errors.tpl create mode 100644 helm/ghost/charts/common/templates/_images.tpl create mode 100644 helm/ghost/charts/common/templates/_ingress.tpl create mode 100644 helm/ghost/charts/common/templates/_labels.tpl create mode 100644 helm/ghost/charts/common/templates/_names.tpl create mode 100644 helm/ghost/charts/common/templates/_secrets.tpl create mode 100644 helm/ghost/charts/common/templates/_storage.tpl create mode 100644 helm/ghost/charts/common/templates/_tplvalues.tpl create mode 100644 helm/ghost/charts/common/templates/_utils.tpl create mode 100644 helm/ghost/charts/common/templates/_warnings.tpl create mode 100644 helm/ghost/charts/common/templates/validations/_cassandra.tpl create mode 100644 helm/ghost/charts/common/templates/validations/_mariadb.tpl create mode 100644 helm/ghost/charts/common/templates/validations/_mongodb.tpl create mode 100644 helm/ghost/charts/common/templates/validations/_mysql.tpl create mode 100644 helm/ghost/charts/common/templates/validations/_postgresql.tpl create mode 100644 helm/ghost/charts/common/templates/validations/_redis.tpl create mode 100644 helm/ghost/charts/common/templates/validations/_validations.tpl create mode 100644 helm/ghost/charts/common/values.yaml create mode 100644 helm/ghost/charts/mysql/.helmignore create mode 100644 helm/ghost/charts/mysql/Chart.lock create mode 100644 helm/ghost/charts/mysql/Chart.yaml create mode 100644 helm/ghost/charts/mysql/README.md create mode 100644 helm/ghost/charts/mysql/charts/common/.helmignore create mode 100644 helm/ghost/charts/mysql/charts/common/Chart.yaml create mode 100644 helm/ghost/charts/mysql/charts/common/README.md create mode 100644 helm/ghost/charts/mysql/charts/common/templates/_affinities.tpl create mode 100644 helm/ghost/charts/mysql/charts/common/templates/_capabilities.tpl create mode 100644 helm/ghost/charts/mysql/charts/common/templates/_errors.tpl create mode 100644 helm/ghost/charts/mysql/charts/common/templates/_images.tpl create mode 100644 helm/ghost/charts/mysql/charts/common/templates/_ingress.tpl create mode 100644 helm/ghost/charts/mysql/charts/common/templates/_labels.tpl create mode 100644 helm/ghost/charts/mysql/charts/common/templates/_names.tpl create mode 100644 helm/ghost/charts/mysql/charts/common/templates/_secrets.tpl create mode 100644 helm/ghost/charts/mysql/charts/common/templates/_storage.tpl create mode 100644 helm/ghost/charts/mysql/charts/common/templates/_tplvalues.tpl create mode 100644 helm/ghost/charts/mysql/charts/common/templates/_utils.tpl create mode 100644 helm/ghost/charts/mysql/charts/common/templates/_warnings.tpl create mode 100644 helm/ghost/charts/mysql/charts/common/templates/validations/_cassandra.tpl create mode 100644 helm/ghost/charts/mysql/charts/common/templates/validations/_mariadb.tpl create mode 100644 helm/ghost/charts/mysql/charts/common/templates/validations/_mongodb.tpl create mode 100644 helm/ghost/charts/mysql/charts/common/templates/validations/_mysql.tpl create mode 100644 helm/ghost/charts/mysql/charts/common/templates/validations/_postgresql.tpl create mode 100644 helm/ghost/charts/mysql/charts/common/templates/validations/_redis.tpl create mode 100644 helm/ghost/charts/mysql/charts/common/templates/validations/_validations.tpl create mode 100644 helm/ghost/charts/mysql/charts/common/values.yaml create mode 100644 helm/ghost/charts/mysql/templates/NOTES.txt create mode 100644 helm/ghost/charts/mysql/templates/_helpers.tpl create mode 100644 helm/ghost/charts/mysql/templates/extra-list.yaml create mode 100644 helm/ghost/charts/mysql/templates/metrics-svc.yaml create mode 100644 helm/ghost/charts/mysql/templates/networkpolicy.yaml create mode 100644 helm/ghost/charts/mysql/templates/primary/configmap.yaml create mode 100644 helm/ghost/charts/mysql/templates/primary/initialization-configmap.yaml create mode 100644 helm/ghost/charts/mysql/templates/primary/pdb.yaml create mode 100644 helm/ghost/charts/mysql/templates/primary/statefulset.yaml create mode 100644 helm/ghost/charts/mysql/templates/primary/svc-headless.yaml create mode 100644 helm/ghost/charts/mysql/templates/primary/svc.yaml create mode 100644 helm/ghost/charts/mysql/templates/prometheusrule.yaml create mode 100644 helm/ghost/charts/mysql/templates/role.yaml create mode 100644 helm/ghost/charts/mysql/templates/rolebinding.yaml create mode 100644 helm/ghost/charts/mysql/templates/secondary/configmap.yaml create mode 100644 helm/ghost/charts/mysql/templates/secondary/pdb.yaml create mode 100644 helm/ghost/charts/mysql/templates/secondary/statefulset.yaml create mode 100644 helm/ghost/charts/mysql/templates/secondary/svc-headless.yaml create mode 100644 helm/ghost/charts/mysql/templates/secondary/svc.yaml create mode 100644 helm/ghost/charts/mysql/templates/secrets.yaml create mode 100644 helm/ghost/charts/mysql/templates/serviceaccount.yaml create mode 100644 helm/ghost/charts/mysql/templates/servicemonitor.yaml create mode 100644 helm/ghost/charts/mysql/values.schema.json create mode 100644 helm/ghost/charts/mysql/values.yaml create mode 100644 helm/ghost/override_values_blog.yaml create mode 100644 helm/ghost/override_values_docs.yaml create mode 100644 helm/ghost/templates/NOTES.txt create mode 100644 helm/ghost/templates/_helpers.tpl create mode 100644 helm/ghost/templates/deployment.yaml create mode 100644 helm/ghost/templates/external-db-secrets.yaml create mode 100644 helm/ghost/templates/extra-list.yaml create mode 100644 helm/ghost/templates/ingress.yaml create mode 100644 helm/ghost/templates/networkpolicy-backend-ingress.yaml create mode 100644 helm/ghost/templates/networkpolicy-egress.yaml create mode 100644 helm/ghost/templates/networkpolicy-ingress.yaml create mode 100644 helm/ghost/templates/pvc.yaml create mode 100644 helm/ghost/templates/secrets.yaml create mode 100644 helm/ghost/templates/service-account.yaml create mode 100644 helm/ghost/templates/svc.yaml create mode 100644 helm/ghost/templates/tls-secrets.yaml create mode 100644 helm/ghost/values.schema.json create mode 100644 helm/ghost/values.yaml create mode 100644 helm/grafana/.helmignore create mode 100644 helm/grafana/Chart.yaml create mode 100644 helm/grafana/README.md create mode 100644 helm/grafana/ci/default-values.yaml create mode 100644 helm/grafana/ci/with-affinity-values.yaml create mode 100644 helm/grafana/ci/with-dashboard-json-values.yaml create mode 100644 helm/grafana/ci/with-dashboard-values.yaml create mode 100644 helm/grafana/ci/with-extraconfigmapmounts-values.yaml create mode 100644 helm/grafana/ci/with-image-renderer-values.yaml create mode 100644 helm/grafana/ci/with-persistence.yaml create mode 100644 helm/grafana/dashboards/custom-dashboard.json create mode 100644 helm/grafana/templates/NOTES.txt create mode 100644 helm/grafana/templates/_helpers.tpl create mode 100644 helm/grafana/templates/_pod.tpl create mode 100644 helm/grafana/templates/clusterrole.yaml create mode 100644 helm/grafana/templates/clusterrolebinding.yaml create mode 100644 helm/grafana/templates/configmap-dashboard-provider.yaml create mode 100644 helm/grafana/templates/configmap.yaml create mode 100644 helm/grafana/templates/dashboards-json-configmap.yaml create mode 100644 helm/grafana/templates/deployment.yaml create mode 100644 helm/grafana/templates/extra-manifests.yaml create mode 100644 helm/grafana/templates/headless-service.yaml create mode 100644 helm/grafana/templates/hpa.yaml create mode 100644 helm/grafana/templates/image-renderer-deployment.yaml create mode 100644 helm/grafana/templates/image-renderer-hpa.yaml create mode 100644 helm/grafana/templates/image-renderer-network-policy.yaml create mode 100644 helm/grafana/templates/image-renderer-service.yaml create mode 100644 helm/grafana/templates/image-renderer-servicemonitor.yaml create mode 100644 helm/grafana/templates/ingress.yaml create mode 100644 helm/grafana/templates/networkpolicy.yaml create mode 100644 helm/grafana/templates/poddisruptionbudget.yaml create mode 100644 helm/grafana/templates/podsecuritypolicy.yaml create mode 100644 helm/grafana/templates/pvc.yaml create mode 100644 helm/grafana/templates/role.yaml create mode 100644 helm/grafana/templates/rolebinding.yaml create mode 100644 helm/grafana/templates/secret-env.yaml create mode 100644 helm/grafana/templates/secret.yaml create mode 100644 helm/grafana/templates/service.yaml create mode 100644 helm/grafana/templates/serviceaccount.yaml create mode 100644 helm/grafana/templates/servicemonitor.yaml create mode 100644 helm/grafana/templates/statefulset.yaml create mode 100644 helm/grafana/templates/tests/test-configmap.yaml create mode 100644 helm/grafana/templates/tests/test-podsecuritypolicy.yaml create mode 100644 helm/grafana/templates/tests/test-role.yaml create mode 100644 helm/grafana/templates/tests/test-rolebinding.yaml create mode 100644 helm/grafana/templates/tests/test-serviceaccount.yaml create mode 100644 helm/grafana/templates/tests/test.yaml create mode 100644 helm/grafana/values.yaml create mode 100644 helm/jenkins/.helmignore create mode 100644 helm/jenkins/CHANGELOG.md create mode 100644 helm/jenkins/Chart.yaml create mode 100644 helm/jenkins/README.md create mode 100644 helm/jenkins/Tiltfile create mode 100644 helm/jenkins/VALUES_SUMMARY.md create mode 100644 helm/jenkins/ci/default-values.yaml create mode 100644 helm/jenkins/ci/other-values.yaml create mode 100644 helm/jenkins/ci/with-secrets-values.yaml create mode 100644 helm/jenkins/override_values.yaml create mode 100644 helm/jenkins/templates/NOTES.txt create mode 100644 helm/jenkins/templates/_helpers.tpl create mode 100644 helm/jenkins/templates/config-init-scripts.yaml create mode 100644 helm/jenkins/templates/config.yaml create mode 100644 helm/jenkins/templates/deprecation.yaml create mode 100644 helm/jenkins/templates/home-pvc.yaml create mode 100644 helm/jenkins/templates/jcasc-config.yaml create mode 100644 helm/jenkins/templates/jenkins-agent-svc.yaml create mode 100644 helm/jenkins/templates/jenkins-aws-security-group-policies.yaml create mode 100644 helm/jenkins/templates/jenkins-backup-cronjob.yaml create mode 100644 helm/jenkins/templates/jenkins-backup-rbac.yaml create mode 100644 helm/jenkins/templates/jenkins-controller-alerting-rules.yaml create mode 100644 helm/jenkins/templates/jenkins-controller-backendconfig.yaml create mode 100644 helm/jenkins/templates/jenkins-controller-ingress.yaml create mode 100644 helm/jenkins/templates/jenkins-controller-networkpolicy.yaml create mode 100644 helm/jenkins/templates/jenkins-controller-pdb.yaml create mode 100644 helm/jenkins/templates/jenkins-controller-podmonitor.yaml create mode 100644 helm/jenkins/templates/jenkins-controller-route.yaml create mode 100644 helm/jenkins/templates/jenkins-controller-secondary-ingress.yaml create mode 100644 helm/jenkins/templates/jenkins-controller-servicemonitor.yaml create mode 100644 helm/jenkins/templates/jenkins-controller-statefulset.yaml create mode 100644 helm/jenkins/templates/jenkins-controller-svc.yaml create mode 100644 helm/jenkins/templates/rbac.yaml create mode 100644 helm/jenkins/templates/secret-additional.yaml create mode 100644 helm/jenkins/templates/secret-claims.yaml create mode 100644 helm/jenkins/templates/secret-https-jks.yaml create mode 100644 helm/jenkins/templates/secret.yaml create mode 100644 helm/jenkins/templates/service-account-agent.yaml create mode 100644 helm/jenkins/templates/service-account.yaml create mode 100644 helm/jenkins/templates/tests/jenkins-test.yaml create mode 100644 helm/jenkins/templates/tests/test-config.yaml create mode 100644 helm/jenkins/unittests/__snapshot__/jenkins-controller-statefulset-test.yaml.snap create mode 100644 helm/jenkins/unittests/config-init-scripts-test.yaml create mode 100644 helm/jenkins/unittests/config-test.yaml create mode 100644 helm/jenkins/unittests/home-pvc-test.yaml create mode 100644 helm/jenkins/unittests/jcasc-config-test.yaml create mode 100644 helm/jenkins/unittests/jenkins-agent-svc-test.yaml create mode 100644 helm/jenkins/unittests/jenkins-backup-cronjob-test.yaml create mode 100644 helm/jenkins/unittests/jenkins-controller-alerting-rules-test.yaml create mode 100644 helm/jenkins/unittests/jenkins-controller-ingress-1.19-test.yaml create mode 100644 helm/jenkins/unittests/jenkins-controller-ingress-test.yaml create mode 100644 helm/jenkins/unittests/jenkins-controller-networkpolicy-test.yaml create mode 100644 helm/jenkins/unittests/jenkins-controller-pdb-1.21-test.yaml create mode 100644 helm/jenkins/unittests/jenkins-controller-pdb-test.yaml create mode 100644 helm/jenkins/unittests/jenkins-controller-secondary-ingress-1.19-test.yaml create mode 100644 helm/jenkins/unittests/jenkins-controller-secondary-ingress-test.yaml create mode 100644 helm/jenkins/unittests/jenkins-controller-servicemonitor_test.yaml create mode 100644 helm/jenkins/unittests/jenkins-controller-statefulset-test.yaml create mode 100644 helm/jenkins/unittests/jenkins-controller-svc-test.yaml create mode 100644 helm/jenkins/unittests/rbac-test.yaml create mode 100644 helm/jenkins/unittests/secret-additional-test.yaml create mode 100644 helm/jenkins/unittests/secret-claims-test.yaml create mode 100644 helm/jenkins/unittests/secret-existing-test.yaml create mode 100644 helm/jenkins/unittests/secret-test.yaml create mode 100644 helm/jenkins/unittests/service-account-agent-test.yaml create mode 100644 helm/jenkins/unittests/service-account-test.yaml create mode 100644 helm/jenkins/values.yaml create mode 100644 helm/nexus-repository-manager/.helmignore create mode 100644 helm/nexus-repository-manager/Chart.yaml create mode 100644 helm/nexus-repository-manager/LICENSE create mode 100644 helm/nexus-repository-manager/README.md create mode 100644 helm/nexus-repository-manager/override-values.yaml create mode 100644 helm/nexus-repository-manager/templates/NOTES.txt create mode 100644 helm/nexus-repository-manager/templates/_helpers.tpl create mode 100644 helm/nexus-repository-manager/templates/configmap-properties.yaml create mode 100644 helm/nexus-repository-manager/templates/configmap.yaml create mode 100644 helm/nexus-repository-manager/templates/deployment.yaml create mode 100644 helm/nexus-repository-manager/templates/ingress.yaml create mode 100644 helm/nexus-repository-manager/templates/proxy-route.yaml create mode 100644 helm/nexus-repository-manager/templates/pv.yaml create mode 100644 helm/nexus-repository-manager/templates/pvc.yaml create mode 100644 helm/nexus-repository-manager/templates/route.yaml create mode 100644 helm/nexus-repository-manager/templates/secret.yaml create mode 100644 helm/nexus-repository-manager/templates/service.yaml create mode 100644 helm/nexus-repository-manager/templates/serviceaccount.yaml create mode 100644 helm/nexus-repository-manager/values.yaml create mode 100644 helm/nfs-provisioner-nas/Chart.yaml create mode 100644 helm/nfs-provisioner-nas/README.md create mode 100644 helm/nfs-provisioner-nas/ci/test-values.yaml create mode 100644 helm/nfs-provisioner-nas/override-values.yaml create mode 100644 helm/nfs-provisioner-nas/templates/_helpers.tpl create mode 100644 helm/nfs-provisioner-nas/templates/clusterrole.yaml create mode 100644 helm/nfs-provisioner-nas/templates/clusterrolebinding.yaml create mode 100644 helm/nfs-provisioner-nas/templates/deployment.yaml create mode 100644 helm/nfs-provisioner-nas/templates/persistentvolume.yaml create mode 100644 helm/nfs-provisioner-nas/templates/persistentvolumeclaim.yaml create mode 100644 helm/nfs-provisioner-nas/templates/podsecuritypolicy.yaml create mode 100644 helm/nfs-provisioner-nas/templates/role.yaml create mode 100644 helm/nfs-provisioner-nas/templates/rolebinding.yaml create mode 100644 helm/nfs-provisioner-nas/templates/serviceaccount.yaml create mode 100644 helm/nfs-provisioner-nas/templates/storageclass.yaml create mode 100644 helm/nfs-provisioner-nas/test/configmap.yaml create mode 100644 helm/nfs-provisioner-nas/test/deployment.yaml create mode 100644 helm/nfs-provisioner-nas/test/pvc.yaml create mode 100644 helm/nfs-provisioner-nas/values.yaml create mode 100644 helm/openebs/Chart.lock create mode 100644 helm/openebs/Chart.yaml create mode 100644 helm/openebs/OWNERS create mode 100644 helm/openebs/README.md create mode 100644 helm/openebs/charts/cstor/.helmignore create mode 100644 helm/openebs/charts/cstor/Chart.lock create mode 100644 helm/openebs/charts/cstor/Chart.yaml create mode 100644 helm/openebs/charts/cstor/README.md create mode 100644 helm/openebs/charts/cstor/charts/openebs-ndm/Chart.yaml create mode 100644 helm/openebs/charts/cstor/charts/openebs-ndm/README.md create mode 100644 helm/openebs/charts/cstor/charts/openebs-ndm/crds/blockdevice.yaml create mode 100644 helm/openebs/charts/cstor/charts/openebs-ndm/crds/blockdeviceclaim.yaml create mode 100644 helm/openebs/charts/cstor/charts/openebs-ndm/templates/NOTES.txt create mode 100644 helm/openebs/charts/cstor/charts/openebs-ndm/templates/_helpers.tpl create mode 100644 helm/openebs/charts/cstor/charts/openebs-ndm/templates/cluster-exporter-service.yaml create mode 100644 helm/openebs/charts/cstor/charts/openebs-ndm/templates/cluster-exporter.yaml create mode 100644 helm/openebs/charts/cstor/charts/openebs-ndm/templates/configmap.yaml create mode 100644 helm/openebs/charts/cstor/charts/openebs-ndm/templates/daemonset.yaml create mode 100644 helm/openebs/charts/cstor/charts/openebs-ndm/templates/deployment.yaml create mode 100644 helm/openebs/charts/cstor/charts/openebs-ndm/templates/node-exporter-service.yaml create mode 100644 helm/openebs/charts/cstor/charts/openebs-ndm/templates/node-exporter.yaml create mode 100644 helm/openebs/charts/cstor/charts/openebs-ndm/templates/rbac.yaml create mode 100644 helm/openebs/charts/cstor/charts/openebs-ndm/values.yaml create mode 100644 helm/openebs/charts/cstor/crds/cstorbackup.yaml create mode 100644 helm/openebs/charts/cstor/crds/cstorcompletedbackup.yaml create mode 100644 helm/openebs/charts/cstor/crds/cstorpoolcluster.yaml create mode 100644 helm/openebs/charts/cstor/crds/cstorpoolinstance.yaml create mode 100644 helm/openebs/charts/cstor/crds/cstorrestore.yaml create mode 100644 helm/openebs/charts/cstor/crds/cstorvolume.yaml create mode 100644 helm/openebs/charts/cstor/crds/cstorvolumeattachment.yaml create mode 100644 helm/openebs/charts/cstor/crds/cstorvolumeconfig.yaml create mode 100644 helm/openebs/charts/cstor/crds/cstorvolumepolicy.yaml create mode 100644 helm/openebs/charts/cstor/crds/cstorvolumereplica.yaml create mode 100644 helm/openebs/charts/cstor/crds/migrationtask.yaml create mode 100644 helm/openebs/charts/cstor/crds/upgradetask.yaml create mode 100644 helm/openebs/charts/cstor/crds/volumesnapshot.yaml create mode 100644 helm/openebs/charts/cstor/crds/volumesnapshotclass.yaml create mode 100644 helm/openebs/charts/cstor/crds/volumesnapshotcontent.yaml create mode 100644 helm/openebs/charts/cstor/templates/NOTES.txt create mode 100644 helm/openebs/charts/cstor/templates/_helpers.tpl create mode 100644 helm/openebs/charts/cstor/templates/admission-server.yaml create mode 100644 helm/openebs/charts/cstor/templates/cleanup-webhook.yaml create mode 100644 helm/openebs/charts/cstor/templates/csi-controller-rbac.yaml create mode 100644 helm/openebs/charts/cstor/templates/csi-controller.yaml create mode 100644 helm/openebs/charts/cstor/templates/csi-driver.yaml create mode 100644 helm/openebs/charts/cstor/templates/csi-iscsiadm-config.yaml create mode 100644 helm/openebs/charts/cstor/templates/csi-node-rbac.yaml create mode 100644 helm/openebs/charts/cstor/templates/csi-node.yaml create mode 100644 helm/openebs/charts/cstor/templates/cspc-operator.yaml create mode 100644 helm/openebs/charts/cstor/templates/cvc-operator-service.yaml create mode 100644 helm/openebs/charts/cstor/templates/cvc-operator.yaml create mode 100644 helm/openebs/charts/cstor/templates/priority-class.yaml create mode 100644 helm/openebs/charts/cstor/templates/psp.yaml create mode 100644 helm/openebs/charts/cstor/templates/rbac.yaml create mode 100644 helm/openebs/charts/cstor/templates/snapshot-class.yaml create mode 100644 helm/openebs/charts/cstor/values.yaml create mode 100644 helm/openebs/charts/jiva/.helmignore create mode 100644 helm/openebs/charts/jiva/Chart.lock create mode 100644 helm/openebs/charts/jiva/Chart.yaml create mode 100644 helm/openebs/charts/jiva/README.md create mode 100644 helm/openebs/charts/jiva/charts/localpv-provisioner/.helmignore create mode 100644 helm/openebs/charts/jiva/charts/localpv-provisioner/Chart.lock create mode 100644 helm/openebs/charts/jiva/charts/localpv-provisioner/Chart.yaml create mode 100644 helm/openebs/charts/jiva/charts/localpv-provisioner/README.md create mode 100644 helm/openebs/charts/jiva/charts/localpv-provisioner/charts/openebs-ndm/Chart.yaml create mode 100644 helm/openebs/charts/jiva/charts/localpv-provisioner/charts/openebs-ndm/README.md create mode 100644 helm/openebs/charts/jiva/charts/localpv-provisioner/charts/openebs-ndm/crds/blockdevice.yaml create mode 100644 helm/openebs/charts/jiva/charts/localpv-provisioner/charts/openebs-ndm/crds/blockdeviceclaim.yaml create mode 100644 helm/openebs/charts/jiva/charts/localpv-provisioner/charts/openebs-ndm/templates/NOTES.txt create mode 100644 helm/openebs/charts/jiva/charts/localpv-provisioner/charts/openebs-ndm/templates/_helpers.tpl create mode 100644 helm/openebs/charts/jiva/charts/localpv-provisioner/charts/openebs-ndm/templates/cluster-exporter-service.yaml create mode 100644 helm/openebs/charts/jiva/charts/localpv-provisioner/charts/openebs-ndm/templates/cluster-exporter.yaml create mode 100644 helm/openebs/charts/jiva/charts/localpv-provisioner/charts/openebs-ndm/templates/configmap.yaml create mode 100644 helm/openebs/charts/jiva/charts/localpv-provisioner/charts/openebs-ndm/templates/daemonset.yaml create mode 100644 helm/openebs/charts/jiva/charts/localpv-provisioner/charts/openebs-ndm/templates/deployment.yaml create mode 100644 helm/openebs/charts/jiva/charts/localpv-provisioner/charts/openebs-ndm/templates/node-exporter-service.yaml create mode 100644 helm/openebs/charts/jiva/charts/localpv-provisioner/charts/openebs-ndm/templates/node-exporter.yaml create mode 100644 helm/openebs/charts/jiva/charts/localpv-provisioner/charts/openebs-ndm/templates/rbac.yaml create mode 100644 helm/openebs/charts/jiva/charts/localpv-provisioner/charts/openebs-ndm/values.yaml create mode 100644 helm/openebs/charts/jiva/charts/localpv-provisioner/templates/NOTES.txt create mode 100644 helm/openebs/charts/jiva/charts/localpv-provisioner/templates/_helpers.tpl create mode 100644 helm/openebs/charts/jiva/charts/localpv-provisioner/templates/deployment.yaml create mode 100644 helm/openebs/charts/jiva/charts/localpv-provisioner/templates/device-class.yaml create mode 100644 helm/openebs/charts/jiva/charts/localpv-provisioner/templates/hostpath-class.yaml create mode 100644 helm/openebs/charts/jiva/charts/localpv-provisioner/templates/psp.yaml create mode 100644 helm/openebs/charts/jiva/charts/localpv-provisioner/templates/rbac.yaml create mode 100644 helm/openebs/charts/jiva/charts/localpv-provisioner/values.yaml create mode 100644 helm/openebs/charts/jiva/crds/jivavolumepolicy.yaml create mode 100644 helm/openebs/charts/jiva/crds/jivavolumes.yaml create mode 100644 helm/openebs/charts/jiva/crds/upgradetask.yaml create mode 100644 helm/openebs/charts/jiva/templates/NOTES.txt create mode 100644 helm/openebs/charts/jiva/templates/_helpers.tpl create mode 100644 helm/openebs/charts/jiva/templates/csi-controller-rbac.yaml create mode 100644 helm/openebs/charts/jiva/templates/csi-controller.yaml create mode 100644 helm/openebs/charts/jiva/templates/csi-driver.yaml create mode 100644 helm/openebs/charts/jiva/templates/csi-iscsiadm-config.yaml create mode 100644 helm/openebs/charts/jiva/templates/csi-node-rbac.yaml create mode 100644 helm/openebs/charts/jiva/templates/csi-node.yaml create mode 100644 helm/openebs/charts/jiva/templates/default-policy.yaml create mode 100644 helm/openebs/charts/jiva/templates/default-storageclass.yaml create mode 100644 helm/openebs/charts/jiva/templates/jiva-operator-rbac.yaml create mode 100644 helm/openebs/charts/jiva/templates/jiva-operator.yaml create mode 100644 helm/openebs/charts/jiva/templates/priority-class.yaml create mode 100644 helm/openebs/charts/jiva/templates/psp.yaml create mode 100644 helm/openebs/charts/jiva/values.yaml create mode 100644 helm/openebs/charts/localpv-provisioner/.helmignore create mode 100644 helm/openebs/charts/localpv-provisioner/Chart.lock create mode 100644 helm/openebs/charts/localpv-provisioner/Chart.yaml create mode 100644 helm/openebs/charts/localpv-provisioner/README.md create mode 100644 helm/openebs/charts/localpv-provisioner/charts/openebs-ndm/Chart.yaml create mode 100644 helm/openebs/charts/localpv-provisioner/charts/openebs-ndm/README.md create mode 100644 helm/openebs/charts/localpv-provisioner/charts/openebs-ndm/crds/blockdevice.yaml create mode 100644 helm/openebs/charts/localpv-provisioner/charts/openebs-ndm/crds/blockdeviceclaim.yaml create mode 100644 helm/openebs/charts/localpv-provisioner/charts/openebs-ndm/templates/NOTES.txt create mode 100644 helm/openebs/charts/localpv-provisioner/charts/openebs-ndm/templates/_helpers.tpl create mode 100644 helm/openebs/charts/localpv-provisioner/charts/openebs-ndm/templates/cluster-exporter-service.yaml create mode 100644 helm/openebs/charts/localpv-provisioner/charts/openebs-ndm/templates/cluster-exporter.yaml create mode 100644 helm/openebs/charts/localpv-provisioner/charts/openebs-ndm/templates/configmap.yaml create mode 100644 helm/openebs/charts/localpv-provisioner/charts/openebs-ndm/templates/daemonset.yaml create mode 100644 helm/openebs/charts/localpv-provisioner/charts/openebs-ndm/templates/deployment.yaml create mode 100644 helm/openebs/charts/localpv-provisioner/charts/openebs-ndm/templates/node-exporter-service.yaml create mode 100644 helm/openebs/charts/localpv-provisioner/charts/openebs-ndm/templates/node-exporter.yaml create mode 100644 helm/openebs/charts/localpv-provisioner/charts/openebs-ndm/templates/rbac.yaml create mode 100644 helm/openebs/charts/localpv-provisioner/charts/openebs-ndm/values.yaml create mode 100644 helm/openebs/charts/localpv-provisioner/templates/NOTES.txt create mode 100644 helm/openebs/charts/localpv-provisioner/templates/_helpers.tpl create mode 100644 helm/openebs/charts/localpv-provisioner/templates/deployment.yaml create mode 100644 helm/openebs/charts/localpv-provisioner/templates/device-class.yaml create mode 100644 helm/openebs/charts/localpv-provisioner/templates/hostpath-class.yaml create mode 100644 helm/openebs/charts/localpv-provisioner/templates/psp.yaml create mode 100644 helm/openebs/charts/localpv-provisioner/templates/rbac.yaml create mode 100644 helm/openebs/charts/localpv-provisioner/values.yaml create mode 100644 helm/openebs/charts/lvm-localpv/.helmignore create mode 100644 helm/openebs/charts/lvm-localpv/Chart.yaml create mode 100644 helm/openebs/charts/lvm-localpv/README.md create mode 100644 helm/openebs/charts/lvm-localpv/crds/lvmnode.yaml create mode 100644 helm/openebs/charts/lvm-localpv/crds/lvmsnapshot.yaml create mode 100644 helm/openebs/charts/lvm-localpv/crds/lvmvolume.yaml create mode 100644 helm/openebs/charts/lvm-localpv/templates/NOTES.txt create mode 100644 helm/openebs/charts/lvm-localpv/templates/_helpers.tpl create mode 100644 helm/openebs/charts/lvm-localpv/templates/csidriver.yaml create mode 100644 helm/openebs/charts/lvm-localpv/templates/lvm-controller.yaml create mode 100644 helm/openebs/charts/lvm-localpv/templates/lvm-node-service.yaml create mode 100644 helm/openebs/charts/lvm-localpv/templates/lvm-node.yaml create mode 100644 helm/openebs/charts/lvm-localpv/templates/priority-class.yaml create mode 100644 helm/openebs/charts/lvm-localpv/templates/psp.yaml create mode 100644 helm/openebs/charts/lvm-localpv/templates/rbac.yaml create mode 100644 helm/openebs/charts/lvm-localpv/templates/volumesnapshotclasses-crd.yaml create mode 100644 helm/openebs/charts/lvm-localpv/templates/volumesnapshotcontents-crd.yaml create mode 100644 helm/openebs/charts/lvm-localpv/templates/volumesnapshots-crd.yaml create mode 100644 helm/openebs/charts/lvm-localpv/values.yaml create mode 100644 helm/openebs/charts/mayastor/.helmignore create mode 100644 helm/openebs/charts/mayastor/Chart.lock create mode 100644 helm/openebs/charts/mayastor/Chart.yaml create mode 100644 helm/openebs/charts/mayastor/README.md.tmpl create mode 100644 helm/openebs/charts/mayastor/charts/etcd/.helmignore create mode 100644 helm/openebs/charts/mayastor/charts/etcd/Chart.lock create mode 100644 helm/openebs/charts/mayastor/charts/etcd/Chart.yaml create mode 100644 helm/openebs/charts/mayastor/charts/etcd/README.md create mode 100644 helm/openebs/charts/mayastor/charts/etcd/charts/common/.helmignore create mode 100644 helm/openebs/charts/mayastor/charts/etcd/charts/common/Chart.yaml create mode 100644 helm/openebs/charts/mayastor/charts/etcd/charts/common/README.md create mode 100644 helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/_affinities.tpl create mode 100644 helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/_capabilities.tpl create mode 100644 helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/_errors.tpl create mode 100644 helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/_images.tpl create mode 100644 helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/_ingress.tpl create mode 100644 helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/_labels.tpl create mode 100644 helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/_names.tpl create mode 100644 helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/_secrets.tpl create mode 100644 helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/_storage.tpl create mode 100644 helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/_tplvalues.tpl create mode 100644 helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/_utils.tpl create mode 100644 helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/_warnings.tpl create mode 100644 helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/validations/_cassandra.tpl create mode 100644 helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/validations/_mariadb.tpl create mode 100644 helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/validations/_mongodb.tpl create mode 100644 helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/validations/_mysql.tpl create mode 100644 helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/validations/_postgresql.tpl create mode 100644 helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/validations/_redis.tpl create mode 100644 helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/validations/_validations.tpl create mode 100644 helm/openebs/charts/mayastor/charts/etcd/charts/common/values.yaml create mode 100644 helm/openebs/charts/mayastor/charts/etcd/templates/NOTES.txt create mode 100644 helm/openebs/charts/mayastor/charts/etcd/templates/_helpers.tpl create mode 100644 helm/openebs/charts/mayastor/charts/etcd/templates/configmap.yaml create mode 100644 helm/openebs/charts/mayastor/charts/etcd/templates/cronjob.yaml create mode 100644 helm/openebs/charts/mayastor/charts/etcd/templates/extra-list.yaml create mode 100644 helm/openebs/charts/mayastor/charts/etcd/templates/networkpolicy.yaml create mode 100644 helm/openebs/charts/mayastor/charts/etcd/templates/pdb.yaml create mode 100644 helm/openebs/charts/mayastor/charts/etcd/templates/podmonitor.yaml create mode 100644 helm/openebs/charts/mayastor/charts/etcd/templates/prometheusrule.yaml create mode 100644 helm/openebs/charts/mayastor/charts/etcd/templates/secrets.yaml create mode 100644 helm/openebs/charts/mayastor/charts/etcd/templates/serviceaccount.yaml create mode 100644 helm/openebs/charts/mayastor/charts/etcd/templates/snapshot-pvc.yaml create mode 100644 helm/openebs/charts/mayastor/charts/etcd/templates/statefulset.yaml create mode 100644 helm/openebs/charts/mayastor/charts/etcd/templates/svc-headless.yaml create mode 100644 helm/openebs/charts/mayastor/charts/etcd/templates/svc.yaml create mode 100644 helm/openebs/charts/mayastor/charts/etcd/templates/token-secrets.yaml create mode 100644 helm/openebs/charts/mayastor/charts/etcd/values.yaml create mode 100644 helm/openebs/charts/mayastor/charts/jaeger-operator/.helmignore create mode 100644 helm/openebs/charts/mayastor/charts/jaeger-operator/Chart.yaml create mode 100644 helm/openebs/charts/mayastor/charts/jaeger-operator/README.md create mode 100644 helm/openebs/charts/mayastor/charts/jaeger-operator/crds/crd.yaml create mode 100644 helm/openebs/charts/mayastor/charts/jaeger-operator/templates/NOTES.txt create mode 100644 helm/openebs/charts/mayastor/charts/jaeger-operator/templates/_helpers.tpl create mode 100644 helm/openebs/charts/mayastor/charts/jaeger-operator/templates/crds.yaml create mode 100644 helm/openebs/charts/mayastor/charts/jaeger-operator/templates/deployment.yaml create mode 100644 helm/openebs/charts/mayastor/charts/jaeger-operator/templates/jaeger.yaml create mode 100644 helm/openebs/charts/mayastor/charts/jaeger-operator/templates/psp.yaml create mode 100644 helm/openebs/charts/mayastor/charts/jaeger-operator/templates/role-binding.yaml create mode 100644 helm/openebs/charts/mayastor/charts/jaeger-operator/templates/role.yaml create mode 100644 helm/openebs/charts/mayastor/charts/jaeger-operator/templates/service-account.yaml create mode 100644 helm/openebs/charts/mayastor/charts/jaeger-operator/templates/service.yaml create mode 100644 helm/openebs/charts/mayastor/charts/jaeger-operator/values.yaml create mode 100644 helm/openebs/charts/mayastor/charts/localpv-provisioner/.helmignore create mode 100644 helm/openebs/charts/mayastor/charts/localpv-provisioner/Chart.lock create mode 100644 helm/openebs/charts/mayastor/charts/localpv-provisioner/Chart.yaml create mode 100644 helm/openebs/charts/mayastor/charts/localpv-provisioner/README.md create mode 100644 helm/openebs/charts/mayastor/charts/localpv-provisioner/charts/openebs-ndm/Chart.yaml create mode 100644 helm/openebs/charts/mayastor/charts/localpv-provisioner/charts/openebs-ndm/README.md create mode 100644 helm/openebs/charts/mayastor/charts/localpv-provisioner/charts/openebs-ndm/crds/blockdevice.yaml create mode 100644 helm/openebs/charts/mayastor/charts/localpv-provisioner/charts/openebs-ndm/crds/blockdeviceclaim.yaml create mode 100644 helm/openebs/charts/mayastor/charts/localpv-provisioner/charts/openebs-ndm/templates/NOTES.txt create mode 100644 helm/openebs/charts/mayastor/charts/localpv-provisioner/charts/openebs-ndm/templates/_helpers.tpl create mode 100644 helm/openebs/charts/mayastor/charts/localpv-provisioner/charts/openebs-ndm/templates/cluster-exporter-service.yaml create mode 100644 helm/openebs/charts/mayastor/charts/localpv-provisioner/charts/openebs-ndm/templates/cluster-exporter.yaml create mode 100644 helm/openebs/charts/mayastor/charts/localpv-provisioner/charts/openebs-ndm/templates/configmap.yaml create mode 100644 helm/openebs/charts/mayastor/charts/localpv-provisioner/charts/openebs-ndm/templates/daemonset.yaml create mode 100644 helm/openebs/charts/mayastor/charts/localpv-provisioner/charts/openebs-ndm/templates/deployment.yaml create mode 100644 helm/openebs/charts/mayastor/charts/localpv-provisioner/charts/openebs-ndm/templates/node-exporter-service.yaml create mode 100644 helm/openebs/charts/mayastor/charts/localpv-provisioner/charts/openebs-ndm/templates/node-exporter.yaml create mode 100644 helm/openebs/charts/mayastor/charts/localpv-provisioner/charts/openebs-ndm/templates/rbac.yaml create mode 100644 helm/openebs/charts/mayastor/charts/localpv-provisioner/charts/openebs-ndm/values.yaml create mode 100644 helm/openebs/charts/mayastor/charts/localpv-provisioner/templates/NOTES.txt create mode 100644 helm/openebs/charts/mayastor/charts/localpv-provisioner/templates/_helpers.tpl create mode 100644 helm/openebs/charts/mayastor/charts/localpv-provisioner/templates/deployment.yaml create mode 100644 helm/openebs/charts/mayastor/charts/localpv-provisioner/templates/device-class.yaml create mode 100644 helm/openebs/charts/mayastor/charts/localpv-provisioner/templates/hostpath-class.yaml create mode 100644 helm/openebs/charts/mayastor/charts/localpv-provisioner/templates/psp.yaml create mode 100644 helm/openebs/charts/mayastor/charts/localpv-provisioner/templates/rbac.yaml create mode 100644 helm/openebs/charts/mayastor/charts/localpv-provisioner/values.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/.helmignore create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/Chart.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/README.md create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/.helmignore create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/Chart.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/Makefile create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/README.md create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/default/Makefile create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/default/README.md create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/default/test/goss.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/deployment/Makefile create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/deployment/README.md create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/deployment/test/goss.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/deployment/values.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/oss/Makefile create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/oss/README.md create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/oss/test/goss.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/oss/values.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/security/Makefile create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/security/README.md create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/security/test/goss.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/security/values.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/upgrade/Makefile create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/upgrade/README.md create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/upgrade/test/goss.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/upgrade/values.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/templates/NOTES.txt create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/templates/_helpers.tpl create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/templates/clusterrole.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/templates/clusterrolebinding.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/templates/configmap.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/templates/daemonset.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/templates/deployment.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/templates/role.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/templates/rolebinding.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/templates/serviceaccount.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/values.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/fluent-bit/.helmignore create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/fluent-bit/Chart.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/fluent-bit/README.md create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/fluent-bit/templates/NOTES.txt create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/fluent-bit/templates/_helpers.tpl create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/fluent-bit/templates/clusterrole.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/fluent-bit/templates/clusterrolebinding.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/fluent-bit/templates/configmap.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/fluent-bit/templates/daemonset.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/fluent-bit/templates/podsecuritypolicy.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/fluent-bit/templates/role.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/fluent-bit/templates/rolebinding.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/fluent-bit/templates/service-headless.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/fluent-bit/templates/serviceaccount.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/fluent-bit/templates/servicemonitor.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/fluent-bit/values.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/.helmignore create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/Chart.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/README.md create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/ci/default-values.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/ci/with-dashboard-json-values.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/ci/with-dashboard-values.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/ci/with-image-renderer-values.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/dashboards/custom-dashboard.json create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/NOTES.txt create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/_helpers.tpl create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/_pod.tpl create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/clusterrole.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/clusterrolebinding.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/configmap-dashboard-provider.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/configmap.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/dashboards-json-configmap.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/deployment.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/extra-manifests.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/headless-service.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/hpa.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/image-renderer-deployment.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/image-renderer-network-policy.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/image-renderer-service.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/ingress.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/networkpolicy.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/poddisruptionbudget.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/podsecuritypolicy.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/pvc.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/role.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/rolebinding.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/secret-env.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/secret.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/service.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/serviceaccount.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/servicemonitor.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/statefulset.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/tests/test-configmap.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/tests/test-podsecuritypolicy.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/tests/test-role.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/tests/test-rolebinding.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/tests/test-serviceaccount.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/tests/test.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/values.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/.helmignore create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/Chart.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/Makefile create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/README.md create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/default/Makefile create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/default/README.md create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/default/test/goss.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/elasticsearch/Makefile create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/elasticsearch/README.md create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/elasticsearch/test/goss.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/elasticsearch/values.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/oss/Makefile create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/oss/README.md create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/oss/test/goss.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/oss/values.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/security/Makefile create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/security/README.md create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/security/test/goss.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/security/values.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/upgrade/Makefile create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/upgrade/README.md create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/upgrade/test/goss.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/upgrade/values.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/templates/NOTES.txt create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/templates/_helpers.tpl create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/templates/configmap-config.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/templates/configmap-pattern.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/templates/configmap-pipeline.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/templates/ingress.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/templates/poddisruptionbudget.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/templates/podsecuritypolicy.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/templates/role.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/templates/rolebinding.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/templates/secret.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/templates/service-headless.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/templates/service.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/templates/serviceaccount.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/templates/statefulset.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/values.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/.helmignore create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/Chart.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/README.md create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/templates/NOTES.txt create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/templates/_helpers.tpl create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/templates/configmap-alert.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/templates/ingress.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/templates/networkpolicy.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/templates/pdb.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/templates/podsecuritypolicy.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/templates/prometheusrule.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/templates/role.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/templates/rolebinding.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/templates/secret.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/templates/service-headless.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/templates/service.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/templates/serviceaccount.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/templates/servicemonitor.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/templates/statefulset.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/values.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/.helmignore create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/Chart.lock create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/Chart.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/README.md create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/.helmignore create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/Chart.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/README.md create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/templates/NOTES.txt create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/templates/_helpers.tpl create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/templates/clusterrolebinding.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/templates/deployment.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/templates/kubeconfig-secret.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/templates/pdb.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/templates/podsecuritypolicy.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/templates/psp-clusterrole.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/templates/psp-clusterrolebinding.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/templates/role.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/templates/rolebinding.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/templates/service.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/templates/serviceaccount.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/templates/servicemonitor.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/templates/stsdiscovery-role.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/templates/stsdiscovery-rolebinding.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/values.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/NOTES.txt create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/_helpers.tpl create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/alertmanager/clusterrole.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/alertmanager/clusterrolebinding.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/alertmanager/cm.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/alertmanager/deploy.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/alertmanager/headless-svc.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/alertmanager/ingress.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/alertmanager/netpol.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/alertmanager/pdb.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/alertmanager/psp.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/alertmanager/pvc.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/alertmanager/role.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/alertmanager/rolebinding.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/alertmanager/service.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/alertmanager/serviceaccount.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/alertmanager/sts.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/node-exporter/daemonset.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/node-exporter/psp.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/node-exporter/role.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/node-exporter/rolebinding.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/node-exporter/serviceaccount.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/node-exporter/svc.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/pushgateway/clusterrole.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/pushgateway/clusterrolebinding.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/pushgateway/deploy.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/pushgateway/ingress.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/pushgateway/netpol.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/pushgateway/pdb.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/pushgateway/psp.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/pushgateway/pvc.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/pushgateway/service.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/pushgateway/serviceaccount.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/pushgateway/vpa.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/server/clusterrole.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/server/clusterrolebinding.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/server/cm.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/server/deploy.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/server/headless-svc.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/server/ingress.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/server/netpol.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/server/pdb.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/server/psp.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/server/pvc.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/server/rolebinding.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/server/service.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/server/serviceaccount.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/server/sts.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/server/vpa.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/values.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/.helmignore create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/Chart.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/README.md create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/README.md.gotmpl create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/ci/default-values.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/ci/netpol-values.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/ci/service-values.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/templates/NOTES.txt create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/templates/_helpers.tpl create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/templates/clusterrole.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/templates/clusterrolebinding.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/templates/daemonset.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/templates/extra-manifests.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/templates/networkpolicy.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/templates/podsecuritypolicy.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/templates/role.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/templates/rolebinding.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/templates/secret.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/templates/service-extra.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/templates/service-metrics.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/templates/serviceaccount.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/templates/servicemonitor.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/values.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/requirements.lock create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/requirements.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/templates/NOTES.txt create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/templates/_helpers.tpl create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/templates/datasources.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/templates/tests/loki-test-configmap.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/templates/tests/loki-test-pod.yaml create mode 100644 helm/openebs/charts/mayastor/charts/loki-stack/values.yaml create mode 100644 helm/openebs/charts/mayastor/charts/nats/.helmignore create mode 100644 helm/openebs/charts/mayastor/charts/nats/Chart.yaml create mode 100644 helm/openebs/charts/mayastor/charts/nats/README.md create mode 100644 helm/openebs/charts/mayastor/charts/nats/templates/NOTES.txt create mode 100644 helm/openebs/charts/mayastor/charts/nats/templates/_helpers.tpl create mode 100644 helm/openebs/charts/mayastor/charts/nats/templates/configmap.yaml create mode 100644 helm/openebs/charts/mayastor/charts/nats/templates/nats-box.yaml create mode 100644 helm/openebs/charts/mayastor/charts/nats/templates/networkpolicy.yaml create mode 100644 helm/openebs/charts/mayastor/charts/nats/templates/pdb.yaml create mode 100644 helm/openebs/charts/mayastor/charts/nats/templates/rbac.yaml create mode 100644 helm/openebs/charts/mayastor/charts/nats/templates/service.yaml create mode 100644 helm/openebs/charts/mayastor/charts/nats/templates/serviceMonitor.yaml create mode 100644 helm/openebs/charts/mayastor/charts/nats/templates/statefulset.yaml create mode 100644 helm/openebs/charts/mayastor/charts/nats/templates/tests/test-request-reply.yaml create mode 100644 helm/openebs/charts/mayastor/charts/nats/values.yaml create mode 100644 helm/openebs/charts/mayastor/crds/csi-volume-snapshot-class.yaml create mode 100644 helm/openebs/charts/mayastor/crds/csi-volume-snapshot-content.yaml create mode 100644 helm/openebs/charts/mayastor/crds/csi-volume-snapshot.yaml create mode 100644 helm/openebs/charts/mayastor/crds/jaeger.yaml create mode 100644 helm/openebs/charts/mayastor/doc.yaml create mode 100644 helm/openebs/charts/mayastor/product.yaml create mode 100644 helm/openebs/charts/mayastor/templates/NOTES.txt create mode 100644 helm/openebs/charts/mayastor/templates/_helpers.tpl create mode 100644 helm/openebs/charts/mayastor/templates/etcd/storage/localpv-storageclass.yaml create mode 100644 helm/openebs/charts/mayastor/templates/etcd/storage/localpv.yaml create mode 100644 helm/openebs/charts/mayastor/templates/jaeger-operator/jaeger.yaml create mode 100644 helm/openebs/charts/mayastor/templates/loki-stack/storage/localpv-storageclass.yaml create mode 100644 helm/openebs/charts/mayastor/templates/loki-stack/storage/localpv.yaml create mode 100644 helm/openebs/charts/mayastor/templates/mayastor/agents/core/agent-core-deployment.yaml create mode 100644 helm/openebs/charts/mayastor/templates/mayastor/agents/core/agent-core-service.yaml create mode 100644 helm/openebs/charts/mayastor/templates/mayastor/agents/ha/ha-node-daemonset.yaml create mode 100644 helm/openebs/charts/mayastor/templates/mayastor/apis/api-rest-deployment.yaml create mode 100644 helm/openebs/charts/mayastor/templates/mayastor/apis/api-rest-service.yaml create mode 100644 helm/openebs/charts/mayastor/templates/mayastor/csi/csi-controller-deployment.yaml create mode 100644 helm/openebs/charts/mayastor/templates/mayastor/csi/csi-node-daemonset.yaml create mode 100644 helm/openebs/charts/mayastor/templates/mayastor/io/io-engine-daemonset.yaml create mode 100644 helm/openebs/charts/mayastor/templates/mayastor/metrics/metrics-exporter-pool-service.yaml create mode 100644 helm/openebs/charts/mayastor/templates/mayastor/obs/obs-callhome-deployment.yaml create mode 100644 helm/openebs/charts/mayastor/templates/mayastor/obs/stats-service.yaml create mode 100644 helm/openebs/charts/mayastor/templates/mayastor/operators/operator-diskpool-deployment.yaml create mode 100644 helm/openebs/charts/mayastor/templates/mayastor/priority-class/priority-class.yaml create mode 100644 helm/openebs/charts/mayastor/templates/mayastor/rbac/rbac.yaml create mode 100644 helm/openebs/charts/mayastor/templates/storageclass.yaml create mode 100644 helm/openebs/charts/mayastor/values.yaml create mode 100644 helm/openebs/charts/nfs-provisioner/Chart.yaml create mode 100644 helm/openebs/charts/nfs-provisioner/README.md create mode 100644 helm/openebs/charts/nfs-provisioner/templates/NOTES.txt create mode 100644 helm/openebs/charts/nfs-provisioner/templates/_helpers.tpl create mode 100644 helm/openebs/charts/nfs-provisioner/templates/clusterrole.yaml create mode 100644 helm/openebs/charts/nfs-provisioner/templates/clusterrolebinding.yaml create mode 100644 helm/openebs/charts/nfs-provisioner/templates/deployment.yaml create mode 100644 helm/openebs/charts/nfs-provisioner/templates/kernel-nfs-storageclass.yaml create mode 100644 helm/openebs/charts/nfs-provisioner/templates/psp.yaml create mode 100644 helm/openebs/charts/nfs-provisioner/templates/serviceaccount.yaml create mode 100644 helm/openebs/charts/nfs-provisioner/values.yaml create mode 100644 helm/openebs/charts/openebs-ndm/Chart.yaml create mode 100644 helm/openebs/charts/openebs-ndm/README.md create mode 100644 helm/openebs/charts/openebs-ndm/crds/blockdevice.yaml create mode 100644 helm/openebs/charts/openebs-ndm/crds/blockdeviceclaim.yaml create mode 100644 helm/openebs/charts/openebs-ndm/templates/NOTES.txt create mode 100644 helm/openebs/charts/openebs-ndm/templates/_helpers.tpl create mode 100644 helm/openebs/charts/openebs-ndm/templates/cluster-exporter-service.yaml create mode 100644 helm/openebs/charts/openebs-ndm/templates/cluster-exporter.yaml create mode 100644 helm/openebs/charts/openebs-ndm/templates/configmap.yaml create mode 100644 helm/openebs/charts/openebs-ndm/templates/daemonset.yaml create mode 100644 helm/openebs/charts/openebs-ndm/templates/deployment.yaml create mode 100644 helm/openebs/charts/openebs-ndm/templates/node-exporter-service.yaml create mode 100644 helm/openebs/charts/openebs-ndm/templates/node-exporter.yaml create mode 100644 helm/openebs/charts/openebs-ndm/templates/rbac.yaml create mode 100644 helm/openebs/charts/openebs-ndm/values.yaml create mode 100644 helm/openebs/charts/zfs-localpv/.helmignore create mode 100644 helm/openebs/charts/zfs-localpv/Chart.yaml create mode 100644 helm/openebs/charts/zfs-localpv/README.md create mode 100644 helm/openebs/charts/zfs-localpv/crds/volumesnapshotclasses.yaml create mode 100644 helm/openebs/charts/zfs-localpv/crds/volumesnapshotcontents.yaml create mode 100644 helm/openebs/charts/zfs-localpv/crds/volumesnapshots.yaml create mode 100644 helm/openebs/charts/zfs-localpv/crds/zfsbackup.yaml create mode 100644 helm/openebs/charts/zfs-localpv/crds/zfsnode.yaml create mode 100644 helm/openebs/charts/zfs-localpv/crds/zfsrestore.yaml create mode 100644 helm/openebs/charts/zfs-localpv/crds/zfssnapshot.yaml create mode 100644 helm/openebs/charts/zfs-localpv/crds/zfsvolume.yaml create mode 100644 helm/openebs/charts/zfs-localpv/templates/NOTES.txt create mode 100644 helm/openebs/charts/zfs-localpv/templates/_helpers.tpl create mode 100644 helm/openebs/charts/zfs-localpv/templates/configmap.yaml create mode 100644 helm/openebs/charts/zfs-localpv/templates/csidriver.yaml create mode 100644 helm/openebs/charts/zfs-localpv/templates/priority-class.yaml create mode 100644 helm/openebs/charts/zfs-localpv/templates/psp.yaml create mode 100644 helm/openebs/charts/zfs-localpv/templates/rbac.yaml create mode 100644 helm/openebs/charts/zfs-localpv/templates/zfs-contoller.yaml create mode 100644 helm/openebs/charts/zfs-localpv/templates/zfs-node.yaml create mode 100644 helm/openebs/charts/zfs-localpv/values.yaml create mode 100644 helm/openebs/crds/blockdevice.yaml create mode 100644 helm/openebs/crds/blockdeviceclaim.yaml create mode 100644 helm/openebs/override_values.yaml create mode 100644 helm/openebs/templates/NOTES.txt create mode 100644 helm/openebs/templates/_helpers.tpl create mode 100644 helm/openebs/templates/clusterrole.yaml create mode 100644 helm/openebs/templates/clusterrolebinding.yaml create mode 100644 helm/openebs/templates/kyverno/allow-capabilities.yaml create mode 100644 helm/openebs/templates/kyverno/allow-host-namespaces.yaml create mode 100644 helm/openebs/templates/kyverno/allow-host-ports.yaml create mode 100644 helm/openebs/templates/kyverno/allow-privilege-escalation.yaml create mode 100644 helm/openebs/templates/kyverno/allow-privileged-containers.yaml create mode 100644 helm/openebs/templates/kyverno/allow-proc-mount.yaml create mode 100644 helm/openebs/templates/kyverno/allow-selinux.yaml create mode 100644 helm/openebs/templates/kyverno/require-user-groups.yaml create mode 100644 helm/openebs/templates/legacy/cleanup-webhook.yaml create mode 100644 helm/openebs/templates/legacy/deployment-admission-server.yaml create mode 100644 helm/openebs/templates/legacy/deployment-maya-apiserver.yaml create mode 100644 helm/openebs/templates/legacy/deployment-maya-provisioner.yaml create mode 100644 helm/openebs/templates/legacy/deployment-maya-snapshot-operator.yaml create mode 100644 helm/openebs/templates/legacy/service-maya-apiserver.yaml create mode 100644 helm/openebs/templates/localprovisioner/deployment-local-provisioner.yaml create mode 100644 helm/openebs/templates/localprovisioner/device-class.yaml create mode 100644 helm/openebs/templates/localprovisioner/hostpath-class.yaml create mode 100644 helm/openebs/templates/ndm/cluster-exporter-service.yaml create mode 100644 helm/openebs/templates/ndm/cluster-exporter.yaml create mode 100644 helm/openebs/templates/ndm/cm-node-disk-manager.yaml create mode 100644 helm/openebs/templates/ndm/daemonset-ndm.yaml create mode 100644 helm/openebs/templates/ndm/deployment-ndm-operator.yaml create mode 100644 helm/openebs/templates/ndm/node-exporter-service.yaml create mode 100644 helm/openebs/templates/ndm/node-exporter.yaml create mode 100644 helm/openebs/templates/psp-clusterrole.yaml create mode 100644 helm/openebs/templates/psp-clusterrolebinding.yaml create mode 100644 helm/openebs/templates/psp.yaml create mode 100644 helm/openebs/templates/serviceaccount.yaml create mode 100644 helm/openebs/values.yaml create mode 100644 helm/sonarqube/.helmignore create mode 100644 helm/sonarqube/CHANGELOG.md create mode 100644 helm/sonarqube/Chart.lock create mode 100644 helm/sonarqube/Chart.yaml create mode 100644 helm/sonarqube/README.md create mode 100644 helm/sonarqube/charts/ingress-nginx/.helmignore create mode 100644 helm/sonarqube/charts/ingress-nginx/CHANGELOG.md create mode 100644 helm/sonarqube/charts/ingress-nginx/Chart.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/OWNERS create mode 100644 helm/sonarqube/charts/ingress-nginx/README.md create mode 100644 helm/sonarqube/charts/ingress-nginx/README.md.gotmpl create mode 100644 helm/sonarqube/charts/ingress-nginx/changelog.md.gotmpl create mode 100644 helm/sonarqube/charts/ingress-nginx/changelog/.gitkeep create mode 100644 helm/sonarqube/charts/ingress-nginx/changelog/Changelog-4.5.2.md create mode 100644 helm/sonarqube/charts/ingress-nginx/changelog/Changelog-4.6.0.md create mode 100644 helm/sonarqube/charts/ingress-nginx/changelog/Changelog-4.6.1.md create mode 100644 helm/sonarqube/charts/ingress-nginx/changelog/Changelog-4.7.0.md create mode 100644 helm/sonarqube/charts/ingress-nginx/changelog/Changelog-4.7.1.md create mode 100644 helm/sonarqube/charts/ingress-nginx/ci/controller-admission-tls-cert-manager-values.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/ci/controller-custom-ingressclass-flags.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/ci/daemonset-customconfig-values.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/ci/daemonset-customnodeport-values.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/ci/daemonset-extra-modules.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/ci/daemonset-headers-values.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/ci/daemonset-internal-lb-values.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/ci/daemonset-nodeport-values.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/ci/daemonset-podannotations-values.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/ci/daemonset-tcp-udp-configMapNamespace-values.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/ci/daemonset-tcp-udp-portNamePrefix-values.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/ci/daemonset-tcp-udp-values.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/ci/daemonset-tcp-values.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/ci/deamonset-default-values.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/ci/deamonset-metrics-values.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/ci/deamonset-psp-values.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/ci/deamonset-webhook-and-psp-values.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/ci/deamonset-webhook-values.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/ci/deployment-autoscaling-behavior-values.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/ci/deployment-autoscaling-values.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/ci/deployment-customconfig-values.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/ci/deployment-customnodeport-values.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/ci/deployment-default-values.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/ci/deployment-extra-modules-default-container-sec-context.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/ci/deployment-extra-modules-specific-container-sec-context.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/ci/deployment-extra-modules.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/ci/deployment-headers-values.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/ci/deployment-internal-lb-values.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/ci/deployment-metrics-values.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/ci/deployment-nodeport-values.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/ci/deployment-podannotations-values.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/ci/deployment-psp-values.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/ci/deployment-tcp-udp-configMapNamespace-values.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/ci/deployment-tcp-udp-portNamePrefix-values.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/ci/deployment-tcp-udp-values.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/ci/deployment-tcp-values.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/ci/deployment-webhook-and-psp-values.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/ci/deployment-webhook-extraEnvs-values.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/ci/deployment-webhook-resources-values.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/ci/deployment-webhook-values.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/templates/NOTES.txt create mode 100644 helm/sonarqube/charts/ingress-nginx/templates/_helpers.tpl create mode 100644 helm/sonarqube/charts/ingress-nginx/templates/_params.tpl create mode 100644 helm/sonarqube/charts/ingress-nginx/templates/admission-webhooks/cert-manager.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/templates/admission-webhooks/job-patch/clusterrole.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/templates/admission-webhooks/job-patch/clusterrolebinding.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/templates/admission-webhooks/job-patch/job-createSecret.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/templates/admission-webhooks/job-patch/job-patchWebhook.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/templates/admission-webhooks/job-patch/networkpolicy.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/templates/admission-webhooks/job-patch/psp.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/templates/admission-webhooks/job-patch/role.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/templates/admission-webhooks/job-patch/rolebinding.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/templates/admission-webhooks/job-patch/serviceaccount.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/templates/admission-webhooks/validating-webhook.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/templates/clusterrole.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/templates/clusterrolebinding.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/templates/controller-configmap-addheaders.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/templates/controller-configmap-proxyheaders.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/templates/controller-configmap-tcp.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/templates/controller-configmap-udp.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/templates/controller-configmap.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/templates/controller-daemonset.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/templates/controller-deployment.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/templates/controller-hpa.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/templates/controller-ingressclass.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/templates/controller-keda.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/templates/controller-poddisruptionbudget.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/templates/controller-prometheusrules.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/templates/controller-psp.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/templates/controller-role.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/templates/controller-rolebinding.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/templates/controller-secret.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/templates/controller-service-internal.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/templates/controller-service-metrics.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/templates/controller-service-webhook.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/templates/controller-service.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/templates/controller-serviceaccount.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/templates/controller-servicemonitor.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/templates/controller-webhooks-networkpolicy.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/templates/default-backend-deployment.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/templates/default-backend-hpa.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/templates/default-backend-poddisruptionbudget.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/templates/default-backend-psp.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/templates/default-backend-role.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/templates/default-backend-rolebinding.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/templates/default-backend-service.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/templates/default-backend-serviceaccount.yaml create mode 100644 helm/sonarqube/charts/ingress-nginx/values.yaml create mode 100644 helm/sonarqube/charts/postgresql/.helmignore create mode 100644 helm/sonarqube/charts/postgresql/Chart.lock create mode 100644 helm/sonarqube/charts/postgresql/Chart.yaml create mode 100644 helm/sonarqube/charts/postgresql/README.md create mode 100644 helm/sonarqube/charts/postgresql/charts/common/.helmignore create mode 100644 helm/sonarqube/charts/postgresql/charts/common/Chart.yaml create mode 100644 helm/sonarqube/charts/postgresql/charts/common/README.md create mode 100644 helm/sonarqube/charts/postgresql/charts/common/templates/_affinities.tpl create mode 100644 helm/sonarqube/charts/postgresql/charts/common/templates/_capabilities.tpl create mode 100644 helm/sonarqube/charts/postgresql/charts/common/templates/_errors.tpl create mode 100644 helm/sonarqube/charts/postgresql/charts/common/templates/_images.tpl create mode 100644 helm/sonarqube/charts/postgresql/charts/common/templates/_ingress.tpl create mode 100644 helm/sonarqube/charts/postgresql/charts/common/templates/_labels.tpl create mode 100644 helm/sonarqube/charts/postgresql/charts/common/templates/_names.tpl create mode 100644 helm/sonarqube/charts/postgresql/charts/common/templates/_secrets.tpl create mode 100644 helm/sonarqube/charts/postgresql/charts/common/templates/_storage.tpl create mode 100644 helm/sonarqube/charts/postgresql/charts/common/templates/_tplvalues.tpl create mode 100644 helm/sonarqube/charts/postgresql/charts/common/templates/_utils.tpl create mode 100644 helm/sonarqube/charts/postgresql/charts/common/templates/_warnings.tpl create mode 100644 helm/sonarqube/charts/postgresql/charts/common/templates/validations/_cassandra.tpl create mode 100644 helm/sonarqube/charts/postgresql/charts/common/templates/validations/_mariadb.tpl create mode 100644 helm/sonarqube/charts/postgresql/charts/common/templates/validations/_mongodb.tpl create mode 100644 helm/sonarqube/charts/postgresql/charts/common/templates/validations/_postgresql.tpl create mode 100644 helm/sonarqube/charts/postgresql/charts/common/templates/validations/_redis.tpl create mode 100644 helm/sonarqube/charts/postgresql/charts/common/templates/validations/_validations.tpl create mode 100644 helm/sonarqube/charts/postgresql/charts/common/values.yaml create mode 100644 helm/sonarqube/charts/postgresql/ci/commonAnnotations.yaml create mode 100644 helm/sonarqube/charts/postgresql/ci/default-values.yaml create mode 100644 helm/sonarqube/charts/postgresql/ci/shmvolume-disabled-values.yaml create mode 100644 helm/sonarqube/charts/postgresql/files/README.md create mode 100644 helm/sonarqube/charts/postgresql/files/conf.d/README.md create mode 100644 helm/sonarqube/charts/postgresql/files/docker-entrypoint-initdb.d/README.md create mode 100644 helm/sonarqube/charts/postgresql/templates/NOTES.txt create mode 100644 helm/sonarqube/charts/postgresql/templates/_helpers.tpl create mode 100644 helm/sonarqube/charts/postgresql/templates/configmap.yaml create mode 100644 helm/sonarqube/charts/postgresql/templates/extended-config-configmap.yaml create mode 100644 helm/sonarqube/charts/postgresql/templates/extra-list.yaml create mode 100644 helm/sonarqube/charts/postgresql/templates/initialization-configmap.yaml create mode 100644 helm/sonarqube/charts/postgresql/templates/metrics-configmap.yaml create mode 100644 helm/sonarqube/charts/postgresql/templates/metrics-svc.yaml create mode 100644 helm/sonarqube/charts/postgresql/templates/networkpolicy.yaml create mode 100644 helm/sonarqube/charts/postgresql/templates/podsecuritypolicy.yaml create mode 100644 helm/sonarqube/charts/postgresql/templates/prometheusrule.yaml create mode 100644 helm/sonarqube/charts/postgresql/templates/role.yaml create mode 100644 helm/sonarqube/charts/postgresql/templates/rolebinding.yaml create mode 100644 helm/sonarqube/charts/postgresql/templates/secrets.yaml create mode 100644 helm/sonarqube/charts/postgresql/templates/serviceaccount.yaml create mode 100644 helm/sonarqube/charts/postgresql/templates/servicemonitor.yaml create mode 100644 helm/sonarqube/charts/postgresql/templates/statefulset-readreplicas.yaml create mode 100644 helm/sonarqube/charts/postgresql/templates/statefulset.yaml create mode 100644 helm/sonarqube/charts/postgresql/templates/svc-headless.yaml create mode 100644 helm/sonarqube/charts/postgresql/templates/svc-read-set.yaml create mode 100644 helm/sonarqube/charts/postgresql/templates/svc-read.yaml create mode 100644 helm/sonarqube/charts/postgresql/templates/svc.yaml create mode 100644 helm/sonarqube/charts/postgresql/templates/tls-secrets.yaml create mode 100644 helm/sonarqube/charts/postgresql/values.schema.json create mode 100644 helm/sonarqube/charts/postgresql/values.yaml create mode 100644 helm/sonarqube/override_values.yaml create mode 100644 helm/sonarqube/templates/NOTES.txt create mode 100644 helm/sonarqube/templates/_helpers.tpl create mode 100644 helm/sonarqube/templates/change-admin-password-hook.yml create mode 100644 helm/sonarqube/templates/config.yaml create mode 100644 helm/sonarqube/templates/deployment.yaml create mode 100644 helm/sonarqube/templates/ingress.yaml create mode 100644 helm/sonarqube/templates/init-fs.yaml create mode 100644 helm/sonarqube/templates/init-sysctl.yaml create mode 100644 helm/sonarqube/templates/install-plugins.yaml create mode 100644 helm/sonarqube/templates/jdbc-config.yaml create mode 100644 helm/sonarqube/templates/networkpolicy.yaml create mode 100644 helm/sonarqube/templates/prometheus-ce-config.yaml create mode 100644 helm/sonarqube/templates/prometheus-config.yaml create mode 100644 helm/sonarqube/templates/prometheus-podmonitor.yaml create mode 100644 helm/sonarqube/templates/pvc.yaml create mode 100644 helm/sonarqube/templates/route.yaml create mode 100644 helm/sonarqube/templates/secret.yaml create mode 100644 helm/sonarqube/templates/service.yaml create mode 100644 helm/sonarqube/templates/serviceaccount.yaml create mode 100644 helm/sonarqube/templates/sonarqube-scc.yaml create mode 100644 helm/sonarqube/templates/sonarqube-sts.yaml create mode 100644 helm/sonarqube/templates/tests/sonarqube-test.yaml create mode 100644 helm/sonarqube/values.schema.json create mode 100644 helm/sonarqube/values.yaml create mode 100644 helm/teleport-cluster/.lint/acme-off.yaml create mode 100644 helm/teleport-cluster/.lint/acme-on.yaml create mode 100644 helm/teleport-cluster/.lint/acme-uri-staging.yaml create mode 100644 helm/teleport-cluster/.lint/affinity.yaml create mode 100644 helm/teleport-cluster/.lint/annotations.yaml create mode 100644 helm/teleport-cluster/.lint/auth-connector-name.yaml create mode 100644 helm/teleport-cluster/.lint/auth-disable-local.yaml create mode 100644 helm/teleport-cluster/.lint/auth-locking-mode.yaml create mode 100644 helm/teleport-cluster/.lint/auth-passwordless.yaml create mode 100644 helm/teleport-cluster/.lint/auth-type-legacy.yaml create mode 100644 helm/teleport-cluster/.lint/auth-type.yaml create mode 100644 helm/teleport-cluster/.lint/auth-webauthn-legacy.yaml create mode 100644 helm/teleport-cluster/.lint/auth-webauthn.yaml create mode 100644 helm/teleport-cluster/.lint/aws-dynamodb-autoscaling.yaml create mode 100644 helm/teleport-cluster/.lint/aws-ha-acme.yaml create mode 100644 helm/teleport-cluster/.lint/aws-ha-antiaffinity.yaml create mode 100644 helm/teleport-cluster/.lint/aws-ha-log.yaml create mode 100644 helm/teleport-cluster/.lint/aws-ha.yaml create mode 100644 helm/teleport-cluster/.lint/aws.yaml create mode 100644 helm/teleport-cluster/.lint/azure.yaml create mode 100644 helm/teleport-cluster/.lint/cert-manager.yaml create mode 100644 helm/teleport-cluster/.lint/cert-secret.yaml create mode 100644 helm/teleport-cluster/.lint/example-minimal-standalone.yaml create mode 100644 helm/teleport-cluster/.lint/existing-tls-secret-with-ca.yaml create mode 100644 helm/teleport-cluster/.lint/existing-tls-secret.yaml create mode 100644 helm/teleport-cluster/.lint/extra-env.yaml create mode 100644 helm/teleport-cluster/.lint/gcp-ha-acme.yaml create mode 100644 helm/teleport-cluster/.lint/gcp-ha-antiaffinity.yaml create mode 100644 helm/teleport-cluster/.lint/gcp-ha-log.yaml create mode 100644 helm/teleport-cluster/.lint/gcp-ha-workload.yaml create mode 100644 helm/teleport-cluster/.lint/gcp-ha.yaml create mode 100644 helm/teleport-cluster/.lint/gcp.yaml create mode 100644 helm/teleport-cluster/.lint/imagepullsecrets.yaml create mode 100644 helm/teleport-cluster/.lint/ingress-publicaddr.yaml create mode 100644 helm/teleport-cluster/.lint/ingress.yaml create mode 100644 helm/teleport-cluster/.lint/initcontainers.yaml create mode 100644 helm/teleport-cluster/.lint/kube-cluster-name.yaml create mode 100644 helm/teleport-cluster/.lint/log-basic.yaml create mode 100644 helm/teleport-cluster/.lint/log-extra.yaml create mode 100644 helm/teleport-cluster/.lint/log-legacy.yaml create mode 100644 helm/teleport-cluster/.lint/node-selector.yaml create mode 100644 helm/teleport-cluster/.lint/operator.yaml create mode 100644 helm/teleport-cluster/.lint/pdb.yaml create mode 100644 helm/teleport-cluster/.lint/persistence-legacy.yaml create mode 100644 helm/teleport-cluster/.lint/podmonitor.yaml create mode 100644 helm/teleport-cluster/.lint/priority-class-name.yaml create mode 100644 helm/teleport-cluster/.lint/probe-timeout-seconds.yaml create mode 100644 helm/teleport-cluster/.lint/proxy-listener-mode-multiplex.yaml create mode 100644 helm/teleport-cluster/.lint/proxy-listener-mode-separate.yaml create mode 100644 helm/teleport-cluster/.lint/public-addresses.yaml create mode 100644 helm/teleport-cluster/.lint/resources.yaml create mode 100644 helm/teleport-cluster/.lint/security-context-empty.yaml create mode 100644 helm/teleport-cluster/.lint/security-context.yaml create mode 100644 helm/teleport-cluster/.lint/separate-mongo-listener.yaml create mode 100644 helm/teleport-cluster/.lint/separate-postgres-listener.yaml create mode 100644 helm/teleport-cluster/.lint/service-account.yaml create mode 100644 helm/teleport-cluster/.lint/service.yaml create mode 100644 helm/teleport-cluster/.lint/session-recording.yaml create mode 100644 helm/teleport-cluster/.lint/standalone-custom-storage-class.yaml create mode 100644 helm/teleport-cluster/.lint/standalone-customsize.yaml create mode 100644 helm/teleport-cluster/.lint/standalone-existingpvc.yaml create mode 100644 helm/teleport-cluster/.lint/tolerations.yaml create mode 100644 helm/teleport-cluster/.lint/version-override.yaml create mode 100644 helm/teleport-cluster/.lint/volumes.yaml create mode 100644 helm/teleport-cluster/Chart.yaml create mode 100644 helm/teleport-cluster/README.md create mode 100644 helm/teleport-cluster/charts/teleport-operator/Chart.yaml create mode 100644 helm/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_githubconnectors.yaml create mode 100644 helm/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_loginrules.yaml create mode 100644 helm/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_oidcconnectors.yaml create mode 100644 helm/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_oktaimportrules.yaml create mode 100644 helm/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_provisiontokens.yaml create mode 100644 helm/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_roles.yaml create mode 100644 helm/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_samlconnectors.yaml create mode 100644 helm/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_users.yaml create mode 100644 helm/teleport-cluster/override_values.yaml create mode 100644 helm/teleport-cluster/teleport_svc.yaml create mode 100644 helm/teleport-cluster/templates/NOTES.txt create mode 100644 helm/teleport-cluster/templates/_helpers.tpl create mode 100644 helm/teleport-cluster/templates/auth/_config.aws.tpl create mode 100644 helm/teleport-cluster/templates/auth/_config.azure.tpl create mode 100644 helm/teleport-cluster/templates/auth/_config.common.tpl create mode 100644 helm/teleport-cluster/templates/auth/_config.gcp.tpl create mode 100644 helm/teleport-cluster/templates/auth/_config.scratch.tpl create mode 100644 helm/teleport-cluster/templates/auth/_config.standalone.tpl create mode 100644 helm/teleport-cluster/templates/auth/clusterrole.yaml create mode 100644 helm/teleport-cluster/templates/auth/clusterrolebinding.yaml create mode 100644 helm/teleport-cluster/templates/auth/config.yaml create mode 100644 helm/teleport-cluster/templates/auth/deployment.yaml create mode 100644 helm/teleport-cluster/templates/auth/pdb.yaml create mode 100644 helm/teleport-cluster/templates/auth/predeploy_config.yaml create mode 100644 helm/teleport-cluster/templates/auth/predeploy_job.yaml create mode 100644 helm/teleport-cluster/templates/auth/pvc.yaml create mode 100644 helm/teleport-cluster/templates/auth/service-previous-version.yaml create mode 100644 helm/teleport-cluster/templates/auth/service.yaml create mode 100644 helm/teleport-cluster/templates/auth/serviceaccount.yaml create mode 100644 helm/teleport-cluster/templates/podmonitor.yaml create mode 100644 helm/teleport-cluster/templates/proxy/_config.aws.tpl create mode 100644 helm/teleport-cluster/templates/proxy/_config.azure.tpl create mode 100644 helm/teleport-cluster/templates/proxy/_config.common.tpl create mode 100644 helm/teleport-cluster/templates/proxy/_config.gcp.tpl create mode 100644 helm/teleport-cluster/templates/proxy/_config.scratch.tpl create mode 100644 helm/teleport-cluster/templates/proxy/_config.standalone.tpl create mode 100644 helm/teleport-cluster/templates/proxy/certificate.yaml create mode 100644 helm/teleport-cluster/templates/proxy/config.yaml create mode 100644 helm/teleport-cluster/templates/proxy/deployment.yaml create mode 100644 helm/teleport-cluster/templates/proxy/ingress.yaml create mode 100644 helm/teleport-cluster/templates/proxy/pdb.yaml create mode 100644 helm/teleport-cluster/templates/proxy/predeploy_config.yaml create mode 100644 helm/teleport-cluster/templates/proxy/predeploy_job.yaml create mode 100644 helm/teleport-cluster/templates/proxy/service.yaml create mode 100644 helm/teleport-cluster/templates/proxy/serviceaccount.yaml create mode 100644 helm/teleport-cluster/templates/psp.yaml create mode 100644 helm/teleport-cluster/tests/README.md create mode 100644 helm/teleport-cluster/tests/__snapshot__/auth_clusterrole_test.yaml.snap create mode 100644 helm/teleport-cluster/tests/__snapshot__/auth_config_test.yaml.snap create mode 100644 helm/teleport-cluster/tests/__snapshot__/auth_deployment_test.yaml.snap create mode 100644 helm/teleport-cluster/tests/__snapshot__/ingress_test.yaml.snap create mode 100644 helm/teleport-cluster/tests/__snapshot__/predeploy_test.yaml.snap create mode 100644 helm/teleport-cluster/tests/__snapshot__/proxy_certificate_test.yaml.snap create mode 100644 helm/teleport-cluster/tests/__snapshot__/proxy_config_test.yaml.snap create mode 100644 helm/teleport-cluster/tests/__snapshot__/proxy_deployment_test.yaml.snap create mode 100644 helm/teleport-cluster/tests/__snapshot__/proxy_service_test.yaml.snap create mode 100644 helm/teleport-cluster/tests/__snapshot__/psp_test.yaml.snap create mode 100644 helm/teleport-cluster/tests/auth_clusterrole_test.yaml create mode 100644 helm/teleport-cluster/tests/auth_clusterrolebinding_test.yaml create mode 100644 helm/teleport-cluster/tests/auth_config_test.yaml create mode 100644 helm/teleport-cluster/tests/auth_deployment_test.yaml create mode 100644 helm/teleport-cluster/tests/auth_pdb_test.yaml create mode 100644 helm/teleport-cluster/tests/auth_pvc_test.yaml create mode 100644 helm/teleport-cluster/tests/auth_serviceaccount_test.yaml create mode 100644 helm/teleport-cluster/tests/ingress_test.yaml create mode 100644 helm/teleport-cluster/tests/podmonitor_test.yaml create mode 100644 helm/teleport-cluster/tests/predeploy_test.yaml create mode 100644 helm/teleport-cluster/tests/proxy_certificate_test.yaml create mode 100644 helm/teleport-cluster/tests/proxy_config_test.yaml create mode 100644 helm/teleport-cluster/tests/proxy_deployment_test.yaml create mode 100644 helm/teleport-cluster/tests/proxy_pdb_test.yaml create mode 100644 helm/teleport-cluster/tests/proxy_service_test.yaml create mode 100644 helm/teleport-cluster/tests/proxy_serviceaccount_test.yaml create mode 100644 helm/teleport-cluster/tests/psp_test.yaml create mode 100644 helm/teleport-cluster/values.schema.json create mode 100644 helm/teleport-cluster/values.yaml create mode 100644 helm/vault/.helmignore create mode 100644 helm/vault/CHANGELOG.md create mode 100644 helm/vault/CODEOWNERS create mode 100644 helm/vault/CONTRIBUTING.md create mode 100644 helm/vault/Chart.yaml create mode 100644 helm/vault/LICENSE create mode 100644 helm/vault/Makefile create mode 100644 helm/vault/README.md create mode 100644 helm/vault/command/admin-policy.hcl create mode 100644 helm/vault/command/command.sh create mode 100644 helm/vault/override_values.yaml create mode 100644 helm/vault/templates/NOTES.txt create mode 100644 helm/vault/templates/_helpers.tpl create mode 100644 helm/vault/templates/csi-agent-configmap.yaml create mode 100644 helm/vault/templates/csi-clusterrole.yaml create mode 100644 helm/vault/templates/csi-clusterrolebinding.yaml create mode 100644 helm/vault/templates/csi-daemonset.yaml create mode 100644 helm/vault/templates/csi-role.yaml create mode 100644 helm/vault/templates/csi-rolebinding.yaml create mode 100644 helm/vault/templates/csi-serviceaccount.yaml create mode 100644 helm/vault/templates/injector-certs-secret.yaml create mode 100644 helm/vault/templates/injector-clusterrole.yaml create mode 100644 helm/vault/templates/injector-clusterrolebinding.yaml create mode 100644 helm/vault/templates/injector-deployment.yaml create mode 100644 helm/vault/templates/injector-disruptionbudget.yaml create mode 100644 helm/vault/templates/injector-mutating-webhook.yaml create mode 100644 helm/vault/templates/injector-network-policy.yaml create mode 100644 helm/vault/templates/injector-psp-role.yaml create mode 100644 helm/vault/templates/injector-psp-rolebinding.yaml create mode 100644 helm/vault/templates/injector-psp.yaml create mode 100644 helm/vault/templates/injector-role.yaml create mode 100644 helm/vault/templates/injector-rolebinding.yaml create mode 100644 helm/vault/templates/injector-service.yaml create mode 100644 helm/vault/templates/injector-serviceaccount.yaml create mode 100644 helm/vault/templates/prometheus-prometheusrules.yaml create mode 100644 helm/vault/templates/prometheus-servicemonitor.yaml create mode 100644 helm/vault/templates/server-clusterrolebinding.yaml create mode 100644 helm/vault/templates/server-config-configmap.yaml create mode 100644 helm/vault/templates/server-discovery-role.yaml create mode 100644 helm/vault/templates/server-discovery-rolebinding.yaml create mode 100644 helm/vault/templates/server-disruptionbudget.yaml create mode 100644 helm/vault/templates/server-ha-active-service.yaml create mode 100644 helm/vault/templates/server-ha-standby-service.yaml create mode 100644 helm/vault/templates/server-headless-service.yaml create mode 100644 helm/vault/templates/server-ingress.yaml create mode 100644 helm/vault/templates/server-network-policy.yaml create mode 100644 helm/vault/templates/server-psp-role.yaml create mode 100644 helm/vault/templates/server-psp-rolebinding.yaml create mode 100644 helm/vault/templates/server-psp.yaml create mode 100644 helm/vault/templates/server-route.yaml create mode 100644 helm/vault/templates/server-service.yaml create mode 100644 helm/vault/templates/server-serviceaccount.yaml create mode 100644 helm/vault/templates/server-statefulset.yaml create mode 100644 helm/vault/templates/tests/server-test.yaml create mode 100644 helm/vault/templates/ui-service.yaml create mode 100644 helm/vault/values.openshift.yaml create mode 100644 helm/vault/values.schema.json create mode 100644 helm/vault/values.yaml create mode 100644 scripts/README.md create mode 100644 yaml/README.md diff --git a/README.md b/README.md index 5cbcf2b..7358e7c 100644 --- a/README.md +++ b/README.md @@ -1 +1,13 @@ -# dsk-devops-toolchains \ No newline at end of file +# dsk-devops-toolchains + +## Helm +| Service | Official Docs | READMD.md | +|:---|:---|:---| +| actions-runner-controller |[docs.github.com](https://docs.github.com/en/actions){: target="_blank"}|[README.md](./helm/actions-runner-controller/README.md) + + +## Docker + +## Yaml + +## Scripts \ No newline at end of file diff --git a/docker/README.md b/docker/README.md new file mode 100644 index 0000000..6871408 --- /dev/null +++ b/docker/README.md @@ -0,0 +1 @@ +# Docker \ No newline at end of file diff --git a/helm/README.md b/helm/README.md new file mode 100644 index 0000000..ac4ab4d --- /dev/null +++ b/helm/README.md @@ -0,0 +1,2 @@ +# Helm + diff --git a/helm/actions-runner-controller/.helmignore b/helm/actions-runner-controller/.helmignore new file mode 100644 index 0000000..61bc153 --- /dev/null +++ b/helm/actions-runner-controller/.helmignore @@ -0,0 +1,25 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ +# Docs +docs/ \ No newline at end of file diff --git a/helm/actions-runner-controller/Chart.yaml b/helm/actions-runner-controller/Chart.yaml new file mode 100644 index 0000000..36b8ecb --- /dev/null +++ b/helm/actions-runner-controller/Chart.yaml @@ -0,0 +1,13 @@ +apiVersion: v2 +appVersion: 0.27.4 +description: A Kubernetes controller that operates self-hosted runners for GitHub + Actions on your Kubernetes cluster. +home: https://github.com/actions/actions-runner-controller +maintainers: +- name: actions-runner-controller + url: https://github.com/actions-runner-controller +name: actions-runner-controller +sources: +- https://github.com/actions/actions-runner-controller +type: application +version: 0.23.3 diff --git a/helm/actions-runner-controller/README.md b/helm/actions-runner-controller/README.md new file mode 100644 index 0000000..d291bb6 --- /dev/null +++ b/helm/actions-runner-controller/README.md @@ -0,0 +1,157 @@ +## Docs + +All additional docs are kept in the `docs/` folder, this README is solely for documenting the values.yaml keys and values + +## Values + +**_The values are documented as of HEAD, to review the configuration options for your chart version ensure you view this file at the relevant [tag](https://github.com/actions/actions-runner-controller/tags)_** + +> _Default values are the defaults set in the charts `values.yaml`, some properties have default configurations in the code for when the property is omitted or invalid_ + +| Key | Description | Default | +|----------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------| +| `labels` | Set labels to apply to all resources in the chart | | +| `replicaCount` | Set the number of controller pods | 1 | +| `webhookPort` | Set the containerPort for the webhook Pod | 9443 | +| `syncPeriod` | Set the period in which the controller reconciles the desired runners count | 1m | +| `enableLeaderElection` | Enable election configuration | true | +| `leaderElectionId` | Set the election ID for the controller group | | +| `githubEnterpriseServerURL` | Set the URL for a self-hosted GitHub Enterprise Server | | +| `githubURL` | Override GitHub URL to be used for GitHub API calls | | +| `githubUploadURL` | Override GitHub Upload URL to be used for GitHub API calls | | +| `runnerGithubURL` | Override GitHub URL to be used by runners during registration | | +| `logLevel` | Set the log level of the controller container | | +| `logFormat` | Set the log format of the controller. Valid options are "text" and "json" | text | +| `additionalVolumes` | Set additional volumes to add to the manager container | | +| `additionalVolumeMounts` | Set additional volume mounts to add to the manager container | | +| `authSecret.create` | Deploy the controller auth secret | false | +| `authSecret.name` | Set the name of the auth secret | controller-manager | +| `authSecret.annotations` | Set annotations for the auth Secret | | +| `authSecret.github_app_id` | The ID of your GitHub App. **This can't be set at the same time as `authSecret.github_token`** | | +| `authSecret.github_app_installation_id` | The ID of your GitHub App installation. **This can't be set at the same time as `authSecret.github_token`** | | +| `authSecret.github_app_private_key` | The multiline string of your GitHub App's private key. **This can't be set at the same time as `authSecret.github_token`** | | +| `authSecret.github_token` | Your chosen GitHub PAT token. **This can't be set at the same time as the `authSecret.github_app_*`** | | +| `authSecret.github_basicauth_username` | Username for GitHub basic auth to use instead of PAT or GitHub APP in case it's running behind a proxy API | | +| `authSecret.github_basicauth_password` | Password for GitHub basic auth to use instead of PAT or GitHub APP in case it's running behind a proxy API | | +| `dockerRegistryMirror` | The default Docker Registry Mirror used by runners. | | +| `hostNetwork` | The "hostNetwork" of the controller container | false | +| `image.repository` | The "repository/image" of the controller container | summerwind/actions-runner-controller | +| `image.tag` | The tag of the controller container | | +| `image.actionsRunnerRepositoryAndTag` | The "repository/image" of the actions runner container | summerwind/actions-runner:latest | +| `image.actionsRunnerImagePullSecrets` | Optional image pull secrets to be included in the runner pod's ImagePullSecrets | | +| `image.dindSidecarRepositoryAndTag` | The "repository/image" of the dind sidecar container | docker:dind | +| `image.pullPolicy` | The pull policy of the controller image | IfNotPresent | +| `metrics.serviceMonitor` | Deploy serviceMonitor kind for for use with prometheus-operator CRDs | false | +| `metrics.serviceAnnotations` | Set annotations for the provisioned metrics service resource | | +| `metrics.port` | Set port of metrics service | 8443 | +| `metrics.proxy.enabled` | Deploy kube-rbac-proxy container in controller pod | true | +| `metrics.proxy.image.repository` | The "repository/image" of the kube-proxy container | quay.io/brancz/kube-rbac-proxy | +| `metrics.proxy.image.tag` | The tag of the kube-proxy image to use when pulling the container | v0.13.1 | +| `metrics.serviceMonitorLabels` | Set labels to apply to ServiceMonitor resources | | +| `imagePullSecrets` | Specifies the secret to be used when pulling the controller pod containers | | +| `fullnameOverride` | Override the full resource names | | +| `nameOverride` | Override the resource name prefix | | +| `serviceAccount.annotations` | Set annotations to the service account | | +| `serviceAccount.create` | Deploy the controller pod under a service account | true | +| `podAnnotations` | Set annotations for the controller pod | | +| `podLabels` | Set labels for the controller pod | | +| `serviceAccount.name` | Set the name of the service account | | +| `securityContext` | Set the security context for each container in the controller pod | | +| `podSecurityContext` | Set the security context to controller pod | | +| `service.annotations` | Set annotations for the provisioned webhook service resource | | +| `service.port` | Set controller service ports | | +| `service.type` | Set controller service type | | +| `topologySpreadConstraints` | Set the controller pod topologySpreadConstraints | | +| `nodeSelector` | Set the controller pod nodeSelector | | +| `resources` | Set the controller pod resources | | +| `affinity` | Set the controller pod affinity rules | | +| `podDisruptionBudget.enabled` | Enables a PDB to ensure HA of controller pods | false | +| `podDisruptionBudget.minAvailable` | Minimum number of pods that must be available after eviction | | +| `podDisruptionBudget.maxUnavailable` | Maximum number of pods that can be unavailable after eviction. Kubernetes 1.7+ required. | | +| `tolerations` | Set the controller pod tolerations | | +| `env` | Set environment variables for the controller container | | +| `priorityClassName` | Set the controller pod priorityClassName | | +| `scope.watchNamespace` | Tells the controller and the github webhook server which namespace to watch if `scope.singleNamespace` is true | `Release.Namespace` (the default namespace of the helm chart). | +| `scope.singleNamespace` | Limit the controller to watch a single namespace | false | +| `certManagerEnabled` | Enable cert-manager. If disabled you must set admissionWebHooks.caBundle and create TLS secrets manually | true | +| `runner.statusUpdateHook.enabled` | Use custom RBAC for runners (role, role binding and service account), this will enable reporting runner statuses | false | +| `admissionWebHooks.caBundle` | Base64-encoded PEM bundle containing the CA that signed the webhook's serving certificate | | +| `githubWebhookServer.logLevel` | Set the log level of the githubWebhookServer container | | +| `githubWebhookServer.logFormat` | Set the log format of the githubWebhookServer controller. Valid options are "text" and "json" | text | +| `githubWebhookServer.replicaCount` | Set the number of webhook server pods | 1 | +| `githubWebhookServer.useRunnerGroupsVisibility` | Enable supporting runner groups with custom visibility, you also need to set `githubWebhookServer.secret.enabled` to enable this feature. | false | +| `githubWebhookServer.enabled` | Deploy the webhook server pod | false | +| `githubWebhookServer.queueLimit` | Set the queue size limit in the githubWebhookServer | | +| `githubWebhookServer.secret.enabled` | Passes the webhook hook secret to the github-webhook-server | false | +| `githubWebhookServer.secret.create` | Deploy the webhook hook secret | false | +| `githubWebhookServer.secret.name` | Set the name of the webhook hook secret | github-webhook-server | +| `githubWebhookServer.secret.github_webhook_secret_token` | Set the webhook secret token value | | +| `githubWebhookServer.imagePullSecrets` | Specifies the secret to be used when pulling the githubWebhookServer pod containers | | +| `githubWebhookServer.nameOverride` | Override the resource name prefix | | +| `githubWebhookServer.fullnameOverride` | Override the full resource names | | +| `githubWebhookServer.serviceAccount.create` | Deploy the githubWebhookServer under a service account | true | +| `githubWebhookServer.serviceAccount.annotations` | Set annotations for the service account | | +| `githubWebhookServer.serviceAccount.name` | Set the service account name | | +| `githubWebhookServer.podAnnotations` | Set annotations for the githubWebhookServer pod | | +| `githubWebhookServer.podLabels` | Set labels for the githubWebhookServer pod | | +| `githubWebhookServer.podSecurityContext` | Set the security context to githubWebhookServer pod | | +| `githubWebhookServer.securityContext` | Set the security context for each container in the githubWebhookServer pod | | +| `githubWebhookServer.resources` | Set the githubWebhookServer pod resources | | +| `githubWebhookServer.topologySpreadConstraints` | Set the githubWebhookServer pod topologySpreadConstraints | | +| `githubWebhookServer.nodeSelector` | Set the githubWebhookServer pod nodeSelector | | +| `githubWebhookServer.tolerations` | Set the githubWebhookServer pod tolerations | | +| `githubWebhookServer.affinity` | Set the githubWebhookServer pod affinity rules | | +| `githubWebhookServer.priorityClassName` | Set the githubWebhookServer pod priorityClassName | | +| `githubWebhookServer.terminationGracePeriodSeconds` | Set the githubWebhookServer pod terminationGracePeriodSeconds. Useful when using preStop hooks to drain/sleep. | `10` | +| `githubWebhookServer.lifecycle` | Set the githubWebhookServer pod lifecycle hooks | `{}` | +| `githubWebhookServer.service.type` | Set githubWebhookServer service type | | +| `githubWebhookServer.service.ports` | Set githubWebhookServer service ports | `[{"port":80, "targetPort:"http", "protocol":"TCP", "name":"http"}]` | +| `githubWebhookServer.service.loadBalancerSourceRanges` | Set githubWebhookServer loadBalancerSourceRanges for restricting loadBalancer type services | `[]` | +| `githubWebhookServer.ingress.enabled` | Deploy an ingress kind for the githubWebhookServer | false | +| `githubWebhookServer.ingress.annotations` | Set annotations for the ingress kind | | +| `githubWebhookServer.ingress.hosts` | Set hosts configuration for ingress | `[{"host": "chart-example.local", "paths": []}]` | +| `githubWebhookServer.ingress.tls` | Set tls configuration for ingress | | +| `githubWebhookServer.ingress.ingressClassName` | Set ingress class name | | +| `githubWebhookServer.podDisruptionBudget.enabled` | Enables a PDB to ensure HA of githubwebhook pods | false | +| `githubWebhookServer.podDisruptionBudget.minAvailable` | Minimum number of pods that must be available after eviction | | +| `githubWebhookServer.podDisruptionBudget.maxUnavailable` | Maximum number of pods that can be unavailable after eviction. Kubernetes 1.7+ required. | | +| `actionsMetricsServer.logLevel` | Set the log level of the actionsMetricsServer container | | +| `actionsMetricsServer.logFormat` | Set the log format of the actionsMetricsServer controller. Valid options are "text" and "json" | text | +| `actionsMetricsServer.enabled` | Deploy the actions metrics server pod | false | +| `actionsMetricsServer.secret.enabled` | Passes the webhook hook secret to the actions-metrics-server | false | +| `actionsMetricsServer.secret.create` | Deploy the webhook hook secret | false | +| `actionsMetricsServer.secret.name` | Set the name of the webhook hook secret | actions-metrics-server | +| `actionsMetricsServer.secret.github_webhook_secret_token` | Set the webhook secret token value | | +| `actionsMetricsServer.imagePullSecrets` | Specifies the secret to be used when pulling the actionsMetricsServer pod containers | | +| `actionsMetricsServer.nameOverride` | Override the resource name prefix | | +| `actionsMetricsServer.fullnameOverride` | Override the full resource names | | +| `actionsMetricsServer.serviceAccount.create` | Deploy the actionsMetricsServer under a service account | true | +| `actionsMetricsServer.serviceAccount.annotations` | Set annotations for the service account | | +| `actionsMetricsServer.serviceAccount.name` | Set the service account name | | +| `actionsMetricsServer.podAnnotations` | Set annotations for the actionsMetricsServer pod | | +| `actionsMetricsServer.podLabels` | Set labels for the actionsMetricsServer pod | | +| `actionsMetricsServer.podSecurityContext` | Set the security context to actionsMetricsServer pod | | +| `actionsMetricsServer.securityContext` | Set the security context for each container in the actionsMetricsServer pod | | +| `actionsMetricsServer.resources` | Set the actionsMetricsServer pod resources | | +| `actionsMetricsServer.topologySpreadConstraints` | Set the actionsMetricsServer pod topologySpreadConstraints | | +| `actionsMetricsServer.nodeSelector` | Set the actionsMetricsServer pod nodeSelector | | +| `actionsMetricsServer.tolerations` | Set the actionsMetricsServer pod tolerations | | +| `actionsMetricsServer.affinity` | Set the actionsMetricsServer pod affinity rules | | +| `actionsMetricsServer.priorityClassName` | Set the actionsMetricsServer pod priorityClassName | | +| `actionsMetricsServer.terminationGracePeriodSeconds` | Set the actionsMetricsServer pod terminationGracePeriodSeconds. Useful when using preStop hooks to drain/sleep. | `10` | +| `actionsMetricsServer.lifecycle` | Set the actionsMetricsServer pod lifecycle hooks | `{}` | +| `actionsMetricsServer.service.type` | Set actionsMetricsServer service type | | +| `actionsMetricsServer.service.ports` | Set actionsMetricsServer service ports | `[{"port":80, "targetPort:"http", "protocol":"TCP", "name":"http"}]` | +| `actionsMetricsServer.service.loadBalancerSourceRanges` | Set actionsMetricsServer loadBalancerSourceRanges for restricting loadBalancer type services | `[]` | +| `actionsMetricsServer.ingress.enabled` | Deploy an ingress kind for the actionsMetricsServer | false | +| `actionsMetricsServer.ingress.annotations` | Set annotations for the ingress kind | | +| `actionsMetricsServer.ingress.hosts` | Set hosts configuration for ingress | `[{"host": "chart-example.local", "paths": []}]` | +| `actionsMetricsServer.ingress.tls` | Set tls configuration for ingress | | +| `actionsMetricsServer.ingress.ingressClassName` | Set ingress class name | | +| `actionsMetrics.serviceMonitor` | Deploy serviceMonitor kind for for use with prometheus-operator CRDs | false | +| `actionsMetrics.serviceAnnotations` | Set annotations for the provisioned actions metrics service resource | | +| `actionsMetrics.port` | Set port of actions metrics service | 8443 | +| `actionsMetrics.proxy.enabled` | Deploy kube-rbac-proxy container in controller pod | true | +| `actionsMetrics.proxy.image.repository` | The "repository/image" of the kube-proxy container | quay.io/brancz/kube-rbac-proxy | +| `actionsMetrics.proxy.image.tag` | The tag of the kube-proxy image to use when pulling the container | v0.13.1 | +| `actionsMetrics.serviceMonitorLabels` | Set labels to apply to ServiceMonitor resources | | diff --git a/helm/actions-runner-controller/ci/ci-values.yaml b/helm/actions-runner-controller/ci/ci-values.yaml new file mode 100644 index 0000000..e8ddb8d --- /dev/null +++ b/helm/actions-runner-controller/ci/ci-values.yaml @@ -0,0 +1,30 @@ +# This file sets some opinionated values for kube-score to use +# when parsing the chart +image: + pullPolicy: Always + +podSecurityContext: + fsGroup: 2000 + +securityContext: + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + runAsUser: 2000 + +resources: + limits: + cpu: 100m + memory: 128Mi + requests: + cpu: 100m + memory: 128Mi + +authSecret: + create: false + +# Set the following to true to create a dummy secret, allowing the manager pod to start +# This is only useful in CI +createDummySecret: true \ No newline at end of file diff --git a/helm/actions-runner-controller/crds/actions.summerwind.dev_horizontalrunnerautoscalers.yaml b/helm/actions-runner-controller/crds/actions.summerwind.dev_horizontalrunnerautoscalers.yaml new file mode 100644 index 0000000..da1fd06 --- /dev/null +++ b/helm/actions-runner-controller/crds/actions.summerwind.dev_horizontalrunnerautoscalers.yaml @@ -0,0 +1,259 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.7.0 + creationTimestamp: null + name: horizontalrunnerautoscalers.actions.summerwind.dev +spec: + group: actions.summerwind.dev + names: + kind: HorizontalRunnerAutoscaler + listKind: HorizontalRunnerAutoscalerList + plural: horizontalrunnerautoscalers + shortNames: + - hra + singular: horizontalrunnerautoscaler + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.minReplicas + name: Min + type: number + - jsonPath: .spec.maxReplicas + name: Max + type: number + - jsonPath: .status.desiredReplicas + name: Desired + type: number + - jsonPath: .status.scheduledOverridesSummary + name: Schedule + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + description: HorizontalRunnerAutoscaler is the Schema for the horizontalrunnerautoscaler 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: HorizontalRunnerAutoscalerSpec defines the desired state of HorizontalRunnerAutoscaler + properties: + capacityReservations: + items: + description: CapacityReservation specifies the number of replicas temporarily added to the scale target until ExpirationTime. + properties: + effectiveTime: + format: date-time + type: string + expirationTime: + format: date-time + type: string + name: + type: string + replicas: + type: integer + type: object + type: array + githubAPICredentialsFrom: + properties: + secretRef: + properties: + name: + type: string + required: + - name + type: object + type: object + maxReplicas: + description: MaxReplicas is the maximum number of replicas the deployment is allowed to scale + type: integer + metrics: + description: Metrics is the collection of various metric targets to calculate desired number of runners + items: + properties: + repositoryNames: + description: RepositoryNames is the list of repository names to be used for calculating the metric. For example, a repository name is the REPO part of `github.com/USER/REPO`. + items: + type: string + type: array + scaleDownAdjustment: + description: ScaleDownAdjustment is the number of runners removed on scale-down. You can only specify either ScaleDownFactor or ScaleDownAdjustment. + type: integer + scaleDownFactor: + description: ScaleDownFactor is the multiplicative factor applied to the current number of runners used to determine how many pods should be removed. + type: string + scaleDownThreshold: + description: ScaleDownThreshold is the percentage of busy runners less than which will trigger the hpa to scale the runners down. + type: string + scaleUpAdjustment: + description: ScaleUpAdjustment is the number of runners added on scale-up. You can only specify either ScaleUpFactor or ScaleUpAdjustment. + type: integer + scaleUpFactor: + description: ScaleUpFactor is the multiplicative factor applied to the current number of runners used to determine how many pods should be added. + type: string + scaleUpThreshold: + description: ScaleUpThreshold is the percentage of busy runners greater than which will trigger the hpa to scale runners up. + type: string + type: + description: Type is the type of metric to be used for autoscaling. It can be TotalNumberOfQueuedAndInProgressWorkflowRuns or PercentageRunnersBusy. + type: string + type: object + type: array + minReplicas: + description: MinReplicas is the minimum number of replicas the deployment is allowed to scale + type: integer + scaleDownDelaySecondsAfterScaleOut: + description: ScaleDownDelaySecondsAfterScaleUp is the approximate delay for a scale down followed by a scale up Used to prevent flapping (down->up->down->... loop) + type: integer + scaleTargetRef: + description: ScaleTargetRef sis the reference to scaled resource like RunnerDeployment + properties: + kind: + description: Kind is the type of resource being referenced + enum: + - RunnerDeployment + - RunnerSet + type: string + name: + description: Name is the name of resource being referenced + type: string + type: object + scaleUpTriggers: + description: "ScaleUpTriggers is an experimental feature to increase the desired replicas by 1 on each webhook requested received by the webhookBasedAutoscaler. \n This feature requires you to also enable and deploy the webhookBasedAutoscaler onto your cluster. \n Note that the added runners remain until the next sync period at least, and they may or may not be used by GitHub Actions depending on the timing. They are intended to be used to gain \"resource slack\" immediately after you receive a webhook from GitHub, so that you can loosely expect MinReplicas runners to be always available." + items: + properties: + amount: + type: integer + duration: + type: string + githubEvent: + properties: + checkRun: + description: https://docs.github.com/en/actions/reference/events-that-trigger-workflows#check_run + properties: + names: + description: Names is a list of GitHub Actions glob patterns. Any check_run event whose name matches one of patterns in the list can trigger autoscaling. Note that check_run name seem to equal to the job name you've defined in your actions workflow yaml file. So it is very likely that you can utilize this to trigger depending on the job. + items: + type: string + type: array + repositories: + description: Repositories is a list of GitHub repositories. Any check_run event whose repository matches one of repositories in the list can trigger autoscaling. + items: + type: string + type: array + status: + type: string + types: + description: 'One of: created, rerequested, or completed' + items: + type: string + type: array + type: object + pullRequest: + description: https://docs.github.com/en/actions/reference/events-that-trigger-workflows#pull_request + properties: + branches: + items: + type: string + type: array + types: + items: + type: string + type: array + type: object + push: + description: PushSpec is the condition for triggering scale-up on push event Also see https://docs.github.com/en/actions/reference/events-that-trigger-workflows#push + type: object + workflowJob: + description: https://docs.github.com/en/developers/webhooks-and-events/webhooks/webhook-events-and-payloads#workflow_job + type: object + type: object + type: object + type: array + scheduledOverrides: + description: ScheduledOverrides is the list of ScheduledOverride. It can be used to override a few fields of HorizontalRunnerAutoscalerSpec on schedule. The earlier a scheduled override is, the higher it is prioritized. + items: + description: ScheduledOverride can be used to override a few fields of HorizontalRunnerAutoscalerSpec on schedule. A schedule can optionally be recurring, so that the corresponding override happens every day, week, month, or year. + properties: + endTime: + description: EndTime is the time at which the first override ends. + format: date-time + type: string + minReplicas: + description: MinReplicas is the number of runners while overriding. If omitted, it doesn't override minReplicas. + minimum: 0 + nullable: true + type: integer + recurrenceRule: + properties: + frequency: + description: Frequency is the name of a predefined interval of each recurrence. The valid values are "Daily", "Weekly", "Monthly", and "Yearly". If empty, the corresponding override happens only once. + enum: + - Daily + - Weekly + - Monthly + - Yearly + type: string + untilTime: + description: UntilTime is the time of the final recurrence. If empty, the schedule recurs forever. + format: date-time + type: string + type: object + startTime: + description: StartTime is the time at which the first override starts. + format: date-time + type: string + required: + - endTime + - startTime + type: object + type: array + type: object + status: + properties: + cacheEntries: + items: + properties: + expirationTime: + format: date-time + type: string + key: + type: string + value: + type: integer + type: object + type: array + desiredReplicas: + description: DesiredReplicas is the total number of desired, non-terminated and latest pods to be set for the primary RunnerSet This doesn't include outdated pods while upgrading the deployment and replacing the runnerset. + type: integer + lastSuccessfulScaleOutTime: + format: date-time + nullable: true + type: string + observedGeneration: + description: ObservedGeneration is the most recent generation observed for the target. It corresponds to e.g. RunnerDeployment's generation, which is updated on mutation by the API Server. + format: int64 + type: integer + scheduledOverridesSummary: + description: ScheduledOverridesSummary is the summary of active and upcoming scheduled overrides to be shown in e.g. a column of a `kubectl get hra` output for observability. + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} + preserveUnknownFields: false +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/helm/actions-runner-controller/crds/actions.summerwind.dev_runnerdeployments.yaml b/helm/actions-runner-controller/crds/actions.summerwind.dev_runnerdeployments.yaml new file mode 100644 index 0000000..cb5f54a --- /dev/null +++ b/helm/actions-runner-controller/crds/actions.summerwind.dev_runnerdeployments.yaml @@ -0,0 +1,5393 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.7.0 + creationTimestamp: null + name: runnerdeployments.actions.summerwind.dev +spec: + group: actions.summerwind.dev + names: + kind: RunnerDeployment + listKind: RunnerDeploymentList + plural: runnerdeployments + shortNames: + - rdeploy + singular: runnerdeployment + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.template.spec.enterprise + name: Enterprise + type: string + - jsonPath: .spec.template.spec.organization + name: Organization + type: string + - jsonPath: .spec.template.spec.repository + name: Repository + type: string + - jsonPath: .spec.template.spec.group + name: Group + type: string + - jsonPath: .spec.template.spec.labels + name: Labels + type: string + - jsonPath: .spec.replicas + name: Desired + type: number + - jsonPath: .status.replicas + name: Current + type: number + - jsonPath: .status.updatedReplicas + name: Up-To-Date + type: number + - jsonPath: .status.availableReplicas + name: Available + type: number + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: RunnerDeployment is the Schema for the runnerdeployments 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: RunnerDeploymentSpec defines the desired state of RunnerDeployment + properties: + effectiveTime: + description: EffectiveTime is the time the upstream controller requested to sync Replicas. It is usually populated by the webhook-based autoscaler via HRA. The value is inherited to RunnerReplicaSet(s) and used to prevent ephemeral runners from unnecessarily recreated. + format: date-time + nullable: true + type: string + replicas: + nullable: true + type: integer + selector: + 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. + nullable: true + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: RunnerSpec defines the desired state of Runner + properties: + affinity: + description: Affinity is a group of affinity scheduling rules. + properties: + nodeAffinity: + description: Describes node affinity scheduling rules for the pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to nodes that satisfy the affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding "weight" to the sum if the node matches the corresponding matchExpressions; the node(s) with the highest sum are the most preferred. + items: + description: An empty preferred scheduling term matches all objects with implicit weight 0 (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated with the corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements by node's labels. + items: + description: A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: Represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements by node's fields. + items: + description: A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: Represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + description: Weight associated with matching the corresponding nodeSelectorTerm, in the range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to an update), the system may or may not try to eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector terms. The terms are ORed. + items: + description: A null or empty node selector term matches no objects. The requirements of them are ANDed. The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements by node's labels. + items: + description: A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: Represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements by node's fields. + items: + description: A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: Represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + description: Describes pod affinity scheduling rules (e.g. co-locate this pod in the same node, zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to nodes that satisfy the affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaceSelector: + description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the corresponding podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system may or may not try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching the labelSelector relative to the given namespace(s)) that this pod should be co-located (affinity) or not co-located (anti-affinity) with, where co-located is defined as running on a node whose value of the label with key matches that of any node on which a pod of the set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaceSelector: + description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules (e.g. avoid putting this pod in the same node, zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to nodes that satisfy the anti-affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling anti-affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaceSelector: + description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the corresponding podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the anti-affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the anti-affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system may or may not try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching the labelSelector relative to the given namespace(s)) that this pod should be co-located (affinity) or not co-located (anti-affinity) with, where co-located is defined as running on a node whose value of the label with key matches that of any node on which a pod of the set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaceSelector: + description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + automountServiceAccountToken: + type: boolean + containerMode: + type: string + containers: + items: + description: A single application container that you want to run within a pod. + properties: + args: + description: 'Arguments to the entrypoint. The container image''s CMD is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container''s environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + command: + description: 'Entrypoint array. Not executed within a shell. The container image''s ENTRYPOINT is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container''s environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + env: + description: List of environment variables to set in the container. Cannot be updated. + items: + description: EnvVar represents an environment variable present in a Container. + properties: + name: + description: Name of the environment variable. Must be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded using the previously defined environment variables in the container and any service environment variables. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['''']`, `metadata.annotations['''']`, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + description: List of sources to populate environment variables in the container. The keys defined within a source must be a C_IDENTIFIER. All invalid keys will be reported as an event when the container is starting. When a key exists in multiple sources, the value associated with the last source will take precedence. Values defined by an Env with a duplicate key will take precedence. Cannot be updated. + items: + description: EnvFromSource represents the source of a set of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap must be defined + type: boolean + type: object + prefix: + description: An optional identifier to prepend to each key in the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret must be defined + type: boolean + type: object + type: object + type: array + image: + description: 'Container image name. More info: https://kubernetes.io/docs/concepts/containers/images This field is optional to allow higher level config management to default or override container images in workload controllers like Deployments and StatefulSets.' + type: string + imagePullPolicy: + description: 'Image pull policy. One of Always, Never, IfNotPresent. Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. Cannot be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images' + type: string + lifecycle: + description: Actions that the management system should take in response to container lifecycle events. Cannot be updated. + properties: + postStart: + description: 'PostStart is called immediately after a container is created. If the handler fails, the container is terminated and restarted according to its restart policy. Other management of the container blocks until the hook completes. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept for the backward compatibility. There are no validation of this field and lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: 'PreStop is called immediately before a container is terminated due to an API request or management event such as liveness/startup probe failure, preemption, resource contention, etc. The handler is not called if the container crashes or exits. The Pod''s termination grace period countdown begins before the PreStop hook is executed. Regardless of the outcome of the handler, the container will eventually terminate within the Pod''s termination grace period (unless delayed by finalizers). Other management of the container blocks until the hook completes or until the termination grace period is reached. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept for the backward compatibility. There are no validation of this field and lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + description: 'Periodic probe of container liveness. Container will be restarted if the probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to be considered failed after having succeeded. Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. This is a beta field and requires enabling GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). \n If this is not specified, the default behavior is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has started before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to be considered successful after having failed. Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + name: + description: Name of the container specified as a DNS_LABEL. Each container in a pod must have a unique name (DNS_LABEL). Cannot be updated. + type: string + ports: + description: List of ports to expose from the container. Not specifying a port here DOES NOT prevent that port from being exposed. Any port which is listening on the default "0.0.0.0" address inside a container will be accessible from the network. Modifying this array with strategic merge patch may corrupt the data. For more information See https://github.com/kubernetes/kubernetes/issues/108255. Cannot be updated. + items: + description: ContainerPort represents a network port in a single container. + properties: + containerPort: + description: Number of port to expose on the pod's IP address. This must be a valid port number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external port to. + type: string + hostPort: + description: Number of port to expose on the host. If specified, this must be a valid port number, 0 < x < 65536. If HostNetwork is specified, this must match ContainerPort. Most containers do not need this. + format: int32 + type: integer + name: + description: If specified, this must be an IANA_SVC_NAME and unique within the pod. Each named port in a pod must have a unique name. Name for the port that can be referred to by services. + type: string + protocol: + default: TCP + description: Protocol for port. Must be UDP, TCP, or SCTP. Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: 'Periodic probe of container service readiness. Container will be removed from service endpoints if the probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to be considered failed after having succeeded. Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. This is a beta field and requires enabling GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). \n If this is not specified, the default behavior is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has started before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to be considered successful after having failed. Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + resources: + description: 'Compute Resources required by this container. Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + properties: + claims: + description: "Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container. \n This is an alpha field and requires enabling the DynamicResourceAllocation feature gate. \n This field is immutable." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. It makes that resource available inside a container. + type: string + required: + - name + type: object + type: array + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + securityContext: + description: 'SecurityContext defines the security options the container should be run with. If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/' + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether a process can gain more privileges than its parent process. This bool directly controls if the no_new_privs flag will be set on the container process. AllowPrivilegeEscalation is true always when the container is: 1) run as Privileged 2) has CAP_SYS_ADMIN Note that this field cannot be set when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running containers. Defaults to the default set of capabilities granted by the container runtime. Note that this field cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes in privileged containers are essentially equivalent to root on the host. Defaults to false. Note that this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount to use for the containers. The default is DefaultProcMount which uses the container runtime defaults for readonly paths and masked paths. This requires the ProcMountType feature flag to be enabled. Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root filesystem. Default is false. Note that this field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container process. Uses runtime default if unset. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root user. If true, the Kubelet will validate the image at runtime to ensure that it does not run as UID 0 (root) and fail to start the container if it does. If unset or false, no such validation will be performed. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container process. Defaults to user specified in image metadata if unspecified. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the container. If unspecified, the container runtime will allocate a random SELinux context for each container. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies to the container. + type: string + role: + description: Role is a SELinux role label that applies to the container. + type: string + type: + description: Type is a SELinux type label that applies to the container. + type: string + user: + description: User is a SELinux user label that applies to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. If seccomp options are provided at both the pod & container level, the container options override the pod options. Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile location. Must only be set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp profile will be applied. Valid options are: \n Localhost - a profile defined in a file on the node should be used. RuntimeDefault - the container runtime default profile should be used. Unconfined - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to all containers. If unspecified, the options from the PodSecurityContext will be used. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should be run as a 'Host Process' container. This field is alpha-level and will only be honored by components that enable the WindowsHostProcessContainers feature flag. Setting this field without the feature flag will result in errors when validating the Pod. All of a Pod's containers must have the same effective HostProcess value (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint of the container process. Defaults to the user specified in image metadata if unspecified. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + startupProbe: + description: 'StartupProbe indicates that the Pod has successfully initialized. If specified, no other probes are executed until this completes successfully. If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. This can be used to provide different probe parameters at the beginning of a Pod''s lifecycle, when it might take a long time to load data or warm a cache, than during steady-state operation. This cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to be considered failed after having succeeded. Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. This is a beta field and requires enabling GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). \n If this is not specified, the default behavior is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has started before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to be considered successful after having failed. Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + stdin: + description: Whether this container should allocate a buffer for stdin in the container runtime. If this is not set, reads from stdin in the container will always result in EOF. Default is false. + type: boolean + stdinOnce: + description: Whether the container runtime should close the stdin channel after it has been opened by a single attach. When stdin is true the stdin stream will remain open across multiple attach sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the first client attaches to stdin, and then remains open and accepts data until the client disconnects, at which time stdin is closed and remains closed until the container is restarted. If this flag is false, a container processes that reads from stdin will never receive an EOF. Default is false + type: boolean + terminationMessagePath: + description: 'Optional: Path at which the file to which the container''s termination message will be written is mounted into the container''s filesystem. Message written is intended to be brief final status, such as an assertion failure message. Will be truncated by the node if greater than 4096 bytes. The total message length across all containers will be limited to 12kb. Defaults to /dev/termination-log. Cannot be updated.' + type: string + terminationMessagePolicy: + description: Indicate how the termination message should be populated. File will use the contents of terminationMessagePath to populate the container status message on both success and failure. FallbackToLogsOnError will use the last chunk of container log output if the termination message file is empty and the container exited with an error. The log output is limited to 2048 bytes or 80 lines, whichever is smaller. Defaults to File. Cannot be updated. + type: string + tty: + description: Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. Default is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices to be used by the container. + items: + description: volumeDevice describes a mapping of a raw block device within a container. + properties: + devicePath: + description: devicePath is the path inside of the container that the device will be mapped to. + type: string + name: + description: name must match the name of a persistentVolumeClaim in the pod + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + description: Pod volumes to mount into the container's filesystem. Cannot be updated. + items: + description: VolumeMount describes a mounting of a Volume within a container. + properties: + mountPath: + description: Path within the container at which the volume should be mounted. Must not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts are propagated from the host to container and the other way around. When not set, MountPropagationNone is used. This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write otherwise (false or unspecified). Defaults to false. + type: boolean + subPath: + description: Path within the volume from which the container's volume should be mounted. Defaults to "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume from which the container's volume should be mounted. Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. Defaults to "" (volume's root). SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + description: Container's working directory. If not specified, the container runtime's default will be used, which might be configured in the container image. Cannot be updated. + type: string + required: + - name + type: object + type: array + dnsConfig: + description: PodDNSConfig defines the DNS parameters of a pod in addition to those generated from DNSPolicy. + properties: + nameservers: + description: A list of DNS name server IP addresses. This will be appended to the base nameservers generated from DNSPolicy. Duplicated nameservers will be removed. + items: + type: string + type: array + options: + description: A list of DNS resolver options. This will be merged with the base options generated from DNSPolicy. Duplicated entries will be removed. Resolution options given in Options will override those that appear in the base DNSPolicy. + items: + description: PodDNSConfigOption defines DNS resolver options of a pod. + properties: + name: + description: Required. + type: string + value: + type: string + type: object + type: array + searches: + description: A list of DNS search domains for host-name lookup. This will be appended to the base search paths generated from DNSPolicy. Duplicated search paths will be removed. + items: + type: string + type: array + type: object + dnsPolicy: + description: DNSPolicy defines how a pod's DNS will be configured. + type: string + dockerEnabled: + type: boolean + dockerEnv: + items: + description: EnvVar represents an environment variable present in a Container. + properties: + name: + description: Name of the environment variable. Must be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded using the previously defined environment variables in the container and any service environment variables. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['''']`, `metadata.annotations['''']`, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + dockerMTU: + format: int64 + type: integer + dockerRegistryMirror: + type: string + dockerVolumeMounts: + items: + description: VolumeMount describes a mounting of a Volume within a container. + properties: + mountPath: + description: Path within the container at which the volume should be mounted. Must not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts are propagated from the host to container and the other way around. When not set, MountPropagationNone is used. This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write otherwise (false or unspecified). Defaults to false. + type: boolean + subPath: + description: Path within the volume from which the container's volume should be mounted. Defaults to "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume from which the container's volume should be mounted. Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. Defaults to "" (volume's root). SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + dockerdContainerResources: + description: ResourceRequirements describes the compute resource requirements. + properties: + claims: + description: "Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container. \n This is an alpha field and requires enabling the DynamicResourceAllocation feature gate. \n This field is immutable." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. It makes that resource available inside a container. + type: string + required: + - name + type: object + type: array + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + dockerdWithinRunnerContainer: + type: boolean + enableServiceLinks: + type: boolean + enterprise: + pattern: ^[^/]+$ + type: string + env: + items: + description: EnvVar represents an environment variable present in a Container. + properties: + name: + description: Name of the environment variable. Must be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded using the previously defined environment variables in the container and any service environment variables. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['''']`, `metadata.annotations['''']`, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + description: EnvFromSource represents the source of a set of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap must be defined + type: boolean + type: object + prefix: + description: An optional identifier to prepend to each key in the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret must be defined + type: boolean + type: object + type: object + type: array + ephemeral: + type: boolean + ephemeralContainers: + items: + description: "An EphemeralContainer is a temporary container that you may add to an existing Pod for user-initiated activities such as debugging. Ephemeral containers have no resource or scheduling guarantees, and they will not be restarted when they exit or when a Pod is removed or restarted. The kubelet may evict a Pod if an ephemeral container causes the Pod to exceed its resource allocation. \n To add an ephemeral container, use the ephemeralcontainers subresource of an existing Pod. Ephemeral containers may not be removed or restarted." + properties: + args: + description: 'Arguments to the entrypoint. The image''s CMD is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container''s environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + command: + description: 'Entrypoint array. Not executed within a shell. The image''s ENTRYPOINT is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container''s environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + env: + description: List of environment variables to set in the container. Cannot be updated. + items: + description: EnvVar represents an environment variable present in a Container. + properties: + name: + description: Name of the environment variable. Must be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded using the previously defined environment variables in the container and any service environment variables. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['''']`, `metadata.annotations['''']`, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + description: List of sources to populate environment variables in the container. The keys defined within a source must be a C_IDENTIFIER. All invalid keys will be reported as an event when the container is starting. When a key exists in multiple sources, the value associated with the last source will take precedence. Values defined by an Env with a duplicate key will take precedence. Cannot be updated. + items: + description: EnvFromSource represents the source of a set of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap must be defined + type: boolean + type: object + prefix: + description: An optional identifier to prepend to each key in the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret must be defined + type: boolean + type: object + type: object + type: array + image: + description: 'Container image name. More info: https://kubernetes.io/docs/concepts/containers/images' + type: string + imagePullPolicy: + description: 'Image pull policy. One of Always, Never, IfNotPresent. Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. Cannot be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images' + type: string + lifecycle: + description: Lifecycle is not allowed for ephemeral containers. + properties: + postStart: + description: 'PostStart is called immediately after a container is created. If the handler fails, the container is terminated and restarted according to its restart policy. Other management of the container blocks until the hook completes. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept for the backward compatibility. There are no validation of this field and lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: 'PreStop is called immediately before a container is terminated due to an API request or management event such as liveness/startup probe failure, preemption, resource contention, etc. The handler is not called if the container crashes or exits. The Pod''s termination grace period countdown begins before the PreStop hook is executed. Regardless of the outcome of the handler, the container will eventually terminate within the Pod''s termination grace period (unless delayed by finalizers). Other management of the container blocks until the hook completes or until the termination grace period is reached. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept for the backward compatibility. There are no validation of this field and lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + description: Probes are not allowed for ephemeral containers. + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to be considered failed after having succeeded. Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. This is a beta field and requires enabling GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). \n If this is not specified, the default behavior is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has started before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to be considered successful after having failed. Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + name: + description: Name of the ephemeral container specified as a DNS_LABEL. This name must be unique among all containers, init containers and ephemeral containers. + type: string + ports: + description: Ports are not allowed for ephemeral containers. + items: + description: ContainerPort represents a network port in a single container. + properties: + containerPort: + description: Number of port to expose on the pod's IP address. This must be a valid port number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external port to. + type: string + hostPort: + description: Number of port to expose on the host. If specified, this must be a valid port number, 0 < x < 65536. If HostNetwork is specified, this must match ContainerPort. Most containers do not need this. + format: int32 + type: integer + name: + description: If specified, this must be an IANA_SVC_NAME and unique within the pod. Each named port in a pod must have a unique name. Name for the port that can be referred to by services. + type: string + protocol: + default: TCP + description: Protocol for port. Must be UDP, TCP, or SCTP. Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: Probes are not allowed for ephemeral containers. + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to be considered failed after having succeeded. Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. This is a beta field and requires enabling GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). \n If this is not specified, the default behavior is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has started before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to be considered successful after having failed. Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + resources: + description: Resources are not allowed for ephemeral containers. Ephemeral containers use spare resources already allocated to the pod. + properties: + claims: + description: "Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container. \n This is an alpha field and requires enabling the DynamicResourceAllocation feature gate. \n This field is immutable." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. It makes that resource available inside a container. + type: string + required: + - name + type: object + type: array + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + securityContext: + description: 'Optional: SecurityContext defines the security options the ephemeral container should be run with. If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext.' + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether a process can gain more privileges than its parent process. This bool directly controls if the no_new_privs flag will be set on the container process. AllowPrivilegeEscalation is true always when the container is: 1) run as Privileged 2) has CAP_SYS_ADMIN Note that this field cannot be set when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running containers. Defaults to the default set of capabilities granted by the container runtime. Note that this field cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes in privileged containers are essentially equivalent to root on the host. Defaults to false. Note that this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount to use for the containers. The default is DefaultProcMount which uses the container runtime defaults for readonly paths and masked paths. This requires the ProcMountType feature flag to be enabled. Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root filesystem. Default is false. Note that this field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container process. Uses runtime default if unset. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root user. If true, the Kubelet will validate the image at runtime to ensure that it does not run as UID 0 (root) and fail to start the container if it does. If unset or false, no such validation will be performed. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container process. Defaults to user specified in image metadata if unspecified. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the container. If unspecified, the container runtime will allocate a random SELinux context for each container. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies to the container. + type: string + role: + description: Role is a SELinux role label that applies to the container. + type: string + type: + description: Type is a SELinux type label that applies to the container. + type: string + user: + description: User is a SELinux user label that applies to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. If seccomp options are provided at both the pod & container level, the container options override the pod options. Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile location. Must only be set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp profile will be applied. Valid options are: \n Localhost - a profile defined in a file on the node should be used. RuntimeDefault - the container runtime default profile should be used. Unconfined - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to all containers. If unspecified, the options from the PodSecurityContext will be used. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should be run as a 'Host Process' container. This field is alpha-level and will only be honored by components that enable the WindowsHostProcessContainers feature flag. Setting this field without the feature flag will result in errors when validating the Pod. All of a Pod's containers must have the same effective HostProcess value (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint of the container process. Defaults to the user specified in image metadata if unspecified. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + startupProbe: + description: Probes are not allowed for ephemeral containers. + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to be considered failed after having succeeded. Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. This is a beta field and requires enabling GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). \n If this is not specified, the default behavior is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has started before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to be considered successful after having failed. Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + stdin: + description: Whether this container should allocate a buffer for stdin in the container runtime. If this is not set, reads from stdin in the container will always result in EOF. Default is false. + type: boolean + stdinOnce: + description: Whether the container runtime should close the stdin channel after it has been opened by a single attach. When stdin is true the stdin stream will remain open across multiple attach sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the first client attaches to stdin, and then remains open and accepts data until the client disconnects, at which time stdin is closed and remains closed until the container is restarted. If this flag is false, a container processes that reads from stdin will never receive an EOF. Default is false + type: boolean + targetContainerName: + description: "If set, the name of the container from PodSpec that this ephemeral container targets. The ephemeral container will be run in the namespaces (IPC, PID, etc) of this container. If not set then the ephemeral container uses the namespaces configured in the Pod spec. \n The container runtime must implement support for this feature. If the runtime does not support namespace targeting then the result of setting this field is undefined." + type: string + terminationMessagePath: + description: 'Optional: Path at which the file to which the container''s termination message will be written is mounted into the container''s filesystem. Message written is intended to be brief final status, such as an assertion failure message. Will be truncated by the node if greater than 4096 bytes. The total message length across all containers will be limited to 12kb. Defaults to /dev/termination-log. Cannot be updated.' + type: string + terminationMessagePolicy: + description: Indicate how the termination message should be populated. File will use the contents of terminationMessagePath to populate the container status message on both success and failure. FallbackToLogsOnError will use the last chunk of container log output if the termination message file is empty and the container exited with an error. The log output is limited to 2048 bytes or 80 lines, whichever is smaller. Defaults to File. Cannot be updated. + type: string + tty: + description: Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. Default is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices to be used by the container. + items: + description: volumeDevice describes a mapping of a raw block device within a container. + properties: + devicePath: + description: devicePath is the path inside of the container that the device will be mapped to. + type: string + name: + description: name must match the name of a persistentVolumeClaim in the pod + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + description: Pod volumes to mount into the container's filesystem. Subpath mounts are not allowed for ephemeral containers. Cannot be updated. + items: + description: VolumeMount describes a mounting of a Volume within a container. + properties: + mountPath: + description: Path within the container at which the volume should be mounted. Must not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts are propagated from the host to container and the other way around. When not set, MountPropagationNone is used. This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write otherwise (false or unspecified). Defaults to false. + type: boolean + subPath: + description: Path within the volume from which the container's volume should be mounted. Defaults to "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume from which the container's volume should be mounted. Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. Defaults to "" (volume's root). SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + description: Container's working directory. If not specified, the container runtime's default will be used, which might be configured in the container image. Cannot be updated. + type: string + required: + - name + type: object + type: array + githubAPICredentialsFrom: + properties: + secretRef: + properties: + name: + type: string + required: + - name + type: object + type: object + group: + type: string + hostAliases: + items: + description: HostAlias holds the mapping between IP and hostnames that will be injected as an entry in the pod's hosts file. + properties: + hostnames: + description: Hostnames for the above IP address. + items: + type: string + type: array + ip: + description: IP address of the host file entry. + type: string + type: object + type: array + image: + type: string + imagePullPolicy: + description: PullPolicy describes a policy for if/when to pull a container image + type: string + imagePullSecrets: + items: + description: LocalObjectReference contains enough information to let you locate the referenced object inside the same namespace. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + type: array + initContainers: + items: + description: A single application container that you want to run within a pod. + properties: + args: + description: 'Arguments to the entrypoint. The container image''s CMD is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container''s environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + command: + description: 'Entrypoint array. Not executed within a shell. The container image''s ENTRYPOINT is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container''s environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + env: + description: List of environment variables to set in the container. Cannot be updated. + items: + description: EnvVar represents an environment variable present in a Container. + properties: + name: + description: Name of the environment variable. Must be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded using the previously defined environment variables in the container and any service environment variables. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['''']`, `metadata.annotations['''']`, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + description: List of sources to populate environment variables in the container. The keys defined within a source must be a C_IDENTIFIER. All invalid keys will be reported as an event when the container is starting. When a key exists in multiple sources, the value associated with the last source will take precedence. Values defined by an Env with a duplicate key will take precedence. Cannot be updated. + items: + description: EnvFromSource represents the source of a set of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap must be defined + type: boolean + type: object + prefix: + description: An optional identifier to prepend to each key in the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret must be defined + type: boolean + type: object + type: object + type: array + image: + description: 'Container image name. More info: https://kubernetes.io/docs/concepts/containers/images This field is optional to allow higher level config management to default or override container images in workload controllers like Deployments and StatefulSets.' + type: string + imagePullPolicy: + description: 'Image pull policy. One of Always, Never, IfNotPresent. Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. Cannot be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images' + type: string + lifecycle: + description: Actions that the management system should take in response to container lifecycle events. Cannot be updated. + properties: + postStart: + description: 'PostStart is called immediately after a container is created. If the handler fails, the container is terminated and restarted according to its restart policy. Other management of the container blocks until the hook completes. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept for the backward compatibility. There are no validation of this field and lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: 'PreStop is called immediately before a container is terminated due to an API request or management event such as liveness/startup probe failure, preemption, resource contention, etc. The handler is not called if the container crashes or exits. The Pod''s termination grace period countdown begins before the PreStop hook is executed. Regardless of the outcome of the handler, the container will eventually terminate within the Pod''s termination grace period (unless delayed by finalizers). Other management of the container blocks until the hook completes or until the termination grace period is reached. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept for the backward compatibility. There are no validation of this field and lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + description: 'Periodic probe of container liveness. Container will be restarted if the probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to be considered failed after having succeeded. Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. This is a beta field and requires enabling GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). \n If this is not specified, the default behavior is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has started before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to be considered successful after having failed. Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + name: + description: Name of the container specified as a DNS_LABEL. Each container in a pod must have a unique name (DNS_LABEL). Cannot be updated. + type: string + ports: + description: List of ports to expose from the container. Not specifying a port here DOES NOT prevent that port from being exposed. Any port which is listening on the default "0.0.0.0" address inside a container will be accessible from the network. Modifying this array with strategic merge patch may corrupt the data. For more information See https://github.com/kubernetes/kubernetes/issues/108255. Cannot be updated. + items: + description: ContainerPort represents a network port in a single container. + properties: + containerPort: + description: Number of port to expose on the pod's IP address. This must be a valid port number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external port to. + type: string + hostPort: + description: Number of port to expose on the host. If specified, this must be a valid port number, 0 < x < 65536. If HostNetwork is specified, this must match ContainerPort. Most containers do not need this. + format: int32 + type: integer + name: + description: If specified, this must be an IANA_SVC_NAME and unique within the pod. Each named port in a pod must have a unique name. Name for the port that can be referred to by services. + type: string + protocol: + default: TCP + description: Protocol for port. Must be UDP, TCP, or SCTP. Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: 'Periodic probe of container service readiness. Container will be removed from service endpoints if the probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to be considered failed after having succeeded. Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. This is a beta field and requires enabling GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). \n If this is not specified, the default behavior is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has started before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to be considered successful after having failed. Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + resources: + description: 'Compute Resources required by this container. Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + properties: + claims: + description: "Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container. \n This is an alpha field and requires enabling the DynamicResourceAllocation feature gate. \n This field is immutable." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. It makes that resource available inside a container. + type: string + required: + - name + type: object + type: array + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + securityContext: + description: 'SecurityContext defines the security options the container should be run with. If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/' + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether a process can gain more privileges than its parent process. This bool directly controls if the no_new_privs flag will be set on the container process. AllowPrivilegeEscalation is true always when the container is: 1) run as Privileged 2) has CAP_SYS_ADMIN Note that this field cannot be set when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running containers. Defaults to the default set of capabilities granted by the container runtime. Note that this field cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes in privileged containers are essentially equivalent to root on the host. Defaults to false. Note that this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount to use for the containers. The default is DefaultProcMount which uses the container runtime defaults for readonly paths and masked paths. This requires the ProcMountType feature flag to be enabled. Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root filesystem. Default is false. Note that this field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container process. Uses runtime default if unset. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root user. If true, the Kubelet will validate the image at runtime to ensure that it does not run as UID 0 (root) and fail to start the container if it does. If unset or false, no such validation will be performed. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container process. Defaults to user specified in image metadata if unspecified. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the container. If unspecified, the container runtime will allocate a random SELinux context for each container. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies to the container. + type: string + role: + description: Role is a SELinux role label that applies to the container. + type: string + type: + description: Type is a SELinux type label that applies to the container. + type: string + user: + description: User is a SELinux user label that applies to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. If seccomp options are provided at both the pod & container level, the container options override the pod options. Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile location. Must only be set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp profile will be applied. Valid options are: \n Localhost - a profile defined in a file on the node should be used. RuntimeDefault - the container runtime default profile should be used. Unconfined - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to all containers. If unspecified, the options from the PodSecurityContext will be used. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should be run as a 'Host Process' container. This field is alpha-level and will only be honored by components that enable the WindowsHostProcessContainers feature flag. Setting this field without the feature flag will result in errors when validating the Pod. All of a Pod's containers must have the same effective HostProcess value (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint of the container process. Defaults to the user specified in image metadata if unspecified. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + startupProbe: + description: 'StartupProbe indicates that the Pod has successfully initialized. If specified, no other probes are executed until this completes successfully. If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. This can be used to provide different probe parameters at the beginning of a Pod''s lifecycle, when it might take a long time to load data or warm a cache, than during steady-state operation. This cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to be considered failed after having succeeded. Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. This is a beta field and requires enabling GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). \n If this is not specified, the default behavior is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has started before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to be considered successful after having failed. Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + stdin: + description: Whether this container should allocate a buffer for stdin in the container runtime. If this is not set, reads from stdin in the container will always result in EOF. Default is false. + type: boolean + stdinOnce: + description: Whether the container runtime should close the stdin channel after it has been opened by a single attach. When stdin is true the stdin stream will remain open across multiple attach sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the first client attaches to stdin, and then remains open and accepts data until the client disconnects, at which time stdin is closed and remains closed until the container is restarted. If this flag is false, a container processes that reads from stdin will never receive an EOF. Default is false + type: boolean + terminationMessagePath: + description: 'Optional: Path at which the file to which the container''s termination message will be written is mounted into the container''s filesystem. Message written is intended to be brief final status, such as an assertion failure message. Will be truncated by the node if greater than 4096 bytes. The total message length across all containers will be limited to 12kb. Defaults to /dev/termination-log. Cannot be updated.' + type: string + terminationMessagePolicy: + description: Indicate how the termination message should be populated. File will use the contents of terminationMessagePath to populate the container status message on both success and failure. FallbackToLogsOnError will use the last chunk of container log output if the termination message file is empty and the container exited with an error. The log output is limited to 2048 bytes or 80 lines, whichever is smaller. Defaults to File. Cannot be updated. + type: string + tty: + description: Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. Default is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices to be used by the container. + items: + description: volumeDevice describes a mapping of a raw block device within a container. + properties: + devicePath: + description: devicePath is the path inside of the container that the device will be mapped to. + type: string + name: + description: name must match the name of a persistentVolumeClaim in the pod + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + description: Pod volumes to mount into the container's filesystem. Cannot be updated. + items: + description: VolumeMount describes a mounting of a Volume within a container. + properties: + mountPath: + description: Path within the container at which the volume should be mounted. Must not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts are propagated from the host to container and the other way around. When not set, MountPropagationNone is used. This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write otherwise (false or unspecified). Defaults to false. + type: boolean + subPath: + description: Path within the volume from which the container's volume should be mounted. Defaults to "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume from which the container's volume should be mounted. Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. Defaults to "" (volume's root). SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + description: Container's working directory. If not specified, the container runtime's default will be used, which might be configured in the container image. Cannot be updated. + type: string + required: + - name + type: object + type: array + labels: + items: + type: string + type: array + nodeSelector: + additionalProperties: + type: string + type: object + organization: + pattern: ^[^/]+$ + type: string + priorityClassName: + type: string + repository: + pattern: ^[^/]+/[^/]+$ + type: string + resources: + description: ResourceRequirements describes the compute resource requirements. + properties: + claims: + description: "Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container. \n This is an alpha field and requires enabling the DynamicResourceAllocation feature gate. \n This field is immutable." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. It makes that resource available inside a container. + type: string + required: + - name + type: object + type: array + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + runtimeClassName: + description: 'RuntimeClassName is the container runtime configuration that containers should run under. More info: https://kubernetes.io/docs/concepts/containers/runtime-class' + type: string + securityContext: + description: PodSecurityContext holds pod-level security attributes and common container settings. Some fields are also present in container.securityContext. Field values of container.securityContext take precedence over field values of PodSecurityContext. + properties: + fsGroup: + description: "A special supplemental group that applies to all containers in a pod. Some volume types allow the Kubelet to change the ownership of that volume to be owned by the pod: \n 1. The owning GID will be the FSGroup 2. The setgid bit is set (new files created in the volume will be owned by FSGroup) 3. The permission bits are OR'd with rw-rw---- \n If unset, the Kubelet will not modify the ownership and permissions of any volume. Note that this field cannot be set when spec.os.name is windows." + format: int64 + type: integer + fsGroupChangePolicy: + description: 'fsGroupChangePolicy defines behavior of changing ownership and permission of the volume before being exposed inside Pod. This field will only apply to volume types which support fsGroup based ownership(and permissions). It will have no effect on ephemeral volume types such as: secret, configmaps and emptydir. Valid values are "OnRootMismatch" and "Always". If not specified, "Always" is used. Note that this field cannot be set when spec.os.name is windows.' + type: string + runAsGroup: + description: The GID to run the entrypoint of the container process. Uses runtime default if unset. May also be set in SecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence for that container. Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root user. If true, the Kubelet will validate the image at runtime to ensure that it does not run as UID 0 (root) and fail to start the container if it does. If unset or false, no such validation will be performed. May also be set in SecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container process. Defaults to user specified in image metadata if unspecified. May also be set in SecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence for that container. Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to all containers. If unspecified, the container runtime will allocate a random SELinux context for each container. May also be set in SecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence for that container. Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies to the container. + type: string + role: + description: Role is a SELinux role label that applies to the container. + type: string + type: + description: Type is a SELinux type label that applies to the container. + type: string + user: + description: User is a SELinux user label that applies to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by the containers in this pod. Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile location. Must only be set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp profile will be applied. Valid options are: \n Localhost - a profile defined in a file on the node should be used. RuntimeDefault - the container runtime default profile should be used. Unconfined - no profile should be applied." + type: string + required: + - type + type: object + supplementalGroups: + description: A list of groups applied to the first process run in each container, in addition to the container's primary GID, the fsGroup (if specified), and group memberships defined in the container image for the uid of the container process. If unspecified, no additional groups are added to any container. Note that group memberships defined in the container image for the uid of the container process are still effective, even if they are not included in this list. Note that this field cannot be set when spec.os.name is windows. + items: + format: int64 + type: integer + type: array + sysctls: + description: Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported sysctls (by the container runtime) might fail to launch. Note that this field cannot be set when spec.os.name is windows. + items: + description: Sysctl defines a kernel parameter to be set + properties: + name: + description: Name of a property to set + type: string + value: + description: Value of a property to set + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + description: The Windows specific settings applied to all containers. If unspecified, the options within a container's SecurityContext will be used. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should be run as a 'Host Process' container. This field is alpha-level and will only be honored by components that enable the WindowsHostProcessContainers feature flag. Setting this field without the feature flag will result in errors when validating the Pod. All of a Pod's containers must have the same effective HostProcess value (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint of the container process. Defaults to the user specified in image metadata if unspecified. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + serviceAccountName: + type: string + sidecarContainers: + items: + description: A single application container that you want to run within a pod. + properties: + args: + description: 'Arguments to the entrypoint. The container image''s CMD is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container''s environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + command: + description: 'Entrypoint array. Not executed within a shell. The container image''s ENTRYPOINT is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container''s environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + env: + description: List of environment variables to set in the container. Cannot be updated. + items: + description: EnvVar represents an environment variable present in a Container. + properties: + name: + description: Name of the environment variable. Must be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded using the previously defined environment variables in the container and any service environment variables. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['''']`, `metadata.annotations['''']`, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + description: List of sources to populate environment variables in the container. The keys defined within a source must be a C_IDENTIFIER. All invalid keys will be reported as an event when the container is starting. When a key exists in multiple sources, the value associated with the last source will take precedence. Values defined by an Env with a duplicate key will take precedence. Cannot be updated. + items: + description: EnvFromSource represents the source of a set of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap must be defined + type: boolean + type: object + prefix: + description: An optional identifier to prepend to each key in the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret must be defined + type: boolean + type: object + type: object + type: array + image: + description: 'Container image name. More info: https://kubernetes.io/docs/concepts/containers/images This field is optional to allow higher level config management to default or override container images in workload controllers like Deployments and StatefulSets.' + type: string + imagePullPolicy: + description: 'Image pull policy. One of Always, Never, IfNotPresent. Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. Cannot be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images' + type: string + lifecycle: + description: Actions that the management system should take in response to container lifecycle events. Cannot be updated. + properties: + postStart: + description: 'PostStart is called immediately after a container is created. If the handler fails, the container is terminated and restarted according to its restart policy. Other management of the container blocks until the hook completes. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept for the backward compatibility. There are no validation of this field and lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: 'PreStop is called immediately before a container is terminated due to an API request or management event such as liveness/startup probe failure, preemption, resource contention, etc. The handler is not called if the container crashes or exits. The Pod''s termination grace period countdown begins before the PreStop hook is executed. Regardless of the outcome of the handler, the container will eventually terminate within the Pod''s termination grace period (unless delayed by finalizers). Other management of the container blocks until the hook completes or until the termination grace period is reached. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept for the backward compatibility. There are no validation of this field and lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + description: 'Periodic probe of container liveness. Container will be restarted if the probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to be considered failed after having succeeded. Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. This is a beta field and requires enabling GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). \n If this is not specified, the default behavior is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has started before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to be considered successful after having failed. Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + name: + description: Name of the container specified as a DNS_LABEL. Each container in a pod must have a unique name (DNS_LABEL). Cannot be updated. + type: string + ports: + description: List of ports to expose from the container. Not specifying a port here DOES NOT prevent that port from being exposed. Any port which is listening on the default "0.0.0.0" address inside a container will be accessible from the network. Modifying this array with strategic merge patch may corrupt the data. For more information See https://github.com/kubernetes/kubernetes/issues/108255. Cannot be updated. + items: + description: ContainerPort represents a network port in a single container. + properties: + containerPort: + description: Number of port to expose on the pod's IP address. This must be a valid port number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external port to. + type: string + hostPort: + description: Number of port to expose on the host. If specified, this must be a valid port number, 0 < x < 65536. If HostNetwork is specified, this must match ContainerPort. Most containers do not need this. + format: int32 + type: integer + name: + description: If specified, this must be an IANA_SVC_NAME and unique within the pod. Each named port in a pod must have a unique name. Name for the port that can be referred to by services. + type: string + protocol: + default: TCP + description: Protocol for port. Must be UDP, TCP, or SCTP. Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: 'Periodic probe of container service readiness. Container will be removed from service endpoints if the probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to be considered failed after having succeeded. Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. This is a beta field and requires enabling GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). \n If this is not specified, the default behavior is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has started before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to be considered successful after having failed. Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + resources: + description: 'Compute Resources required by this container. Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + properties: + claims: + description: "Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container. \n This is an alpha field and requires enabling the DynamicResourceAllocation feature gate. \n This field is immutable." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. It makes that resource available inside a container. + type: string + required: + - name + type: object + type: array + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + securityContext: + description: 'SecurityContext defines the security options the container should be run with. If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/' + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether a process can gain more privileges than its parent process. This bool directly controls if the no_new_privs flag will be set on the container process. AllowPrivilegeEscalation is true always when the container is: 1) run as Privileged 2) has CAP_SYS_ADMIN Note that this field cannot be set when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running containers. Defaults to the default set of capabilities granted by the container runtime. Note that this field cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes in privileged containers are essentially equivalent to root on the host. Defaults to false. Note that this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount to use for the containers. The default is DefaultProcMount which uses the container runtime defaults for readonly paths and masked paths. This requires the ProcMountType feature flag to be enabled. Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root filesystem. Default is false. Note that this field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container process. Uses runtime default if unset. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root user. If true, the Kubelet will validate the image at runtime to ensure that it does not run as UID 0 (root) and fail to start the container if it does. If unset or false, no such validation will be performed. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container process. Defaults to user specified in image metadata if unspecified. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the container. If unspecified, the container runtime will allocate a random SELinux context for each container. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies to the container. + type: string + role: + description: Role is a SELinux role label that applies to the container. + type: string + type: + description: Type is a SELinux type label that applies to the container. + type: string + user: + description: User is a SELinux user label that applies to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. If seccomp options are provided at both the pod & container level, the container options override the pod options. Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile location. Must only be set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp profile will be applied. Valid options are: \n Localhost - a profile defined in a file on the node should be used. RuntimeDefault - the container runtime default profile should be used. Unconfined - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to all containers. If unspecified, the options from the PodSecurityContext will be used. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should be run as a 'Host Process' container. This field is alpha-level and will only be honored by components that enable the WindowsHostProcessContainers feature flag. Setting this field without the feature flag will result in errors when validating the Pod. All of a Pod's containers must have the same effective HostProcess value (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint of the container process. Defaults to the user specified in image metadata if unspecified. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + startupProbe: + description: 'StartupProbe indicates that the Pod has successfully initialized. If specified, no other probes are executed until this completes successfully. If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. This can be used to provide different probe parameters at the beginning of a Pod''s lifecycle, when it might take a long time to load data or warm a cache, than during steady-state operation. This cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to be considered failed after having succeeded. Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. This is a beta field and requires enabling GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). \n If this is not specified, the default behavior is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has started before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to be considered successful after having failed. Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + stdin: + description: Whether this container should allocate a buffer for stdin in the container runtime. If this is not set, reads from stdin in the container will always result in EOF. Default is false. + type: boolean + stdinOnce: + description: Whether the container runtime should close the stdin channel after it has been opened by a single attach. When stdin is true the stdin stream will remain open across multiple attach sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the first client attaches to stdin, and then remains open and accepts data until the client disconnects, at which time stdin is closed and remains closed until the container is restarted. If this flag is false, a container processes that reads from stdin will never receive an EOF. Default is false + type: boolean + terminationMessagePath: + description: 'Optional: Path at which the file to which the container''s termination message will be written is mounted into the container''s filesystem. Message written is intended to be brief final status, such as an assertion failure message. Will be truncated by the node if greater than 4096 bytes. The total message length across all containers will be limited to 12kb. Defaults to /dev/termination-log. Cannot be updated.' + type: string + terminationMessagePolicy: + description: Indicate how the termination message should be populated. File will use the contents of terminationMessagePath to populate the container status message on both success and failure. FallbackToLogsOnError will use the last chunk of container log output if the termination message file is empty and the container exited with an error. The log output is limited to 2048 bytes or 80 lines, whichever is smaller. Defaults to File. Cannot be updated. + type: string + tty: + description: Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. Default is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices to be used by the container. + items: + description: volumeDevice describes a mapping of a raw block device within a container. + properties: + devicePath: + description: devicePath is the path inside of the container that the device will be mapped to. + type: string + name: + description: name must match the name of a persistentVolumeClaim in the pod + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + description: Pod volumes to mount into the container's filesystem. Cannot be updated. + items: + description: VolumeMount describes a mounting of a Volume within a container. + properties: + mountPath: + description: Path within the container at which the volume should be mounted. Must not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts are propagated from the host to container and the other way around. When not set, MountPropagationNone is used. This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write otherwise (false or unspecified). Defaults to false. + type: boolean + subPath: + description: Path within the volume from which the container's volume should be mounted. Defaults to "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume from which the container's volume should be mounted. Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. Defaults to "" (volume's root). SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + description: Container's working directory. If not specified, the container runtime's default will be used, which might be configured in the container image. Cannot be updated. + type: string + required: + - name + type: object + type: array + terminationGracePeriodSeconds: + format: int64 + type: integer + tolerations: + items: + description: The pod this Toleration is attached to tolerates any taint that matches the triple using the matching operator . + properties: + effect: + description: Effect indicates the taint effect to match. Empty means match all taint effects. When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Key is the taint key that the toleration applies to. Empty means match all taint keys. If the key is empty, operator must be Exists; this combination means to match all values and all keys. + type: string + operator: + description: Operator represents a key's relationship to the value. Valid operators are Exists and Equal. Defaults to Equal. Exists is equivalent to wildcard for value, so that a pod can tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period of time the toleration (which must be of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, it is not set, which means tolerate the taint forever (do not evict). Zero and negative values will be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration matches to. If the operator is Exists, the value should be empty, otherwise just a regular string. + type: string + type: object + type: array + topologySpreadConstraints: + items: + description: TopologySpreadConstraint specifies how to spread matching pods among the given topology. + properties: + labelSelector: + description: LabelSelector is used to find matching pods. Pods that match this label selector are counted to determine the number of pods in their corresponding topology domain. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + matchLabelKeys: + description: MatchLabelKeys is a set of pod label keys to select the pods over which spreading will be calculated. The keys are used to lookup values from the incoming pod labels, those key-value labels are ANDed with labelSelector to select the group of existing pods over which spreading will be calculated for the incoming pod. Keys that don't exist in the incoming pod labels will be ignored. A null or empty list means only match against labelSelector. + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + description: 'MaxSkew describes the degree to which pods may be unevenly distributed. When `whenUnsatisfiable=DoNotSchedule`, it is the maximum permitted difference between the number of matching pods in the target topology and the global minimum. The global minimum is the minimum number of matching pods in an eligible domain or zero if the number of eligible domains is less than MinDomains. For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same labelSelector spread as 2/2/1: In this case, the global minimum is 1. | zone1 | zone2 | zone3 | | P P | P P | P | - if MaxSkew is 1, incoming pod can only be scheduled to zone3 to become 2/2/2; scheduling it onto zone1(zone2) would make the ActualSkew(3-1) on zone1(zone2) violate MaxSkew(1). - if MaxSkew is 2, incoming pod can be scheduled onto any zone. When `whenUnsatisfiable=ScheduleAnyway`, it is used to give higher precedence to topologies that satisfy it. It''s a required field. Default value is 1 and 0 is not allowed.' + format: int32 + type: integer + minDomains: + description: "MinDomains indicates a minimum number of eligible domains. When the number of eligible domains with matching topology keys is less than minDomains, Pod Topology Spread treats \"global minimum\" as 0, and then the calculation of Skew is performed. And when the number of eligible domains with matching topology keys equals or greater than minDomains, this value has no effect on scheduling. As a result, when the number of eligible domains is less than minDomains, scheduler won't schedule more than maxSkew Pods to those domains. If value is nil, the constraint behaves as if MinDomains is equal to 1. Valid values are integers greater than 0. When value is not nil, WhenUnsatisfiable must be DoNotSchedule. \n For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same labelSelector spread as 2/2/2: | zone1 | zone2 | zone3 | | P P | P P | P P | The number of domains is less than 5(MinDomains), so \"global minimum\" is treated as 0. In this situation, new pod with the same labelSelector cannot be scheduled, because computed skew will be 3(3 - 0) if new Pod is scheduled to any of the three zones, it will violate MaxSkew. \n This is a beta field and requires the MinDomainsInPodTopologySpread feature gate to be enabled (enabled by default)." + format: int32 + type: integer + nodeAffinityPolicy: + description: "NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector when calculating pod topology spread skew. Options are: - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations. \n If this value is nil, the behavior is equivalent to the Honor policy. This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag." + type: string + nodeTaintsPolicy: + description: "NodeTaintsPolicy indicates how we will treat node taints when calculating pod topology spread skew. Options are: - Honor: nodes without taints, along with tainted nodes for which the incoming pod has a toleration, are included. - Ignore: node taints are ignored. All nodes are included. \n If this value is nil, the behavior is equivalent to the Ignore policy. This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag." + type: string + topologyKey: + description: TopologyKey is the key of node labels. Nodes that have a label with this key and identical values are considered to be in the same topology. We consider each as a "bucket", and try to put balanced number of pods into each bucket. We define a domain as a particular instance of a topology. Also, we define an eligible domain as a domain whose nodes meet the requirements of nodeAffinityPolicy and nodeTaintsPolicy. e.g. If TopologyKey is "kubernetes.io/hostname", each Node is a domain of that topology. And, if TopologyKey is "topology.kubernetes.io/zone", each zone is a domain of that topology. It's a required field. + type: string + whenUnsatisfiable: + description: 'WhenUnsatisfiable indicates how to deal with a pod if it doesn''t satisfy the spread constraint. - DoNotSchedule (default) tells the scheduler not to schedule it. - ScheduleAnyway tells the scheduler to schedule the pod in any location, but giving higher precedence to topologies that would help reduce the skew. A constraint is considered "Unsatisfiable" for an incoming pod if and only if every possible node assignment for that pod would violate "MaxSkew" on some topology. For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same labelSelector spread as 3/1/1: | zone1 | zone2 | zone3 | | P P P | P | P | If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can only be scheduled to zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies MaxSkew(1). In other words, the cluster can still be imbalanced, but scheduler won''t make it *more* imbalanced. It''s a required field.' + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + volumeMounts: + items: + description: VolumeMount describes a mounting of a Volume within a container. + properties: + mountPath: + description: Path within the container at which the volume should be mounted. Must not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts are propagated from the host to container and the other way around. When not set, MountPropagationNone is used. This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write otherwise (false or unspecified). Defaults to false. + type: boolean + subPath: + description: Path within the volume from which the container's volume should be mounted. Defaults to "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume from which the container's volume should be mounted. Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. Defaults to "" (volume's root). SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + volumeSizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + volumeStorageMedium: + type: string + volumes: + items: + description: Volume represents a named volume in a pod that may be accessed by any container in the pod. + properties: + awsElasticBlockStore: + description: 'awsElasticBlockStore represents an AWS Disk resource that is attached to a kubelet''s host machine and then exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + properties: + fsType: + description: 'fsType is the filesystem type of the volume that you want to mount. Tip: Ensure that the filesystem type is supported by the host operating system. Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore TODO: how do we prevent errors in the filesystem from compromising the machine' + type: string + partition: + description: 'partition is the partition in the volume that you want to mount. If omitted, the default is to mount by volume name. Examples: For volume /dev/sda1, you specify the partition as "1". Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty).' + format: int32 + type: integer + readOnly: + description: 'readOnly value true will force the readOnly setting in VolumeMounts. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + type: boolean + volumeID: + description: 'volumeID is unique ID of the persistent disk resource in AWS (Amazon EBS volume). More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + type: string + required: + - volumeID + type: object + azureDisk: + description: azureDisk represents an Azure Data Disk mount on the host and bind mount to the pod. + properties: + cachingMode: + description: 'cachingMode is the Host Caching mode: None, Read Only, Read Write.' + type: string + diskName: + description: diskName is the Name of the data disk in the blob storage + type: string + diskURI: + description: diskURI is the URI of data disk in the blob storage + type: string + fsType: + description: fsType is Filesystem type to mount. Must be a filesystem type supported by the host operating system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + kind: + description: 'kind expected values are Shared: multiple blob disks per storage account Dedicated: single blob disk per storage account Managed: azure managed data disk (only in managed availability set). defaults to shared' + type: string + readOnly: + description: readOnly Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + description: azureFile represents an Azure File Service mount on the host and bind mount to the pod. + properties: + readOnly: + description: readOnly defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. + type: boolean + secretName: + description: secretName is the name of secret that contains Azure Storage Account Name and Key + type: string + shareName: + description: shareName is the azure share Name + type: string + required: + - secretName + - shareName + type: object + cephfs: + description: cephFS represents a Ceph FS mount on the host that shares a pod's lifetime + properties: + monitors: + description: 'monitors is Required: Monitors is a collection of Ceph monitors More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + items: + type: string + type: array + path: + description: 'path is Optional: Used as the mounted root, rather than the full Ceph tree, default is /' + type: string + readOnly: + description: 'readOnly is Optional: Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: boolean + secretFile: + description: 'secretFile is Optional: SecretFile is the path to key ring for User, default is /etc/ceph/user.secret More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: string + secretRef: + description: 'secretRef is Optional: SecretRef is reference to the authentication secret for User, default is empty. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + user: + description: 'user is optional: User is the rados user name, default is admin More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: string + required: + - monitors + type: object + cinder: + description: 'cinder represents a cinder volume attached and mounted on kubelets host machine. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + properties: + fsType: + description: 'fsType is the filesystem type to mount. Must be a filesystem type supported by the host operating system. Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: string + readOnly: + description: 'readOnly defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: boolean + secretRef: + description: 'secretRef is optional: points to a secret object containing parameters used to connect to OpenStack.' + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + volumeID: + description: 'volumeID used to identify the volume in cinder. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: string + required: + - volumeID + type: object + configMap: + description: configMap represents a configMap that should populate this volume + properties: + defaultMode: + description: 'defaultMode is optional: mode bits used to set permissions on created files by default. Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. Defaults to 0644. Directories within the path are not affected by this setting. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.' + format: int32 + type: integer + items: + description: items if unspecified, each key-value pair in the Data field of the referenced ConfigMap will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the ConfigMap, the volume setup will error unless it is marked optional. Paths must be relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits used to set permissions on this file. Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. If not specified, the volume defaultMode will be used. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.' + format: int32 + type: integer + path: + description: path is the relative path of the file to map the key to. May not be an absolute path. May not contain the path element '..'. May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: optional specify whether the ConfigMap or its keys must be defined + type: boolean + type: object + csi: + description: csi (Container Storage Interface) represents ephemeral storage that is handled by certain external CSI drivers (Beta feature). + properties: + driver: + description: driver is the name of the CSI driver that handles this volume. Consult with your admin for the correct name as registered in the cluster. + type: string + fsType: + description: fsType to mount. Ex. "ext4", "xfs", "ntfs". If not provided, the empty value is passed to the associated CSI driver which will determine the default filesystem to apply. + type: string + nodePublishSecretRef: + description: nodePublishSecretRef is a reference to the secret object containing sensitive information to pass to the CSI driver to complete the CSI NodePublishVolume and NodeUnpublishVolume calls. This field is optional, and may be empty if no secret is required. If the secret object contains more than one secret, all secret references are passed. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + readOnly: + description: readOnly specifies a read-only configuration for the volume. Defaults to false (read/write). + type: boolean + volumeAttributes: + additionalProperties: + type: string + description: volumeAttributes stores driver-specific properties that are passed to the CSI driver. Consult your driver's documentation for supported values. + type: object + required: + - driver + type: object + downwardAPI: + description: downwardAPI represents downward API about the pod that should populate this volume + properties: + defaultMode: + description: 'Optional: mode bits to use on created files by default. Must be a Optional: mode bits used to set permissions on created files by default. Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. Defaults to 0644. Directories within the path are not affected by this setting. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.' + format: int32 + type: integer + items: + description: Items is a list of downward API volume file + items: + description: DownwardAPIVolumeFile represents information to create the file containing the pod field + properties: + fieldRef: + description: 'Required: Selects a field of the pod: only annotations, labels, name and namespace are supported.' + properties: + apiVersion: + description: Version of the schema the FieldPath is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified API version. + type: string + required: + - fieldPath + type: object + mode: + description: 'Optional: mode bits used to set permissions on this file, must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. If not specified, the volume defaultMode will be used. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.' + format: int32 + type: integer + path: + description: 'Required: Path is the relative path name of the file to be created. Must not be absolute or contain the ''..'' path. Must be utf-8 encoded. The first item of the relative path must not start with ''..''' + type: string + resourceFieldRef: + description: 'Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + required: + - path + type: object + type: array + type: object + emptyDir: + description: 'emptyDir represents a temporary directory that shares a pod''s lifetime. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + properties: + medium: + description: 'medium represents what type of storage medium should back this directory. The default is "" which means to use the node''s default medium. Must be an empty string (default) or Memory. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + description: 'sizeLimit is the total amount of local storage required for this EmptyDir volume. The size limit is also applicable for memory medium. The maximum usage on memory medium EmptyDir would be the minimum value between the SizeLimit specified here and the sum of memory limits of all containers in a pod. The default is nil which means that the limit is undefined. More info: http://kubernetes.io/docs/user-guide/volumes#emptydir' + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + description: "ephemeral represents a volume that is handled by a cluster storage driver. The volume's lifecycle is tied to the pod that defines it - it will be created before the pod starts, and deleted when the pod is removed. \n Use this if: a) the volume is only needed while the pod runs, b) features of normal volumes like restoring from snapshot or capacity tracking are needed, c) the storage driver is specified through a storage class, and d) the storage driver supports dynamic volume provisioning through a PersistentVolumeClaim (see EphemeralVolumeSource for more information on the connection between this volume type and PersistentVolumeClaim). \n Use PersistentVolumeClaim or one of the vendor-specific APIs for volumes that persist for longer than the lifecycle of an individual pod. \n Use CSI for light-weight local ephemeral volumes if the CSI driver is meant to be used that way - see the documentation of the driver for more information. \n A pod can use both types of ephemeral volumes and persistent volumes at the same time." + properties: + volumeClaimTemplate: + description: "Will be used to create a stand-alone PVC to provision the volume. The pod in which this EphemeralVolumeSource is embedded will be the owner of the PVC, i.e. the PVC will be deleted together with the pod. The name of the PVC will be `-` where `` is the name from the `PodSpec.Volumes` array entry. Pod validation will reject the pod if the concatenated name is not valid for a PVC (for example, too long). \n An existing PVC with that name that is not owned by the pod will *not* be used for the pod to avoid using an unrelated volume by mistake. Starting the pod is then blocked until the unrelated PVC is removed. If such a pre-created PVC is meant to be used by the pod, the PVC has to updated with an owner reference to the pod once the pod exists. Normally this should not be necessary, but it may be useful when manually reconstructing a broken cluster. \n This field is read-only and no changes will be made by Kubernetes to the PVC after it has been created. \n Required, must not be nil." + properties: + metadata: + description: May contain labels and annotations that will be copied into the PVC when creating it. No other fields are allowed and will be rejected during validation. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: The specification for the PersistentVolumeClaim. The entire content is copied unchanged into the PVC that gets created from this template. The same fields as in a PersistentVolumeClaim are also valid here. + properties: + accessModes: + description: 'accessModes contains the desired access modes the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' + items: + type: string + type: array + dataSource: + description: 'dataSource field can be used to specify either: * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) * An existing PVC (PersistentVolumeClaim) If the provisioner or an external controller can support the specified data source, it will create a new volume based on the contents of the specified data source. When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. If the namespace is specified, then dataSourceRef will not be copied to dataSource.' + properties: + apiGroup: + description: APIGroup is the group for the resource being referenced. If APIGroup is not specified, the specified Kind must be in the core API group. For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + dataSourceRef: + description: 'dataSourceRef specifies the object from which to populate the volume with data, if a non-empty volume is desired. This may be any object from a non-empty API group (non core object) or a PersistentVolumeClaim object. When this field is specified, volume binding will only succeed if the type of the specified object matches some installed volume populator or dynamic provisioner. This field will replace the functionality of the dataSource field and as such if both fields are non-empty, they must have the same value. For backwards compatibility, when namespace isn''t specified in dataSourceRef, both fields (dataSource and dataSourceRef) will be set to the same value automatically if one of them is empty and the other is non-empty. When namespace is specified in dataSourceRef, dataSource isn''t set to the same value and must be empty. There are three important differences between dataSource and dataSourceRef: * While dataSource only allows two specific types of objects, dataSourceRef allows any non-core object, as well as PersistentVolumeClaim objects. * While dataSource ignores disallowed values (dropping them), dataSourceRef preserves all values, and generates an error if a disallowed value is specified. * While dataSource only allows local objects, dataSourceRef allows objects in any namespaces. (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled.' + properties: + apiGroup: + description: APIGroup is the group for the resource being referenced. If APIGroup is not specified, the specified Kind must be in the core API group. For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + namespace: + description: Namespace is the namespace of resource being referenced Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: 'resources represents the minimum resources the volume should have. If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements that are lower than previous value but must still be higher than capacity recorded in the status field of the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources' + properties: + claims: + description: "Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container. \n This is an alpha field and requires enabling the DynamicResourceAllocation feature gate. \n This field is immutable." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. It makes that resource available inside a container. + type: string + required: + - name + type: object + type: array + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + selector: + description: selector is a label query over volumes to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + storageClassName: + description: 'storageClassName is the name of the StorageClass required by the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' + type: string + volumeMode: + description: volumeMode defines what type of volume is required by the claim. Value of Filesystem is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference to the PersistentVolume backing this claim. + type: string + type: object + required: + - spec + type: object + type: object + fc: + description: fc represents a Fibre Channel resource that is attached to a kubelet's host machine and then exposed to the pod. + properties: + fsType: + description: 'fsType is the filesystem type to mount. Must be a filesystem type supported by the host operating system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. TODO: how do we prevent errors in the filesystem from compromising the machine' + type: string + lun: + description: 'lun is Optional: FC target lun number' + format: int32 + type: integer + readOnly: + description: 'readOnly is Optional: Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts.' + type: boolean + targetWWNs: + description: 'targetWWNs is Optional: FC target worldwide names (WWNs)' + items: + type: string + type: array + wwids: + description: 'wwids Optional: FC volume world wide identifiers (wwids) Either wwids or combination of targetWWNs and lun must be set, but not both simultaneously.' + items: + type: string + type: array + type: object + flexVolume: + description: flexVolume represents a generic volume resource that is provisioned/attached using an exec based plugin. + properties: + driver: + description: driver is the name of the driver to use for this volume. + type: string + fsType: + description: fsType is the filesystem type to mount. Must be a filesystem type supported by the host operating system. Ex. "ext4", "xfs", "ntfs". The default filesystem depends on FlexVolume script. + type: string + options: + additionalProperties: + type: string + description: 'options is Optional: this field holds extra command options if any.' + type: object + readOnly: + description: 'readOnly is Optional: defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts.' + type: boolean + secretRef: + description: 'secretRef is Optional: secretRef is reference to the secret object containing sensitive information to pass to the plugin scripts. This may be empty if no secret object is specified. If the secret object contains more than one secret, all secrets are passed to the plugin scripts.' + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + required: + - driver + type: object + flocker: + description: flocker represents a Flocker volume attached to a kubelet's host machine. This depends on the Flocker control service being running + properties: + datasetName: + description: datasetName is Name of the dataset stored as metadata -> name on the dataset for Flocker should be considered as deprecated + type: string + datasetUUID: + description: datasetUUID is the UUID of the dataset. This is unique identifier of a Flocker dataset + type: string + type: object + gcePersistentDisk: + description: 'gcePersistentDisk represents a GCE Disk resource that is attached to a kubelet''s host machine and then exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + properties: + fsType: + description: 'fsType is filesystem type of the volume that you want to mount. Tip: Ensure that the filesystem type is supported by the host operating system. Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk TODO: how do we prevent errors in the filesystem from compromising the machine' + type: string + partition: + description: 'partition is the partition in the volume that you want to mount. If omitted, the default is to mount by volume name. Examples: For volume /dev/sda1, you specify the partition as "1". Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + format: int32 + type: integer + pdName: + description: 'pdName is unique name of the PD resource in GCE. Used to identify the disk in GCE. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + type: string + readOnly: + description: 'readOnly here will force the ReadOnly setting in VolumeMounts. Defaults to false. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + type: boolean + required: + - pdName + type: object + gitRepo: + description: 'gitRepo represents a git repository at a particular revision. DEPRECATED: GitRepo is deprecated. To provision a container with a git repo, mount an EmptyDir into an InitContainer that clones the repo using git, then mount the EmptyDir into the Pod''s container.' + properties: + directory: + description: directory is the target directory name. Must not contain or start with '..'. If '.' is supplied, the volume directory will be the git repository. Otherwise, if specified, the volume will contain the git repository in the subdirectory with the given name. + type: string + repository: + description: repository is the URL + type: string + revision: + description: revision is the commit hash for the specified revision. + type: string + required: + - repository + type: object + glusterfs: + description: 'glusterfs represents a Glusterfs mount on the host that shares a pod''s lifetime. More info: https://examples.k8s.io/volumes/glusterfs/README.md' + properties: + endpoints: + description: 'endpoints is the endpoint name that details Glusterfs topology. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: string + path: + description: 'path is the Glusterfs volume path. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: string + readOnly: + description: 'readOnly here will force the Glusterfs volume to be mounted with read-only permissions. Defaults to false. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: boolean + required: + - endpoints + - path + type: object + hostPath: + description: 'hostPath represents a pre-existing file or directory on the host machine that is directly exposed to the container. This is generally used for system agents or other privileged things that are allowed to see the host machine. Most containers will NOT need this. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath --- TODO(jonesdl) We need to restrict who can use host directory mounts and who can/can not mount host directories as read/write.' + properties: + path: + description: 'path of the directory on the host. If the path is a symlink, it will follow the link to the real path. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' + type: string + type: + description: 'type for HostPath Volume Defaults to "" More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' + type: string + required: + - path + type: object + iscsi: + description: 'iscsi represents an ISCSI Disk resource that is attached to a kubelet''s host machine and then exposed to the pod. More info: https://examples.k8s.io/volumes/iscsi/README.md' + properties: + chapAuthDiscovery: + description: chapAuthDiscovery defines whether support iSCSI Discovery CHAP authentication + type: boolean + chapAuthSession: + description: chapAuthSession defines whether support iSCSI Session CHAP authentication + type: boolean + fsType: + description: 'fsType is the filesystem type of the volume that you want to mount. Tip: Ensure that the filesystem type is supported by the host operating system. Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi TODO: how do we prevent errors in the filesystem from compromising the machine' + type: string + initiatorName: + description: initiatorName is the custom iSCSI Initiator Name. If initiatorName is specified with iscsiInterface simultaneously, new iSCSI interface : will be created for the connection. + type: string + iqn: + description: iqn is the target iSCSI Qualified Name. + type: string + iscsiInterface: + description: iscsiInterface is the interface Name that uses an iSCSI transport. Defaults to 'default' (tcp). + type: string + lun: + description: lun represents iSCSI Target Lun number. + format: int32 + type: integer + portals: + description: portals is the iSCSI Target Portal List. The portal is either an IP or ip_addr:port if the port is other than default (typically TCP ports 860 and 3260). + items: + type: string + type: array + readOnly: + description: readOnly here will force the ReadOnly setting in VolumeMounts. Defaults to false. + type: boolean + secretRef: + description: secretRef is the CHAP Secret for iSCSI target and initiator authentication + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + targetPortal: + description: targetPortal is iSCSI Target Portal. The Portal is either an IP or ip_addr:port if the port is other than default (typically TCP ports 860 and 3260). + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + description: 'name of the volume. Must be a DNS_LABEL and unique within the pod. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + nfs: + description: 'nfs represents an NFS mount on the host that shares a pod''s lifetime More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + properties: + path: + description: 'path that is exported by the NFS server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: string + readOnly: + description: 'readOnly here will force the NFS export to be mounted with read-only permissions. Defaults to false. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: boolean + server: + description: 'server is the hostname or IP address of the NFS server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + description: 'persistentVolumeClaimVolumeSource represents a reference to a PersistentVolumeClaim in the same namespace. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + properties: + claimName: + description: 'claimName is the name of a PersistentVolumeClaim in the same namespace as the pod using this volume. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + type: string + readOnly: + description: readOnly Will force the ReadOnly setting in VolumeMounts. Default false. + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + description: photonPersistentDisk represents a PhotonController persistent disk attached and mounted on kubelets host machine + properties: + fsType: + description: fsType is the filesystem type to mount. Must be a filesystem type supported by the host operating system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + pdID: + description: pdID is the ID that identifies Photon Controller persistent disk + type: string + required: + - pdID + type: object + portworxVolume: + description: portworxVolume represents a portworx volume attached and mounted on kubelets host machine + properties: + fsType: + description: fSType represents the filesystem type to mount Must be a filesystem type supported by the host operating system. Ex. "ext4", "xfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: readOnly defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. + type: boolean + volumeID: + description: volumeID uniquely identifies a Portworx volume + type: string + required: + - volumeID + type: object + projected: + description: projected items for all in one resources secrets, configmaps, and downward API + properties: + defaultMode: + description: defaultMode are the mode bits used to set permissions on created files by default. Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. Directories within the path are not affected by this setting. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + sources: + description: sources is the list of volume projections + items: + description: Projection that may be projected along with other supported volume types + properties: + configMap: + description: configMap information about the configMap data to project + properties: + items: + description: items if unspecified, each key-value pair in the Data field of the referenced ConfigMap will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the ConfigMap, the volume setup will error unless it is marked optional. Paths must be relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits used to set permissions on this file. Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. If not specified, the volume defaultMode will be used. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.' + format: int32 + type: integer + path: + description: path is the relative path of the file to map the key to. May not be an absolute path. May not contain the path element '..'. May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: optional specify whether the ConfigMap or its keys must be defined + type: boolean + type: object + downwardAPI: + description: downwardAPI information about the downwardAPI data to project + properties: + items: + description: Items is a list of DownwardAPIVolume file + items: + description: DownwardAPIVolumeFile represents information to create the file containing the pod field + properties: + fieldRef: + description: 'Required: Selects a field of the pod: only annotations, labels, name and namespace are supported.' + properties: + apiVersion: + description: Version of the schema the FieldPath is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified API version. + type: string + required: + - fieldPath + type: object + mode: + description: 'Optional: mode bits used to set permissions on this file, must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. If not specified, the volume defaultMode will be used. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.' + format: int32 + type: integer + path: + description: 'Required: Path is the relative path name of the file to be created. Must not be absolute or contain the ''..'' path. Must be utf-8 encoded. The first item of the relative path must not start with ''..''' + type: string + resourceFieldRef: + description: 'Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + required: + - path + type: object + type: array + type: object + secret: + description: secret information about the secret data to project + properties: + items: + description: items if unspecified, each key-value pair in the Data field of the referenced Secret will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the Secret, the volume setup will error unless it is marked optional. Paths must be relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits used to set permissions on this file. Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. If not specified, the volume defaultMode will be used. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.' + format: int32 + type: integer + path: + description: path is the relative path of the file to map the key to. May not be an absolute path. May not contain the path element '..'. May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: optional field specify whether the Secret or its key must be defined + type: boolean + type: object + serviceAccountToken: + description: serviceAccountToken is information about the serviceAccountToken data to project + properties: + audience: + description: audience is the intended audience of the token. A recipient of a token must identify itself with an identifier specified in the audience of the token, and otherwise should reject the token. The audience defaults to the identifier of the apiserver. + type: string + expirationSeconds: + description: expirationSeconds is the requested duration of validity of the service account token. As the token approaches expiration, the kubelet volume plugin will proactively rotate the service account token. The kubelet will start trying to rotate the token if the token is older than 80 percent of its time to live or if the token is older than 24 hours.Defaults to 1 hour and must be at least 10 minutes. + format: int64 + type: integer + path: + description: path is the path relative to the mount point of the file to project the token into. + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + description: quobyte represents a Quobyte mount on the host that shares a pod's lifetime + properties: + group: + description: group to map volume access to Default is no group + type: string + readOnly: + description: readOnly here will force the Quobyte volume to be mounted with read-only permissions. Defaults to false. + type: boolean + registry: + description: registry represents a single or multiple Quobyte Registry services specified as a string as host:port pair (multiple entries are separated with commas) which acts as the central registry for volumes + type: string + tenant: + description: tenant owning the given Quobyte volume in the Backend Used with dynamically provisioned Quobyte volumes, value is set by the plugin + type: string + user: + description: user to map volume access to Defaults to serivceaccount user + type: string + volume: + description: volume is a string that references an already created Quobyte volume by name. + type: string + required: + - registry + - volume + type: object + rbd: + description: 'rbd represents a Rados Block Device mount on the host that shares a pod''s lifetime. More info: https://examples.k8s.io/volumes/rbd/README.md' + properties: + fsType: + description: 'fsType is the filesystem type of the volume that you want to mount. Tip: Ensure that the filesystem type is supported by the host operating system. Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd TODO: how do we prevent errors in the filesystem from compromising the machine' + type: string + image: + description: 'image is the rados image name. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + keyring: + description: 'keyring is the path to key ring for RBDUser. Default is /etc/ceph/keyring. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + monitors: + description: 'monitors is a collection of Ceph monitors. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + items: + type: string + type: array + pool: + description: 'pool is the rados pool name. Default is rbd. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + readOnly: + description: 'readOnly here will force the ReadOnly setting in VolumeMounts. Defaults to false. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: boolean + secretRef: + description: 'secretRef is name of the authentication secret for RBDUser. If provided overrides keyring. Default is nil. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + user: + description: 'user is the rados user name. Default is admin. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + required: + - image + - monitors + type: object + scaleIO: + description: scaleIO represents a ScaleIO persistent volume attached and mounted on Kubernetes nodes. + properties: + fsType: + description: fsType is the filesystem type to mount. Must be a filesystem type supported by the host operating system. Ex. "ext4", "xfs", "ntfs". Default is "xfs". + type: string + gateway: + description: gateway is the host address of the ScaleIO API Gateway. + type: string + protectionDomain: + description: protectionDomain is the name of the ScaleIO Protection Domain for the configured storage. + type: string + readOnly: + description: readOnly Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: secretRef references to the secret for ScaleIO user and other sensitive information. If this is not provided, Login operation will fail. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + sslEnabled: + description: sslEnabled Flag enable/disable SSL communication with Gateway, default false + type: boolean + storageMode: + description: storageMode indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned. Default is ThinProvisioned. + type: string + storagePool: + description: storagePool is the ScaleIO Storage Pool associated with the protection domain. + type: string + system: + description: system is the name of the storage system as configured in ScaleIO. + type: string + volumeName: + description: volumeName is the name of a volume already created in the ScaleIO system that is associated with this volume source. + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + description: 'secret represents a secret that should populate this volume. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + properties: + defaultMode: + description: 'defaultMode is Optional: mode bits used to set permissions on created files by default. Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. Defaults to 0644. Directories within the path are not affected by this setting. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.' + format: int32 + type: integer + items: + description: items If unspecified, each key-value pair in the Data field of the referenced Secret will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the Secret, the volume setup will error unless it is marked optional. Paths must be relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits used to set permissions on this file. Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. If not specified, the volume defaultMode will be used. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.' + format: int32 + type: integer + path: + description: path is the relative path of the file to map the key to. May not be an absolute path. May not contain the path element '..'. May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + optional: + description: optional field specify whether the Secret or its keys must be defined + type: boolean + secretName: + description: 'secretName is the name of the secret in the pod''s namespace to use. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + type: string + type: object + storageos: + description: storageOS represents a StorageOS volume attached and mounted on Kubernetes nodes. + properties: + fsType: + description: fsType is the filesystem type to mount. Must be a filesystem type supported by the host operating system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: readOnly defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: secretRef specifies the secret to use for obtaining the StorageOS API credentials. If not specified, default values will be attempted. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + volumeName: + description: volumeName is the human-readable name of the StorageOS volume. Volume names are only unique within a namespace. + type: string + volumeNamespace: + description: volumeNamespace specifies the scope of the volume within StorageOS. If no namespace is specified then the Pod's namespace will be used. This allows the Kubernetes name scoping to be mirrored within StorageOS for tighter integration. Set VolumeName to any name to override the default behaviour. Set to "default" if you are not using namespaces within StorageOS. Namespaces that do not pre-exist within StorageOS will be created. + type: string + type: object + vsphereVolume: + description: vsphereVolume represents a vSphere volume attached and mounted on kubelets host machine + properties: + fsType: + description: fsType is filesystem type to mount. Must be a filesystem type supported by the host operating system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + storagePolicyID: + description: storagePolicyID is the storage Policy Based Management (SPBM) profile ID associated with the StoragePolicyName. + type: string + storagePolicyName: + description: storagePolicyName is the storage Policy Based Management (SPBM) profile name. + type: string + volumePath: + description: volumePath is the path that identifies vSphere volume vmdk + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + workDir: + type: string + workVolumeClaimTemplate: + properties: + accessModes: + items: + type: string + type: array + resources: + description: ResourceRequirements describes the compute resource requirements. + properties: + claims: + description: "Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container. \n This is an alpha field and requires enabling the DynamicResourceAllocation feature gate. \n This field is immutable." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. It makes that resource available inside a container. + type: string + required: + - name + type: object + type: array + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + storageClassName: + type: string + required: + - accessModes + - resources + - storageClassName + type: object + type: object + type: object + required: + - template + type: object + status: + properties: + availableReplicas: + description: AvailableReplicas is the total number of available runners which have been successfully registered to GitHub and still running. This corresponds to the sum of status.availableReplicas of all the runner replica sets. + type: integer + desiredReplicas: + description: DesiredReplicas is the total number of desired, non-terminated and latest pods to be set for the primary RunnerSet This doesn't include outdated pods while upgrading the deployment and replacing the runnerset. + type: integer + readyReplicas: + description: ReadyReplicas is the total number of available runners which have been successfully registered to GitHub and still running. This corresponds to the sum of status.readyReplicas of all the runner replica sets. + type: integer + replicas: + description: Replicas is the total number of replicas + type: integer + updatedReplicas: + description: ReadyReplicas is the total number of available runners which have been successfully registered to GitHub and still running. This corresponds to status.replicas of the runner replica set that has the desired template hash. + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} + preserveUnknownFields: false +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/helm/actions-runner-controller/crds/actions.summerwind.dev_runnerreplicasets.yaml b/helm/actions-runner-controller/crds/actions.summerwind.dev_runnerreplicasets.yaml new file mode 100644 index 0000000..a2e6aba --- /dev/null +++ b/helm/actions-runner-controller/crds/actions.summerwind.dev_runnerreplicasets.yaml @@ -0,0 +1,5372 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.7.0 + creationTimestamp: null + name: runnerreplicasets.actions.summerwind.dev +spec: + group: actions.summerwind.dev + names: + kind: RunnerReplicaSet + listKind: RunnerReplicaSetList + plural: runnerreplicasets + shortNames: + - rrs + singular: runnerreplicaset + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.replicas + name: Desired + type: number + - jsonPath: .status.replicas + name: Current + type: number + - jsonPath: .status.readyReplicas + name: Ready + type: number + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: RunnerReplicaSet is the Schema for the runnerreplicasets 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: RunnerReplicaSetSpec defines the desired state of RunnerReplicaSet + properties: + effectiveTime: + description: EffectiveTime is the time the upstream controller requested to sync Replicas. It is usually populated by the webhook-based autoscaler via HRA and RunnerDeployment. The value is used to prevent runnerreplicaset controller from unnecessarily recreating ephemeral runners based on potentially outdated Replicas value. + format: date-time + nullable: true + type: string + replicas: + nullable: true + type: integer + selector: + 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. + nullable: true + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: RunnerSpec defines the desired state of Runner + properties: + affinity: + description: Affinity is a group of affinity scheduling rules. + properties: + nodeAffinity: + description: Describes node affinity scheduling rules for the pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to nodes that satisfy the affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding "weight" to the sum if the node matches the corresponding matchExpressions; the node(s) with the highest sum are the most preferred. + items: + description: An empty preferred scheduling term matches all objects with implicit weight 0 (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated with the corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements by node's labels. + items: + description: A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: Represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements by node's fields. + items: + description: A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: Represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + description: Weight associated with matching the corresponding nodeSelectorTerm, in the range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to an update), the system may or may not try to eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector terms. The terms are ORed. + items: + description: A null or empty node selector term matches no objects. The requirements of them are ANDed. The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements by node's labels. + items: + description: A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: Represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements by node's fields. + items: + description: A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: Represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + description: Describes pod affinity scheduling rules (e.g. co-locate this pod in the same node, zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to nodes that satisfy the affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaceSelector: + description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the corresponding podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system may or may not try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching the labelSelector relative to the given namespace(s)) that this pod should be co-located (affinity) or not co-located (anti-affinity) with, where co-located is defined as running on a node whose value of the label with key matches that of any node on which a pod of the set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaceSelector: + description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules (e.g. avoid putting this pod in the same node, zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to nodes that satisfy the anti-affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling anti-affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaceSelector: + description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the corresponding podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the anti-affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the anti-affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system may or may not try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching the labelSelector relative to the given namespace(s)) that this pod should be co-located (affinity) or not co-located (anti-affinity) with, where co-located is defined as running on a node whose value of the label with key matches that of any node on which a pod of the set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaceSelector: + description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + automountServiceAccountToken: + type: boolean + containerMode: + type: string + containers: + items: + description: A single application container that you want to run within a pod. + properties: + args: + description: 'Arguments to the entrypoint. The container image''s CMD is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container''s environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + command: + description: 'Entrypoint array. Not executed within a shell. The container image''s ENTRYPOINT is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container''s environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + env: + description: List of environment variables to set in the container. Cannot be updated. + items: + description: EnvVar represents an environment variable present in a Container. + properties: + name: + description: Name of the environment variable. Must be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded using the previously defined environment variables in the container and any service environment variables. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['''']`, `metadata.annotations['''']`, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + description: List of sources to populate environment variables in the container. The keys defined within a source must be a C_IDENTIFIER. All invalid keys will be reported as an event when the container is starting. When a key exists in multiple sources, the value associated with the last source will take precedence. Values defined by an Env with a duplicate key will take precedence. Cannot be updated. + items: + description: EnvFromSource represents the source of a set of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap must be defined + type: boolean + type: object + prefix: + description: An optional identifier to prepend to each key in the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret must be defined + type: boolean + type: object + type: object + type: array + image: + description: 'Container image name. More info: https://kubernetes.io/docs/concepts/containers/images This field is optional to allow higher level config management to default or override container images in workload controllers like Deployments and StatefulSets.' + type: string + imagePullPolicy: + description: 'Image pull policy. One of Always, Never, IfNotPresent. Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. Cannot be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images' + type: string + lifecycle: + description: Actions that the management system should take in response to container lifecycle events. Cannot be updated. + properties: + postStart: + description: 'PostStart is called immediately after a container is created. If the handler fails, the container is terminated and restarted according to its restart policy. Other management of the container blocks until the hook completes. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept for the backward compatibility. There are no validation of this field and lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: 'PreStop is called immediately before a container is terminated due to an API request or management event such as liveness/startup probe failure, preemption, resource contention, etc. The handler is not called if the container crashes or exits. The Pod''s termination grace period countdown begins before the PreStop hook is executed. Regardless of the outcome of the handler, the container will eventually terminate within the Pod''s termination grace period (unless delayed by finalizers). Other management of the container blocks until the hook completes or until the termination grace period is reached. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept for the backward compatibility. There are no validation of this field and lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + description: 'Periodic probe of container liveness. Container will be restarted if the probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to be considered failed after having succeeded. Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. This is a beta field and requires enabling GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). \n If this is not specified, the default behavior is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has started before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to be considered successful after having failed. Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + name: + description: Name of the container specified as a DNS_LABEL. Each container in a pod must have a unique name (DNS_LABEL). Cannot be updated. + type: string + ports: + description: List of ports to expose from the container. Not specifying a port here DOES NOT prevent that port from being exposed. Any port which is listening on the default "0.0.0.0" address inside a container will be accessible from the network. Modifying this array with strategic merge patch may corrupt the data. For more information See https://github.com/kubernetes/kubernetes/issues/108255. Cannot be updated. + items: + description: ContainerPort represents a network port in a single container. + properties: + containerPort: + description: Number of port to expose on the pod's IP address. This must be a valid port number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external port to. + type: string + hostPort: + description: Number of port to expose on the host. If specified, this must be a valid port number, 0 < x < 65536. If HostNetwork is specified, this must match ContainerPort. Most containers do not need this. + format: int32 + type: integer + name: + description: If specified, this must be an IANA_SVC_NAME and unique within the pod. Each named port in a pod must have a unique name. Name for the port that can be referred to by services. + type: string + protocol: + default: TCP + description: Protocol for port. Must be UDP, TCP, or SCTP. Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: 'Periodic probe of container service readiness. Container will be removed from service endpoints if the probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to be considered failed after having succeeded. Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. This is a beta field and requires enabling GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). \n If this is not specified, the default behavior is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has started before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to be considered successful after having failed. Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + resources: + description: 'Compute Resources required by this container. Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + properties: + claims: + description: "Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container. \n This is an alpha field and requires enabling the DynamicResourceAllocation feature gate. \n This field is immutable." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. It makes that resource available inside a container. + type: string + required: + - name + type: object + type: array + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + securityContext: + description: 'SecurityContext defines the security options the container should be run with. If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/' + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether a process can gain more privileges than its parent process. This bool directly controls if the no_new_privs flag will be set on the container process. AllowPrivilegeEscalation is true always when the container is: 1) run as Privileged 2) has CAP_SYS_ADMIN Note that this field cannot be set when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running containers. Defaults to the default set of capabilities granted by the container runtime. Note that this field cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes in privileged containers are essentially equivalent to root on the host. Defaults to false. Note that this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount to use for the containers. The default is DefaultProcMount which uses the container runtime defaults for readonly paths and masked paths. This requires the ProcMountType feature flag to be enabled. Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root filesystem. Default is false. Note that this field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container process. Uses runtime default if unset. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root user. If true, the Kubelet will validate the image at runtime to ensure that it does not run as UID 0 (root) and fail to start the container if it does. If unset or false, no such validation will be performed. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container process. Defaults to user specified in image metadata if unspecified. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the container. If unspecified, the container runtime will allocate a random SELinux context for each container. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies to the container. + type: string + role: + description: Role is a SELinux role label that applies to the container. + type: string + type: + description: Type is a SELinux type label that applies to the container. + type: string + user: + description: User is a SELinux user label that applies to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. If seccomp options are provided at both the pod & container level, the container options override the pod options. Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile location. Must only be set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp profile will be applied. Valid options are: \n Localhost - a profile defined in a file on the node should be used. RuntimeDefault - the container runtime default profile should be used. Unconfined - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to all containers. If unspecified, the options from the PodSecurityContext will be used. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should be run as a 'Host Process' container. This field is alpha-level and will only be honored by components that enable the WindowsHostProcessContainers feature flag. Setting this field without the feature flag will result in errors when validating the Pod. All of a Pod's containers must have the same effective HostProcess value (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint of the container process. Defaults to the user specified in image metadata if unspecified. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + startupProbe: + description: 'StartupProbe indicates that the Pod has successfully initialized. If specified, no other probes are executed until this completes successfully. If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. This can be used to provide different probe parameters at the beginning of a Pod''s lifecycle, when it might take a long time to load data or warm a cache, than during steady-state operation. This cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to be considered failed after having succeeded. Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. This is a beta field and requires enabling GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). \n If this is not specified, the default behavior is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has started before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to be considered successful after having failed. Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + stdin: + description: Whether this container should allocate a buffer for stdin in the container runtime. If this is not set, reads from stdin in the container will always result in EOF. Default is false. + type: boolean + stdinOnce: + description: Whether the container runtime should close the stdin channel after it has been opened by a single attach. When stdin is true the stdin stream will remain open across multiple attach sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the first client attaches to stdin, and then remains open and accepts data until the client disconnects, at which time stdin is closed and remains closed until the container is restarted. If this flag is false, a container processes that reads from stdin will never receive an EOF. Default is false + type: boolean + terminationMessagePath: + description: 'Optional: Path at which the file to which the container''s termination message will be written is mounted into the container''s filesystem. Message written is intended to be brief final status, such as an assertion failure message. Will be truncated by the node if greater than 4096 bytes. The total message length across all containers will be limited to 12kb. Defaults to /dev/termination-log. Cannot be updated.' + type: string + terminationMessagePolicy: + description: Indicate how the termination message should be populated. File will use the contents of terminationMessagePath to populate the container status message on both success and failure. FallbackToLogsOnError will use the last chunk of container log output if the termination message file is empty and the container exited with an error. The log output is limited to 2048 bytes or 80 lines, whichever is smaller. Defaults to File. Cannot be updated. + type: string + tty: + description: Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. Default is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices to be used by the container. + items: + description: volumeDevice describes a mapping of a raw block device within a container. + properties: + devicePath: + description: devicePath is the path inside of the container that the device will be mapped to. + type: string + name: + description: name must match the name of a persistentVolumeClaim in the pod + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + description: Pod volumes to mount into the container's filesystem. Cannot be updated. + items: + description: VolumeMount describes a mounting of a Volume within a container. + properties: + mountPath: + description: Path within the container at which the volume should be mounted. Must not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts are propagated from the host to container and the other way around. When not set, MountPropagationNone is used. This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write otherwise (false or unspecified). Defaults to false. + type: boolean + subPath: + description: Path within the volume from which the container's volume should be mounted. Defaults to "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume from which the container's volume should be mounted. Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. Defaults to "" (volume's root). SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + description: Container's working directory. If not specified, the container runtime's default will be used, which might be configured in the container image. Cannot be updated. + type: string + required: + - name + type: object + type: array + dnsConfig: + description: PodDNSConfig defines the DNS parameters of a pod in addition to those generated from DNSPolicy. + properties: + nameservers: + description: A list of DNS name server IP addresses. This will be appended to the base nameservers generated from DNSPolicy. Duplicated nameservers will be removed. + items: + type: string + type: array + options: + description: A list of DNS resolver options. This will be merged with the base options generated from DNSPolicy. Duplicated entries will be removed. Resolution options given in Options will override those that appear in the base DNSPolicy. + items: + description: PodDNSConfigOption defines DNS resolver options of a pod. + properties: + name: + description: Required. + type: string + value: + type: string + type: object + type: array + searches: + description: A list of DNS search domains for host-name lookup. This will be appended to the base search paths generated from DNSPolicy. Duplicated search paths will be removed. + items: + type: string + type: array + type: object + dnsPolicy: + description: DNSPolicy defines how a pod's DNS will be configured. + type: string + dockerEnabled: + type: boolean + dockerEnv: + items: + description: EnvVar represents an environment variable present in a Container. + properties: + name: + description: Name of the environment variable. Must be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded using the previously defined environment variables in the container and any service environment variables. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['''']`, `metadata.annotations['''']`, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + dockerMTU: + format: int64 + type: integer + dockerRegistryMirror: + type: string + dockerVolumeMounts: + items: + description: VolumeMount describes a mounting of a Volume within a container. + properties: + mountPath: + description: Path within the container at which the volume should be mounted. Must not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts are propagated from the host to container and the other way around. When not set, MountPropagationNone is used. This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write otherwise (false or unspecified). Defaults to false. + type: boolean + subPath: + description: Path within the volume from which the container's volume should be mounted. Defaults to "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume from which the container's volume should be mounted. Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. Defaults to "" (volume's root). SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + dockerdContainerResources: + description: ResourceRequirements describes the compute resource requirements. + properties: + claims: + description: "Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container. \n This is an alpha field and requires enabling the DynamicResourceAllocation feature gate. \n This field is immutable." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. It makes that resource available inside a container. + type: string + required: + - name + type: object + type: array + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + dockerdWithinRunnerContainer: + type: boolean + enableServiceLinks: + type: boolean + enterprise: + pattern: ^[^/]+$ + type: string + env: + items: + description: EnvVar represents an environment variable present in a Container. + properties: + name: + description: Name of the environment variable. Must be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded using the previously defined environment variables in the container and any service environment variables. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['''']`, `metadata.annotations['''']`, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + description: EnvFromSource represents the source of a set of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap must be defined + type: boolean + type: object + prefix: + description: An optional identifier to prepend to each key in the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret must be defined + type: boolean + type: object + type: object + type: array + ephemeral: + type: boolean + ephemeralContainers: + items: + description: "An EphemeralContainer is a temporary container that you may add to an existing Pod for user-initiated activities such as debugging. Ephemeral containers have no resource or scheduling guarantees, and they will not be restarted when they exit or when a Pod is removed or restarted. The kubelet may evict a Pod if an ephemeral container causes the Pod to exceed its resource allocation. \n To add an ephemeral container, use the ephemeralcontainers subresource of an existing Pod. Ephemeral containers may not be removed or restarted." + properties: + args: + description: 'Arguments to the entrypoint. The image''s CMD is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container''s environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + command: + description: 'Entrypoint array. Not executed within a shell. The image''s ENTRYPOINT is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container''s environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + env: + description: List of environment variables to set in the container. Cannot be updated. + items: + description: EnvVar represents an environment variable present in a Container. + properties: + name: + description: Name of the environment variable. Must be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded using the previously defined environment variables in the container and any service environment variables. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['''']`, `metadata.annotations['''']`, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + description: List of sources to populate environment variables in the container. The keys defined within a source must be a C_IDENTIFIER. All invalid keys will be reported as an event when the container is starting. When a key exists in multiple sources, the value associated with the last source will take precedence. Values defined by an Env with a duplicate key will take precedence. Cannot be updated. + items: + description: EnvFromSource represents the source of a set of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap must be defined + type: boolean + type: object + prefix: + description: An optional identifier to prepend to each key in the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret must be defined + type: boolean + type: object + type: object + type: array + image: + description: 'Container image name. More info: https://kubernetes.io/docs/concepts/containers/images' + type: string + imagePullPolicy: + description: 'Image pull policy. One of Always, Never, IfNotPresent. Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. Cannot be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images' + type: string + lifecycle: + description: Lifecycle is not allowed for ephemeral containers. + properties: + postStart: + description: 'PostStart is called immediately after a container is created. If the handler fails, the container is terminated and restarted according to its restart policy. Other management of the container blocks until the hook completes. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept for the backward compatibility. There are no validation of this field and lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: 'PreStop is called immediately before a container is terminated due to an API request or management event such as liveness/startup probe failure, preemption, resource contention, etc. The handler is not called if the container crashes or exits. The Pod''s termination grace period countdown begins before the PreStop hook is executed. Regardless of the outcome of the handler, the container will eventually terminate within the Pod''s termination grace period (unless delayed by finalizers). Other management of the container blocks until the hook completes or until the termination grace period is reached. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept for the backward compatibility. There are no validation of this field and lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + description: Probes are not allowed for ephemeral containers. + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to be considered failed after having succeeded. Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. This is a beta field and requires enabling GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). \n If this is not specified, the default behavior is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has started before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to be considered successful after having failed. Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + name: + description: Name of the ephemeral container specified as a DNS_LABEL. This name must be unique among all containers, init containers and ephemeral containers. + type: string + ports: + description: Ports are not allowed for ephemeral containers. + items: + description: ContainerPort represents a network port in a single container. + properties: + containerPort: + description: Number of port to expose on the pod's IP address. This must be a valid port number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external port to. + type: string + hostPort: + description: Number of port to expose on the host. If specified, this must be a valid port number, 0 < x < 65536. If HostNetwork is specified, this must match ContainerPort. Most containers do not need this. + format: int32 + type: integer + name: + description: If specified, this must be an IANA_SVC_NAME and unique within the pod. Each named port in a pod must have a unique name. Name for the port that can be referred to by services. + type: string + protocol: + default: TCP + description: Protocol for port. Must be UDP, TCP, or SCTP. Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: Probes are not allowed for ephemeral containers. + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to be considered failed after having succeeded. Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. This is a beta field and requires enabling GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). \n If this is not specified, the default behavior is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has started before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to be considered successful after having failed. Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + resources: + description: Resources are not allowed for ephemeral containers. Ephemeral containers use spare resources already allocated to the pod. + properties: + claims: + description: "Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container. \n This is an alpha field and requires enabling the DynamicResourceAllocation feature gate. \n This field is immutable." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. It makes that resource available inside a container. + type: string + required: + - name + type: object + type: array + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + securityContext: + description: 'Optional: SecurityContext defines the security options the ephemeral container should be run with. If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext.' + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether a process can gain more privileges than its parent process. This bool directly controls if the no_new_privs flag will be set on the container process. AllowPrivilegeEscalation is true always when the container is: 1) run as Privileged 2) has CAP_SYS_ADMIN Note that this field cannot be set when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running containers. Defaults to the default set of capabilities granted by the container runtime. Note that this field cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes in privileged containers are essentially equivalent to root on the host. Defaults to false. Note that this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount to use for the containers. The default is DefaultProcMount which uses the container runtime defaults for readonly paths and masked paths. This requires the ProcMountType feature flag to be enabled. Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root filesystem. Default is false. Note that this field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container process. Uses runtime default if unset. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root user. If true, the Kubelet will validate the image at runtime to ensure that it does not run as UID 0 (root) and fail to start the container if it does. If unset or false, no such validation will be performed. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container process. Defaults to user specified in image metadata if unspecified. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the container. If unspecified, the container runtime will allocate a random SELinux context for each container. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies to the container. + type: string + role: + description: Role is a SELinux role label that applies to the container. + type: string + type: + description: Type is a SELinux type label that applies to the container. + type: string + user: + description: User is a SELinux user label that applies to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. If seccomp options are provided at both the pod & container level, the container options override the pod options. Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile location. Must only be set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp profile will be applied. Valid options are: \n Localhost - a profile defined in a file on the node should be used. RuntimeDefault - the container runtime default profile should be used. Unconfined - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to all containers. If unspecified, the options from the PodSecurityContext will be used. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should be run as a 'Host Process' container. This field is alpha-level and will only be honored by components that enable the WindowsHostProcessContainers feature flag. Setting this field without the feature flag will result in errors when validating the Pod. All of a Pod's containers must have the same effective HostProcess value (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint of the container process. Defaults to the user specified in image metadata if unspecified. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + startupProbe: + description: Probes are not allowed for ephemeral containers. + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to be considered failed after having succeeded. Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. This is a beta field and requires enabling GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). \n If this is not specified, the default behavior is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has started before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to be considered successful after having failed. Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + stdin: + description: Whether this container should allocate a buffer for stdin in the container runtime. If this is not set, reads from stdin in the container will always result in EOF. Default is false. + type: boolean + stdinOnce: + description: Whether the container runtime should close the stdin channel after it has been opened by a single attach. When stdin is true the stdin stream will remain open across multiple attach sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the first client attaches to stdin, and then remains open and accepts data until the client disconnects, at which time stdin is closed and remains closed until the container is restarted. If this flag is false, a container processes that reads from stdin will never receive an EOF. Default is false + type: boolean + targetContainerName: + description: "If set, the name of the container from PodSpec that this ephemeral container targets. The ephemeral container will be run in the namespaces (IPC, PID, etc) of this container. If not set then the ephemeral container uses the namespaces configured in the Pod spec. \n The container runtime must implement support for this feature. If the runtime does not support namespace targeting then the result of setting this field is undefined." + type: string + terminationMessagePath: + description: 'Optional: Path at which the file to which the container''s termination message will be written is mounted into the container''s filesystem. Message written is intended to be brief final status, such as an assertion failure message. Will be truncated by the node if greater than 4096 bytes. The total message length across all containers will be limited to 12kb. Defaults to /dev/termination-log. Cannot be updated.' + type: string + terminationMessagePolicy: + description: Indicate how the termination message should be populated. File will use the contents of terminationMessagePath to populate the container status message on both success and failure. FallbackToLogsOnError will use the last chunk of container log output if the termination message file is empty and the container exited with an error. The log output is limited to 2048 bytes or 80 lines, whichever is smaller. Defaults to File. Cannot be updated. + type: string + tty: + description: Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. Default is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices to be used by the container. + items: + description: volumeDevice describes a mapping of a raw block device within a container. + properties: + devicePath: + description: devicePath is the path inside of the container that the device will be mapped to. + type: string + name: + description: name must match the name of a persistentVolumeClaim in the pod + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + description: Pod volumes to mount into the container's filesystem. Subpath mounts are not allowed for ephemeral containers. Cannot be updated. + items: + description: VolumeMount describes a mounting of a Volume within a container. + properties: + mountPath: + description: Path within the container at which the volume should be mounted. Must not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts are propagated from the host to container and the other way around. When not set, MountPropagationNone is used. This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write otherwise (false or unspecified). Defaults to false. + type: boolean + subPath: + description: Path within the volume from which the container's volume should be mounted. Defaults to "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume from which the container's volume should be mounted. Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. Defaults to "" (volume's root). SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + description: Container's working directory. If not specified, the container runtime's default will be used, which might be configured in the container image. Cannot be updated. + type: string + required: + - name + type: object + type: array + githubAPICredentialsFrom: + properties: + secretRef: + properties: + name: + type: string + required: + - name + type: object + type: object + group: + type: string + hostAliases: + items: + description: HostAlias holds the mapping between IP and hostnames that will be injected as an entry in the pod's hosts file. + properties: + hostnames: + description: Hostnames for the above IP address. + items: + type: string + type: array + ip: + description: IP address of the host file entry. + type: string + type: object + type: array + image: + type: string + imagePullPolicy: + description: PullPolicy describes a policy for if/when to pull a container image + type: string + imagePullSecrets: + items: + description: LocalObjectReference contains enough information to let you locate the referenced object inside the same namespace. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + type: array + initContainers: + items: + description: A single application container that you want to run within a pod. + properties: + args: + description: 'Arguments to the entrypoint. The container image''s CMD is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container''s environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + command: + description: 'Entrypoint array. Not executed within a shell. The container image''s ENTRYPOINT is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container''s environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + env: + description: List of environment variables to set in the container. Cannot be updated. + items: + description: EnvVar represents an environment variable present in a Container. + properties: + name: + description: Name of the environment variable. Must be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded using the previously defined environment variables in the container and any service environment variables. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['''']`, `metadata.annotations['''']`, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + description: List of sources to populate environment variables in the container. The keys defined within a source must be a C_IDENTIFIER. All invalid keys will be reported as an event when the container is starting. When a key exists in multiple sources, the value associated with the last source will take precedence. Values defined by an Env with a duplicate key will take precedence. Cannot be updated. + items: + description: EnvFromSource represents the source of a set of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap must be defined + type: boolean + type: object + prefix: + description: An optional identifier to prepend to each key in the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret must be defined + type: boolean + type: object + type: object + type: array + image: + description: 'Container image name. More info: https://kubernetes.io/docs/concepts/containers/images This field is optional to allow higher level config management to default or override container images in workload controllers like Deployments and StatefulSets.' + type: string + imagePullPolicy: + description: 'Image pull policy. One of Always, Never, IfNotPresent. Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. Cannot be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images' + type: string + lifecycle: + description: Actions that the management system should take in response to container lifecycle events. Cannot be updated. + properties: + postStart: + description: 'PostStart is called immediately after a container is created. If the handler fails, the container is terminated and restarted according to its restart policy. Other management of the container blocks until the hook completes. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept for the backward compatibility. There are no validation of this field and lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: 'PreStop is called immediately before a container is terminated due to an API request or management event such as liveness/startup probe failure, preemption, resource contention, etc. The handler is not called if the container crashes or exits. The Pod''s termination grace period countdown begins before the PreStop hook is executed. Regardless of the outcome of the handler, the container will eventually terminate within the Pod''s termination grace period (unless delayed by finalizers). Other management of the container blocks until the hook completes or until the termination grace period is reached. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept for the backward compatibility. There are no validation of this field and lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + description: 'Periodic probe of container liveness. Container will be restarted if the probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to be considered failed after having succeeded. Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. This is a beta field and requires enabling GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). \n If this is not specified, the default behavior is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has started before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to be considered successful after having failed. Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + name: + description: Name of the container specified as a DNS_LABEL. Each container in a pod must have a unique name (DNS_LABEL). Cannot be updated. + type: string + ports: + description: List of ports to expose from the container. Not specifying a port here DOES NOT prevent that port from being exposed. Any port which is listening on the default "0.0.0.0" address inside a container will be accessible from the network. Modifying this array with strategic merge patch may corrupt the data. For more information See https://github.com/kubernetes/kubernetes/issues/108255. Cannot be updated. + items: + description: ContainerPort represents a network port in a single container. + properties: + containerPort: + description: Number of port to expose on the pod's IP address. This must be a valid port number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external port to. + type: string + hostPort: + description: Number of port to expose on the host. If specified, this must be a valid port number, 0 < x < 65536. If HostNetwork is specified, this must match ContainerPort. Most containers do not need this. + format: int32 + type: integer + name: + description: If specified, this must be an IANA_SVC_NAME and unique within the pod. Each named port in a pod must have a unique name. Name for the port that can be referred to by services. + type: string + protocol: + default: TCP + description: Protocol for port. Must be UDP, TCP, or SCTP. Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: 'Periodic probe of container service readiness. Container will be removed from service endpoints if the probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to be considered failed after having succeeded. Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. This is a beta field and requires enabling GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). \n If this is not specified, the default behavior is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has started before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to be considered successful after having failed. Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + resources: + description: 'Compute Resources required by this container. Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + properties: + claims: + description: "Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container. \n This is an alpha field and requires enabling the DynamicResourceAllocation feature gate. \n This field is immutable." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. It makes that resource available inside a container. + type: string + required: + - name + type: object + type: array + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + securityContext: + description: 'SecurityContext defines the security options the container should be run with. If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/' + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether a process can gain more privileges than its parent process. This bool directly controls if the no_new_privs flag will be set on the container process. AllowPrivilegeEscalation is true always when the container is: 1) run as Privileged 2) has CAP_SYS_ADMIN Note that this field cannot be set when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running containers. Defaults to the default set of capabilities granted by the container runtime. Note that this field cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes in privileged containers are essentially equivalent to root on the host. Defaults to false. Note that this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount to use for the containers. The default is DefaultProcMount which uses the container runtime defaults for readonly paths and masked paths. This requires the ProcMountType feature flag to be enabled. Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root filesystem. Default is false. Note that this field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container process. Uses runtime default if unset. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root user. If true, the Kubelet will validate the image at runtime to ensure that it does not run as UID 0 (root) and fail to start the container if it does. If unset or false, no such validation will be performed. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container process. Defaults to user specified in image metadata if unspecified. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the container. If unspecified, the container runtime will allocate a random SELinux context for each container. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies to the container. + type: string + role: + description: Role is a SELinux role label that applies to the container. + type: string + type: + description: Type is a SELinux type label that applies to the container. + type: string + user: + description: User is a SELinux user label that applies to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. If seccomp options are provided at both the pod & container level, the container options override the pod options. Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile location. Must only be set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp profile will be applied. Valid options are: \n Localhost - a profile defined in a file on the node should be used. RuntimeDefault - the container runtime default profile should be used. Unconfined - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to all containers. If unspecified, the options from the PodSecurityContext will be used. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should be run as a 'Host Process' container. This field is alpha-level and will only be honored by components that enable the WindowsHostProcessContainers feature flag. Setting this field without the feature flag will result in errors when validating the Pod. All of a Pod's containers must have the same effective HostProcess value (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint of the container process. Defaults to the user specified in image metadata if unspecified. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + startupProbe: + description: 'StartupProbe indicates that the Pod has successfully initialized. If specified, no other probes are executed until this completes successfully. If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. This can be used to provide different probe parameters at the beginning of a Pod''s lifecycle, when it might take a long time to load data or warm a cache, than during steady-state operation. This cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to be considered failed after having succeeded. Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. This is a beta field and requires enabling GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). \n If this is not specified, the default behavior is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has started before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to be considered successful after having failed. Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + stdin: + description: Whether this container should allocate a buffer for stdin in the container runtime. If this is not set, reads from stdin in the container will always result in EOF. Default is false. + type: boolean + stdinOnce: + description: Whether the container runtime should close the stdin channel after it has been opened by a single attach. When stdin is true the stdin stream will remain open across multiple attach sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the first client attaches to stdin, and then remains open and accepts data until the client disconnects, at which time stdin is closed and remains closed until the container is restarted. If this flag is false, a container processes that reads from stdin will never receive an EOF. Default is false + type: boolean + terminationMessagePath: + description: 'Optional: Path at which the file to which the container''s termination message will be written is mounted into the container''s filesystem. Message written is intended to be brief final status, such as an assertion failure message. Will be truncated by the node if greater than 4096 bytes. The total message length across all containers will be limited to 12kb. Defaults to /dev/termination-log. Cannot be updated.' + type: string + terminationMessagePolicy: + description: Indicate how the termination message should be populated. File will use the contents of terminationMessagePath to populate the container status message on both success and failure. FallbackToLogsOnError will use the last chunk of container log output if the termination message file is empty and the container exited with an error. The log output is limited to 2048 bytes or 80 lines, whichever is smaller. Defaults to File. Cannot be updated. + type: string + tty: + description: Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. Default is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices to be used by the container. + items: + description: volumeDevice describes a mapping of a raw block device within a container. + properties: + devicePath: + description: devicePath is the path inside of the container that the device will be mapped to. + type: string + name: + description: name must match the name of a persistentVolumeClaim in the pod + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + description: Pod volumes to mount into the container's filesystem. Cannot be updated. + items: + description: VolumeMount describes a mounting of a Volume within a container. + properties: + mountPath: + description: Path within the container at which the volume should be mounted. Must not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts are propagated from the host to container and the other way around. When not set, MountPropagationNone is used. This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write otherwise (false or unspecified). Defaults to false. + type: boolean + subPath: + description: Path within the volume from which the container's volume should be mounted. Defaults to "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume from which the container's volume should be mounted. Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. Defaults to "" (volume's root). SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + description: Container's working directory. If not specified, the container runtime's default will be used, which might be configured in the container image. Cannot be updated. + type: string + required: + - name + type: object + type: array + labels: + items: + type: string + type: array + nodeSelector: + additionalProperties: + type: string + type: object + organization: + pattern: ^[^/]+$ + type: string + priorityClassName: + type: string + repository: + pattern: ^[^/]+/[^/]+$ + type: string + resources: + description: ResourceRequirements describes the compute resource requirements. + properties: + claims: + description: "Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container. \n This is an alpha field and requires enabling the DynamicResourceAllocation feature gate. \n This field is immutable." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. It makes that resource available inside a container. + type: string + required: + - name + type: object + type: array + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + runtimeClassName: + description: 'RuntimeClassName is the container runtime configuration that containers should run under. More info: https://kubernetes.io/docs/concepts/containers/runtime-class' + type: string + securityContext: + description: PodSecurityContext holds pod-level security attributes and common container settings. Some fields are also present in container.securityContext. Field values of container.securityContext take precedence over field values of PodSecurityContext. + properties: + fsGroup: + description: "A special supplemental group that applies to all containers in a pod. Some volume types allow the Kubelet to change the ownership of that volume to be owned by the pod: \n 1. The owning GID will be the FSGroup 2. The setgid bit is set (new files created in the volume will be owned by FSGroup) 3. The permission bits are OR'd with rw-rw---- \n If unset, the Kubelet will not modify the ownership and permissions of any volume. Note that this field cannot be set when spec.os.name is windows." + format: int64 + type: integer + fsGroupChangePolicy: + description: 'fsGroupChangePolicy defines behavior of changing ownership and permission of the volume before being exposed inside Pod. This field will only apply to volume types which support fsGroup based ownership(and permissions). It will have no effect on ephemeral volume types such as: secret, configmaps and emptydir. Valid values are "OnRootMismatch" and "Always". If not specified, "Always" is used. Note that this field cannot be set when spec.os.name is windows.' + type: string + runAsGroup: + description: The GID to run the entrypoint of the container process. Uses runtime default if unset. May also be set in SecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence for that container. Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root user. If true, the Kubelet will validate the image at runtime to ensure that it does not run as UID 0 (root) and fail to start the container if it does. If unset or false, no such validation will be performed. May also be set in SecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container process. Defaults to user specified in image metadata if unspecified. May also be set in SecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence for that container. Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to all containers. If unspecified, the container runtime will allocate a random SELinux context for each container. May also be set in SecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence for that container. Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies to the container. + type: string + role: + description: Role is a SELinux role label that applies to the container. + type: string + type: + description: Type is a SELinux type label that applies to the container. + type: string + user: + description: User is a SELinux user label that applies to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by the containers in this pod. Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile location. Must only be set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp profile will be applied. Valid options are: \n Localhost - a profile defined in a file on the node should be used. RuntimeDefault - the container runtime default profile should be used. Unconfined - no profile should be applied." + type: string + required: + - type + type: object + supplementalGroups: + description: A list of groups applied to the first process run in each container, in addition to the container's primary GID, the fsGroup (if specified), and group memberships defined in the container image for the uid of the container process. If unspecified, no additional groups are added to any container. Note that group memberships defined in the container image for the uid of the container process are still effective, even if they are not included in this list. Note that this field cannot be set when spec.os.name is windows. + items: + format: int64 + type: integer + type: array + sysctls: + description: Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported sysctls (by the container runtime) might fail to launch. Note that this field cannot be set when spec.os.name is windows. + items: + description: Sysctl defines a kernel parameter to be set + properties: + name: + description: Name of a property to set + type: string + value: + description: Value of a property to set + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + description: The Windows specific settings applied to all containers. If unspecified, the options within a container's SecurityContext will be used. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should be run as a 'Host Process' container. This field is alpha-level and will only be honored by components that enable the WindowsHostProcessContainers feature flag. Setting this field without the feature flag will result in errors when validating the Pod. All of a Pod's containers must have the same effective HostProcess value (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint of the container process. Defaults to the user specified in image metadata if unspecified. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + serviceAccountName: + type: string + sidecarContainers: + items: + description: A single application container that you want to run within a pod. + properties: + args: + description: 'Arguments to the entrypoint. The container image''s CMD is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container''s environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + command: + description: 'Entrypoint array. Not executed within a shell. The container image''s ENTRYPOINT is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container''s environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + env: + description: List of environment variables to set in the container. Cannot be updated. + items: + description: EnvVar represents an environment variable present in a Container. + properties: + name: + description: Name of the environment variable. Must be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded using the previously defined environment variables in the container and any service environment variables. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['''']`, `metadata.annotations['''']`, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + description: List of sources to populate environment variables in the container. The keys defined within a source must be a C_IDENTIFIER. All invalid keys will be reported as an event when the container is starting. When a key exists in multiple sources, the value associated with the last source will take precedence. Values defined by an Env with a duplicate key will take precedence. Cannot be updated. + items: + description: EnvFromSource represents the source of a set of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap must be defined + type: boolean + type: object + prefix: + description: An optional identifier to prepend to each key in the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret must be defined + type: boolean + type: object + type: object + type: array + image: + description: 'Container image name. More info: https://kubernetes.io/docs/concepts/containers/images This field is optional to allow higher level config management to default or override container images in workload controllers like Deployments and StatefulSets.' + type: string + imagePullPolicy: + description: 'Image pull policy. One of Always, Never, IfNotPresent. Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. Cannot be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images' + type: string + lifecycle: + description: Actions that the management system should take in response to container lifecycle events. Cannot be updated. + properties: + postStart: + description: 'PostStart is called immediately after a container is created. If the handler fails, the container is terminated and restarted according to its restart policy. Other management of the container blocks until the hook completes. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept for the backward compatibility. There are no validation of this field and lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: 'PreStop is called immediately before a container is terminated due to an API request or management event such as liveness/startup probe failure, preemption, resource contention, etc. The handler is not called if the container crashes or exits. The Pod''s termination grace period countdown begins before the PreStop hook is executed. Regardless of the outcome of the handler, the container will eventually terminate within the Pod''s termination grace period (unless delayed by finalizers). Other management of the container blocks until the hook completes or until the termination grace period is reached. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept for the backward compatibility. There are no validation of this field and lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + description: 'Periodic probe of container liveness. Container will be restarted if the probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to be considered failed after having succeeded. Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. This is a beta field and requires enabling GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). \n If this is not specified, the default behavior is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has started before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to be considered successful after having failed. Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + name: + description: Name of the container specified as a DNS_LABEL. Each container in a pod must have a unique name (DNS_LABEL). Cannot be updated. + type: string + ports: + description: List of ports to expose from the container. Not specifying a port here DOES NOT prevent that port from being exposed. Any port which is listening on the default "0.0.0.0" address inside a container will be accessible from the network. Modifying this array with strategic merge patch may corrupt the data. For more information See https://github.com/kubernetes/kubernetes/issues/108255. Cannot be updated. + items: + description: ContainerPort represents a network port in a single container. + properties: + containerPort: + description: Number of port to expose on the pod's IP address. This must be a valid port number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external port to. + type: string + hostPort: + description: Number of port to expose on the host. If specified, this must be a valid port number, 0 < x < 65536. If HostNetwork is specified, this must match ContainerPort. Most containers do not need this. + format: int32 + type: integer + name: + description: If specified, this must be an IANA_SVC_NAME and unique within the pod. Each named port in a pod must have a unique name. Name for the port that can be referred to by services. + type: string + protocol: + default: TCP + description: Protocol for port. Must be UDP, TCP, or SCTP. Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: 'Periodic probe of container service readiness. Container will be removed from service endpoints if the probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to be considered failed after having succeeded. Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. This is a beta field and requires enabling GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). \n If this is not specified, the default behavior is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has started before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to be considered successful after having failed. Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + resources: + description: 'Compute Resources required by this container. Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + properties: + claims: + description: "Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container. \n This is an alpha field and requires enabling the DynamicResourceAllocation feature gate. \n This field is immutable." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. It makes that resource available inside a container. + type: string + required: + - name + type: object + type: array + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + securityContext: + description: 'SecurityContext defines the security options the container should be run with. If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/' + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether a process can gain more privileges than its parent process. This bool directly controls if the no_new_privs flag will be set on the container process. AllowPrivilegeEscalation is true always when the container is: 1) run as Privileged 2) has CAP_SYS_ADMIN Note that this field cannot be set when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running containers. Defaults to the default set of capabilities granted by the container runtime. Note that this field cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes in privileged containers are essentially equivalent to root on the host. Defaults to false. Note that this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount to use for the containers. The default is DefaultProcMount which uses the container runtime defaults for readonly paths and masked paths. This requires the ProcMountType feature flag to be enabled. Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root filesystem. Default is false. Note that this field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container process. Uses runtime default if unset. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root user. If true, the Kubelet will validate the image at runtime to ensure that it does not run as UID 0 (root) and fail to start the container if it does. If unset or false, no such validation will be performed. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container process. Defaults to user specified in image metadata if unspecified. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the container. If unspecified, the container runtime will allocate a random SELinux context for each container. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies to the container. + type: string + role: + description: Role is a SELinux role label that applies to the container. + type: string + type: + description: Type is a SELinux type label that applies to the container. + type: string + user: + description: User is a SELinux user label that applies to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. If seccomp options are provided at both the pod & container level, the container options override the pod options. Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile location. Must only be set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp profile will be applied. Valid options are: \n Localhost - a profile defined in a file on the node should be used. RuntimeDefault - the container runtime default profile should be used. Unconfined - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to all containers. If unspecified, the options from the PodSecurityContext will be used. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should be run as a 'Host Process' container. This field is alpha-level and will only be honored by components that enable the WindowsHostProcessContainers feature flag. Setting this field without the feature flag will result in errors when validating the Pod. All of a Pod's containers must have the same effective HostProcess value (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint of the container process. Defaults to the user specified in image metadata if unspecified. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + startupProbe: + description: 'StartupProbe indicates that the Pod has successfully initialized. If specified, no other probes are executed until this completes successfully. If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. This can be used to provide different probe parameters at the beginning of a Pod''s lifecycle, when it might take a long time to load data or warm a cache, than during steady-state operation. This cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to be considered failed after having succeeded. Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. This is a beta field and requires enabling GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). \n If this is not specified, the default behavior is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has started before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to be considered successful after having failed. Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + stdin: + description: Whether this container should allocate a buffer for stdin in the container runtime. If this is not set, reads from stdin in the container will always result in EOF. Default is false. + type: boolean + stdinOnce: + description: Whether the container runtime should close the stdin channel after it has been opened by a single attach. When stdin is true the stdin stream will remain open across multiple attach sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the first client attaches to stdin, and then remains open and accepts data until the client disconnects, at which time stdin is closed and remains closed until the container is restarted. If this flag is false, a container processes that reads from stdin will never receive an EOF. Default is false + type: boolean + terminationMessagePath: + description: 'Optional: Path at which the file to which the container''s termination message will be written is mounted into the container''s filesystem. Message written is intended to be brief final status, such as an assertion failure message. Will be truncated by the node if greater than 4096 bytes. The total message length across all containers will be limited to 12kb. Defaults to /dev/termination-log. Cannot be updated.' + type: string + terminationMessagePolicy: + description: Indicate how the termination message should be populated. File will use the contents of terminationMessagePath to populate the container status message on both success and failure. FallbackToLogsOnError will use the last chunk of container log output if the termination message file is empty and the container exited with an error. The log output is limited to 2048 bytes or 80 lines, whichever is smaller. Defaults to File. Cannot be updated. + type: string + tty: + description: Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. Default is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices to be used by the container. + items: + description: volumeDevice describes a mapping of a raw block device within a container. + properties: + devicePath: + description: devicePath is the path inside of the container that the device will be mapped to. + type: string + name: + description: name must match the name of a persistentVolumeClaim in the pod + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + description: Pod volumes to mount into the container's filesystem. Cannot be updated. + items: + description: VolumeMount describes a mounting of a Volume within a container. + properties: + mountPath: + description: Path within the container at which the volume should be mounted. Must not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts are propagated from the host to container and the other way around. When not set, MountPropagationNone is used. This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write otherwise (false or unspecified). Defaults to false. + type: boolean + subPath: + description: Path within the volume from which the container's volume should be mounted. Defaults to "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume from which the container's volume should be mounted. Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. Defaults to "" (volume's root). SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + description: Container's working directory. If not specified, the container runtime's default will be used, which might be configured in the container image. Cannot be updated. + type: string + required: + - name + type: object + type: array + terminationGracePeriodSeconds: + format: int64 + type: integer + tolerations: + items: + description: The pod this Toleration is attached to tolerates any taint that matches the triple using the matching operator . + properties: + effect: + description: Effect indicates the taint effect to match. Empty means match all taint effects. When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Key is the taint key that the toleration applies to. Empty means match all taint keys. If the key is empty, operator must be Exists; this combination means to match all values and all keys. + type: string + operator: + description: Operator represents a key's relationship to the value. Valid operators are Exists and Equal. Defaults to Equal. Exists is equivalent to wildcard for value, so that a pod can tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period of time the toleration (which must be of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, it is not set, which means tolerate the taint forever (do not evict). Zero and negative values will be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration matches to. If the operator is Exists, the value should be empty, otherwise just a regular string. + type: string + type: object + type: array + topologySpreadConstraints: + items: + description: TopologySpreadConstraint specifies how to spread matching pods among the given topology. + properties: + labelSelector: + description: LabelSelector is used to find matching pods. Pods that match this label selector are counted to determine the number of pods in their corresponding topology domain. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + matchLabelKeys: + description: MatchLabelKeys is a set of pod label keys to select the pods over which spreading will be calculated. The keys are used to lookup values from the incoming pod labels, those key-value labels are ANDed with labelSelector to select the group of existing pods over which spreading will be calculated for the incoming pod. Keys that don't exist in the incoming pod labels will be ignored. A null or empty list means only match against labelSelector. + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + description: 'MaxSkew describes the degree to which pods may be unevenly distributed. When `whenUnsatisfiable=DoNotSchedule`, it is the maximum permitted difference between the number of matching pods in the target topology and the global minimum. The global minimum is the minimum number of matching pods in an eligible domain or zero if the number of eligible domains is less than MinDomains. For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same labelSelector spread as 2/2/1: In this case, the global minimum is 1. | zone1 | zone2 | zone3 | | P P | P P | P | - if MaxSkew is 1, incoming pod can only be scheduled to zone3 to become 2/2/2; scheduling it onto zone1(zone2) would make the ActualSkew(3-1) on zone1(zone2) violate MaxSkew(1). - if MaxSkew is 2, incoming pod can be scheduled onto any zone. When `whenUnsatisfiable=ScheduleAnyway`, it is used to give higher precedence to topologies that satisfy it. It''s a required field. Default value is 1 and 0 is not allowed.' + format: int32 + type: integer + minDomains: + description: "MinDomains indicates a minimum number of eligible domains. When the number of eligible domains with matching topology keys is less than minDomains, Pod Topology Spread treats \"global minimum\" as 0, and then the calculation of Skew is performed. And when the number of eligible domains with matching topology keys equals or greater than minDomains, this value has no effect on scheduling. As a result, when the number of eligible domains is less than minDomains, scheduler won't schedule more than maxSkew Pods to those domains. If value is nil, the constraint behaves as if MinDomains is equal to 1. Valid values are integers greater than 0. When value is not nil, WhenUnsatisfiable must be DoNotSchedule. \n For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same labelSelector spread as 2/2/2: | zone1 | zone2 | zone3 | | P P | P P | P P | The number of domains is less than 5(MinDomains), so \"global minimum\" is treated as 0. In this situation, new pod with the same labelSelector cannot be scheduled, because computed skew will be 3(3 - 0) if new Pod is scheduled to any of the three zones, it will violate MaxSkew. \n This is a beta field and requires the MinDomainsInPodTopologySpread feature gate to be enabled (enabled by default)." + format: int32 + type: integer + nodeAffinityPolicy: + description: "NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector when calculating pod topology spread skew. Options are: - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations. \n If this value is nil, the behavior is equivalent to the Honor policy. This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag." + type: string + nodeTaintsPolicy: + description: "NodeTaintsPolicy indicates how we will treat node taints when calculating pod topology spread skew. Options are: - Honor: nodes without taints, along with tainted nodes for which the incoming pod has a toleration, are included. - Ignore: node taints are ignored. All nodes are included. \n If this value is nil, the behavior is equivalent to the Ignore policy. This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag." + type: string + topologyKey: + description: TopologyKey is the key of node labels. Nodes that have a label with this key and identical values are considered to be in the same topology. We consider each as a "bucket", and try to put balanced number of pods into each bucket. We define a domain as a particular instance of a topology. Also, we define an eligible domain as a domain whose nodes meet the requirements of nodeAffinityPolicy and nodeTaintsPolicy. e.g. If TopologyKey is "kubernetes.io/hostname", each Node is a domain of that topology. And, if TopologyKey is "topology.kubernetes.io/zone", each zone is a domain of that topology. It's a required field. + type: string + whenUnsatisfiable: + description: 'WhenUnsatisfiable indicates how to deal with a pod if it doesn''t satisfy the spread constraint. - DoNotSchedule (default) tells the scheduler not to schedule it. - ScheduleAnyway tells the scheduler to schedule the pod in any location, but giving higher precedence to topologies that would help reduce the skew. A constraint is considered "Unsatisfiable" for an incoming pod if and only if every possible node assignment for that pod would violate "MaxSkew" on some topology. For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same labelSelector spread as 3/1/1: | zone1 | zone2 | zone3 | | P P P | P | P | If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can only be scheduled to zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies MaxSkew(1). In other words, the cluster can still be imbalanced, but scheduler won''t make it *more* imbalanced. It''s a required field.' + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + volumeMounts: + items: + description: VolumeMount describes a mounting of a Volume within a container. + properties: + mountPath: + description: Path within the container at which the volume should be mounted. Must not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts are propagated from the host to container and the other way around. When not set, MountPropagationNone is used. This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write otherwise (false or unspecified). Defaults to false. + type: boolean + subPath: + description: Path within the volume from which the container's volume should be mounted. Defaults to "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume from which the container's volume should be mounted. Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. Defaults to "" (volume's root). SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + volumeSizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + volumeStorageMedium: + type: string + volumes: + items: + description: Volume represents a named volume in a pod that may be accessed by any container in the pod. + properties: + awsElasticBlockStore: + description: 'awsElasticBlockStore represents an AWS Disk resource that is attached to a kubelet''s host machine and then exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + properties: + fsType: + description: 'fsType is the filesystem type of the volume that you want to mount. Tip: Ensure that the filesystem type is supported by the host operating system. Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore TODO: how do we prevent errors in the filesystem from compromising the machine' + type: string + partition: + description: 'partition is the partition in the volume that you want to mount. If omitted, the default is to mount by volume name. Examples: For volume /dev/sda1, you specify the partition as "1". Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty).' + format: int32 + type: integer + readOnly: + description: 'readOnly value true will force the readOnly setting in VolumeMounts. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + type: boolean + volumeID: + description: 'volumeID is unique ID of the persistent disk resource in AWS (Amazon EBS volume). More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + type: string + required: + - volumeID + type: object + azureDisk: + description: azureDisk represents an Azure Data Disk mount on the host and bind mount to the pod. + properties: + cachingMode: + description: 'cachingMode is the Host Caching mode: None, Read Only, Read Write.' + type: string + diskName: + description: diskName is the Name of the data disk in the blob storage + type: string + diskURI: + description: diskURI is the URI of data disk in the blob storage + type: string + fsType: + description: fsType is Filesystem type to mount. Must be a filesystem type supported by the host operating system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + kind: + description: 'kind expected values are Shared: multiple blob disks per storage account Dedicated: single blob disk per storage account Managed: azure managed data disk (only in managed availability set). defaults to shared' + type: string + readOnly: + description: readOnly Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + description: azureFile represents an Azure File Service mount on the host and bind mount to the pod. + properties: + readOnly: + description: readOnly defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. + type: boolean + secretName: + description: secretName is the name of secret that contains Azure Storage Account Name and Key + type: string + shareName: + description: shareName is the azure share Name + type: string + required: + - secretName + - shareName + type: object + cephfs: + description: cephFS represents a Ceph FS mount on the host that shares a pod's lifetime + properties: + monitors: + description: 'monitors is Required: Monitors is a collection of Ceph monitors More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + items: + type: string + type: array + path: + description: 'path is Optional: Used as the mounted root, rather than the full Ceph tree, default is /' + type: string + readOnly: + description: 'readOnly is Optional: Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: boolean + secretFile: + description: 'secretFile is Optional: SecretFile is the path to key ring for User, default is /etc/ceph/user.secret More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: string + secretRef: + description: 'secretRef is Optional: SecretRef is reference to the authentication secret for User, default is empty. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + user: + description: 'user is optional: User is the rados user name, default is admin More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: string + required: + - monitors + type: object + cinder: + description: 'cinder represents a cinder volume attached and mounted on kubelets host machine. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + properties: + fsType: + description: 'fsType is the filesystem type to mount. Must be a filesystem type supported by the host operating system. Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: string + readOnly: + description: 'readOnly defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: boolean + secretRef: + description: 'secretRef is optional: points to a secret object containing parameters used to connect to OpenStack.' + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + volumeID: + description: 'volumeID used to identify the volume in cinder. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: string + required: + - volumeID + type: object + configMap: + description: configMap represents a configMap that should populate this volume + properties: + defaultMode: + description: 'defaultMode is optional: mode bits used to set permissions on created files by default. Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. Defaults to 0644. Directories within the path are not affected by this setting. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.' + format: int32 + type: integer + items: + description: items if unspecified, each key-value pair in the Data field of the referenced ConfigMap will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the ConfigMap, the volume setup will error unless it is marked optional. Paths must be relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits used to set permissions on this file. Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. If not specified, the volume defaultMode will be used. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.' + format: int32 + type: integer + path: + description: path is the relative path of the file to map the key to. May not be an absolute path. May not contain the path element '..'. May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: optional specify whether the ConfigMap or its keys must be defined + type: boolean + type: object + csi: + description: csi (Container Storage Interface) represents ephemeral storage that is handled by certain external CSI drivers (Beta feature). + properties: + driver: + description: driver is the name of the CSI driver that handles this volume. Consult with your admin for the correct name as registered in the cluster. + type: string + fsType: + description: fsType to mount. Ex. "ext4", "xfs", "ntfs". If not provided, the empty value is passed to the associated CSI driver which will determine the default filesystem to apply. + type: string + nodePublishSecretRef: + description: nodePublishSecretRef is a reference to the secret object containing sensitive information to pass to the CSI driver to complete the CSI NodePublishVolume and NodeUnpublishVolume calls. This field is optional, and may be empty if no secret is required. If the secret object contains more than one secret, all secret references are passed. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + readOnly: + description: readOnly specifies a read-only configuration for the volume. Defaults to false (read/write). + type: boolean + volumeAttributes: + additionalProperties: + type: string + description: volumeAttributes stores driver-specific properties that are passed to the CSI driver. Consult your driver's documentation for supported values. + type: object + required: + - driver + type: object + downwardAPI: + description: downwardAPI represents downward API about the pod that should populate this volume + properties: + defaultMode: + description: 'Optional: mode bits to use on created files by default. Must be a Optional: mode bits used to set permissions on created files by default. Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. Defaults to 0644. Directories within the path are not affected by this setting. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.' + format: int32 + type: integer + items: + description: Items is a list of downward API volume file + items: + description: DownwardAPIVolumeFile represents information to create the file containing the pod field + properties: + fieldRef: + description: 'Required: Selects a field of the pod: only annotations, labels, name and namespace are supported.' + properties: + apiVersion: + description: Version of the schema the FieldPath is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified API version. + type: string + required: + - fieldPath + type: object + mode: + description: 'Optional: mode bits used to set permissions on this file, must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. If not specified, the volume defaultMode will be used. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.' + format: int32 + type: integer + path: + description: 'Required: Path is the relative path name of the file to be created. Must not be absolute or contain the ''..'' path. Must be utf-8 encoded. The first item of the relative path must not start with ''..''' + type: string + resourceFieldRef: + description: 'Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + required: + - path + type: object + type: array + type: object + emptyDir: + description: 'emptyDir represents a temporary directory that shares a pod''s lifetime. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + properties: + medium: + description: 'medium represents what type of storage medium should back this directory. The default is "" which means to use the node''s default medium. Must be an empty string (default) or Memory. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + description: 'sizeLimit is the total amount of local storage required for this EmptyDir volume. The size limit is also applicable for memory medium. The maximum usage on memory medium EmptyDir would be the minimum value between the SizeLimit specified here and the sum of memory limits of all containers in a pod. The default is nil which means that the limit is undefined. More info: http://kubernetes.io/docs/user-guide/volumes#emptydir' + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + description: "ephemeral represents a volume that is handled by a cluster storage driver. The volume's lifecycle is tied to the pod that defines it - it will be created before the pod starts, and deleted when the pod is removed. \n Use this if: a) the volume is only needed while the pod runs, b) features of normal volumes like restoring from snapshot or capacity tracking are needed, c) the storage driver is specified through a storage class, and d) the storage driver supports dynamic volume provisioning through a PersistentVolumeClaim (see EphemeralVolumeSource for more information on the connection between this volume type and PersistentVolumeClaim). \n Use PersistentVolumeClaim or one of the vendor-specific APIs for volumes that persist for longer than the lifecycle of an individual pod. \n Use CSI for light-weight local ephemeral volumes if the CSI driver is meant to be used that way - see the documentation of the driver for more information. \n A pod can use both types of ephemeral volumes and persistent volumes at the same time." + properties: + volumeClaimTemplate: + description: "Will be used to create a stand-alone PVC to provision the volume. The pod in which this EphemeralVolumeSource is embedded will be the owner of the PVC, i.e. the PVC will be deleted together with the pod. The name of the PVC will be `-` where `` is the name from the `PodSpec.Volumes` array entry. Pod validation will reject the pod if the concatenated name is not valid for a PVC (for example, too long). \n An existing PVC with that name that is not owned by the pod will *not* be used for the pod to avoid using an unrelated volume by mistake. Starting the pod is then blocked until the unrelated PVC is removed. If such a pre-created PVC is meant to be used by the pod, the PVC has to updated with an owner reference to the pod once the pod exists. Normally this should not be necessary, but it may be useful when manually reconstructing a broken cluster. \n This field is read-only and no changes will be made by Kubernetes to the PVC after it has been created. \n Required, must not be nil." + properties: + metadata: + description: May contain labels and annotations that will be copied into the PVC when creating it. No other fields are allowed and will be rejected during validation. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: The specification for the PersistentVolumeClaim. The entire content is copied unchanged into the PVC that gets created from this template. The same fields as in a PersistentVolumeClaim are also valid here. + properties: + accessModes: + description: 'accessModes contains the desired access modes the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' + items: + type: string + type: array + dataSource: + description: 'dataSource field can be used to specify either: * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) * An existing PVC (PersistentVolumeClaim) If the provisioner or an external controller can support the specified data source, it will create a new volume based on the contents of the specified data source. When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. If the namespace is specified, then dataSourceRef will not be copied to dataSource.' + properties: + apiGroup: + description: APIGroup is the group for the resource being referenced. If APIGroup is not specified, the specified Kind must be in the core API group. For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + dataSourceRef: + description: 'dataSourceRef specifies the object from which to populate the volume with data, if a non-empty volume is desired. This may be any object from a non-empty API group (non core object) or a PersistentVolumeClaim object. When this field is specified, volume binding will only succeed if the type of the specified object matches some installed volume populator or dynamic provisioner. This field will replace the functionality of the dataSource field and as such if both fields are non-empty, they must have the same value. For backwards compatibility, when namespace isn''t specified in dataSourceRef, both fields (dataSource and dataSourceRef) will be set to the same value automatically if one of them is empty and the other is non-empty. When namespace is specified in dataSourceRef, dataSource isn''t set to the same value and must be empty. There are three important differences between dataSource and dataSourceRef: * While dataSource only allows two specific types of objects, dataSourceRef allows any non-core object, as well as PersistentVolumeClaim objects. * While dataSource ignores disallowed values (dropping them), dataSourceRef preserves all values, and generates an error if a disallowed value is specified. * While dataSource only allows local objects, dataSourceRef allows objects in any namespaces. (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled.' + properties: + apiGroup: + description: APIGroup is the group for the resource being referenced. If APIGroup is not specified, the specified Kind must be in the core API group. For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + namespace: + description: Namespace is the namespace of resource being referenced Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: 'resources represents the minimum resources the volume should have. If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements that are lower than previous value but must still be higher than capacity recorded in the status field of the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources' + properties: + claims: + description: "Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container. \n This is an alpha field and requires enabling the DynamicResourceAllocation feature gate. \n This field is immutable." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. It makes that resource available inside a container. + type: string + required: + - name + type: object + type: array + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + selector: + description: selector is a label query over volumes to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + storageClassName: + description: 'storageClassName is the name of the StorageClass required by the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' + type: string + volumeMode: + description: volumeMode defines what type of volume is required by the claim. Value of Filesystem is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference to the PersistentVolume backing this claim. + type: string + type: object + required: + - spec + type: object + type: object + fc: + description: fc represents a Fibre Channel resource that is attached to a kubelet's host machine and then exposed to the pod. + properties: + fsType: + description: 'fsType is the filesystem type to mount. Must be a filesystem type supported by the host operating system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. TODO: how do we prevent errors in the filesystem from compromising the machine' + type: string + lun: + description: 'lun is Optional: FC target lun number' + format: int32 + type: integer + readOnly: + description: 'readOnly is Optional: Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts.' + type: boolean + targetWWNs: + description: 'targetWWNs is Optional: FC target worldwide names (WWNs)' + items: + type: string + type: array + wwids: + description: 'wwids Optional: FC volume world wide identifiers (wwids) Either wwids or combination of targetWWNs and lun must be set, but not both simultaneously.' + items: + type: string + type: array + type: object + flexVolume: + description: flexVolume represents a generic volume resource that is provisioned/attached using an exec based plugin. + properties: + driver: + description: driver is the name of the driver to use for this volume. + type: string + fsType: + description: fsType is the filesystem type to mount. Must be a filesystem type supported by the host operating system. Ex. "ext4", "xfs", "ntfs". The default filesystem depends on FlexVolume script. + type: string + options: + additionalProperties: + type: string + description: 'options is Optional: this field holds extra command options if any.' + type: object + readOnly: + description: 'readOnly is Optional: defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts.' + type: boolean + secretRef: + description: 'secretRef is Optional: secretRef is reference to the secret object containing sensitive information to pass to the plugin scripts. This may be empty if no secret object is specified. If the secret object contains more than one secret, all secrets are passed to the plugin scripts.' + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + required: + - driver + type: object + flocker: + description: flocker represents a Flocker volume attached to a kubelet's host machine. This depends on the Flocker control service being running + properties: + datasetName: + description: datasetName is Name of the dataset stored as metadata -> name on the dataset for Flocker should be considered as deprecated + type: string + datasetUUID: + description: datasetUUID is the UUID of the dataset. This is unique identifier of a Flocker dataset + type: string + type: object + gcePersistentDisk: + description: 'gcePersistentDisk represents a GCE Disk resource that is attached to a kubelet''s host machine and then exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + properties: + fsType: + description: 'fsType is filesystem type of the volume that you want to mount. Tip: Ensure that the filesystem type is supported by the host operating system. Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk TODO: how do we prevent errors in the filesystem from compromising the machine' + type: string + partition: + description: 'partition is the partition in the volume that you want to mount. If omitted, the default is to mount by volume name. Examples: For volume /dev/sda1, you specify the partition as "1". Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + format: int32 + type: integer + pdName: + description: 'pdName is unique name of the PD resource in GCE. Used to identify the disk in GCE. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + type: string + readOnly: + description: 'readOnly here will force the ReadOnly setting in VolumeMounts. Defaults to false. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + type: boolean + required: + - pdName + type: object + gitRepo: + description: 'gitRepo represents a git repository at a particular revision. DEPRECATED: GitRepo is deprecated. To provision a container with a git repo, mount an EmptyDir into an InitContainer that clones the repo using git, then mount the EmptyDir into the Pod''s container.' + properties: + directory: + description: directory is the target directory name. Must not contain or start with '..'. If '.' is supplied, the volume directory will be the git repository. Otherwise, if specified, the volume will contain the git repository in the subdirectory with the given name. + type: string + repository: + description: repository is the URL + type: string + revision: + description: revision is the commit hash for the specified revision. + type: string + required: + - repository + type: object + glusterfs: + description: 'glusterfs represents a Glusterfs mount on the host that shares a pod''s lifetime. More info: https://examples.k8s.io/volumes/glusterfs/README.md' + properties: + endpoints: + description: 'endpoints is the endpoint name that details Glusterfs topology. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: string + path: + description: 'path is the Glusterfs volume path. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: string + readOnly: + description: 'readOnly here will force the Glusterfs volume to be mounted with read-only permissions. Defaults to false. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: boolean + required: + - endpoints + - path + type: object + hostPath: + description: 'hostPath represents a pre-existing file or directory on the host machine that is directly exposed to the container. This is generally used for system agents or other privileged things that are allowed to see the host machine. Most containers will NOT need this. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath --- TODO(jonesdl) We need to restrict who can use host directory mounts and who can/can not mount host directories as read/write.' + properties: + path: + description: 'path of the directory on the host. If the path is a symlink, it will follow the link to the real path. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' + type: string + type: + description: 'type for HostPath Volume Defaults to "" More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' + type: string + required: + - path + type: object + iscsi: + description: 'iscsi represents an ISCSI Disk resource that is attached to a kubelet''s host machine and then exposed to the pod. More info: https://examples.k8s.io/volumes/iscsi/README.md' + properties: + chapAuthDiscovery: + description: chapAuthDiscovery defines whether support iSCSI Discovery CHAP authentication + type: boolean + chapAuthSession: + description: chapAuthSession defines whether support iSCSI Session CHAP authentication + type: boolean + fsType: + description: 'fsType is the filesystem type of the volume that you want to mount. Tip: Ensure that the filesystem type is supported by the host operating system. Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi TODO: how do we prevent errors in the filesystem from compromising the machine' + type: string + initiatorName: + description: initiatorName is the custom iSCSI Initiator Name. If initiatorName is specified with iscsiInterface simultaneously, new iSCSI interface : will be created for the connection. + type: string + iqn: + description: iqn is the target iSCSI Qualified Name. + type: string + iscsiInterface: + description: iscsiInterface is the interface Name that uses an iSCSI transport. Defaults to 'default' (tcp). + type: string + lun: + description: lun represents iSCSI Target Lun number. + format: int32 + type: integer + portals: + description: portals is the iSCSI Target Portal List. The portal is either an IP or ip_addr:port if the port is other than default (typically TCP ports 860 and 3260). + items: + type: string + type: array + readOnly: + description: readOnly here will force the ReadOnly setting in VolumeMounts. Defaults to false. + type: boolean + secretRef: + description: secretRef is the CHAP Secret for iSCSI target and initiator authentication + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + targetPortal: + description: targetPortal is iSCSI Target Portal. The Portal is either an IP or ip_addr:port if the port is other than default (typically TCP ports 860 and 3260). + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + description: 'name of the volume. Must be a DNS_LABEL and unique within the pod. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + nfs: + description: 'nfs represents an NFS mount on the host that shares a pod''s lifetime More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + properties: + path: + description: 'path that is exported by the NFS server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: string + readOnly: + description: 'readOnly here will force the NFS export to be mounted with read-only permissions. Defaults to false. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: boolean + server: + description: 'server is the hostname or IP address of the NFS server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + description: 'persistentVolumeClaimVolumeSource represents a reference to a PersistentVolumeClaim in the same namespace. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + properties: + claimName: + description: 'claimName is the name of a PersistentVolumeClaim in the same namespace as the pod using this volume. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + type: string + readOnly: + description: readOnly Will force the ReadOnly setting in VolumeMounts. Default false. + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + description: photonPersistentDisk represents a PhotonController persistent disk attached and mounted on kubelets host machine + properties: + fsType: + description: fsType is the filesystem type to mount. Must be a filesystem type supported by the host operating system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + pdID: + description: pdID is the ID that identifies Photon Controller persistent disk + type: string + required: + - pdID + type: object + portworxVolume: + description: portworxVolume represents a portworx volume attached and mounted on kubelets host machine + properties: + fsType: + description: fSType represents the filesystem type to mount Must be a filesystem type supported by the host operating system. Ex. "ext4", "xfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: readOnly defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. + type: boolean + volumeID: + description: volumeID uniquely identifies a Portworx volume + type: string + required: + - volumeID + type: object + projected: + description: projected items for all in one resources secrets, configmaps, and downward API + properties: + defaultMode: + description: defaultMode are the mode bits used to set permissions on created files by default. Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. Directories within the path are not affected by this setting. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + sources: + description: sources is the list of volume projections + items: + description: Projection that may be projected along with other supported volume types + properties: + configMap: + description: configMap information about the configMap data to project + properties: + items: + description: items if unspecified, each key-value pair in the Data field of the referenced ConfigMap will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the ConfigMap, the volume setup will error unless it is marked optional. Paths must be relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits used to set permissions on this file. Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. If not specified, the volume defaultMode will be used. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.' + format: int32 + type: integer + path: + description: path is the relative path of the file to map the key to. May not be an absolute path. May not contain the path element '..'. May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: optional specify whether the ConfigMap or its keys must be defined + type: boolean + type: object + downwardAPI: + description: downwardAPI information about the downwardAPI data to project + properties: + items: + description: Items is a list of DownwardAPIVolume file + items: + description: DownwardAPIVolumeFile represents information to create the file containing the pod field + properties: + fieldRef: + description: 'Required: Selects a field of the pod: only annotations, labels, name and namespace are supported.' + properties: + apiVersion: + description: Version of the schema the FieldPath is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified API version. + type: string + required: + - fieldPath + type: object + mode: + description: 'Optional: mode bits used to set permissions on this file, must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. If not specified, the volume defaultMode will be used. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.' + format: int32 + type: integer + path: + description: 'Required: Path is the relative path name of the file to be created. Must not be absolute or contain the ''..'' path. Must be utf-8 encoded. The first item of the relative path must not start with ''..''' + type: string + resourceFieldRef: + description: 'Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + required: + - path + type: object + type: array + type: object + secret: + description: secret information about the secret data to project + properties: + items: + description: items if unspecified, each key-value pair in the Data field of the referenced Secret will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the Secret, the volume setup will error unless it is marked optional. Paths must be relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits used to set permissions on this file. Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. If not specified, the volume defaultMode will be used. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.' + format: int32 + type: integer + path: + description: path is the relative path of the file to map the key to. May not be an absolute path. May not contain the path element '..'. May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: optional field specify whether the Secret or its key must be defined + type: boolean + type: object + serviceAccountToken: + description: serviceAccountToken is information about the serviceAccountToken data to project + properties: + audience: + description: audience is the intended audience of the token. A recipient of a token must identify itself with an identifier specified in the audience of the token, and otherwise should reject the token. The audience defaults to the identifier of the apiserver. + type: string + expirationSeconds: + description: expirationSeconds is the requested duration of validity of the service account token. As the token approaches expiration, the kubelet volume plugin will proactively rotate the service account token. The kubelet will start trying to rotate the token if the token is older than 80 percent of its time to live or if the token is older than 24 hours.Defaults to 1 hour and must be at least 10 minutes. + format: int64 + type: integer + path: + description: path is the path relative to the mount point of the file to project the token into. + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + description: quobyte represents a Quobyte mount on the host that shares a pod's lifetime + properties: + group: + description: group to map volume access to Default is no group + type: string + readOnly: + description: readOnly here will force the Quobyte volume to be mounted with read-only permissions. Defaults to false. + type: boolean + registry: + description: registry represents a single or multiple Quobyte Registry services specified as a string as host:port pair (multiple entries are separated with commas) which acts as the central registry for volumes + type: string + tenant: + description: tenant owning the given Quobyte volume in the Backend Used with dynamically provisioned Quobyte volumes, value is set by the plugin + type: string + user: + description: user to map volume access to Defaults to serivceaccount user + type: string + volume: + description: volume is a string that references an already created Quobyte volume by name. + type: string + required: + - registry + - volume + type: object + rbd: + description: 'rbd represents a Rados Block Device mount on the host that shares a pod''s lifetime. More info: https://examples.k8s.io/volumes/rbd/README.md' + properties: + fsType: + description: 'fsType is the filesystem type of the volume that you want to mount. Tip: Ensure that the filesystem type is supported by the host operating system. Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd TODO: how do we prevent errors in the filesystem from compromising the machine' + type: string + image: + description: 'image is the rados image name. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + keyring: + description: 'keyring is the path to key ring for RBDUser. Default is /etc/ceph/keyring. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + monitors: + description: 'monitors is a collection of Ceph monitors. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + items: + type: string + type: array + pool: + description: 'pool is the rados pool name. Default is rbd. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + readOnly: + description: 'readOnly here will force the ReadOnly setting in VolumeMounts. Defaults to false. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: boolean + secretRef: + description: 'secretRef is name of the authentication secret for RBDUser. If provided overrides keyring. Default is nil. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + user: + description: 'user is the rados user name. Default is admin. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + required: + - image + - monitors + type: object + scaleIO: + description: scaleIO represents a ScaleIO persistent volume attached and mounted on Kubernetes nodes. + properties: + fsType: + description: fsType is the filesystem type to mount. Must be a filesystem type supported by the host operating system. Ex. "ext4", "xfs", "ntfs". Default is "xfs". + type: string + gateway: + description: gateway is the host address of the ScaleIO API Gateway. + type: string + protectionDomain: + description: protectionDomain is the name of the ScaleIO Protection Domain for the configured storage. + type: string + readOnly: + description: readOnly Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: secretRef references to the secret for ScaleIO user and other sensitive information. If this is not provided, Login operation will fail. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + sslEnabled: + description: sslEnabled Flag enable/disable SSL communication with Gateway, default false + type: boolean + storageMode: + description: storageMode indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned. Default is ThinProvisioned. + type: string + storagePool: + description: storagePool is the ScaleIO Storage Pool associated with the protection domain. + type: string + system: + description: system is the name of the storage system as configured in ScaleIO. + type: string + volumeName: + description: volumeName is the name of a volume already created in the ScaleIO system that is associated with this volume source. + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + description: 'secret represents a secret that should populate this volume. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + properties: + defaultMode: + description: 'defaultMode is Optional: mode bits used to set permissions on created files by default. Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. Defaults to 0644. Directories within the path are not affected by this setting. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.' + format: int32 + type: integer + items: + description: items If unspecified, each key-value pair in the Data field of the referenced Secret will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the Secret, the volume setup will error unless it is marked optional. Paths must be relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits used to set permissions on this file. Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. If not specified, the volume defaultMode will be used. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.' + format: int32 + type: integer + path: + description: path is the relative path of the file to map the key to. May not be an absolute path. May not contain the path element '..'. May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + optional: + description: optional field specify whether the Secret or its keys must be defined + type: boolean + secretName: + description: 'secretName is the name of the secret in the pod''s namespace to use. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + type: string + type: object + storageos: + description: storageOS represents a StorageOS volume attached and mounted on Kubernetes nodes. + properties: + fsType: + description: fsType is the filesystem type to mount. Must be a filesystem type supported by the host operating system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: readOnly defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: secretRef specifies the secret to use for obtaining the StorageOS API credentials. If not specified, default values will be attempted. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + volumeName: + description: volumeName is the human-readable name of the StorageOS volume. Volume names are only unique within a namespace. + type: string + volumeNamespace: + description: volumeNamespace specifies the scope of the volume within StorageOS. If no namespace is specified then the Pod's namespace will be used. This allows the Kubernetes name scoping to be mirrored within StorageOS for tighter integration. Set VolumeName to any name to override the default behaviour. Set to "default" if you are not using namespaces within StorageOS. Namespaces that do not pre-exist within StorageOS will be created. + type: string + type: object + vsphereVolume: + description: vsphereVolume represents a vSphere volume attached and mounted on kubelets host machine + properties: + fsType: + description: fsType is filesystem type to mount. Must be a filesystem type supported by the host operating system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + storagePolicyID: + description: storagePolicyID is the storage Policy Based Management (SPBM) profile ID associated with the StoragePolicyName. + type: string + storagePolicyName: + description: storagePolicyName is the storage Policy Based Management (SPBM) profile name. + type: string + volumePath: + description: volumePath is the path that identifies vSphere volume vmdk + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + workDir: + type: string + workVolumeClaimTemplate: + properties: + accessModes: + items: + type: string + type: array + resources: + description: ResourceRequirements describes the compute resource requirements. + properties: + claims: + description: "Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container. \n This is an alpha field and requires enabling the DynamicResourceAllocation feature gate. \n This field is immutable." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. It makes that resource available inside a container. + type: string + required: + - name + type: object + type: array + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + storageClassName: + type: string + required: + - accessModes + - resources + - storageClassName + type: object + type: object + type: object + required: + - template + type: object + status: + properties: + availableReplicas: + description: AvailableReplicas is the number of runners that are created and Runnning. This is currently same as ReadyReplicas but perserved for future use. + type: integer + readyReplicas: + description: ReadyReplicas is the number of runners that are created and Runnning. + type: integer + replicas: + description: Replicas is the number of runners that are created and still being managed by this runner replica set. + type: integer + required: + - availableReplicas + - readyReplicas + type: object + type: object + served: true + storage: true + subresources: + status: {} + preserveUnknownFields: false +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/helm/actions-runner-controller/crds/actions.summerwind.dev_runners.yaml b/helm/actions-runner-controller/crds/actions.summerwind.dev_runners.yaml new file mode 100644 index 0000000..beaea51 --- /dev/null +++ b/helm/actions-runner-controller/crds/actions.summerwind.dev_runners.yaml @@ -0,0 +1,5370 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.7.0 + creationTimestamp: null + name: runners.actions.summerwind.dev +spec: + group: actions.summerwind.dev + names: + kind: Runner + listKind: RunnerList + plural: runners + singular: runner + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.enterprise + name: Enterprise + type: string + - jsonPath: .spec.organization + name: Organization + type: string + - jsonPath: .spec.repository + name: Repository + type: string + - jsonPath: .spec.group + name: Group + type: string + - jsonPath: .spec.labels + name: Labels + type: string + - jsonPath: .status.phase + name: Status + type: string + - jsonPath: .status.message + name: Message + type: string + - jsonPath: .status.workflow.repository + name: WF Repo + type: string + - jsonPath: .status.workflow.runID + name: WF Run + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: Runner is the Schema for the runners 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: RunnerSpec defines the desired state of Runner + properties: + affinity: + description: Affinity is a group of affinity scheduling rules. + properties: + nodeAffinity: + description: Describes node affinity scheduling rules for the pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to nodes that satisfy the affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding "weight" to the sum if the node matches the corresponding matchExpressions; the node(s) with the highest sum are the most preferred. + items: + description: An empty preferred scheduling term matches all objects with implicit weight 0 (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated with the corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements by node's labels. + items: + description: A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: Represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements by node's fields. + items: + description: A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: Represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + description: Weight associated with matching the corresponding nodeSelectorTerm, in the range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to an update), the system may or may not try to eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector terms. The terms are ORed. + items: + description: A null or empty node selector term matches no objects. The requirements of them are ANDed. The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements by node's labels. + items: + description: A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: Represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements by node's fields. + items: + description: A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: Represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + description: Describes pod affinity scheduling rules (e.g. co-locate this pod in the same node, zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to nodes that satisfy the affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaceSelector: + description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the corresponding podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system may or may not try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching the labelSelector relative to the given namespace(s)) that this pod should be co-located (affinity) or not co-located (anti-affinity) with, where co-located is defined as running on a node whose value of the label with key matches that of any node on which a pod of the set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaceSelector: + description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules (e.g. avoid putting this pod in the same node, zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to nodes that satisfy the anti-affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling anti-affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaceSelector: + description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the corresponding podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the anti-affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the anti-affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system may or may not try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching the labelSelector relative to the given namespace(s)) that this pod should be co-located (affinity) or not co-located (anti-affinity) with, where co-located is defined as running on a node whose value of the label with key matches that of any node on which a pod of the set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaceSelector: + description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + automountServiceAccountToken: + type: boolean + containerMode: + type: string + containers: + items: + description: A single application container that you want to run within a pod. + properties: + args: + description: 'Arguments to the entrypoint. The container image''s CMD is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container''s environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + command: + description: 'Entrypoint array. Not executed within a shell. The container image''s ENTRYPOINT is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container''s environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + env: + description: List of environment variables to set in the container. Cannot be updated. + items: + description: EnvVar represents an environment variable present in a Container. + properties: + name: + description: Name of the environment variable. Must be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded using the previously defined environment variables in the container and any service environment variables. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['''']`, `metadata.annotations['''']`, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + description: List of sources to populate environment variables in the container. The keys defined within a source must be a C_IDENTIFIER. All invalid keys will be reported as an event when the container is starting. When a key exists in multiple sources, the value associated with the last source will take precedence. Values defined by an Env with a duplicate key will take precedence. Cannot be updated. + items: + description: EnvFromSource represents the source of a set of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap must be defined + type: boolean + type: object + prefix: + description: An optional identifier to prepend to each key in the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret must be defined + type: boolean + type: object + type: object + type: array + image: + description: 'Container image name. More info: https://kubernetes.io/docs/concepts/containers/images This field is optional to allow higher level config management to default or override container images in workload controllers like Deployments and StatefulSets.' + type: string + imagePullPolicy: + description: 'Image pull policy. One of Always, Never, IfNotPresent. Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. Cannot be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images' + type: string + lifecycle: + description: Actions that the management system should take in response to container lifecycle events. Cannot be updated. + properties: + postStart: + description: 'PostStart is called immediately after a container is created. If the handler fails, the container is terminated and restarted according to its restart policy. Other management of the container blocks until the hook completes. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept for the backward compatibility. There are no validation of this field and lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: 'PreStop is called immediately before a container is terminated due to an API request or management event such as liveness/startup probe failure, preemption, resource contention, etc. The handler is not called if the container crashes or exits. The Pod''s termination grace period countdown begins before the PreStop hook is executed. Regardless of the outcome of the handler, the container will eventually terminate within the Pod''s termination grace period (unless delayed by finalizers). Other management of the container blocks until the hook completes or until the termination grace period is reached. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept for the backward compatibility. There are no validation of this field and lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + description: 'Periodic probe of container liveness. Container will be restarted if the probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to be considered failed after having succeeded. Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. This is a beta field and requires enabling GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). \n If this is not specified, the default behavior is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has started before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to be considered successful after having failed. Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + name: + description: Name of the container specified as a DNS_LABEL. Each container in a pod must have a unique name (DNS_LABEL). Cannot be updated. + type: string + ports: + description: List of ports to expose from the container. Not specifying a port here DOES NOT prevent that port from being exposed. Any port which is listening on the default "0.0.0.0" address inside a container will be accessible from the network. Modifying this array with strategic merge patch may corrupt the data. For more information See https://github.com/kubernetes/kubernetes/issues/108255. Cannot be updated. + items: + description: ContainerPort represents a network port in a single container. + properties: + containerPort: + description: Number of port to expose on the pod's IP address. This must be a valid port number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external port to. + type: string + hostPort: + description: Number of port to expose on the host. If specified, this must be a valid port number, 0 < x < 65536. If HostNetwork is specified, this must match ContainerPort. Most containers do not need this. + format: int32 + type: integer + name: + description: If specified, this must be an IANA_SVC_NAME and unique within the pod. Each named port in a pod must have a unique name. Name for the port that can be referred to by services. + type: string + protocol: + default: TCP + description: Protocol for port. Must be UDP, TCP, or SCTP. Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: 'Periodic probe of container service readiness. Container will be removed from service endpoints if the probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to be considered failed after having succeeded. Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. This is a beta field and requires enabling GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). \n If this is not specified, the default behavior is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has started before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to be considered successful after having failed. Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + resources: + description: 'Compute Resources required by this container. Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + properties: + claims: + description: "Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container. \n This is an alpha field and requires enabling the DynamicResourceAllocation feature gate. \n This field is immutable." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. It makes that resource available inside a container. + type: string + required: + - name + type: object + type: array + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + securityContext: + description: 'SecurityContext defines the security options the container should be run with. If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/' + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether a process can gain more privileges than its parent process. This bool directly controls if the no_new_privs flag will be set on the container process. AllowPrivilegeEscalation is true always when the container is: 1) run as Privileged 2) has CAP_SYS_ADMIN Note that this field cannot be set when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running containers. Defaults to the default set of capabilities granted by the container runtime. Note that this field cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes in privileged containers are essentially equivalent to root on the host. Defaults to false. Note that this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount to use for the containers. The default is DefaultProcMount which uses the container runtime defaults for readonly paths and masked paths. This requires the ProcMountType feature flag to be enabled. Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root filesystem. Default is false. Note that this field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container process. Uses runtime default if unset. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root user. If true, the Kubelet will validate the image at runtime to ensure that it does not run as UID 0 (root) and fail to start the container if it does. If unset or false, no such validation will be performed. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container process. Defaults to user specified in image metadata if unspecified. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the container. If unspecified, the container runtime will allocate a random SELinux context for each container. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies to the container. + type: string + role: + description: Role is a SELinux role label that applies to the container. + type: string + type: + description: Type is a SELinux type label that applies to the container. + type: string + user: + description: User is a SELinux user label that applies to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. If seccomp options are provided at both the pod & container level, the container options override the pod options. Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile location. Must only be set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp profile will be applied. Valid options are: \n Localhost - a profile defined in a file on the node should be used. RuntimeDefault - the container runtime default profile should be used. Unconfined - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to all containers. If unspecified, the options from the PodSecurityContext will be used. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should be run as a 'Host Process' container. This field is alpha-level and will only be honored by components that enable the WindowsHostProcessContainers feature flag. Setting this field without the feature flag will result in errors when validating the Pod. All of a Pod's containers must have the same effective HostProcess value (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint of the container process. Defaults to the user specified in image metadata if unspecified. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + startupProbe: + description: 'StartupProbe indicates that the Pod has successfully initialized. If specified, no other probes are executed until this completes successfully. If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. This can be used to provide different probe parameters at the beginning of a Pod''s lifecycle, when it might take a long time to load data or warm a cache, than during steady-state operation. This cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to be considered failed after having succeeded. Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. This is a beta field and requires enabling GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). \n If this is not specified, the default behavior is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has started before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to be considered successful after having failed. Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + stdin: + description: Whether this container should allocate a buffer for stdin in the container runtime. If this is not set, reads from stdin in the container will always result in EOF. Default is false. + type: boolean + stdinOnce: + description: Whether the container runtime should close the stdin channel after it has been opened by a single attach. When stdin is true the stdin stream will remain open across multiple attach sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the first client attaches to stdin, and then remains open and accepts data until the client disconnects, at which time stdin is closed and remains closed until the container is restarted. If this flag is false, a container processes that reads from stdin will never receive an EOF. Default is false + type: boolean + terminationMessagePath: + description: 'Optional: Path at which the file to which the container''s termination message will be written is mounted into the container''s filesystem. Message written is intended to be brief final status, such as an assertion failure message. Will be truncated by the node if greater than 4096 bytes. The total message length across all containers will be limited to 12kb. Defaults to /dev/termination-log. Cannot be updated.' + type: string + terminationMessagePolicy: + description: Indicate how the termination message should be populated. File will use the contents of terminationMessagePath to populate the container status message on both success and failure. FallbackToLogsOnError will use the last chunk of container log output if the termination message file is empty and the container exited with an error. The log output is limited to 2048 bytes or 80 lines, whichever is smaller. Defaults to File. Cannot be updated. + type: string + tty: + description: Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. Default is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices to be used by the container. + items: + description: volumeDevice describes a mapping of a raw block device within a container. + properties: + devicePath: + description: devicePath is the path inside of the container that the device will be mapped to. + type: string + name: + description: name must match the name of a persistentVolumeClaim in the pod + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + description: Pod volumes to mount into the container's filesystem. Cannot be updated. + items: + description: VolumeMount describes a mounting of a Volume within a container. + properties: + mountPath: + description: Path within the container at which the volume should be mounted. Must not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts are propagated from the host to container and the other way around. When not set, MountPropagationNone is used. This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write otherwise (false or unspecified). Defaults to false. + type: boolean + subPath: + description: Path within the volume from which the container's volume should be mounted. Defaults to "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume from which the container's volume should be mounted. Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. Defaults to "" (volume's root). SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + description: Container's working directory. If not specified, the container runtime's default will be used, which might be configured in the container image. Cannot be updated. + type: string + required: + - name + type: object + type: array + dnsConfig: + description: PodDNSConfig defines the DNS parameters of a pod in addition to those generated from DNSPolicy. + properties: + nameservers: + description: A list of DNS name server IP addresses. This will be appended to the base nameservers generated from DNSPolicy. Duplicated nameservers will be removed. + items: + type: string + type: array + options: + description: A list of DNS resolver options. This will be merged with the base options generated from DNSPolicy. Duplicated entries will be removed. Resolution options given in Options will override those that appear in the base DNSPolicy. + items: + description: PodDNSConfigOption defines DNS resolver options of a pod. + properties: + name: + description: Required. + type: string + value: + type: string + type: object + type: array + searches: + description: A list of DNS search domains for host-name lookup. This will be appended to the base search paths generated from DNSPolicy. Duplicated search paths will be removed. + items: + type: string + type: array + type: object + dnsPolicy: + description: DNSPolicy defines how a pod's DNS will be configured. + type: string + dockerEnabled: + type: boolean + dockerEnv: + items: + description: EnvVar represents an environment variable present in a Container. + properties: + name: + description: Name of the environment variable. Must be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded using the previously defined environment variables in the container and any service environment variables. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['''']`, `metadata.annotations['''']`, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + dockerMTU: + format: int64 + type: integer + dockerRegistryMirror: + type: string + dockerVolumeMounts: + items: + description: VolumeMount describes a mounting of a Volume within a container. + properties: + mountPath: + description: Path within the container at which the volume should be mounted. Must not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts are propagated from the host to container and the other way around. When not set, MountPropagationNone is used. This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write otherwise (false or unspecified). Defaults to false. + type: boolean + subPath: + description: Path within the volume from which the container's volume should be mounted. Defaults to "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume from which the container's volume should be mounted. Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. Defaults to "" (volume's root). SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + dockerdContainerResources: + description: ResourceRequirements describes the compute resource requirements. + properties: + claims: + description: "Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container. \n This is an alpha field and requires enabling the DynamicResourceAllocation feature gate. \n This field is immutable." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. It makes that resource available inside a container. + type: string + required: + - name + type: object + type: array + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + dockerdWithinRunnerContainer: + type: boolean + enableServiceLinks: + type: boolean + enterprise: + pattern: ^[^/]+$ + type: string + env: + items: + description: EnvVar represents an environment variable present in a Container. + properties: + name: + description: Name of the environment variable. Must be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded using the previously defined environment variables in the container and any service environment variables. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['''']`, `metadata.annotations['''']`, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + description: EnvFromSource represents the source of a set of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap must be defined + type: boolean + type: object + prefix: + description: An optional identifier to prepend to each key in the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret must be defined + type: boolean + type: object + type: object + type: array + ephemeral: + type: boolean + ephemeralContainers: + items: + description: "An EphemeralContainer is a temporary container that you may add to an existing Pod for user-initiated activities such as debugging. Ephemeral containers have no resource or scheduling guarantees, and they will not be restarted when they exit or when a Pod is removed or restarted. The kubelet may evict a Pod if an ephemeral container causes the Pod to exceed its resource allocation. \n To add an ephemeral container, use the ephemeralcontainers subresource of an existing Pod. Ephemeral containers may not be removed or restarted." + properties: + args: + description: 'Arguments to the entrypoint. The image''s CMD is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container''s environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + command: + description: 'Entrypoint array. Not executed within a shell. The image''s ENTRYPOINT is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container''s environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + env: + description: List of environment variables to set in the container. Cannot be updated. + items: + description: EnvVar represents an environment variable present in a Container. + properties: + name: + description: Name of the environment variable. Must be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded using the previously defined environment variables in the container and any service environment variables. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['''']`, `metadata.annotations['''']`, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + description: List of sources to populate environment variables in the container. The keys defined within a source must be a C_IDENTIFIER. All invalid keys will be reported as an event when the container is starting. When a key exists in multiple sources, the value associated with the last source will take precedence. Values defined by an Env with a duplicate key will take precedence. Cannot be updated. + items: + description: EnvFromSource represents the source of a set of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap must be defined + type: boolean + type: object + prefix: + description: An optional identifier to prepend to each key in the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret must be defined + type: boolean + type: object + type: object + type: array + image: + description: 'Container image name. More info: https://kubernetes.io/docs/concepts/containers/images' + type: string + imagePullPolicy: + description: 'Image pull policy. One of Always, Never, IfNotPresent. Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. Cannot be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images' + type: string + lifecycle: + description: Lifecycle is not allowed for ephemeral containers. + properties: + postStart: + description: 'PostStart is called immediately after a container is created. If the handler fails, the container is terminated and restarted according to its restart policy. Other management of the container blocks until the hook completes. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept for the backward compatibility. There are no validation of this field and lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: 'PreStop is called immediately before a container is terminated due to an API request or management event such as liveness/startup probe failure, preemption, resource contention, etc. The handler is not called if the container crashes or exits. The Pod''s termination grace period countdown begins before the PreStop hook is executed. Regardless of the outcome of the handler, the container will eventually terminate within the Pod''s termination grace period (unless delayed by finalizers). Other management of the container blocks until the hook completes or until the termination grace period is reached. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept for the backward compatibility. There are no validation of this field and lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + description: Probes are not allowed for ephemeral containers. + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to be considered failed after having succeeded. Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. This is a beta field and requires enabling GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). \n If this is not specified, the default behavior is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has started before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to be considered successful after having failed. Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + name: + description: Name of the ephemeral container specified as a DNS_LABEL. This name must be unique among all containers, init containers and ephemeral containers. + type: string + ports: + description: Ports are not allowed for ephemeral containers. + items: + description: ContainerPort represents a network port in a single container. + properties: + containerPort: + description: Number of port to expose on the pod's IP address. This must be a valid port number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external port to. + type: string + hostPort: + description: Number of port to expose on the host. If specified, this must be a valid port number, 0 < x < 65536. If HostNetwork is specified, this must match ContainerPort. Most containers do not need this. + format: int32 + type: integer + name: + description: If specified, this must be an IANA_SVC_NAME and unique within the pod. Each named port in a pod must have a unique name. Name for the port that can be referred to by services. + type: string + protocol: + default: TCP + description: Protocol for port. Must be UDP, TCP, or SCTP. Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: Probes are not allowed for ephemeral containers. + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to be considered failed after having succeeded. Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. This is a beta field and requires enabling GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). \n If this is not specified, the default behavior is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has started before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to be considered successful after having failed. Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + resources: + description: Resources are not allowed for ephemeral containers. Ephemeral containers use spare resources already allocated to the pod. + properties: + claims: + description: "Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container. \n This is an alpha field and requires enabling the DynamicResourceAllocation feature gate. \n This field is immutable." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. It makes that resource available inside a container. + type: string + required: + - name + type: object + type: array + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + securityContext: + description: 'Optional: SecurityContext defines the security options the ephemeral container should be run with. If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext.' + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether a process can gain more privileges than its parent process. This bool directly controls if the no_new_privs flag will be set on the container process. AllowPrivilegeEscalation is true always when the container is: 1) run as Privileged 2) has CAP_SYS_ADMIN Note that this field cannot be set when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running containers. Defaults to the default set of capabilities granted by the container runtime. Note that this field cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes in privileged containers are essentially equivalent to root on the host. Defaults to false. Note that this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount to use for the containers. The default is DefaultProcMount which uses the container runtime defaults for readonly paths and masked paths. This requires the ProcMountType feature flag to be enabled. Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root filesystem. Default is false. Note that this field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container process. Uses runtime default if unset. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root user. If true, the Kubelet will validate the image at runtime to ensure that it does not run as UID 0 (root) and fail to start the container if it does. If unset or false, no such validation will be performed. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container process. Defaults to user specified in image metadata if unspecified. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the container. If unspecified, the container runtime will allocate a random SELinux context for each container. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies to the container. + type: string + role: + description: Role is a SELinux role label that applies to the container. + type: string + type: + description: Type is a SELinux type label that applies to the container. + type: string + user: + description: User is a SELinux user label that applies to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. If seccomp options are provided at both the pod & container level, the container options override the pod options. Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile location. Must only be set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp profile will be applied. Valid options are: \n Localhost - a profile defined in a file on the node should be used. RuntimeDefault - the container runtime default profile should be used. Unconfined - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to all containers. If unspecified, the options from the PodSecurityContext will be used. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should be run as a 'Host Process' container. This field is alpha-level and will only be honored by components that enable the WindowsHostProcessContainers feature flag. Setting this field without the feature flag will result in errors when validating the Pod. All of a Pod's containers must have the same effective HostProcess value (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint of the container process. Defaults to the user specified in image metadata if unspecified. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + startupProbe: + description: Probes are not allowed for ephemeral containers. + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to be considered failed after having succeeded. Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. This is a beta field and requires enabling GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). \n If this is not specified, the default behavior is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has started before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to be considered successful after having failed. Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + stdin: + description: Whether this container should allocate a buffer for stdin in the container runtime. If this is not set, reads from stdin in the container will always result in EOF. Default is false. + type: boolean + stdinOnce: + description: Whether the container runtime should close the stdin channel after it has been opened by a single attach. When stdin is true the stdin stream will remain open across multiple attach sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the first client attaches to stdin, and then remains open and accepts data until the client disconnects, at which time stdin is closed and remains closed until the container is restarted. If this flag is false, a container processes that reads from stdin will never receive an EOF. Default is false + type: boolean + targetContainerName: + description: "If set, the name of the container from PodSpec that this ephemeral container targets. The ephemeral container will be run in the namespaces (IPC, PID, etc) of this container. If not set then the ephemeral container uses the namespaces configured in the Pod spec. \n The container runtime must implement support for this feature. If the runtime does not support namespace targeting then the result of setting this field is undefined." + type: string + terminationMessagePath: + description: 'Optional: Path at which the file to which the container''s termination message will be written is mounted into the container''s filesystem. Message written is intended to be brief final status, such as an assertion failure message. Will be truncated by the node if greater than 4096 bytes. The total message length across all containers will be limited to 12kb. Defaults to /dev/termination-log. Cannot be updated.' + type: string + terminationMessagePolicy: + description: Indicate how the termination message should be populated. File will use the contents of terminationMessagePath to populate the container status message on both success and failure. FallbackToLogsOnError will use the last chunk of container log output if the termination message file is empty and the container exited with an error. The log output is limited to 2048 bytes or 80 lines, whichever is smaller. Defaults to File. Cannot be updated. + type: string + tty: + description: Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. Default is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices to be used by the container. + items: + description: volumeDevice describes a mapping of a raw block device within a container. + properties: + devicePath: + description: devicePath is the path inside of the container that the device will be mapped to. + type: string + name: + description: name must match the name of a persistentVolumeClaim in the pod + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + description: Pod volumes to mount into the container's filesystem. Subpath mounts are not allowed for ephemeral containers. Cannot be updated. + items: + description: VolumeMount describes a mounting of a Volume within a container. + properties: + mountPath: + description: Path within the container at which the volume should be mounted. Must not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts are propagated from the host to container and the other way around. When not set, MountPropagationNone is used. This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write otherwise (false or unspecified). Defaults to false. + type: boolean + subPath: + description: Path within the volume from which the container's volume should be mounted. Defaults to "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume from which the container's volume should be mounted. Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. Defaults to "" (volume's root). SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + description: Container's working directory. If not specified, the container runtime's default will be used, which might be configured in the container image. Cannot be updated. + type: string + required: + - name + type: object + type: array + githubAPICredentialsFrom: + properties: + secretRef: + properties: + name: + type: string + required: + - name + type: object + type: object + group: + type: string + hostAliases: + items: + description: HostAlias holds the mapping between IP and hostnames that will be injected as an entry in the pod's hosts file. + properties: + hostnames: + description: Hostnames for the above IP address. + items: + type: string + type: array + ip: + description: IP address of the host file entry. + type: string + type: object + type: array + image: + type: string + imagePullPolicy: + description: PullPolicy describes a policy for if/when to pull a container image + type: string + imagePullSecrets: + items: + description: LocalObjectReference contains enough information to let you locate the referenced object inside the same namespace. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + type: array + initContainers: + items: + description: A single application container that you want to run within a pod. + properties: + args: + description: 'Arguments to the entrypoint. The container image''s CMD is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container''s environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + command: + description: 'Entrypoint array. Not executed within a shell. The container image''s ENTRYPOINT is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container''s environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + env: + description: List of environment variables to set in the container. Cannot be updated. + items: + description: EnvVar represents an environment variable present in a Container. + properties: + name: + description: Name of the environment variable. Must be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded using the previously defined environment variables in the container and any service environment variables. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['''']`, `metadata.annotations['''']`, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + description: List of sources to populate environment variables in the container. The keys defined within a source must be a C_IDENTIFIER. All invalid keys will be reported as an event when the container is starting. When a key exists in multiple sources, the value associated with the last source will take precedence. Values defined by an Env with a duplicate key will take precedence. Cannot be updated. + items: + description: EnvFromSource represents the source of a set of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap must be defined + type: boolean + type: object + prefix: + description: An optional identifier to prepend to each key in the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret must be defined + type: boolean + type: object + type: object + type: array + image: + description: 'Container image name. More info: https://kubernetes.io/docs/concepts/containers/images This field is optional to allow higher level config management to default or override container images in workload controllers like Deployments and StatefulSets.' + type: string + imagePullPolicy: + description: 'Image pull policy. One of Always, Never, IfNotPresent. Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. Cannot be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images' + type: string + lifecycle: + description: Actions that the management system should take in response to container lifecycle events. Cannot be updated. + properties: + postStart: + description: 'PostStart is called immediately after a container is created. If the handler fails, the container is terminated and restarted according to its restart policy. Other management of the container blocks until the hook completes. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept for the backward compatibility. There are no validation of this field and lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: 'PreStop is called immediately before a container is terminated due to an API request or management event such as liveness/startup probe failure, preemption, resource contention, etc. The handler is not called if the container crashes or exits. The Pod''s termination grace period countdown begins before the PreStop hook is executed. Regardless of the outcome of the handler, the container will eventually terminate within the Pod''s termination grace period (unless delayed by finalizers). Other management of the container blocks until the hook completes or until the termination grace period is reached. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept for the backward compatibility. There are no validation of this field and lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + description: 'Periodic probe of container liveness. Container will be restarted if the probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to be considered failed after having succeeded. Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. This is a beta field and requires enabling GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). \n If this is not specified, the default behavior is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has started before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to be considered successful after having failed. Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + name: + description: Name of the container specified as a DNS_LABEL. Each container in a pod must have a unique name (DNS_LABEL). Cannot be updated. + type: string + ports: + description: List of ports to expose from the container. Not specifying a port here DOES NOT prevent that port from being exposed. Any port which is listening on the default "0.0.0.0" address inside a container will be accessible from the network. Modifying this array with strategic merge patch may corrupt the data. For more information See https://github.com/kubernetes/kubernetes/issues/108255. Cannot be updated. + items: + description: ContainerPort represents a network port in a single container. + properties: + containerPort: + description: Number of port to expose on the pod's IP address. This must be a valid port number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external port to. + type: string + hostPort: + description: Number of port to expose on the host. If specified, this must be a valid port number, 0 < x < 65536. If HostNetwork is specified, this must match ContainerPort. Most containers do not need this. + format: int32 + type: integer + name: + description: If specified, this must be an IANA_SVC_NAME and unique within the pod. Each named port in a pod must have a unique name. Name for the port that can be referred to by services. + type: string + protocol: + default: TCP + description: Protocol for port. Must be UDP, TCP, or SCTP. Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: 'Periodic probe of container service readiness. Container will be removed from service endpoints if the probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to be considered failed after having succeeded. Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. This is a beta field and requires enabling GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). \n If this is not specified, the default behavior is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has started before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to be considered successful after having failed. Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + resources: + description: 'Compute Resources required by this container. Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + properties: + claims: + description: "Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container. \n This is an alpha field and requires enabling the DynamicResourceAllocation feature gate. \n This field is immutable." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. It makes that resource available inside a container. + type: string + required: + - name + type: object + type: array + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + securityContext: + description: 'SecurityContext defines the security options the container should be run with. If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/' + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether a process can gain more privileges than its parent process. This bool directly controls if the no_new_privs flag will be set on the container process. AllowPrivilegeEscalation is true always when the container is: 1) run as Privileged 2) has CAP_SYS_ADMIN Note that this field cannot be set when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running containers. Defaults to the default set of capabilities granted by the container runtime. Note that this field cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes in privileged containers are essentially equivalent to root on the host. Defaults to false. Note that this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount to use for the containers. The default is DefaultProcMount which uses the container runtime defaults for readonly paths and masked paths. This requires the ProcMountType feature flag to be enabled. Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root filesystem. Default is false. Note that this field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container process. Uses runtime default if unset. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root user. If true, the Kubelet will validate the image at runtime to ensure that it does not run as UID 0 (root) and fail to start the container if it does. If unset or false, no such validation will be performed. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container process. Defaults to user specified in image metadata if unspecified. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the container. If unspecified, the container runtime will allocate a random SELinux context for each container. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies to the container. + type: string + role: + description: Role is a SELinux role label that applies to the container. + type: string + type: + description: Type is a SELinux type label that applies to the container. + type: string + user: + description: User is a SELinux user label that applies to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. If seccomp options are provided at both the pod & container level, the container options override the pod options. Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile location. Must only be set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp profile will be applied. Valid options are: \n Localhost - a profile defined in a file on the node should be used. RuntimeDefault - the container runtime default profile should be used. Unconfined - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to all containers. If unspecified, the options from the PodSecurityContext will be used. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should be run as a 'Host Process' container. This field is alpha-level and will only be honored by components that enable the WindowsHostProcessContainers feature flag. Setting this field without the feature flag will result in errors when validating the Pod. All of a Pod's containers must have the same effective HostProcess value (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint of the container process. Defaults to the user specified in image metadata if unspecified. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + startupProbe: + description: 'StartupProbe indicates that the Pod has successfully initialized. If specified, no other probes are executed until this completes successfully. If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. This can be used to provide different probe parameters at the beginning of a Pod''s lifecycle, when it might take a long time to load data or warm a cache, than during steady-state operation. This cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to be considered failed after having succeeded. Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. This is a beta field and requires enabling GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). \n If this is not specified, the default behavior is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has started before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to be considered successful after having failed. Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + stdin: + description: Whether this container should allocate a buffer for stdin in the container runtime. If this is not set, reads from stdin in the container will always result in EOF. Default is false. + type: boolean + stdinOnce: + description: Whether the container runtime should close the stdin channel after it has been opened by a single attach. When stdin is true the stdin stream will remain open across multiple attach sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the first client attaches to stdin, and then remains open and accepts data until the client disconnects, at which time stdin is closed and remains closed until the container is restarted. If this flag is false, a container processes that reads from stdin will never receive an EOF. Default is false + type: boolean + terminationMessagePath: + description: 'Optional: Path at which the file to which the container''s termination message will be written is mounted into the container''s filesystem. Message written is intended to be brief final status, such as an assertion failure message. Will be truncated by the node if greater than 4096 bytes. The total message length across all containers will be limited to 12kb. Defaults to /dev/termination-log. Cannot be updated.' + type: string + terminationMessagePolicy: + description: Indicate how the termination message should be populated. File will use the contents of terminationMessagePath to populate the container status message on both success and failure. FallbackToLogsOnError will use the last chunk of container log output if the termination message file is empty and the container exited with an error. The log output is limited to 2048 bytes or 80 lines, whichever is smaller. Defaults to File. Cannot be updated. + type: string + tty: + description: Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. Default is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices to be used by the container. + items: + description: volumeDevice describes a mapping of a raw block device within a container. + properties: + devicePath: + description: devicePath is the path inside of the container that the device will be mapped to. + type: string + name: + description: name must match the name of a persistentVolumeClaim in the pod + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + description: Pod volumes to mount into the container's filesystem. Cannot be updated. + items: + description: VolumeMount describes a mounting of a Volume within a container. + properties: + mountPath: + description: Path within the container at which the volume should be mounted. Must not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts are propagated from the host to container and the other way around. When not set, MountPropagationNone is used. This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write otherwise (false or unspecified). Defaults to false. + type: boolean + subPath: + description: Path within the volume from which the container's volume should be mounted. Defaults to "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume from which the container's volume should be mounted. Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. Defaults to "" (volume's root). SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + description: Container's working directory. If not specified, the container runtime's default will be used, which might be configured in the container image. Cannot be updated. + type: string + required: + - name + type: object + type: array + labels: + items: + type: string + type: array + nodeSelector: + additionalProperties: + type: string + type: object + organization: + pattern: ^[^/]+$ + type: string + priorityClassName: + type: string + repository: + pattern: ^[^/]+/[^/]+$ + type: string + resources: + description: ResourceRequirements describes the compute resource requirements. + properties: + claims: + description: "Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container. \n This is an alpha field and requires enabling the DynamicResourceAllocation feature gate. \n This field is immutable." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. It makes that resource available inside a container. + type: string + required: + - name + type: object + type: array + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + runtimeClassName: + description: 'RuntimeClassName is the container runtime configuration that containers should run under. More info: https://kubernetes.io/docs/concepts/containers/runtime-class' + type: string + securityContext: + description: PodSecurityContext holds pod-level security attributes and common container settings. Some fields are also present in container.securityContext. Field values of container.securityContext take precedence over field values of PodSecurityContext. + properties: + fsGroup: + description: "A special supplemental group that applies to all containers in a pod. Some volume types allow the Kubelet to change the ownership of that volume to be owned by the pod: \n 1. The owning GID will be the FSGroup 2. The setgid bit is set (new files created in the volume will be owned by FSGroup) 3. The permission bits are OR'd with rw-rw---- \n If unset, the Kubelet will not modify the ownership and permissions of any volume. Note that this field cannot be set when spec.os.name is windows." + format: int64 + type: integer + fsGroupChangePolicy: + description: 'fsGroupChangePolicy defines behavior of changing ownership and permission of the volume before being exposed inside Pod. This field will only apply to volume types which support fsGroup based ownership(and permissions). It will have no effect on ephemeral volume types such as: secret, configmaps and emptydir. Valid values are "OnRootMismatch" and "Always". If not specified, "Always" is used. Note that this field cannot be set when spec.os.name is windows.' + type: string + runAsGroup: + description: The GID to run the entrypoint of the container process. Uses runtime default if unset. May also be set in SecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence for that container. Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root user. If true, the Kubelet will validate the image at runtime to ensure that it does not run as UID 0 (root) and fail to start the container if it does. If unset or false, no such validation will be performed. May also be set in SecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container process. Defaults to user specified in image metadata if unspecified. May also be set in SecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence for that container. Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to all containers. If unspecified, the container runtime will allocate a random SELinux context for each container. May also be set in SecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence for that container. Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies to the container. + type: string + role: + description: Role is a SELinux role label that applies to the container. + type: string + type: + description: Type is a SELinux type label that applies to the container. + type: string + user: + description: User is a SELinux user label that applies to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by the containers in this pod. Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile location. Must only be set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp profile will be applied. Valid options are: \n Localhost - a profile defined in a file on the node should be used. RuntimeDefault - the container runtime default profile should be used. Unconfined - no profile should be applied." + type: string + required: + - type + type: object + supplementalGroups: + description: A list of groups applied to the first process run in each container, in addition to the container's primary GID, the fsGroup (if specified), and group memberships defined in the container image for the uid of the container process. If unspecified, no additional groups are added to any container. Note that group memberships defined in the container image for the uid of the container process are still effective, even if they are not included in this list. Note that this field cannot be set when spec.os.name is windows. + items: + format: int64 + type: integer + type: array + sysctls: + description: Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported sysctls (by the container runtime) might fail to launch. Note that this field cannot be set when spec.os.name is windows. + items: + description: Sysctl defines a kernel parameter to be set + properties: + name: + description: Name of a property to set + type: string + value: + description: Value of a property to set + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + description: The Windows specific settings applied to all containers. If unspecified, the options within a container's SecurityContext will be used. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should be run as a 'Host Process' container. This field is alpha-level and will only be honored by components that enable the WindowsHostProcessContainers feature flag. Setting this field without the feature flag will result in errors when validating the Pod. All of a Pod's containers must have the same effective HostProcess value (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint of the container process. Defaults to the user specified in image metadata if unspecified. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + serviceAccountName: + type: string + sidecarContainers: + items: + description: A single application container that you want to run within a pod. + properties: + args: + description: 'Arguments to the entrypoint. The container image''s CMD is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container''s environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + command: + description: 'Entrypoint array. Not executed within a shell. The container image''s ENTRYPOINT is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container''s environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + env: + description: List of environment variables to set in the container. Cannot be updated. + items: + description: EnvVar represents an environment variable present in a Container. + properties: + name: + description: Name of the environment variable. Must be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded using the previously defined environment variables in the container and any service environment variables. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['''']`, `metadata.annotations['''']`, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + description: List of sources to populate environment variables in the container. The keys defined within a source must be a C_IDENTIFIER. All invalid keys will be reported as an event when the container is starting. When a key exists in multiple sources, the value associated with the last source will take precedence. Values defined by an Env with a duplicate key will take precedence. Cannot be updated. + items: + description: EnvFromSource represents the source of a set of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap must be defined + type: boolean + type: object + prefix: + description: An optional identifier to prepend to each key in the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret must be defined + type: boolean + type: object + type: object + type: array + image: + description: 'Container image name. More info: https://kubernetes.io/docs/concepts/containers/images This field is optional to allow higher level config management to default or override container images in workload controllers like Deployments and StatefulSets.' + type: string + imagePullPolicy: + description: 'Image pull policy. One of Always, Never, IfNotPresent. Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. Cannot be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images' + type: string + lifecycle: + description: Actions that the management system should take in response to container lifecycle events. Cannot be updated. + properties: + postStart: + description: 'PostStart is called immediately after a container is created. If the handler fails, the container is terminated and restarted according to its restart policy. Other management of the container blocks until the hook completes. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept for the backward compatibility. There are no validation of this field and lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: 'PreStop is called immediately before a container is terminated due to an API request or management event such as liveness/startup probe failure, preemption, resource contention, etc. The handler is not called if the container crashes or exits. The Pod''s termination grace period countdown begins before the PreStop hook is executed. Regardless of the outcome of the handler, the container will eventually terminate within the Pod''s termination grace period (unless delayed by finalizers). Other management of the container blocks until the hook completes or until the termination grace period is reached. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept for the backward compatibility. There are no validation of this field and lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + description: 'Periodic probe of container liveness. Container will be restarted if the probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to be considered failed after having succeeded. Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. This is a beta field and requires enabling GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). \n If this is not specified, the default behavior is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has started before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to be considered successful after having failed. Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + name: + description: Name of the container specified as a DNS_LABEL. Each container in a pod must have a unique name (DNS_LABEL). Cannot be updated. + type: string + ports: + description: List of ports to expose from the container. Not specifying a port here DOES NOT prevent that port from being exposed. Any port which is listening on the default "0.0.0.0" address inside a container will be accessible from the network. Modifying this array with strategic merge patch may corrupt the data. For more information See https://github.com/kubernetes/kubernetes/issues/108255. Cannot be updated. + items: + description: ContainerPort represents a network port in a single container. + properties: + containerPort: + description: Number of port to expose on the pod's IP address. This must be a valid port number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external port to. + type: string + hostPort: + description: Number of port to expose on the host. If specified, this must be a valid port number, 0 < x < 65536. If HostNetwork is specified, this must match ContainerPort. Most containers do not need this. + format: int32 + type: integer + name: + description: If specified, this must be an IANA_SVC_NAME and unique within the pod. Each named port in a pod must have a unique name. Name for the port that can be referred to by services. + type: string + protocol: + default: TCP + description: Protocol for port. Must be UDP, TCP, or SCTP. Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: 'Periodic probe of container service readiness. Container will be removed from service endpoints if the probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to be considered failed after having succeeded. Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. This is a beta field and requires enabling GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). \n If this is not specified, the default behavior is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has started before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to be considered successful after having failed. Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + resources: + description: 'Compute Resources required by this container. Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + properties: + claims: + description: "Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container. \n This is an alpha field and requires enabling the DynamicResourceAllocation feature gate. \n This field is immutable." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. It makes that resource available inside a container. + type: string + required: + - name + type: object + type: array + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + securityContext: + description: 'SecurityContext defines the security options the container should be run with. If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/' + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether a process can gain more privileges than its parent process. This bool directly controls if the no_new_privs flag will be set on the container process. AllowPrivilegeEscalation is true always when the container is: 1) run as Privileged 2) has CAP_SYS_ADMIN Note that this field cannot be set when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running containers. Defaults to the default set of capabilities granted by the container runtime. Note that this field cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes in privileged containers are essentially equivalent to root on the host. Defaults to false. Note that this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount to use for the containers. The default is DefaultProcMount which uses the container runtime defaults for readonly paths and masked paths. This requires the ProcMountType feature flag to be enabled. Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root filesystem. Default is false. Note that this field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container process. Uses runtime default if unset. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root user. If true, the Kubelet will validate the image at runtime to ensure that it does not run as UID 0 (root) and fail to start the container if it does. If unset or false, no such validation will be performed. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container process. Defaults to user specified in image metadata if unspecified. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the container. If unspecified, the container runtime will allocate a random SELinux context for each container. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies to the container. + type: string + role: + description: Role is a SELinux role label that applies to the container. + type: string + type: + description: Type is a SELinux type label that applies to the container. + type: string + user: + description: User is a SELinux user label that applies to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. If seccomp options are provided at both the pod & container level, the container options override the pod options. Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile location. Must only be set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp profile will be applied. Valid options are: \n Localhost - a profile defined in a file on the node should be used. RuntimeDefault - the container runtime default profile should be used. Unconfined - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to all containers. If unspecified, the options from the PodSecurityContext will be used. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should be run as a 'Host Process' container. This field is alpha-level and will only be honored by components that enable the WindowsHostProcessContainers feature flag. Setting this field without the feature flag will result in errors when validating the Pod. All of a Pod's containers must have the same effective HostProcess value (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint of the container process. Defaults to the user specified in image metadata if unspecified. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + startupProbe: + description: 'StartupProbe indicates that the Pod has successfully initialized. If specified, no other probes are executed until this completes successfully. If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. This can be used to provide different probe parameters at the beginning of a Pod''s lifecycle, when it might take a long time to load data or warm a cache, than during steady-state operation. This cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to be considered failed after having succeeded. Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. This is a beta field and requires enabling GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). \n If this is not specified, the default behavior is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has started before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to be considered successful after having failed. Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + stdin: + description: Whether this container should allocate a buffer for stdin in the container runtime. If this is not set, reads from stdin in the container will always result in EOF. Default is false. + type: boolean + stdinOnce: + description: Whether the container runtime should close the stdin channel after it has been opened by a single attach. When stdin is true the stdin stream will remain open across multiple attach sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the first client attaches to stdin, and then remains open and accepts data until the client disconnects, at which time stdin is closed and remains closed until the container is restarted. If this flag is false, a container processes that reads from stdin will never receive an EOF. Default is false + type: boolean + terminationMessagePath: + description: 'Optional: Path at which the file to which the container''s termination message will be written is mounted into the container''s filesystem. Message written is intended to be brief final status, such as an assertion failure message. Will be truncated by the node if greater than 4096 bytes. The total message length across all containers will be limited to 12kb. Defaults to /dev/termination-log. Cannot be updated.' + type: string + terminationMessagePolicy: + description: Indicate how the termination message should be populated. File will use the contents of terminationMessagePath to populate the container status message on both success and failure. FallbackToLogsOnError will use the last chunk of container log output if the termination message file is empty and the container exited with an error. The log output is limited to 2048 bytes or 80 lines, whichever is smaller. Defaults to File. Cannot be updated. + type: string + tty: + description: Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. Default is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices to be used by the container. + items: + description: volumeDevice describes a mapping of a raw block device within a container. + properties: + devicePath: + description: devicePath is the path inside of the container that the device will be mapped to. + type: string + name: + description: name must match the name of a persistentVolumeClaim in the pod + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + description: Pod volumes to mount into the container's filesystem. Cannot be updated. + items: + description: VolumeMount describes a mounting of a Volume within a container. + properties: + mountPath: + description: Path within the container at which the volume should be mounted. Must not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts are propagated from the host to container and the other way around. When not set, MountPropagationNone is used. This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write otherwise (false or unspecified). Defaults to false. + type: boolean + subPath: + description: Path within the volume from which the container's volume should be mounted. Defaults to "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume from which the container's volume should be mounted. Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. Defaults to "" (volume's root). SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + description: Container's working directory. If not specified, the container runtime's default will be used, which might be configured in the container image. Cannot be updated. + type: string + required: + - name + type: object + type: array + terminationGracePeriodSeconds: + format: int64 + type: integer + tolerations: + items: + description: The pod this Toleration is attached to tolerates any taint that matches the triple using the matching operator . + properties: + effect: + description: Effect indicates the taint effect to match. Empty means match all taint effects. When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Key is the taint key that the toleration applies to. Empty means match all taint keys. If the key is empty, operator must be Exists; this combination means to match all values and all keys. + type: string + operator: + description: Operator represents a key's relationship to the value. Valid operators are Exists and Equal. Defaults to Equal. Exists is equivalent to wildcard for value, so that a pod can tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period of time the toleration (which must be of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, it is not set, which means tolerate the taint forever (do not evict). Zero and negative values will be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration matches to. If the operator is Exists, the value should be empty, otherwise just a regular string. + type: string + type: object + type: array + topologySpreadConstraints: + items: + description: TopologySpreadConstraint specifies how to spread matching pods among the given topology. + properties: + labelSelector: + description: LabelSelector is used to find matching pods. Pods that match this label selector are counted to determine the number of pods in their corresponding topology domain. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + matchLabelKeys: + description: MatchLabelKeys is a set of pod label keys to select the pods over which spreading will be calculated. The keys are used to lookup values from the incoming pod labels, those key-value labels are ANDed with labelSelector to select the group of existing pods over which spreading will be calculated for the incoming pod. Keys that don't exist in the incoming pod labels will be ignored. A null or empty list means only match against labelSelector. + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + description: 'MaxSkew describes the degree to which pods may be unevenly distributed. When `whenUnsatisfiable=DoNotSchedule`, it is the maximum permitted difference between the number of matching pods in the target topology and the global minimum. The global minimum is the minimum number of matching pods in an eligible domain or zero if the number of eligible domains is less than MinDomains. For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same labelSelector spread as 2/2/1: In this case, the global minimum is 1. | zone1 | zone2 | zone3 | | P P | P P | P | - if MaxSkew is 1, incoming pod can only be scheduled to zone3 to become 2/2/2; scheduling it onto zone1(zone2) would make the ActualSkew(3-1) on zone1(zone2) violate MaxSkew(1). - if MaxSkew is 2, incoming pod can be scheduled onto any zone. When `whenUnsatisfiable=ScheduleAnyway`, it is used to give higher precedence to topologies that satisfy it. It''s a required field. Default value is 1 and 0 is not allowed.' + format: int32 + type: integer + minDomains: + description: "MinDomains indicates a minimum number of eligible domains. When the number of eligible domains with matching topology keys is less than minDomains, Pod Topology Spread treats \"global minimum\" as 0, and then the calculation of Skew is performed. And when the number of eligible domains with matching topology keys equals or greater than minDomains, this value has no effect on scheduling. As a result, when the number of eligible domains is less than minDomains, scheduler won't schedule more than maxSkew Pods to those domains. If value is nil, the constraint behaves as if MinDomains is equal to 1. Valid values are integers greater than 0. When value is not nil, WhenUnsatisfiable must be DoNotSchedule. \n For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same labelSelector spread as 2/2/2: | zone1 | zone2 | zone3 | | P P | P P | P P | The number of domains is less than 5(MinDomains), so \"global minimum\" is treated as 0. In this situation, new pod with the same labelSelector cannot be scheduled, because computed skew will be 3(3 - 0) if new Pod is scheduled to any of the three zones, it will violate MaxSkew. \n This is a beta field and requires the MinDomainsInPodTopologySpread feature gate to be enabled (enabled by default)." + format: int32 + type: integer + nodeAffinityPolicy: + description: "NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector when calculating pod topology spread skew. Options are: - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations. \n If this value is nil, the behavior is equivalent to the Honor policy. This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag." + type: string + nodeTaintsPolicy: + description: "NodeTaintsPolicy indicates how we will treat node taints when calculating pod topology spread skew. Options are: - Honor: nodes without taints, along with tainted nodes for which the incoming pod has a toleration, are included. - Ignore: node taints are ignored. All nodes are included. \n If this value is nil, the behavior is equivalent to the Ignore policy. This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag." + type: string + topologyKey: + description: TopologyKey is the key of node labels. Nodes that have a label with this key and identical values are considered to be in the same topology. We consider each as a "bucket", and try to put balanced number of pods into each bucket. We define a domain as a particular instance of a topology. Also, we define an eligible domain as a domain whose nodes meet the requirements of nodeAffinityPolicy and nodeTaintsPolicy. e.g. If TopologyKey is "kubernetes.io/hostname", each Node is a domain of that topology. And, if TopologyKey is "topology.kubernetes.io/zone", each zone is a domain of that topology. It's a required field. + type: string + whenUnsatisfiable: + description: 'WhenUnsatisfiable indicates how to deal with a pod if it doesn''t satisfy the spread constraint. - DoNotSchedule (default) tells the scheduler not to schedule it. - ScheduleAnyway tells the scheduler to schedule the pod in any location, but giving higher precedence to topologies that would help reduce the skew. A constraint is considered "Unsatisfiable" for an incoming pod if and only if every possible node assignment for that pod would violate "MaxSkew" on some topology. For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same labelSelector spread as 3/1/1: | zone1 | zone2 | zone3 | | P P P | P | P | If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can only be scheduled to zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies MaxSkew(1). In other words, the cluster can still be imbalanced, but scheduler won''t make it *more* imbalanced. It''s a required field.' + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + volumeMounts: + items: + description: VolumeMount describes a mounting of a Volume within a container. + properties: + mountPath: + description: Path within the container at which the volume should be mounted. Must not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts are propagated from the host to container and the other way around. When not set, MountPropagationNone is used. This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write otherwise (false or unspecified). Defaults to false. + type: boolean + subPath: + description: Path within the volume from which the container's volume should be mounted. Defaults to "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume from which the container's volume should be mounted. Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. Defaults to "" (volume's root). SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + volumeSizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + volumeStorageMedium: + type: string + volumes: + items: + description: Volume represents a named volume in a pod that may be accessed by any container in the pod. + properties: + awsElasticBlockStore: + description: 'awsElasticBlockStore represents an AWS Disk resource that is attached to a kubelet''s host machine and then exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + properties: + fsType: + description: 'fsType is the filesystem type of the volume that you want to mount. Tip: Ensure that the filesystem type is supported by the host operating system. Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore TODO: how do we prevent errors in the filesystem from compromising the machine' + type: string + partition: + description: 'partition is the partition in the volume that you want to mount. If omitted, the default is to mount by volume name. Examples: For volume /dev/sda1, you specify the partition as "1". Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty).' + format: int32 + type: integer + readOnly: + description: 'readOnly value true will force the readOnly setting in VolumeMounts. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + type: boolean + volumeID: + description: 'volumeID is unique ID of the persistent disk resource in AWS (Amazon EBS volume). More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + type: string + required: + - volumeID + type: object + azureDisk: + description: azureDisk represents an Azure Data Disk mount on the host and bind mount to the pod. + properties: + cachingMode: + description: 'cachingMode is the Host Caching mode: None, Read Only, Read Write.' + type: string + diskName: + description: diskName is the Name of the data disk in the blob storage + type: string + diskURI: + description: diskURI is the URI of data disk in the blob storage + type: string + fsType: + description: fsType is Filesystem type to mount. Must be a filesystem type supported by the host operating system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + kind: + description: 'kind expected values are Shared: multiple blob disks per storage account Dedicated: single blob disk per storage account Managed: azure managed data disk (only in managed availability set). defaults to shared' + type: string + readOnly: + description: readOnly Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + description: azureFile represents an Azure File Service mount on the host and bind mount to the pod. + properties: + readOnly: + description: readOnly defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. + type: boolean + secretName: + description: secretName is the name of secret that contains Azure Storage Account Name and Key + type: string + shareName: + description: shareName is the azure share Name + type: string + required: + - secretName + - shareName + type: object + cephfs: + description: cephFS represents a Ceph FS mount on the host that shares a pod's lifetime + properties: + monitors: + description: 'monitors is Required: Monitors is a collection of Ceph monitors More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + items: + type: string + type: array + path: + description: 'path is Optional: Used as the mounted root, rather than the full Ceph tree, default is /' + type: string + readOnly: + description: 'readOnly is Optional: Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: boolean + secretFile: + description: 'secretFile is Optional: SecretFile is the path to key ring for User, default is /etc/ceph/user.secret More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: string + secretRef: + description: 'secretRef is Optional: SecretRef is reference to the authentication secret for User, default is empty. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + user: + description: 'user is optional: User is the rados user name, default is admin More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: string + required: + - monitors + type: object + cinder: + description: 'cinder represents a cinder volume attached and mounted on kubelets host machine. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + properties: + fsType: + description: 'fsType is the filesystem type to mount. Must be a filesystem type supported by the host operating system. Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: string + readOnly: + description: 'readOnly defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: boolean + secretRef: + description: 'secretRef is optional: points to a secret object containing parameters used to connect to OpenStack.' + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + volumeID: + description: 'volumeID used to identify the volume in cinder. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: string + required: + - volumeID + type: object + configMap: + description: configMap represents a configMap that should populate this volume + properties: + defaultMode: + description: 'defaultMode is optional: mode bits used to set permissions on created files by default. Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. Defaults to 0644. Directories within the path are not affected by this setting. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.' + format: int32 + type: integer + items: + description: items if unspecified, each key-value pair in the Data field of the referenced ConfigMap will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the ConfigMap, the volume setup will error unless it is marked optional. Paths must be relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits used to set permissions on this file. Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. If not specified, the volume defaultMode will be used. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.' + format: int32 + type: integer + path: + description: path is the relative path of the file to map the key to. May not be an absolute path. May not contain the path element '..'. May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: optional specify whether the ConfigMap or its keys must be defined + type: boolean + type: object + csi: + description: csi (Container Storage Interface) represents ephemeral storage that is handled by certain external CSI drivers (Beta feature). + properties: + driver: + description: driver is the name of the CSI driver that handles this volume. Consult with your admin for the correct name as registered in the cluster. + type: string + fsType: + description: fsType to mount. Ex. "ext4", "xfs", "ntfs". If not provided, the empty value is passed to the associated CSI driver which will determine the default filesystem to apply. + type: string + nodePublishSecretRef: + description: nodePublishSecretRef is a reference to the secret object containing sensitive information to pass to the CSI driver to complete the CSI NodePublishVolume and NodeUnpublishVolume calls. This field is optional, and may be empty if no secret is required. If the secret object contains more than one secret, all secret references are passed. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + readOnly: + description: readOnly specifies a read-only configuration for the volume. Defaults to false (read/write). + type: boolean + volumeAttributes: + additionalProperties: + type: string + description: volumeAttributes stores driver-specific properties that are passed to the CSI driver. Consult your driver's documentation for supported values. + type: object + required: + - driver + type: object + downwardAPI: + description: downwardAPI represents downward API about the pod that should populate this volume + properties: + defaultMode: + description: 'Optional: mode bits to use on created files by default. Must be a Optional: mode bits used to set permissions on created files by default. Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. Defaults to 0644. Directories within the path are not affected by this setting. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.' + format: int32 + type: integer + items: + description: Items is a list of downward API volume file + items: + description: DownwardAPIVolumeFile represents information to create the file containing the pod field + properties: + fieldRef: + description: 'Required: Selects a field of the pod: only annotations, labels, name and namespace are supported.' + properties: + apiVersion: + description: Version of the schema the FieldPath is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified API version. + type: string + required: + - fieldPath + type: object + mode: + description: 'Optional: mode bits used to set permissions on this file, must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. If not specified, the volume defaultMode will be used. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.' + format: int32 + type: integer + path: + description: 'Required: Path is the relative path name of the file to be created. Must not be absolute or contain the ''..'' path. Must be utf-8 encoded. The first item of the relative path must not start with ''..''' + type: string + resourceFieldRef: + description: 'Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + required: + - path + type: object + type: array + type: object + emptyDir: + description: 'emptyDir represents a temporary directory that shares a pod''s lifetime. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + properties: + medium: + description: 'medium represents what type of storage medium should back this directory. The default is "" which means to use the node''s default medium. Must be an empty string (default) or Memory. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + description: 'sizeLimit is the total amount of local storage required for this EmptyDir volume. The size limit is also applicable for memory medium. The maximum usage on memory medium EmptyDir would be the minimum value between the SizeLimit specified here and the sum of memory limits of all containers in a pod. The default is nil which means that the limit is undefined. More info: http://kubernetes.io/docs/user-guide/volumes#emptydir' + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + description: "ephemeral represents a volume that is handled by a cluster storage driver. The volume's lifecycle is tied to the pod that defines it - it will be created before the pod starts, and deleted when the pod is removed. \n Use this if: a) the volume is only needed while the pod runs, b) features of normal volumes like restoring from snapshot or capacity tracking are needed, c) the storage driver is specified through a storage class, and d) the storage driver supports dynamic volume provisioning through a PersistentVolumeClaim (see EphemeralVolumeSource for more information on the connection between this volume type and PersistentVolumeClaim). \n Use PersistentVolumeClaim or one of the vendor-specific APIs for volumes that persist for longer than the lifecycle of an individual pod. \n Use CSI for light-weight local ephemeral volumes if the CSI driver is meant to be used that way - see the documentation of the driver for more information. \n A pod can use both types of ephemeral volumes and persistent volumes at the same time." + properties: + volumeClaimTemplate: + description: "Will be used to create a stand-alone PVC to provision the volume. The pod in which this EphemeralVolumeSource is embedded will be the owner of the PVC, i.e. the PVC will be deleted together with the pod. The name of the PVC will be `-` where `` is the name from the `PodSpec.Volumes` array entry. Pod validation will reject the pod if the concatenated name is not valid for a PVC (for example, too long). \n An existing PVC with that name that is not owned by the pod will *not* be used for the pod to avoid using an unrelated volume by mistake. Starting the pod is then blocked until the unrelated PVC is removed. If such a pre-created PVC is meant to be used by the pod, the PVC has to updated with an owner reference to the pod once the pod exists. Normally this should not be necessary, but it may be useful when manually reconstructing a broken cluster. \n This field is read-only and no changes will be made by Kubernetes to the PVC after it has been created. \n Required, must not be nil." + properties: + metadata: + description: May contain labels and annotations that will be copied into the PVC when creating it. No other fields are allowed and will be rejected during validation. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: The specification for the PersistentVolumeClaim. The entire content is copied unchanged into the PVC that gets created from this template. The same fields as in a PersistentVolumeClaim are also valid here. + properties: + accessModes: + description: 'accessModes contains the desired access modes the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' + items: + type: string + type: array + dataSource: + description: 'dataSource field can be used to specify either: * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) * An existing PVC (PersistentVolumeClaim) If the provisioner or an external controller can support the specified data source, it will create a new volume based on the contents of the specified data source. When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. If the namespace is specified, then dataSourceRef will not be copied to dataSource.' + properties: + apiGroup: + description: APIGroup is the group for the resource being referenced. If APIGroup is not specified, the specified Kind must be in the core API group. For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + dataSourceRef: + description: 'dataSourceRef specifies the object from which to populate the volume with data, if a non-empty volume is desired. This may be any object from a non-empty API group (non core object) or a PersistentVolumeClaim object. When this field is specified, volume binding will only succeed if the type of the specified object matches some installed volume populator or dynamic provisioner. This field will replace the functionality of the dataSource field and as such if both fields are non-empty, they must have the same value. For backwards compatibility, when namespace isn''t specified in dataSourceRef, both fields (dataSource and dataSourceRef) will be set to the same value automatically if one of them is empty and the other is non-empty. When namespace is specified in dataSourceRef, dataSource isn''t set to the same value and must be empty. There are three important differences between dataSource and dataSourceRef: * While dataSource only allows two specific types of objects, dataSourceRef allows any non-core object, as well as PersistentVolumeClaim objects. * While dataSource ignores disallowed values (dropping them), dataSourceRef preserves all values, and generates an error if a disallowed value is specified. * While dataSource only allows local objects, dataSourceRef allows objects in any namespaces. (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled.' + properties: + apiGroup: + description: APIGroup is the group for the resource being referenced. If APIGroup is not specified, the specified Kind must be in the core API group. For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + namespace: + description: Namespace is the namespace of resource being referenced Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: 'resources represents the minimum resources the volume should have. If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements that are lower than previous value but must still be higher than capacity recorded in the status field of the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources' + properties: + claims: + description: "Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container. \n This is an alpha field and requires enabling the DynamicResourceAllocation feature gate. \n This field is immutable." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. It makes that resource available inside a container. + type: string + required: + - name + type: object + type: array + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + selector: + description: selector is a label query over volumes to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + storageClassName: + description: 'storageClassName is the name of the StorageClass required by the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' + type: string + volumeMode: + description: volumeMode defines what type of volume is required by the claim. Value of Filesystem is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference to the PersistentVolume backing this claim. + type: string + type: object + required: + - spec + type: object + type: object + fc: + description: fc represents a Fibre Channel resource that is attached to a kubelet's host machine and then exposed to the pod. + properties: + fsType: + description: 'fsType is the filesystem type to mount. Must be a filesystem type supported by the host operating system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. TODO: how do we prevent errors in the filesystem from compromising the machine' + type: string + lun: + description: 'lun is Optional: FC target lun number' + format: int32 + type: integer + readOnly: + description: 'readOnly is Optional: Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts.' + type: boolean + targetWWNs: + description: 'targetWWNs is Optional: FC target worldwide names (WWNs)' + items: + type: string + type: array + wwids: + description: 'wwids Optional: FC volume world wide identifiers (wwids) Either wwids or combination of targetWWNs and lun must be set, but not both simultaneously.' + items: + type: string + type: array + type: object + flexVolume: + description: flexVolume represents a generic volume resource that is provisioned/attached using an exec based plugin. + properties: + driver: + description: driver is the name of the driver to use for this volume. + type: string + fsType: + description: fsType is the filesystem type to mount. Must be a filesystem type supported by the host operating system. Ex. "ext4", "xfs", "ntfs". The default filesystem depends on FlexVolume script. + type: string + options: + additionalProperties: + type: string + description: 'options is Optional: this field holds extra command options if any.' + type: object + readOnly: + description: 'readOnly is Optional: defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts.' + type: boolean + secretRef: + description: 'secretRef is Optional: secretRef is reference to the secret object containing sensitive information to pass to the plugin scripts. This may be empty if no secret object is specified. If the secret object contains more than one secret, all secrets are passed to the plugin scripts.' + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + required: + - driver + type: object + flocker: + description: flocker represents a Flocker volume attached to a kubelet's host machine. This depends on the Flocker control service being running + properties: + datasetName: + description: datasetName is Name of the dataset stored as metadata -> name on the dataset for Flocker should be considered as deprecated + type: string + datasetUUID: + description: datasetUUID is the UUID of the dataset. This is unique identifier of a Flocker dataset + type: string + type: object + gcePersistentDisk: + description: 'gcePersistentDisk represents a GCE Disk resource that is attached to a kubelet''s host machine and then exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + properties: + fsType: + description: 'fsType is filesystem type of the volume that you want to mount. Tip: Ensure that the filesystem type is supported by the host operating system. Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk TODO: how do we prevent errors in the filesystem from compromising the machine' + type: string + partition: + description: 'partition is the partition in the volume that you want to mount. If omitted, the default is to mount by volume name. Examples: For volume /dev/sda1, you specify the partition as "1". Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + format: int32 + type: integer + pdName: + description: 'pdName is unique name of the PD resource in GCE. Used to identify the disk in GCE. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + type: string + readOnly: + description: 'readOnly here will force the ReadOnly setting in VolumeMounts. Defaults to false. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + type: boolean + required: + - pdName + type: object + gitRepo: + description: 'gitRepo represents a git repository at a particular revision. DEPRECATED: GitRepo is deprecated. To provision a container with a git repo, mount an EmptyDir into an InitContainer that clones the repo using git, then mount the EmptyDir into the Pod''s container.' + properties: + directory: + description: directory is the target directory name. Must not contain or start with '..'. If '.' is supplied, the volume directory will be the git repository. Otherwise, if specified, the volume will contain the git repository in the subdirectory with the given name. + type: string + repository: + description: repository is the URL + type: string + revision: + description: revision is the commit hash for the specified revision. + type: string + required: + - repository + type: object + glusterfs: + description: 'glusterfs represents a Glusterfs mount on the host that shares a pod''s lifetime. More info: https://examples.k8s.io/volumes/glusterfs/README.md' + properties: + endpoints: + description: 'endpoints is the endpoint name that details Glusterfs topology. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: string + path: + description: 'path is the Glusterfs volume path. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: string + readOnly: + description: 'readOnly here will force the Glusterfs volume to be mounted with read-only permissions. Defaults to false. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: boolean + required: + - endpoints + - path + type: object + hostPath: + description: 'hostPath represents a pre-existing file or directory on the host machine that is directly exposed to the container. This is generally used for system agents or other privileged things that are allowed to see the host machine. Most containers will NOT need this. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath --- TODO(jonesdl) We need to restrict who can use host directory mounts and who can/can not mount host directories as read/write.' + properties: + path: + description: 'path of the directory on the host. If the path is a symlink, it will follow the link to the real path. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' + type: string + type: + description: 'type for HostPath Volume Defaults to "" More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' + type: string + required: + - path + type: object + iscsi: + description: 'iscsi represents an ISCSI Disk resource that is attached to a kubelet''s host machine and then exposed to the pod. More info: https://examples.k8s.io/volumes/iscsi/README.md' + properties: + chapAuthDiscovery: + description: chapAuthDiscovery defines whether support iSCSI Discovery CHAP authentication + type: boolean + chapAuthSession: + description: chapAuthSession defines whether support iSCSI Session CHAP authentication + type: boolean + fsType: + description: 'fsType is the filesystem type of the volume that you want to mount. Tip: Ensure that the filesystem type is supported by the host operating system. Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi TODO: how do we prevent errors in the filesystem from compromising the machine' + type: string + initiatorName: + description: initiatorName is the custom iSCSI Initiator Name. If initiatorName is specified with iscsiInterface simultaneously, new iSCSI interface : will be created for the connection. + type: string + iqn: + description: iqn is the target iSCSI Qualified Name. + type: string + iscsiInterface: + description: iscsiInterface is the interface Name that uses an iSCSI transport. Defaults to 'default' (tcp). + type: string + lun: + description: lun represents iSCSI Target Lun number. + format: int32 + type: integer + portals: + description: portals is the iSCSI Target Portal List. The portal is either an IP or ip_addr:port if the port is other than default (typically TCP ports 860 and 3260). + items: + type: string + type: array + readOnly: + description: readOnly here will force the ReadOnly setting in VolumeMounts. Defaults to false. + type: boolean + secretRef: + description: secretRef is the CHAP Secret for iSCSI target and initiator authentication + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + targetPortal: + description: targetPortal is iSCSI Target Portal. The Portal is either an IP or ip_addr:port if the port is other than default (typically TCP ports 860 and 3260). + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + description: 'name of the volume. Must be a DNS_LABEL and unique within the pod. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + nfs: + description: 'nfs represents an NFS mount on the host that shares a pod''s lifetime More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + properties: + path: + description: 'path that is exported by the NFS server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: string + readOnly: + description: 'readOnly here will force the NFS export to be mounted with read-only permissions. Defaults to false. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: boolean + server: + description: 'server is the hostname or IP address of the NFS server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + description: 'persistentVolumeClaimVolumeSource represents a reference to a PersistentVolumeClaim in the same namespace. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + properties: + claimName: + description: 'claimName is the name of a PersistentVolumeClaim in the same namespace as the pod using this volume. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + type: string + readOnly: + description: readOnly Will force the ReadOnly setting in VolumeMounts. Default false. + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + description: photonPersistentDisk represents a PhotonController persistent disk attached and mounted on kubelets host machine + properties: + fsType: + description: fsType is the filesystem type to mount. Must be a filesystem type supported by the host operating system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + pdID: + description: pdID is the ID that identifies Photon Controller persistent disk + type: string + required: + - pdID + type: object + portworxVolume: + description: portworxVolume represents a portworx volume attached and mounted on kubelets host machine + properties: + fsType: + description: fSType represents the filesystem type to mount Must be a filesystem type supported by the host operating system. Ex. "ext4", "xfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: readOnly defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. + type: boolean + volumeID: + description: volumeID uniquely identifies a Portworx volume + type: string + required: + - volumeID + type: object + projected: + description: projected items for all in one resources secrets, configmaps, and downward API + properties: + defaultMode: + description: defaultMode are the mode bits used to set permissions on created files by default. Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. Directories within the path are not affected by this setting. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + sources: + description: sources is the list of volume projections + items: + description: Projection that may be projected along with other supported volume types + properties: + configMap: + description: configMap information about the configMap data to project + properties: + items: + description: items if unspecified, each key-value pair in the Data field of the referenced ConfigMap will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the ConfigMap, the volume setup will error unless it is marked optional. Paths must be relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits used to set permissions on this file. Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. If not specified, the volume defaultMode will be used. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.' + format: int32 + type: integer + path: + description: path is the relative path of the file to map the key to. May not be an absolute path. May not contain the path element '..'. May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: optional specify whether the ConfigMap or its keys must be defined + type: boolean + type: object + downwardAPI: + description: downwardAPI information about the downwardAPI data to project + properties: + items: + description: Items is a list of DownwardAPIVolume file + items: + description: DownwardAPIVolumeFile represents information to create the file containing the pod field + properties: + fieldRef: + description: 'Required: Selects a field of the pod: only annotations, labels, name and namespace are supported.' + properties: + apiVersion: + description: Version of the schema the FieldPath is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified API version. + type: string + required: + - fieldPath + type: object + mode: + description: 'Optional: mode bits used to set permissions on this file, must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. If not specified, the volume defaultMode will be used. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.' + format: int32 + type: integer + path: + description: 'Required: Path is the relative path name of the file to be created. Must not be absolute or contain the ''..'' path. Must be utf-8 encoded. The first item of the relative path must not start with ''..''' + type: string + resourceFieldRef: + description: 'Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + required: + - path + type: object + type: array + type: object + secret: + description: secret information about the secret data to project + properties: + items: + description: items if unspecified, each key-value pair in the Data field of the referenced Secret will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the Secret, the volume setup will error unless it is marked optional. Paths must be relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits used to set permissions on this file. Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. If not specified, the volume defaultMode will be used. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.' + format: int32 + type: integer + path: + description: path is the relative path of the file to map the key to. May not be an absolute path. May not contain the path element '..'. May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: optional field specify whether the Secret or its key must be defined + type: boolean + type: object + serviceAccountToken: + description: serviceAccountToken is information about the serviceAccountToken data to project + properties: + audience: + description: audience is the intended audience of the token. A recipient of a token must identify itself with an identifier specified in the audience of the token, and otherwise should reject the token. The audience defaults to the identifier of the apiserver. + type: string + expirationSeconds: + description: expirationSeconds is the requested duration of validity of the service account token. As the token approaches expiration, the kubelet volume plugin will proactively rotate the service account token. The kubelet will start trying to rotate the token if the token is older than 80 percent of its time to live or if the token is older than 24 hours.Defaults to 1 hour and must be at least 10 minutes. + format: int64 + type: integer + path: + description: path is the path relative to the mount point of the file to project the token into. + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + description: quobyte represents a Quobyte mount on the host that shares a pod's lifetime + properties: + group: + description: group to map volume access to Default is no group + type: string + readOnly: + description: readOnly here will force the Quobyte volume to be mounted with read-only permissions. Defaults to false. + type: boolean + registry: + description: registry represents a single or multiple Quobyte Registry services specified as a string as host:port pair (multiple entries are separated with commas) which acts as the central registry for volumes + type: string + tenant: + description: tenant owning the given Quobyte volume in the Backend Used with dynamically provisioned Quobyte volumes, value is set by the plugin + type: string + user: + description: user to map volume access to Defaults to serivceaccount user + type: string + volume: + description: volume is a string that references an already created Quobyte volume by name. + type: string + required: + - registry + - volume + type: object + rbd: + description: 'rbd represents a Rados Block Device mount on the host that shares a pod''s lifetime. More info: https://examples.k8s.io/volumes/rbd/README.md' + properties: + fsType: + description: 'fsType is the filesystem type of the volume that you want to mount. Tip: Ensure that the filesystem type is supported by the host operating system. Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd TODO: how do we prevent errors in the filesystem from compromising the machine' + type: string + image: + description: 'image is the rados image name. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + keyring: + description: 'keyring is the path to key ring for RBDUser. Default is /etc/ceph/keyring. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + monitors: + description: 'monitors is a collection of Ceph monitors. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + items: + type: string + type: array + pool: + description: 'pool is the rados pool name. Default is rbd. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + readOnly: + description: 'readOnly here will force the ReadOnly setting in VolumeMounts. Defaults to false. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: boolean + secretRef: + description: 'secretRef is name of the authentication secret for RBDUser. If provided overrides keyring. Default is nil. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + user: + description: 'user is the rados user name. Default is admin. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + required: + - image + - monitors + type: object + scaleIO: + description: scaleIO represents a ScaleIO persistent volume attached and mounted on Kubernetes nodes. + properties: + fsType: + description: fsType is the filesystem type to mount. Must be a filesystem type supported by the host operating system. Ex. "ext4", "xfs", "ntfs". Default is "xfs". + type: string + gateway: + description: gateway is the host address of the ScaleIO API Gateway. + type: string + protectionDomain: + description: protectionDomain is the name of the ScaleIO Protection Domain for the configured storage. + type: string + readOnly: + description: readOnly Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: secretRef references to the secret for ScaleIO user and other sensitive information. If this is not provided, Login operation will fail. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + sslEnabled: + description: sslEnabled Flag enable/disable SSL communication with Gateway, default false + type: boolean + storageMode: + description: storageMode indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned. Default is ThinProvisioned. + type: string + storagePool: + description: storagePool is the ScaleIO Storage Pool associated with the protection domain. + type: string + system: + description: system is the name of the storage system as configured in ScaleIO. + type: string + volumeName: + description: volumeName is the name of a volume already created in the ScaleIO system that is associated with this volume source. + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + description: 'secret represents a secret that should populate this volume. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + properties: + defaultMode: + description: 'defaultMode is Optional: mode bits used to set permissions on created files by default. Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. Defaults to 0644. Directories within the path are not affected by this setting. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.' + format: int32 + type: integer + items: + description: items If unspecified, each key-value pair in the Data field of the referenced Secret will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the Secret, the volume setup will error unless it is marked optional. Paths must be relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits used to set permissions on this file. Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. If not specified, the volume defaultMode will be used. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.' + format: int32 + type: integer + path: + description: path is the relative path of the file to map the key to. May not be an absolute path. May not contain the path element '..'. May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + optional: + description: optional field specify whether the Secret or its keys must be defined + type: boolean + secretName: + description: 'secretName is the name of the secret in the pod''s namespace to use. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + type: string + type: object + storageos: + description: storageOS represents a StorageOS volume attached and mounted on Kubernetes nodes. + properties: + fsType: + description: fsType is the filesystem type to mount. Must be a filesystem type supported by the host operating system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: readOnly defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: secretRef specifies the secret to use for obtaining the StorageOS API credentials. If not specified, default values will be attempted. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + volumeName: + description: volumeName is the human-readable name of the StorageOS volume. Volume names are only unique within a namespace. + type: string + volumeNamespace: + description: volumeNamespace specifies the scope of the volume within StorageOS. If no namespace is specified then the Pod's namespace will be used. This allows the Kubernetes name scoping to be mirrored within StorageOS for tighter integration. Set VolumeName to any name to override the default behaviour. Set to "default" if you are not using namespaces within StorageOS. Namespaces that do not pre-exist within StorageOS will be created. + type: string + type: object + vsphereVolume: + description: vsphereVolume represents a vSphere volume attached and mounted on kubelets host machine + properties: + fsType: + description: fsType is filesystem type to mount. Must be a filesystem type supported by the host operating system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + storagePolicyID: + description: storagePolicyID is the storage Policy Based Management (SPBM) profile ID associated with the StoragePolicyName. + type: string + storagePolicyName: + description: storagePolicyName is the storage Policy Based Management (SPBM) profile name. + type: string + volumePath: + description: volumePath is the path that identifies vSphere volume vmdk + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + workDir: + type: string + workVolumeClaimTemplate: + properties: + accessModes: + items: + type: string + type: array + resources: + description: ResourceRequirements describes the compute resource requirements. + properties: + claims: + description: "Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container. \n This is an alpha field and requires enabling the DynamicResourceAllocation feature gate. \n This field is immutable." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. It makes that resource available inside a container. + type: string + required: + - name + type: object + type: array + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + storageClassName: + type: string + required: + - accessModes + - resources + - storageClassName + type: object + type: object + status: + description: RunnerStatus defines the observed state of Runner + properties: + lastRegistrationCheckTime: + format: date-time + nullable: true + type: string + message: + type: string + phase: + type: string + ready: + description: Turns true only if the runner pod is ready. + type: boolean + reason: + type: string + registration: + description: RunnerStatusRegistration contains runner registration status + properties: + enterprise: + type: string + expiresAt: + format: date-time + type: string + labels: + items: + type: string + type: array + organization: + type: string + repository: + type: string + token: + type: string + required: + - expiresAt + - token + type: object + workflow: + description: WorkflowStatus contains various information that is propagated from GitHub Actions workflow run environment variables to ease monitoring workflow run/job/steps that are triggerred on the runner. + properties: + action: + description: Action is the name of the current action or the step ID of the current step that is triggerred within the runner. It corresponds to GITHUB_ACTION defined in https://docs.github.com/en/actions/learn-github-actions/environment-variables + type: string + job: + description: Job is the name of the current job that is triggerred within the runner. It corresponds to GITHUB_JOB defined in https://docs.github.com/en/actions/learn-github-actions/environment-variables + type: string + name: + description: Name is the name of the workflow that is triggerred within the runner. It corresponds to GITHUB_WORKFLOW defined in https://docs.github.com/en/actions/learn-github-actions/environment-variables + type: string + repository: + description: Repository is the owner and repository name of the workflow that is triggerred within the runner. It corresponds to GITHUB_REPOSITORY defined in https://docs.github.com/en/actions/learn-github-actions/environment-variables + type: string + repositoryOwner: + description: ReositoryOwner is the repository owner's name for the workflow that is triggerred within the runner. It corresponds to GITHUB_REPOSITORY_OWNER defined in https://docs.github.com/en/actions/learn-github-actions/environment-variables + type: string + runID: + description: RunID is the unique number for the current workflow run that is triggerred within the runner. It corresponds to GITHUB_RUN_ID defined in https://docs.github.com/en/actions/learn-github-actions/environment-variables + type: string + runNumber: + description: GITHUB_RUN_NUMBER is the unique number for the current workflow run that is triggerred within the runner. It corresponds to GITHUB_RUN_ID defined in https://docs.github.com/en/actions/learn-github-actions/environment-variables + type: string + type: object + type: object + type: object + served: true + storage: true + subresources: + status: {} + preserveUnknownFields: false +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/helm/actions-runner-controller/crds/actions.summerwind.dev_runnersets.yaml b/helm/actions-runner-controller/crds/actions.summerwind.dev_runnersets.yaml new file mode 100644 index 0000000..7cdb815 --- /dev/null +++ b/helm/actions-runner-controller/crds/actions.summerwind.dev_runnersets.yaml @@ -0,0 +1,4682 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.7.0 + creationTimestamp: null + name: runnersets.actions.summerwind.dev +spec: + group: actions.summerwind.dev + names: + kind: RunnerSet + listKind: RunnerSetList + plural: runnersets + singular: runnerset + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.replicas + name: Desired + type: number + - jsonPath: .status.replicas + name: Current + type: number + - jsonPath: .status.updatedReplicas + name: Up-To-Date + type: number + - jsonPath: .status.availableReplicas + name: Available + type: number + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: RunnerSet is the Schema for the runnersets 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: RunnerSetSpec defines the desired state of RunnerSet + properties: + containerMode: + type: string + dockerEnabled: + type: boolean + dockerMTU: + format: int64 + type: integer + dockerRegistryMirror: + type: string + dockerdWithinRunnerContainer: + type: boolean + effectiveTime: + description: EffectiveTime is the time the upstream controller requested to sync Replicas. It is usually populated by the webhook-based autoscaler via HRA. It is used to prevent ephemeral runners from unnecessarily recreated. + format: date-time + nullable: true + type: string + enterprise: + pattern: ^[^/]+$ + type: string + ephemeral: + type: boolean + githubAPICredentialsFrom: + properties: + secretRef: + properties: + name: + type: string + required: + - name + type: object + type: object + group: + type: string + image: + type: string + labels: + items: + type: string + type: array + minReadySeconds: + description: Minimum number of seconds for which a newly created pod should be ready without any of its container crashing for it to be considered available. Defaults to 0 (pod will be considered available as soon as it is ready) + format: int32 + type: integer + ordinals: + description: ordinals controls the numbering of replica indices in a StatefulSet. The default ordinals behavior assigns a "0" index to the first replica and increments the index by one for each additional replica requested. Using the ordinals field requires the StatefulSetStartOrdinal feature gate to be enabled, which is alpha. + properties: + start: + description: 'start is the number representing the first replica''s index. It may be used to number replicas from an alternate index (eg: 1-indexed) over the default 0-indexed names, or to orchestrate progressive movement of replicas from one StatefulSet to another. If set, replica indices will be in the range: [.spec.ordinals.start, .spec.ordinals.start + .spec.replicas). If unset, defaults to 0. Replica indices will be in the range: [0, .spec.replicas).' + format: int32 + type: integer + type: object + organization: + pattern: ^[^/]+$ + type: string + persistentVolumeClaimRetentionPolicy: + description: persistentVolumeClaimRetentionPolicy describes the lifecycle of persistent volume claims created from volumeClaimTemplates. By default, all persistent volume claims are created as needed and retained until manually deleted. This policy allows the lifecycle to be altered, for example by deleting persistent volume claims when their stateful set is deleted, or when their pod is scaled down. This requires the StatefulSetAutoDeletePVC feature gate to be enabled, which is alpha. +optional + properties: + whenDeleted: + description: WhenDeleted specifies what happens to PVCs created from StatefulSet VolumeClaimTemplates when the StatefulSet is deleted. The default policy of `Retain` causes PVCs to not be affected by StatefulSet deletion. The `Delete` policy causes those PVCs to be deleted. + type: string + whenScaled: + description: WhenScaled specifies what happens to PVCs created from StatefulSet VolumeClaimTemplates when the StatefulSet is scaled down. The default policy of `Retain` causes PVCs to not be affected by a scaledown. The `Delete` policy causes the associated PVCs for any excess pods above the replica count to be deleted. + type: string + type: object + podManagementPolicy: + description: podManagementPolicy controls how pods are created during initial scale up, when replacing pods on nodes, or when scaling down. The default policy is `OrderedReady`, where pods are created in increasing order (pod-0, then pod-1, etc) and the controller will wait until each pod is ready before continuing. When scaling down, the pods are removed in the opposite order. The alternative policy is `Parallel` which will create pods in parallel to match the desired scale without waiting, and on scale down will delete all pods at once. + type: string + replicas: + description: 'replicas is the desired number of replicas of the given Template. These are replicas in the sense that they are instantiations of the same Template, but individual replicas also have a consistent identity. If unspecified, defaults to 1. TODO: Consider a rename of this field.' + format: int32 + type: integer + repository: + pattern: ^[^/]+/[^/]+$ + type: string + revisionHistoryLimit: + description: revisionHistoryLimit is the maximum number of revisions that will be maintained in the StatefulSet's revision history. The revision history consists of all revisions not represented by a currently applied StatefulSetSpec version. The default value is 10. + format: int32 + type: integer + selector: + description: 'selector is a label query over pods that should match the replica count. It must match the pod template''s labels. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors' + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + serviceAccountName: + type: string + serviceName: + description: 'serviceName is the name of the service that governs this StatefulSet. This service must exist before the StatefulSet, and is responsible for the network identity of the set. Pods get DNS/hostnames that follow the pattern: pod-specific-string.serviceName.default.svc.cluster.local where "pod-specific-string" is managed by the StatefulSet controller.' + type: string + template: + description: template is the object that describes the pod that will be created if insufficient replicas are detected. Each pod stamped out by the StatefulSet will fulfill this Template, but have a unique identity from the rest of the StatefulSet. Each pod will be named with the format -. For example, a pod in a StatefulSet named "web" with index number "3" would be named "web-3". + properties: + metadata: + description: 'Standard object''s metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata' + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: 'Specification of the desired behavior of the pod. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status' + properties: + activeDeadlineSeconds: + description: Optional duration in seconds the pod may be active on the node relative to StartTime before the system will actively try to mark it failed and kill associated containers. Value must be a positive integer. + format: int64 + type: integer + affinity: + description: If specified, the pod's scheduling constraints + properties: + nodeAffinity: + description: Describes node affinity scheduling rules for the pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to nodes that satisfy the affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding "weight" to the sum if the node matches the corresponding matchExpressions; the node(s) with the highest sum are the most preferred. + items: + description: An empty preferred scheduling term matches all objects with implicit weight 0 (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated with the corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements by node's labels. + items: + description: A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: Represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements by node's fields. + items: + description: A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: Represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + description: Weight associated with matching the corresponding nodeSelectorTerm, in the range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to an update), the system may or may not try to eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector terms. The terms are ORed. + items: + description: A null or empty node selector term matches no objects. The requirements of them are ANDed. The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements by node's labels. + items: + description: A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: Represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements by node's fields. + items: + description: A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: Represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + description: Describes pod affinity scheduling rules (e.g. co-locate this pod in the same node, zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to nodes that satisfy the affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaceSelector: + description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the corresponding podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system may or may not try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching the labelSelector relative to the given namespace(s)) that this pod should be co-located (affinity) or not co-located (anti-affinity) with, where co-located is defined as running on a node whose value of the label with key matches that of any node on which a pod of the set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaceSelector: + description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules (e.g. avoid putting this pod in the same node, zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to nodes that satisfy the anti-affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling anti-affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaceSelector: + description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the corresponding podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the anti-affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the anti-affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system may or may not try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching the labelSelector relative to the given namespace(s)) that this pod should be co-located (affinity) or not co-located (anti-affinity) with, where co-located is defined as running on a node whose value of the label with key matches that of any node on which a pod of the set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaceSelector: + description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + automountServiceAccountToken: + description: AutomountServiceAccountToken indicates whether a service account token should be automatically mounted. + type: boolean + containers: + description: List of containers belonging to the pod. Containers cannot currently be added or removed. There must be at least one container in a Pod. Cannot be updated. + items: + description: A single application container that you want to run within a pod. + properties: + args: + description: 'Arguments to the entrypoint. The container image''s CMD is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container''s environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + command: + description: 'Entrypoint array. Not executed within a shell. The container image''s ENTRYPOINT is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container''s environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + env: + description: List of environment variables to set in the container. Cannot be updated. + items: + description: EnvVar represents an environment variable present in a Container. + properties: + name: + description: Name of the environment variable. Must be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded using the previously defined environment variables in the container and any service environment variables. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['''']`, `metadata.annotations['''']`, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + description: List of sources to populate environment variables in the container. The keys defined within a source must be a C_IDENTIFIER. All invalid keys will be reported as an event when the container is starting. When a key exists in multiple sources, the value associated with the last source will take precedence. Values defined by an Env with a duplicate key will take precedence. Cannot be updated. + items: + description: EnvFromSource represents the source of a set of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap must be defined + type: boolean + type: object + prefix: + description: An optional identifier to prepend to each key in the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret must be defined + type: boolean + type: object + type: object + type: array + image: + description: 'Container image name. More info: https://kubernetes.io/docs/concepts/containers/images This field is optional to allow higher level config management to default or override container images in workload controllers like Deployments and StatefulSets.' + type: string + imagePullPolicy: + description: 'Image pull policy. One of Always, Never, IfNotPresent. Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. Cannot be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images' + type: string + lifecycle: + description: Actions that the management system should take in response to container lifecycle events. Cannot be updated. + properties: + postStart: + description: 'PostStart is called immediately after a container is created. If the handler fails, the container is terminated and restarted according to its restart policy. Other management of the container blocks until the hook completes. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept for the backward compatibility. There are no validation of this field and lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: 'PreStop is called immediately before a container is terminated due to an API request or management event such as liveness/startup probe failure, preemption, resource contention, etc. The handler is not called if the container crashes or exits. The Pod''s termination grace period countdown begins before the PreStop hook is executed. Regardless of the outcome of the handler, the container will eventually terminate within the Pod''s termination grace period (unless delayed by finalizers). Other management of the container blocks until the hook completes or until the termination grace period is reached. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept for the backward compatibility. There are no validation of this field and lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + description: 'Periodic probe of container liveness. Container will be restarted if the probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to be considered failed after having succeeded. Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. This is a beta field and requires enabling GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). \n If this is not specified, the default behavior is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has started before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to be considered successful after having failed. Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + name: + description: Name of the container specified as a DNS_LABEL. Each container in a pod must have a unique name (DNS_LABEL). Cannot be updated. + type: string + ports: + description: List of ports to expose from the container. Not specifying a port here DOES NOT prevent that port from being exposed. Any port which is listening on the default "0.0.0.0" address inside a container will be accessible from the network. Modifying this array with strategic merge patch may corrupt the data. For more information See https://github.com/kubernetes/kubernetes/issues/108255. Cannot be updated. + items: + description: ContainerPort represents a network port in a single container. + properties: + containerPort: + description: Number of port to expose on the pod's IP address. This must be a valid port number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external port to. + type: string + hostPort: + description: Number of port to expose on the host. If specified, this must be a valid port number, 0 < x < 65536. If HostNetwork is specified, this must match ContainerPort. Most containers do not need this. + format: int32 + type: integer + name: + description: If specified, this must be an IANA_SVC_NAME and unique within the pod. Each named port in a pod must have a unique name. Name for the port that can be referred to by services. + type: string + protocol: + default: TCP + description: Protocol for port. Must be UDP, TCP, or SCTP. Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: 'Periodic probe of container service readiness. Container will be removed from service endpoints if the probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to be considered failed after having succeeded. Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. This is a beta field and requires enabling GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). \n If this is not specified, the default behavior is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has started before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to be considered successful after having failed. Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + resources: + description: 'Compute Resources required by this container. Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + properties: + claims: + description: "Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container. \n This is an alpha field and requires enabling the DynamicResourceAllocation feature gate. \n This field is immutable." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. It makes that resource available inside a container. + type: string + required: + - name + type: object + type: array + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + securityContext: + description: 'SecurityContext defines the security options the container should be run with. If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/' + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether a process can gain more privileges than its parent process. This bool directly controls if the no_new_privs flag will be set on the container process. AllowPrivilegeEscalation is true always when the container is: 1) run as Privileged 2) has CAP_SYS_ADMIN Note that this field cannot be set when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running containers. Defaults to the default set of capabilities granted by the container runtime. Note that this field cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes in privileged containers are essentially equivalent to root on the host. Defaults to false. Note that this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount to use for the containers. The default is DefaultProcMount which uses the container runtime defaults for readonly paths and masked paths. This requires the ProcMountType feature flag to be enabled. Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root filesystem. Default is false. Note that this field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container process. Uses runtime default if unset. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root user. If true, the Kubelet will validate the image at runtime to ensure that it does not run as UID 0 (root) and fail to start the container if it does. If unset or false, no such validation will be performed. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container process. Defaults to user specified in image metadata if unspecified. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the container. If unspecified, the container runtime will allocate a random SELinux context for each container. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies to the container. + type: string + role: + description: Role is a SELinux role label that applies to the container. + type: string + type: + description: Type is a SELinux type label that applies to the container. + type: string + user: + description: User is a SELinux user label that applies to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. If seccomp options are provided at both the pod & container level, the container options override the pod options. Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile location. Must only be set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp profile will be applied. Valid options are: \n Localhost - a profile defined in a file on the node should be used. RuntimeDefault - the container runtime default profile should be used. Unconfined - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to all containers. If unspecified, the options from the PodSecurityContext will be used. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should be run as a 'Host Process' container. This field is alpha-level and will only be honored by components that enable the WindowsHostProcessContainers feature flag. Setting this field without the feature flag will result in errors when validating the Pod. All of a Pod's containers must have the same effective HostProcess value (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint of the container process. Defaults to the user specified in image metadata if unspecified. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + startupProbe: + description: 'StartupProbe indicates that the Pod has successfully initialized. If specified, no other probes are executed until this completes successfully. If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. This can be used to provide different probe parameters at the beginning of a Pod''s lifecycle, when it might take a long time to load data or warm a cache, than during steady-state operation. This cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to be considered failed after having succeeded. Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. This is a beta field and requires enabling GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). \n If this is not specified, the default behavior is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has started before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to be considered successful after having failed. Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + stdin: + description: Whether this container should allocate a buffer for stdin in the container runtime. If this is not set, reads from stdin in the container will always result in EOF. Default is false. + type: boolean + stdinOnce: + description: Whether the container runtime should close the stdin channel after it has been opened by a single attach. When stdin is true the stdin stream will remain open across multiple attach sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the first client attaches to stdin, and then remains open and accepts data until the client disconnects, at which time stdin is closed and remains closed until the container is restarted. If this flag is false, a container processes that reads from stdin will never receive an EOF. Default is false + type: boolean + terminationMessagePath: + description: 'Optional: Path at which the file to which the container''s termination message will be written is mounted into the container''s filesystem. Message written is intended to be brief final status, such as an assertion failure message. Will be truncated by the node if greater than 4096 bytes. The total message length across all containers will be limited to 12kb. Defaults to /dev/termination-log. Cannot be updated.' + type: string + terminationMessagePolicy: + description: Indicate how the termination message should be populated. File will use the contents of terminationMessagePath to populate the container status message on both success and failure. FallbackToLogsOnError will use the last chunk of container log output if the termination message file is empty and the container exited with an error. The log output is limited to 2048 bytes or 80 lines, whichever is smaller. Defaults to File. Cannot be updated. + type: string + tty: + description: Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. Default is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices to be used by the container. + items: + description: volumeDevice describes a mapping of a raw block device within a container. + properties: + devicePath: + description: devicePath is the path inside of the container that the device will be mapped to. + type: string + name: + description: name must match the name of a persistentVolumeClaim in the pod + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + description: Pod volumes to mount into the container's filesystem. Cannot be updated. + items: + description: VolumeMount describes a mounting of a Volume within a container. + properties: + mountPath: + description: Path within the container at which the volume should be mounted. Must not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts are propagated from the host to container and the other way around. When not set, MountPropagationNone is used. This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write otherwise (false or unspecified). Defaults to false. + type: boolean + subPath: + description: Path within the volume from which the container's volume should be mounted. Defaults to "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume from which the container's volume should be mounted. Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. Defaults to "" (volume's root). SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + description: Container's working directory. If not specified, the container runtime's default will be used, which might be configured in the container image. Cannot be updated. + type: string + required: + - name + type: object + type: array + dnsConfig: + description: Specifies the DNS parameters of a pod. Parameters specified here will be merged to the generated DNS configuration based on DNSPolicy. + properties: + nameservers: + description: A list of DNS name server IP addresses. This will be appended to the base nameservers generated from DNSPolicy. Duplicated nameservers will be removed. + items: + type: string + type: array + options: + description: A list of DNS resolver options. This will be merged with the base options generated from DNSPolicy. Duplicated entries will be removed. Resolution options given in Options will override those that appear in the base DNSPolicy. + items: + description: PodDNSConfigOption defines DNS resolver options of a pod. + properties: + name: + description: Required. + type: string + value: + type: string + type: object + type: array + searches: + description: A list of DNS search domains for host-name lookup. This will be appended to the base search paths generated from DNSPolicy. Duplicated search paths will be removed. + items: + type: string + type: array + type: object + dnsPolicy: + description: Set DNS policy for the pod. Defaults to "ClusterFirst". Valid values are 'ClusterFirstWithHostNet', 'ClusterFirst', 'Default' or 'None'. DNS parameters given in DNSConfig will be merged with the policy selected with DNSPolicy. To have DNS options set along with hostNetwork, you have to specify DNS policy explicitly to 'ClusterFirstWithHostNet'. + type: string + enableServiceLinks: + description: 'EnableServiceLinks indicates whether information about services should be injected into pod''s environment variables, matching the syntax of Docker links. Optional: Defaults to true.' + type: boolean + ephemeralContainers: + description: List of ephemeral containers run in this pod. Ephemeral containers may be run in an existing pod to perform user-initiated actions such as debugging. This list cannot be specified when creating a pod, and it cannot be modified by updating the pod spec. In order to add an ephemeral container to an existing pod, use the pod's ephemeralcontainers subresource. + items: + description: "An EphemeralContainer is a temporary container that you may add to an existing Pod for user-initiated activities such as debugging. Ephemeral containers have no resource or scheduling guarantees, and they will not be restarted when they exit or when a Pod is removed or restarted. The kubelet may evict a Pod if an ephemeral container causes the Pod to exceed its resource allocation. \n To add an ephemeral container, use the ephemeralcontainers subresource of an existing Pod. Ephemeral containers may not be removed or restarted." + properties: + args: + description: 'Arguments to the entrypoint. The image''s CMD is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container''s environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + command: + description: 'Entrypoint array. Not executed within a shell. The image''s ENTRYPOINT is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container''s environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + env: + description: List of environment variables to set in the container. Cannot be updated. + items: + description: EnvVar represents an environment variable present in a Container. + properties: + name: + description: Name of the environment variable. Must be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded using the previously defined environment variables in the container and any service environment variables. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['''']`, `metadata.annotations['''']`, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + description: List of sources to populate environment variables in the container. The keys defined within a source must be a C_IDENTIFIER. All invalid keys will be reported as an event when the container is starting. When a key exists in multiple sources, the value associated with the last source will take precedence. Values defined by an Env with a duplicate key will take precedence. Cannot be updated. + items: + description: EnvFromSource represents the source of a set of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap must be defined + type: boolean + type: object + prefix: + description: An optional identifier to prepend to each key in the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret must be defined + type: boolean + type: object + type: object + type: array + image: + description: 'Container image name. More info: https://kubernetes.io/docs/concepts/containers/images' + type: string + imagePullPolicy: + description: 'Image pull policy. One of Always, Never, IfNotPresent. Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. Cannot be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images' + type: string + lifecycle: + description: Lifecycle is not allowed for ephemeral containers. + properties: + postStart: + description: 'PostStart is called immediately after a container is created. If the handler fails, the container is terminated and restarted according to its restart policy. Other management of the container blocks until the hook completes. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept for the backward compatibility. There are no validation of this field and lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: 'PreStop is called immediately before a container is terminated due to an API request or management event such as liveness/startup probe failure, preemption, resource contention, etc. The handler is not called if the container crashes or exits. The Pod''s termination grace period countdown begins before the PreStop hook is executed. Regardless of the outcome of the handler, the container will eventually terminate within the Pod''s termination grace period (unless delayed by finalizers). Other management of the container blocks until the hook completes or until the termination grace period is reached. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept for the backward compatibility. There are no validation of this field and lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + description: Probes are not allowed for ephemeral containers. + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to be considered failed after having succeeded. Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. This is a beta field and requires enabling GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). \n If this is not specified, the default behavior is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has started before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to be considered successful after having failed. Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + name: + description: Name of the ephemeral container specified as a DNS_LABEL. This name must be unique among all containers, init containers and ephemeral containers. + type: string + ports: + description: Ports are not allowed for ephemeral containers. + items: + description: ContainerPort represents a network port in a single container. + properties: + containerPort: + description: Number of port to expose on the pod's IP address. This must be a valid port number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external port to. + type: string + hostPort: + description: Number of port to expose on the host. If specified, this must be a valid port number, 0 < x < 65536. If HostNetwork is specified, this must match ContainerPort. Most containers do not need this. + format: int32 + type: integer + name: + description: If specified, this must be an IANA_SVC_NAME and unique within the pod. Each named port in a pod must have a unique name. Name for the port that can be referred to by services. + type: string + protocol: + default: TCP + description: Protocol for port. Must be UDP, TCP, or SCTP. Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: Probes are not allowed for ephemeral containers. + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to be considered failed after having succeeded. Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. This is a beta field and requires enabling GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). \n If this is not specified, the default behavior is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has started before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to be considered successful after having failed. Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + resources: + description: Resources are not allowed for ephemeral containers. Ephemeral containers use spare resources already allocated to the pod. + properties: + claims: + description: "Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container. \n This is an alpha field and requires enabling the DynamicResourceAllocation feature gate. \n This field is immutable." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. It makes that resource available inside a container. + type: string + required: + - name + type: object + type: array + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + securityContext: + description: 'Optional: SecurityContext defines the security options the ephemeral container should be run with. If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext.' + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether a process can gain more privileges than its parent process. This bool directly controls if the no_new_privs flag will be set on the container process. AllowPrivilegeEscalation is true always when the container is: 1) run as Privileged 2) has CAP_SYS_ADMIN Note that this field cannot be set when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running containers. Defaults to the default set of capabilities granted by the container runtime. Note that this field cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes in privileged containers are essentially equivalent to root on the host. Defaults to false. Note that this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount to use for the containers. The default is DefaultProcMount which uses the container runtime defaults for readonly paths and masked paths. This requires the ProcMountType feature flag to be enabled. Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root filesystem. Default is false. Note that this field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container process. Uses runtime default if unset. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root user. If true, the Kubelet will validate the image at runtime to ensure that it does not run as UID 0 (root) and fail to start the container if it does. If unset or false, no such validation will be performed. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container process. Defaults to user specified in image metadata if unspecified. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the container. If unspecified, the container runtime will allocate a random SELinux context for each container. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies to the container. + type: string + role: + description: Role is a SELinux role label that applies to the container. + type: string + type: + description: Type is a SELinux type label that applies to the container. + type: string + user: + description: User is a SELinux user label that applies to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. If seccomp options are provided at both the pod & container level, the container options override the pod options. Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile location. Must only be set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp profile will be applied. Valid options are: \n Localhost - a profile defined in a file on the node should be used. RuntimeDefault - the container runtime default profile should be used. Unconfined - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to all containers. If unspecified, the options from the PodSecurityContext will be used. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should be run as a 'Host Process' container. This field is alpha-level and will only be honored by components that enable the WindowsHostProcessContainers feature flag. Setting this field without the feature flag will result in errors when validating the Pod. All of a Pod's containers must have the same effective HostProcess value (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint of the container process. Defaults to the user specified in image metadata if unspecified. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + startupProbe: + description: Probes are not allowed for ephemeral containers. + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to be considered failed after having succeeded. Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. This is a beta field and requires enabling GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). \n If this is not specified, the default behavior is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has started before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to be considered successful after having failed. Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + stdin: + description: Whether this container should allocate a buffer for stdin in the container runtime. If this is not set, reads from stdin in the container will always result in EOF. Default is false. + type: boolean + stdinOnce: + description: Whether the container runtime should close the stdin channel after it has been opened by a single attach. When stdin is true the stdin stream will remain open across multiple attach sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the first client attaches to stdin, and then remains open and accepts data until the client disconnects, at which time stdin is closed and remains closed until the container is restarted. If this flag is false, a container processes that reads from stdin will never receive an EOF. Default is false + type: boolean + targetContainerName: + description: "If set, the name of the container from PodSpec that this ephemeral container targets. The ephemeral container will be run in the namespaces (IPC, PID, etc) of this container. If not set then the ephemeral container uses the namespaces configured in the Pod spec. \n The container runtime must implement support for this feature. If the runtime does not support namespace targeting then the result of setting this field is undefined." + type: string + terminationMessagePath: + description: 'Optional: Path at which the file to which the container''s termination message will be written is mounted into the container''s filesystem. Message written is intended to be brief final status, such as an assertion failure message. Will be truncated by the node if greater than 4096 bytes. The total message length across all containers will be limited to 12kb. Defaults to /dev/termination-log. Cannot be updated.' + type: string + terminationMessagePolicy: + description: Indicate how the termination message should be populated. File will use the contents of terminationMessagePath to populate the container status message on both success and failure. FallbackToLogsOnError will use the last chunk of container log output if the termination message file is empty and the container exited with an error. The log output is limited to 2048 bytes or 80 lines, whichever is smaller. Defaults to File. Cannot be updated. + type: string + tty: + description: Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. Default is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices to be used by the container. + items: + description: volumeDevice describes a mapping of a raw block device within a container. + properties: + devicePath: + description: devicePath is the path inside of the container that the device will be mapped to. + type: string + name: + description: name must match the name of a persistentVolumeClaim in the pod + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + description: Pod volumes to mount into the container's filesystem. Subpath mounts are not allowed for ephemeral containers. Cannot be updated. + items: + description: VolumeMount describes a mounting of a Volume within a container. + properties: + mountPath: + description: Path within the container at which the volume should be mounted. Must not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts are propagated from the host to container and the other way around. When not set, MountPropagationNone is used. This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write otherwise (false or unspecified). Defaults to false. + type: boolean + subPath: + description: Path within the volume from which the container's volume should be mounted. Defaults to "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume from which the container's volume should be mounted. Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. Defaults to "" (volume's root). SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + description: Container's working directory. If not specified, the container runtime's default will be used, which might be configured in the container image. Cannot be updated. + type: string + required: + - name + type: object + type: array + hostAliases: + description: HostAliases is an optional list of hosts and IPs that will be injected into the pod's hosts file if specified. This is only valid for non-hostNetwork pods. + items: + description: HostAlias holds the mapping between IP and hostnames that will be injected as an entry in the pod's hosts file. + properties: + hostnames: + description: Hostnames for the above IP address. + items: + type: string + type: array + ip: + description: IP address of the host file entry. + type: string + type: object + type: array + hostIPC: + description: 'Use the host''s ipc namespace. Optional: Default to false.' + type: boolean + hostNetwork: + description: Host networking requested for this pod. Use the host's network namespace. If this option is set, the ports that will be used must be specified. Default to false. + type: boolean + hostPID: + description: 'Use the host''s pid namespace. Optional: Default to false.' + type: boolean + hostUsers: + description: 'Use the host''s user namespace. Optional: Default to true. If set to true or not present, the pod will be run in the host user namespace, useful for when the pod needs a feature only available to the host user namespace, such as loading a kernel module with CAP_SYS_MODULE. When set to false, a new userns is created for the pod. Setting false is useful for mitigating container breakout vulnerabilities even allowing users to run their containers as root without actually having root privileges on the host. This field is alpha-level and is only honored by servers that enable the UserNamespacesSupport feature.' + type: boolean + hostname: + description: Specifies the hostname of the Pod If not specified, the pod's hostname will be set to a system-defined value. + type: string + imagePullSecrets: + description: 'ImagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of the images used by this PodSpec. If specified, these secrets will be passed to individual puller implementations for them to use. More info: https://kubernetes.io/docs/concepts/containers/images#specifying-imagepullsecrets-on-a-pod' + items: + description: LocalObjectReference contains enough information to let you locate the referenced object inside the same namespace. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + type: array + initContainers: + description: 'List of initialization containers belonging to the pod. Init containers are executed in order prior to containers being started. If any init container fails, the pod is considered to have failed and is handled according to its restartPolicy. The name for an init container or normal container must be unique among all containers. Init containers may not have Lifecycle actions, Readiness probes, Liveness probes, or Startup probes. The resourceRequirements of an init container are taken into account during scheduling by finding the highest request/limit for each resource type, and then using the max of of that value or the sum of the normal containers. Limits are applied to init containers in a similar fashion. Init containers cannot currently be added or removed. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/' + items: + description: A single application container that you want to run within a pod. + properties: + args: + description: 'Arguments to the entrypoint. The container image''s CMD is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container''s environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + command: + description: 'Entrypoint array. Not executed within a shell. The container image''s ENTRYPOINT is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container''s environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + env: + description: List of environment variables to set in the container. Cannot be updated. + items: + description: EnvVar represents an environment variable present in a Container. + properties: + name: + description: Name of the environment variable. Must be a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded using the previously defined environment variables in the container and any service environment variables. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless of whether the variable exists or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or its key must be defined + type: boolean + required: + - key + type: object + fieldRef: + description: 'Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['''']`, `metadata.annotations['''']`, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified API version. + type: string + required: + - fieldPath + type: object + resourceFieldRef: + description: 'Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + secretKeyRef: + description: Selects a key of a secret in the pod's namespace + properties: + key: + description: The key of the secret to select from. Must be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + description: List of sources to populate environment variables in the container. The keys defined within a source must be a C_IDENTIFIER. All invalid keys will be reported as an event when the container is starting. When a key exists in multiple sources, the value associated with the last source will take precedence. Values defined by an Env with a duplicate key will take precedence. Cannot be updated. + items: + description: EnvFromSource represents the source of a set of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap must be defined + type: boolean + type: object + prefix: + description: An optional identifier to prepend to each key in the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret must be defined + type: boolean + type: object + type: object + type: array + image: + description: 'Container image name. More info: https://kubernetes.io/docs/concepts/containers/images This field is optional to allow higher level config management to default or override container images in workload controllers like Deployments and StatefulSets.' + type: string + imagePullPolicy: + description: 'Image pull policy. One of Always, Never, IfNotPresent. Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. Cannot be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images' + type: string + lifecycle: + description: Actions that the management system should take in response to container lifecycle events. Cannot be updated. + properties: + postStart: + description: 'PostStart is called immediately after a container is created. If the handler fails, the container is terminated and restarted according to its restart policy. Other management of the container blocks until the hook completes. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept for the backward compatibility. There are no validation of this field and lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: 'PreStop is called immediately before a container is terminated due to an API request or management event such as liveness/startup probe failure, preemption, resource contention, etc. The handler is not called if the container crashes or exits. The Pod''s termination grace period countdown begins before the PreStop hook is executed. Regardless of the outcome of the handler, the container will eventually terminate within the Pod''s termination grace period (unless delayed by finalizers). Other management of the container blocks until the hook completes or until the termination grace period is reached. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT supported as a LifecycleHandler and kept for the backward compatibility. There are no validation of this field and lifecycle hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + description: 'Periodic probe of container liveness. Container will be restarted if the probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to be considered failed after having succeeded. Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. This is a beta field and requires enabling GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). \n If this is not specified, the default behavior is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has started before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to be considered successful after having failed. Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + name: + description: Name of the container specified as a DNS_LABEL. Each container in a pod must have a unique name (DNS_LABEL). Cannot be updated. + type: string + ports: + description: List of ports to expose from the container. Not specifying a port here DOES NOT prevent that port from being exposed. Any port which is listening on the default "0.0.0.0" address inside a container will be accessible from the network. Modifying this array with strategic merge patch may corrupt the data. For more information See https://github.com/kubernetes/kubernetes/issues/108255. Cannot be updated. + items: + description: ContainerPort represents a network port in a single container. + properties: + containerPort: + description: Number of port to expose on the pod's IP address. This must be a valid port number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external port to. + type: string + hostPort: + description: Number of port to expose on the host. If specified, this must be a valid port number, 0 < x < 65536. If HostNetwork is specified, this must match ContainerPort. Most containers do not need this. + format: int32 + type: integer + name: + description: If specified, this must be an IANA_SVC_NAME and unique within the pod. Each named port in a pod must have a unique name. Name for the port that can be referred to by services. + type: string + protocol: + default: TCP + description: Protocol for port. Must be UDP, TCP, or SCTP. Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: 'Periodic probe of container service readiness. Container will be removed from service endpoints if the probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to be considered failed after having succeeded. Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. This is a beta field and requires enabling GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). \n If this is not specified, the default behavior is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has started before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to be considered successful after having failed. Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + resources: + description: 'Compute Resources required by this container. Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + properties: + claims: + description: "Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container. \n This is an alpha field and requires enabling the DynamicResourceAllocation feature gate. \n This field is immutable." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. It makes that resource available inside a container. + type: string + required: + - name + type: object + type: array + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + securityContext: + description: 'SecurityContext defines the security options the container should be run with. If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/' + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether a process can gain more privileges than its parent process. This bool directly controls if the no_new_privs flag will be set on the container process. AllowPrivilegeEscalation is true always when the container is: 1) run as Privileged 2) has CAP_SYS_ADMIN Note that this field cannot be set when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running containers. Defaults to the default set of capabilities granted by the container runtime. Note that this field cannot be set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes in privileged containers are essentially equivalent to root on the host. Defaults to false. Note that this field cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount to use for the containers. The default is DefaultProcMount which uses the container runtime defaults for readonly paths and masked paths. This requires the ProcMountType feature flag to be enabled. Note that this field cannot be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root filesystem. Default is false. Note that this field cannot be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container process. Uses runtime default if unset. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root user. If true, the Kubelet will validate the image at runtime to ensure that it does not run as UID 0 (root) and fail to start the container if it does. If unset or false, no such validation will be performed. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container process. Defaults to user specified in image metadata if unspecified. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the container. If unspecified, the container runtime will allocate a random SELinux context for each container. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies to the container. + type: string + role: + description: Role is a SELinux role label that applies to the container. + type: string + type: + description: Type is a SELinux type label that applies to the container. + type: string + user: + description: User is a SELinux user label that applies to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. If seccomp options are provided at both the pod & container level, the container options override the pod options. Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile location. Must only be set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp profile will be applied. Valid options are: \n Localhost - a profile defined in a file on the node should be used. RuntimeDefault - the container runtime default profile should be used. Unconfined - no profile should be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to all containers. If unspecified, the options from the PodSecurityContext will be used. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should be run as a 'Host Process' container. This field is alpha-level and will only be honored by components that enable the WindowsHostProcessContainers feature flag. Setting this field without the feature flag will result in errors when validating the Pod. All of a Pod's containers must have the same effective HostProcess value (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint of the container process. Defaults to the user specified in image metadata if unspecified. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + startupProbe: + description: 'StartupProbe indicates that the Pod has successfully initialized. If specified, no other probes are executed until this completes successfully. If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. This can be used to provide different probe parameters at the beginning of a Pod''s lifecycle, when it might take a long time to load data or warm a cache, than during steady-state operation. This cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to be considered failed after having succeeded. Defaults to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. This is a beta field and requires enabling GRPCContainerProbe feature gate. + properties: + port: + description: Port number of the gRPC service. Number must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). \n If this is not specified, the default behavior is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the pod IP. You probably want to set "Host" in httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header to be used in HTTP probes + properties: + name: + description: The header field name + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has started before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to be considered successful after having failed. Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP port. + properties: + host: + description: 'Optional: Host name to connect to, defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + stdin: + description: Whether this container should allocate a buffer for stdin in the container runtime. If this is not set, reads from stdin in the container will always result in EOF. Default is false. + type: boolean + stdinOnce: + description: Whether the container runtime should close the stdin channel after it has been opened by a single attach. When stdin is true the stdin stream will remain open across multiple attach sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the first client attaches to stdin, and then remains open and accepts data until the client disconnects, at which time stdin is closed and remains closed until the container is restarted. If this flag is false, a container processes that reads from stdin will never receive an EOF. Default is false + type: boolean + terminationMessagePath: + description: 'Optional: Path at which the file to which the container''s termination message will be written is mounted into the container''s filesystem. Message written is intended to be brief final status, such as an assertion failure message. Will be truncated by the node if greater than 4096 bytes. The total message length across all containers will be limited to 12kb. Defaults to /dev/termination-log. Cannot be updated.' + type: string + terminationMessagePolicy: + description: Indicate how the termination message should be populated. File will use the contents of terminationMessagePath to populate the container status message on both success and failure. FallbackToLogsOnError will use the last chunk of container log output if the termination message file is empty and the container exited with an error. The log output is limited to 2048 bytes or 80 lines, whichever is smaller. Defaults to File. Cannot be updated. + type: string + tty: + description: Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. Default is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices to be used by the container. + items: + description: volumeDevice describes a mapping of a raw block device within a container. + properties: + devicePath: + description: devicePath is the path inside of the container that the device will be mapped to. + type: string + name: + description: name must match the name of a persistentVolumeClaim in the pod + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + description: Pod volumes to mount into the container's filesystem. Cannot be updated. + items: + description: VolumeMount describes a mounting of a Volume within a container. + properties: + mountPath: + description: Path within the container at which the volume should be mounted. Must not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts are propagated from the host to container and the other way around. When not set, MountPropagationNone is used. This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write otherwise (false or unspecified). Defaults to false. + type: boolean + subPath: + description: Path within the volume from which the container's volume should be mounted. Defaults to "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume from which the container's volume should be mounted. Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. Defaults to "" (volume's root). SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + description: Container's working directory. If not specified, the container runtime's default will be used, which might be configured in the container image. Cannot be updated. + type: string + required: + - name + type: object + type: array + nodeName: + description: NodeName is a request to schedule this pod onto a specific node. If it is non-empty, the scheduler simply schedules this pod onto that node, assuming that it fits resource requirements. + type: string + nodeSelector: + additionalProperties: + type: string + description: 'NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node''s labels for the pod to be scheduled on that node. More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/' + type: object + x-kubernetes-map-type: atomic + os: + description: "Specifies the OS of the containers in the pod. Some pod and container fields are restricted if this is set. \n If the OS field is set to linux, the following fields must be unset: -securityContext.windowsOptions \n If the OS field is set to windows, following fields must be unset: - spec.hostPID - spec.hostIPC - spec.hostUsers - spec.securityContext.seLinuxOptions - spec.securityContext.seccompProfile - spec.securityContext.fsGroup - spec.securityContext.fsGroupChangePolicy - spec.securityContext.sysctls - spec.shareProcessNamespace - spec.securityContext.runAsUser - spec.securityContext.runAsGroup - spec.securityContext.supplementalGroups - spec.containers[*].securityContext.seLinuxOptions - spec.containers[*].securityContext.seccompProfile - spec.containers[*].securityContext.capabilities - spec.containers[*].securityContext.readOnlyRootFilesystem - spec.containers[*].securityContext.privileged - spec.containers[*].securityContext.allowPrivilegeEscalation - spec.containers[*].securityContext.procMount - spec.containers[*].securityContext.runAsUser - spec.containers[*].securityContext.runAsGroup" + properties: + name: + description: 'Name is the name of the operating system. The currently supported values are linux and windows. Additional value may be defined in future and can be one of: https://github.com/opencontainers/runtime-spec/blob/master/config.md#platform-specific-configuration Clients should expect to handle additional values and treat unrecognized values in this field as os: null' + type: string + required: + - name + type: object + overhead: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Overhead represents the resource overhead associated with running a pod for a given RuntimeClass. This field will be autopopulated at admission time by the RuntimeClass admission controller. If the RuntimeClass admission controller is enabled, overhead must not be set in Pod create requests. The RuntimeClass admission controller will reject Pod create requests which have the overhead already set. If RuntimeClass is configured and selected in the PodSpec, Overhead will be set to the value defined in the corresponding RuntimeClass, otherwise it will remain unset and treated as zero. More info: https://git.k8s.io/enhancements/keps/sig-node/688-pod-overhead/README.md' + type: object + preemptionPolicy: + description: PreemptionPolicy is the Policy for preempting pods with lower priority. One of Never, PreemptLowerPriority. Defaults to PreemptLowerPriority if unset. + type: string + priority: + description: The priority value. Various system components use this field to find the priority of the pod. When Priority Admission Controller is enabled, it prevents users from setting this field. The admission controller populates this field from PriorityClassName. The higher the value, the higher the priority. + format: int32 + type: integer + priorityClassName: + description: If specified, indicates the pod's priority. "system-node-critical" and "system-cluster-critical" are two special keywords which indicate the highest priorities with the former being the highest priority. Any other name must be defined by creating a PriorityClass object with that name. If not specified, the pod priority will be default or zero if there is no default. + type: string + readinessGates: + description: 'If specified, all readiness gates will be evaluated for pod readiness. A pod is ready when all its containers are ready AND all conditions specified in the readiness gates have status equal to "True" More info: https://git.k8s.io/enhancements/keps/sig-network/580-pod-readiness-gates' + items: + description: PodReadinessGate contains the reference to a pod condition + properties: + conditionType: + description: ConditionType refers to a condition in the pod's condition list with matching type. + type: string + required: + - conditionType + type: object + type: array + resourceClaims: + description: "ResourceClaims defines which ResourceClaims must be allocated and reserved before the Pod is allowed to start. The resources will be made available to those containers which consume them by name. \n This is an alpha field and requires enabling the DynamicResourceAllocation feature gate. \n This field is immutable." + items: + description: PodResourceClaim references exactly one ResourceClaim through a ClaimSource. It adds a name to it that uniquely identifies the ResourceClaim inside the Pod. Containers that need access to the ResourceClaim reference it with this name. + properties: + name: + description: Name uniquely identifies this resource claim inside the pod. This must be a DNS_LABEL. + type: string + source: + description: Source describes where to find the ResourceClaim. + properties: + resourceClaimName: + description: ResourceClaimName is the name of a ResourceClaim object in the same namespace as this pod. + type: string + resourceClaimTemplateName: + description: "ResourceClaimTemplateName is the name of a ResourceClaimTemplate object in the same namespace as this pod. \n The template will be used to create a new ResourceClaim, which will be bound to this pod. When this pod is deleted, the ResourceClaim will also be deleted. The name of the ResourceClaim will be -, where is the PodResourceClaim.Name. Pod validation will reject the pod if the concatenated name is not valid for a ResourceClaim (e.g. too long). \n An existing ResourceClaim with that name that is not owned by the pod will not be used for the pod to avoid using an unrelated resource by mistake. Scheduling and pod startup are then blocked until the unrelated ResourceClaim is removed. \n This field is immutable and no changes will be made to the corresponding ResourceClaim by the control plane after creating the ResourceClaim." + type: string + type: object + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + restartPolicy: + description: 'Restart policy for all containers within the pod. One of Always, OnFailure, Never. Default to Always. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy' + type: string + runtimeClassName: + description: 'RuntimeClassName refers to a RuntimeClass object in the node.k8s.io group, which should be used to run this pod. If no RuntimeClass resource matches the named class, the pod will not be run. If unset or empty, the "legacy" RuntimeClass will be used, which is an implicit class with an empty definition that uses the default runtime handler. More info: https://git.k8s.io/enhancements/keps/sig-node/585-runtime-class' + type: string + schedulerName: + description: If specified, the pod will be dispatched by specified scheduler. If not specified, the pod will be dispatched by default scheduler. + type: string + schedulingGates: + description: "SchedulingGates is an opaque list of values that if specified will block scheduling the pod. More info: https://git.k8s.io/enhancements/keps/sig-scheduling/3521-pod-scheduling-readiness. \n This is an alpha-level feature enabled by PodSchedulingReadiness feature gate." + items: + description: PodSchedulingGate is associated to a Pod to guard its scheduling. + properties: + name: + description: Name of the scheduling gate. Each scheduling gate must have a unique name field. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + securityContext: + description: 'SecurityContext holds pod-level security attributes and common container settings. Optional: Defaults to empty. See type description for default values of each field.' + properties: + fsGroup: + description: "A special supplemental group that applies to all containers in a pod. Some volume types allow the Kubelet to change the ownership of that volume to be owned by the pod: \n 1. The owning GID will be the FSGroup 2. The setgid bit is set (new files created in the volume will be owned by FSGroup) 3. The permission bits are OR'd with rw-rw---- \n If unset, the Kubelet will not modify the ownership and permissions of any volume. Note that this field cannot be set when spec.os.name is windows." + format: int64 + type: integer + fsGroupChangePolicy: + description: 'fsGroupChangePolicy defines behavior of changing ownership and permission of the volume before being exposed inside Pod. This field will only apply to volume types which support fsGroup based ownership(and permissions). It will have no effect on ephemeral volume types such as: secret, configmaps and emptydir. Valid values are "OnRootMismatch" and "Always". If not specified, "Always" is used. Note that this field cannot be set when spec.os.name is windows.' + type: string + runAsGroup: + description: The GID to run the entrypoint of the container process. Uses runtime default if unset. May also be set in SecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence for that container. Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root user. If true, the Kubelet will validate the image at runtime to ensure that it does not run as UID 0 (root) and fail to start the container if it does. If unset or false, no such validation will be performed. May also be set in SecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container process. Defaults to user specified in image metadata if unspecified. May also be set in SecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence for that container. Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to all containers. If unspecified, the container runtime will allocate a random SELinux context for each container. May also be set in SecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence for that container. Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies to the container. + type: string + role: + description: Role is a SELinux role label that applies to the container. + type: string + type: + description: Type is a SELinux type label that applies to the container. + type: string + user: + description: User is a SELinux user label that applies to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by the containers in this pod. Note that this field cannot be set when spec.os.name is windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile location. Must only be set if type is "Localhost". + type: string + type: + description: "type indicates which kind of seccomp profile will be applied. Valid options are: \n Localhost - a profile defined in a file on the node should be used. RuntimeDefault - the container runtime default profile should be used. Unconfined - no profile should be applied." + type: string + required: + - type + type: object + supplementalGroups: + description: A list of groups applied to the first process run in each container, in addition to the container's primary GID, the fsGroup (if specified), and group memberships defined in the container image for the uid of the container process. If unspecified, no additional groups are added to any container. Note that group memberships defined in the container image for the uid of the container process are still effective, even if they are not included in this list. Note that this field cannot be set when spec.os.name is windows. + items: + format: int64 + type: integer + type: array + sysctls: + description: Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported sysctls (by the container runtime) might fail to launch. Note that this field cannot be set when spec.os.name is windows. + items: + description: Sysctl defines a kernel parameter to be set + properties: + name: + description: Name of a property to set + type: string + value: + description: Value of a property to set + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + description: The Windows specific settings applied to all containers. If unspecified, the options within a container's SecurityContext will be used. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. Note that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the GMSA credential spec named by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should be run as a 'Host Process' container. This field is alpha-level and will only be honored by components that enable the WindowsHostProcessContainers feature flag. Setting this field without the feature flag will result in errors when validating the Pod. All of a Pod's containers must have the same effective HostProcess value (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). In addition, if HostProcess is true then HostNetwork must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint of the container process. Defaults to the user specified in image metadata if unspecified. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence. + type: string + type: object + type: object + serviceAccount: + description: 'DeprecatedServiceAccount is a depreciated alias for ServiceAccountName. Deprecated: Use serviceAccountName instead.' + type: string + serviceAccountName: + description: 'ServiceAccountName is the name of the ServiceAccount to use to run this pod. More info: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/' + type: string + setHostnameAsFQDN: + description: If true the pod's hostname will be configured as the pod's FQDN, rather than the leaf name (the default). In Linux containers, this means setting the FQDN in the hostname field of the kernel (the nodename field of struct utsname). In Windows containers, this means setting the registry value of hostname for the registry key HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters to FQDN. If a pod does not have FQDN, this has no effect. Default to false. + type: boolean + shareProcessNamespace: + description: 'Share a single process namespace between all of the containers in a pod. When this is set containers will be able to view and signal processes from other containers in the same pod, and the first process in each container will not be assigned PID 1. HostPID and ShareProcessNamespace cannot both be set. Optional: Default to false.' + type: boolean + subdomain: + description: If specified, the fully qualified Pod hostname will be "...svc.". If not specified, the pod will not have a domainname at all. + type: string + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs to terminate gracefully. May be decreased in delete request. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). If this value is nil, the default grace period will be used instead. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. Defaults to 30 seconds. + format: int64 + type: integer + tolerations: + description: If specified, the pod's tolerations. + items: + description: The pod this Toleration is attached to tolerates any taint that matches the triple using the matching operator . + properties: + effect: + description: Effect indicates the taint effect to match. Empty means match all taint effects. When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Key is the taint key that the toleration applies to. Empty means match all taint keys. If the key is empty, operator must be Exists; this combination means to match all values and all keys. + type: string + operator: + description: Operator represents a key's relationship to the value. Valid operators are Exists and Equal. Defaults to Equal. Exists is equivalent to wildcard for value, so that a pod can tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period of time the toleration (which must be of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, it is not set, which means tolerate the taint forever (do not evict). Zero and negative values will be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration matches to. If the operator is Exists, the value should be empty, otherwise just a regular string. + type: string + type: object + type: array + topologySpreadConstraints: + description: TopologySpreadConstraints describes how a group of pods ought to spread across topology domains. Scheduler will schedule pods in a way which abides by the constraints. All topologySpreadConstraints are ANDed. + items: + description: TopologySpreadConstraint specifies how to spread matching pods among the given topology. + properties: + labelSelector: + description: LabelSelector is used to find matching pods. Pods that match this label selector are counted to determine the number of pods in their corresponding topology domain. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + matchLabelKeys: + description: MatchLabelKeys is a set of pod label keys to select the pods over which spreading will be calculated. The keys are used to lookup values from the incoming pod labels, those key-value labels are ANDed with labelSelector to select the group of existing pods over which spreading will be calculated for the incoming pod. Keys that don't exist in the incoming pod labels will be ignored. A null or empty list means only match against labelSelector. + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + description: 'MaxSkew describes the degree to which pods may be unevenly distributed. When `whenUnsatisfiable=DoNotSchedule`, it is the maximum permitted difference between the number of matching pods in the target topology and the global minimum. The global minimum is the minimum number of matching pods in an eligible domain or zero if the number of eligible domains is less than MinDomains. For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same labelSelector spread as 2/2/1: In this case, the global minimum is 1. | zone1 | zone2 | zone3 | | P P | P P | P | - if MaxSkew is 1, incoming pod can only be scheduled to zone3 to become 2/2/2; scheduling it onto zone1(zone2) would make the ActualSkew(3-1) on zone1(zone2) violate MaxSkew(1). - if MaxSkew is 2, incoming pod can be scheduled onto any zone. When `whenUnsatisfiable=ScheduleAnyway`, it is used to give higher precedence to topologies that satisfy it. It''s a required field. Default value is 1 and 0 is not allowed.' + format: int32 + type: integer + minDomains: + description: "MinDomains indicates a minimum number of eligible domains. When the number of eligible domains with matching topology keys is less than minDomains, Pod Topology Spread treats \"global minimum\" as 0, and then the calculation of Skew is performed. And when the number of eligible domains with matching topology keys equals or greater than minDomains, this value has no effect on scheduling. As a result, when the number of eligible domains is less than minDomains, scheduler won't schedule more than maxSkew Pods to those domains. If value is nil, the constraint behaves as if MinDomains is equal to 1. Valid values are integers greater than 0. When value is not nil, WhenUnsatisfiable must be DoNotSchedule. \n For example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains is set to 5 and pods with the same labelSelector spread as 2/2/2: | zone1 | zone2 | zone3 | | P P | P P | P P | The number of domains is less than 5(MinDomains), so \"global minimum\" is treated as 0. In this situation, new pod with the same labelSelector cannot be scheduled, because computed skew will be 3(3 - 0) if new Pod is scheduled to any of the three zones, it will violate MaxSkew. \n This is a beta field and requires the MinDomainsInPodTopologySpread feature gate to be enabled (enabled by default)." + format: int32 + type: integer + nodeAffinityPolicy: + description: "NodeAffinityPolicy indicates how we will treat Pod's nodeAffinity/nodeSelector when calculating pod topology spread skew. Options are: - Honor: only nodes matching nodeAffinity/nodeSelector are included in the calculations. - Ignore: nodeAffinity/nodeSelector are ignored. All nodes are included in the calculations. \n If this value is nil, the behavior is equivalent to the Honor policy. This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag." + type: string + nodeTaintsPolicy: + description: "NodeTaintsPolicy indicates how we will treat node taints when calculating pod topology spread skew. Options are: - Honor: nodes without taints, along with tainted nodes for which the incoming pod has a toleration, are included. - Ignore: node taints are ignored. All nodes are included. \n If this value is nil, the behavior is equivalent to the Ignore policy. This is a beta-level feature default enabled by the NodeInclusionPolicyInPodTopologySpread feature flag." + type: string + topologyKey: + description: TopologyKey is the key of node labels. Nodes that have a label with this key and identical values are considered to be in the same topology. We consider each as a "bucket", and try to put balanced number of pods into each bucket. We define a domain as a particular instance of a topology. Also, we define an eligible domain as a domain whose nodes meet the requirements of nodeAffinityPolicy and nodeTaintsPolicy. e.g. If TopologyKey is "kubernetes.io/hostname", each Node is a domain of that topology. And, if TopologyKey is "topology.kubernetes.io/zone", each zone is a domain of that topology. It's a required field. + type: string + whenUnsatisfiable: + description: 'WhenUnsatisfiable indicates how to deal with a pod if it doesn''t satisfy the spread constraint. - DoNotSchedule (default) tells the scheduler not to schedule it. - ScheduleAnyway tells the scheduler to schedule the pod in any location, but giving higher precedence to topologies that would help reduce the skew. A constraint is considered "Unsatisfiable" for an incoming pod if and only if every possible node assignment for that pod would violate "MaxSkew" on some topology. For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same labelSelector spread as 3/1/1: | zone1 | zone2 | zone3 | | P P P | P | P | If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can only be scheduled to zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies MaxSkew(1). In other words, the cluster can still be imbalanced, but scheduler won''t make it *more* imbalanced. It''s a required field.' + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + x-kubernetes-list-map-keys: + - topologyKey + - whenUnsatisfiable + x-kubernetes-list-type: map + volumes: + description: 'List of volumes that can be mounted by containers belonging to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes' + items: + description: Volume represents a named volume in a pod that may be accessed by any container in the pod. + properties: + awsElasticBlockStore: + description: 'awsElasticBlockStore represents an AWS Disk resource that is attached to a kubelet''s host machine and then exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + properties: + fsType: + description: 'fsType is the filesystem type of the volume that you want to mount. Tip: Ensure that the filesystem type is supported by the host operating system. Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore TODO: how do we prevent errors in the filesystem from compromising the machine' + type: string + partition: + description: 'partition is the partition in the volume that you want to mount. If omitted, the default is to mount by volume name. Examples: For volume /dev/sda1, you specify the partition as "1". Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty).' + format: int32 + type: integer + readOnly: + description: 'readOnly value true will force the readOnly setting in VolumeMounts. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + type: boolean + volumeID: + description: 'volumeID is unique ID of the persistent disk resource in AWS (Amazon EBS volume). More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + type: string + required: + - volumeID + type: object + azureDisk: + description: azureDisk represents an Azure Data Disk mount on the host and bind mount to the pod. + properties: + cachingMode: + description: 'cachingMode is the Host Caching mode: None, Read Only, Read Write.' + type: string + diskName: + description: diskName is the Name of the data disk in the blob storage + type: string + diskURI: + description: diskURI is the URI of data disk in the blob storage + type: string + fsType: + description: fsType is Filesystem type to mount. Must be a filesystem type supported by the host operating system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + kind: + description: 'kind expected values are Shared: multiple blob disks per storage account Dedicated: single blob disk per storage account Managed: azure managed data disk (only in managed availability set). defaults to shared' + type: string + readOnly: + description: readOnly Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + description: azureFile represents an Azure File Service mount on the host and bind mount to the pod. + properties: + readOnly: + description: readOnly defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. + type: boolean + secretName: + description: secretName is the name of secret that contains Azure Storage Account Name and Key + type: string + shareName: + description: shareName is the azure share Name + type: string + required: + - secretName + - shareName + type: object + cephfs: + description: cephFS represents a Ceph FS mount on the host that shares a pod's lifetime + properties: + monitors: + description: 'monitors is Required: Monitors is a collection of Ceph monitors More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + items: + type: string + type: array + path: + description: 'path is Optional: Used as the mounted root, rather than the full Ceph tree, default is /' + type: string + readOnly: + description: 'readOnly is Optional: Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: boolean + secretFile: + description: 'secretFile is Optional: SecretFile is the path to key ring for User, default is /etc/ceph/user.secret More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: string + secretRef: + description: 'secretRef is Optional: SecretRef is reference to the authentication secret for User, default is empty. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + user: + description: 'user is optional: User is the rados user name, default is admin More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: string + required: + - monitors + type: object + cinder: + description: 'cinder represents a cinder volume attached and mounted on kubelets host machine. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + properties: + fsType: + description: 'fsType is the filesystem type to mount. Must be a filesystem type supported by the host operating system. Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: string + readOnly: + description: 'readOnly defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: boolean + secretRef: + description: 'secretRef is optional: points to a secret object containing parameters used to connect to OpenStack.' + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + volumeID: + description: 'volumeID used to identify the volume in cinder. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: string + required: + - volumeID + type: object + configMap: + description: configMap represents a configMap that should populate this volume + properties: + defaultMode: + description: 'defaultMode is optional: mode bits used to set permissions on created files by default. Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. Defaults to 0644. Directories within the path are not affected by this setting. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.' + format: int32 + type: integer + items: + description: items if unspecified, each key-value pair in the Data field of the referenced ConfigMap will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the ConfigMap, the volume setup will error unless it is marked optional. Paths must be relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits used to set permissions on this file. Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. If not specified, the volume defaultMode will be used. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.' + format: int32 + type: integer + path: + description: path is the relative path of the file to map the key to. May not be an absolute path. May not contain the path element '..'. May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: optional specify whether the ConfigMap or its keys must be defined + type: boolean + type: object + csi: + description: csi (Container Storage Interface) represents ephemeral storage that is handled by certain external CSI drivers (Beta feature). + properties: + driver: + description: driver is the name of the CSI driver that handles this volume. Consult with your admin for the correct name as registered in the cluster. + type: string + fsType: + description: fsType to mount. Ex. "ext4", "xfs", "ntfs". If not provided, the empty value is passed to the associated CSI driver which will determine the default filesystem to apply. + type: string + nodePublishSecretRef: + description: nodePublishSecretRef is a reference to the secret object containing sensitive information to pass to the CSI driver to complete the CSI NodePublishVolume and NodeUnpublishVolume calls. This field is optional, and may be empty if no secret is required. If the secret object contains more than one secret, all secret references are passed. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + readOnly: + description: readOnly specifies a read-only configuration for the volume. Defaults to false (read/write). + type: boolean + volumeAttributes: + additionalProperties: + type: string + description: volumeAttributes stores driver-specific properties that are passed to the CSI driver. Consult your driver's documentation for supported values. + type: object + required: + - driver + type: object + downwardAPI: + description: downwardAPI represents downward API about the pod that should populate this volume + properties: + defaultMode: + description: 'Optional: mode bits to use on created files by default. Must be a Optional: mode bits used to set permissions on created files by default. Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. Defaults to 0644. Directories within the path are not affected by this setting. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.' + format: int32 + type: integer + items: + description: Items is a list of downward API volume file + items: + description: DownwardAPIVolumeFile represents information to create the file containing the pod field + properties: + fieldRef: + description: 'Required: Selects a field of the pod: only annotations, labels, name and namespace are supported.' + properties: + apiVersion: + description: Version of the schema the FieldPath is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified API version. + type: string + required: + - fieldPath + type: object + mode: + description: 'Optional: mode bits used to set permissions on this file, must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. If not specified, the volume defaultMode will be used. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.' + format: int32 + type: integer + path: + description: 'Required: Path is the relative path name of the file to be created. Must not be absolute or contain the ''..'' path. Must be utf-8 encoded. The first item of the relative path must not start with ''..''' + type: string + resourceFieldRef: + description: 'Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + required: + - path + type: object + type: array + type: object + emptyDir: + description: 'emptyDir represents a temporary directory that shares a pod''s lifetime. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + properties: + medium: + description: 'medium represents what type of storage medium should back this directory. The default is "" which means to use the node''s default medium. Must be an empty string (default) or Memory. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + description: 'sizeLimit is the total amount of local storage required for this EmptyDir volume. The size limit is also applicable for memory medium. The maximum usage on memory medium EmptyDir would be the minimum value between the SizeLimit specified here and the sum of memory limits of all containers in a pod. The default is nil which means that the limit is undefined. More info: http://kubernetes.io/docs/user-guide/volumes#emptydir' + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + description: "ephemeral represents a volume that is handled by a cluster storage driver. The volume's lifecycle is tied to the pod that defines it - it will be created before the pod starts, and deleted when the pod is removed. \n Use this if: a) the volume is only needed while the pod runs, b) features of normal volumes like restoring from snapshot or capacity tracking are needed, c) the storage driver is specified through a storage class, and d) the storage driver supports dynamic volume provisioning through a PersistentVolumeClaim (see EphemeralVolumeSource for more information on the connection between this volume type and PersistentVolumeClaim). \n Use PersistentVolumeClaim or one of the vendor-specific APIs for volumes that persist for longer than the lifecycle of an individual pod. \n Use CSI for light-weight local ephemeral volumes if the CSI driver is meant to be used that way - see the documentation of the driver for more information. \n A pod can use both types of ephemeral volumes and persistent volumes at the same time." + properties: + volumeClaimTemplate: + description: "Will be used to create a stand-alone PVC to provision the volume. The pod in which this EphemeralVolumeSource is embedded will be the owner of the PVC, i.e. the PVC will be deleted together with the pod. The name of the PVC will be `-` where `` is the name from the `PodSpec.Volumes` array entry. Pod validation will reject the pod if the concatenated name is not valid for a PVC (for example, too long). \n An existing PVC with that name that is not owned by the pod will *not* be used for the pod to avoid using an unrelated volume by mistake. Starting the pod is then blocked until the unrelated PVC is removed. If such a pre-created PVC is meant to be used by the pod, the PVC has to updated with an owner reference to the pod once the pod exists. Normally this should not be necessary, but it may be useful when manually reconstructing a broken cluster. \n This field is read-only and no changes will be made by Kubernetes to the PVC after it has been created. \n Required, must not be nil." + properties: + metadata: + description: May contain labels and annotations that will be copied into the PVC when creating it. No other fields are allowed and will be rejected during validation. + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: The specification for the PersistentVolumeClaim. The entire content is copied unchanged into the PVC that gets created from this template. The same fields as in a PersistentVolumeClaim are also valid here. + properties: + accessModes: + description: 'accessModes contains the desired access modes the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' + items: + type: string + type: array + dataSource: + description: 'dataSource field can be used to specify either: * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) * An existing PVC (PersistentVolumeClaim) If the provisioner or an external controller can support the specified data source, it will create a new volume based on the contents of the specified data source. When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. If the namespace is specified, then dataSourceRef will not be copied to dataSource.' + properties: + apiGroup: + description: APIGroup is the group for the resource being referenced. If APIGroup is not specified, the specified Kind must be in the core API group. For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + dataSourceRef: + description: 'dataSourceRef specifies the object from which to populate the volume with data, if a non-empty volume is desired. This may be any object from a non-empty API group (non core object) or a PersistentVolumeClaim object. When this field is specified, volume binding will only succeed if the type of the specified object matches some installed volume populator or dynamic provisioner. This field will replace the functionality of the dataSource field and as such if both fields are non-empty, they must have the same value. For backwards compatibility, when namespace isn''t specified in dataSourceRef, both fields (dataSource and dataSourceRef) will be set to the same value automatically if one of them is empty and the other is non-empty. When namespace is specified in dataSourceRef, dataSource isn''t set to the same value and must be empty. There are three important differences between dataSource and dataSourceRef: * While dataSource only allows two specific types of objects, dataSourceRef allows any non-core object, as well as PersistentVolumeClaim objects. * While dataSource ignores disallowed values (dropping them), dataSourceRef preserves all values, and generates an error if a disallowed value is specified. * While dataSource only allows local objects, dataSourceRef allows objects in any namespaces. (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled.' + properties: + apiGroup: + description: APIGroup is the group for the resource being referenced. If APIGroup is not specified, the specified Kind must be in the core API group. For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + namespace: + description: Namespace is the namespace of resource being referenced Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: 'resources represents the minimum resources the volume should have. If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements that are lower than previous value but must still be higher than capacity recorded in the status field of the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources' + properties: + claims: + description: "Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container. \n This is an alpha field and requires enabling the DynamicResourceAllocation feature gate. \n This field is immutable." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. It makes that resource available inside a container. + type: string + required: + - name + type: object + type: array + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + selector: + description: selector is a label query over volumes to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + storageClassName: + description: 'storageClassName is the name of the StorageClass required by the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' + type: string + volumeMode: + description: volumeMode defines what type of volume is required by the claim. Value of Filesystem is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference to the PersistentVolume backing this claim. + type: string + type: object + required: + - spec + type: object + type: object + fc: + description: fc represents a Fibre Channel resource that is attached to a kubelet's host machine and then exposed to the pod. + properties: + fsType: + description: 'fsType is the filesystem type to mount. Must be a filesystem type supported by the host operating system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. TODO: how do we prevent errors in the filesystem from compromising the machine' + type: string + lun: + description: 'lun is Optional: FC target lun number' + format: int32 + type: integer + readOnly: + description: 'readOnly is Optional: Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts.' + type: boolean + targetWWNs: + description: 'targetWWNs is Optional: FC target worldwide names (WWNs)' + items: + type: string + type: array + wwids: + description: 'wwids Optional: FC volume world wide identifiers (wwids) Either wwids or combination of targetWWNs and lun must be set, but not both simultaneously.' + items: + type: string + type: array + type: object + flexVolume: + description: flexVolume represents a generic volume resource that is provisioned/attached using an exec based plugin. + properties: + driver: + description: driver is the name of the driver to use for this volume. + type: string + fsType: + description: fsType is the filesystem type to mount. Must be a filesystem type supported by the host operating system. Ex. "ext4", "xfs", "ntfs". The default filesystem depends on FlexVolume script. + type: string + options: + additionalProperties: + type: string + description: 'options is Optional: this field holds extra command options if any.' + type: object + readOnly: + description: 'readOnly is Optional: defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts.' + type: boolean + secretRef: + description: 'secretRef is Optional: secretRef is reference to the secret object containing sensitive information to pass to the plugin scripts. This may be empty if no secret object is specified. If the secret object contains more than one secret, all secrets are passed to the plugin scripts.' + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + required: + - driver + type: object + flocker: + description: flocker represents a Flocker volume attached to a kubelet's host machine. This depends on the Flocker control service being running + properties: + datasetName: + description: datasetName is Name of the dataset stored as metadata -> name on the dataset for Flocker should be considered as deprecated + type: string + datasetUUID: + description: datasetUUID is the UUID of the dataset. This is unique identifier of a Flocker dataset + type: string + type: object + gcePersistentDisk: + description: 'gcePersistentDisk represents a GCE Disk resource that is attached to a kubelet''s host machine and then exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + properties: + fsType: + description: 'fsType is filesystem type of the volume that you want to mount. Tip: Ensure that the filesystem type is supported by the host operating system. Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk TODO: how do we prevent errors in the filesystem from compromising the machine' + type: string + partition: + description: 'partition is the partition in the volume that you want to mount. If omitted, the default is to mount by volume name. Examples: For volume /dev/sda1, you specify the partition as "1". Similarly, the volume partition for /dev/sda is "0" (or you can leave the property empty). More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + format: int32 + type: integer + pdName: + description: 'pdName is unique name of the PD resource in GCE. Used to identify the disk in GCE. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + type: string + readOnly: + description: 'readOnly here will force the ReadOnly setting in VolumeMounts. Defaults to false. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + type: boolean + required: + - pdName + type: object + gitRepo: + description: 'gitRepo represents a git repository at a particular revision. DEPRECATED: GitRepo is deprecated. To provision a container with a git repo, mount an EmptyDir into an InitContainer that clones the repo using git, then mount the EmptyDir into the Pod''s container.' + properties: + directory: + description: directory is the target directory name. Must not contain or start with '..'. If '.' is supplied, the volume directory will be the git repository. Otherwise, if specified, the volume will contain the git repository in the subdirectory with the given name. + type: string + repository: + description: repository is the URL + type: string + revision: + description: revision is the commit hash for the specified revision. + type: string + required: + - repository + type: object + glusterfs: + description: 'glusterfs represents a Glusterfs mount on the host that shares a pod''s lifetime. More info: https://examples.k8s.io/volumes/glusterfs/README.md' + properties: + endpoints: + description: 'endpoints is the endpoint name that details Glusterfs topology. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: string + path: + description: 'path is the Glusterfs volume path. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: string + readOnly: + description: 'readOnly here will force the Glusterfs volume to be mounted with read-only permissions. Defaults to false. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: boolean + required: + - endpoints + - path + type: object + hostPath: + description: 'hostPath represents a pre-existing file or directory on the host machine that is directly exposed to the container. This is generally used for system agents or other privileged things that are allowed to see the host machine. Most containers will NOT need this. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath --- TODO(jonesdl) We need to restrict who can use host directory mounts and who can/can not mount host directories as read/write.' + properties: + path: + description: 'path of the directory on the host. If the path is a symlink, it will follow the link to the real path. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' + type: string + type: + description: 'type for HostPath Volume Defaults to "" More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' + type: string + required: + - path + type: object + iscsi: + description: 'iscsi represents an ISCSI Disk resource that is attached to a kubelet''s host machine and then exposed to the pod. More info: https://examples.k8s.io/volumes/iscsi/README.md' + properties: + chapAuthDiscovery: + description: chapAuthDiscovery defines whether support iSCSI Discovery CHAP authentication + type: boolean + chapAuthSession: + description: chapAuthSession defines whether support iSCSI Session CHAP authentication + type: boolean + fsType: + description: 'fsType is the filesystem type of the volume that you want to mount. Tip: Ensure that the filesystem type is supported by the host operating system. Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi TODO: how do we prevent errors in the filesystem from compromising the machine' + type: string + initiatorName: + description: initiatorName is the custom iSCSI Initiator Name. If initiatorName is specified with iscsiInterface simultaneously, new iSCSI interface : will be created for the connection. + type: string + iqn: + description: iqn is the target iSCSI Qualified Name. + type: string + iscsiInterface: + description: iscsiInterface is the interface Name that uses an iSCSI transport. Defaults to 'default' (tcp). + type: string + lun: + description: lun represents iSCSI Target Lun number. + format: int32 + type: integer + portals: + description: portals is the iSCSI Target Portal List. The portal is either an IP or ip_addr:port if the port is other than default (typically TCP ports 860 and 3260). + items: + type: string + type: array + readOnly: + description: readOnly here will force the ReadOnly setting in VolumeMounts. Defaults to false. + type: boolean + secretRef: + description: secretRef is the CHAP Secret for iSCSI target and initiator authentication + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + targetPortal: + description: targetPortal is iSCSI Target Portal. The Portal is either an IP or ip_addr:port if the port is other than default (typically TCP ports 860 and 3260). + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + description: 'name of the volume. Must be a DNS_LABEL and unique within the pod. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + nfs: + description: 'nfs represents an NFS mount on the host that shares a pod''s lifetime More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + properties: + path: + description: 'path that is exported by the NFS server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: string + readOnly: + description: 'readOnly here will force the NFS export to be mounted with read-only permissions. Defaults to false. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: boolean + server: + description: 'server is the hostname or IP address of the NFS server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + description: 'persistentVolumeClaimVolumeSource represents a reference to a PersistentVolumeClaim in the same namespace. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + properties: + claimName: + description: 'claimName is the name of a PersistentVolumeClaim in the same namespace as the pod using this volume. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + type: string + readOnly: + description: readOnly Will force the ReadOnly setting in VolumeMounts. Default false. + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + description: photonPersistentDisk represents a PhotonController persistent disk attached and mounted on kubelets host machine + properties: + fsType: + description: fsType is the filesystem type to mount. Must be a filesystem type supported by the host operating system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + pdID: + description: pdID is the ID that identifies Photon Controller persistent disk + type: string + required: + - pdID + type: object + portworxVolume: + description: portworxVolume represents a portworx volume attached and mounted on kubelets host machine + properties: + fsType: + description: fSType represents the filesystem type to mount Must be a filesystem type supported by the host operating system. Ex. "ext4", "xfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: readOnly defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. + type: boolean + volumeID: + description: volumeID uniquely identifies a Portworx volume + type: string + required: + - volumeID + type: object + projected: + description: projected items for all in one resources secrets, configmaps, and downward API + properties: + defaultMode: + description: defaultMode are the mode bits used to set permissions on created files by default. Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. Directories within the path are not affected by this setting. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set. + format: int32 + type: integer + sources: + description: sources is the list of volume projections + items: + description: Projection that may be projected along with other supported volume types + properties: + configMap: + description: configMap information about the configMap data to project + properties: + items: + description: items if unspecified, each key-value pair in the Data field of the referenced ConfigMap will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the ConfigMap, the volume setup will error unless it is marked optional. Paths must be relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits used to set permissions on this file. Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. If not specified, the volume defaultMode will be used. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.' + format: int32 + type: integer + path: + description: path is the relative path of the file to map the key to. May not be an absolute path. May not contain the path element '..'. May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: optional specify whether the ConfigMap or its keys must be defined + type: boolean + type: object + downwardAPI: + description: downwardAPI information about the downwardAPI data to project + properties: + items: + description: Items is a list of DownwardAPIVolume file + items: + description: DownwardAPIVolumeFile represents information to create the file containing the pod field + properties: + fieldRef: + description: 'Required: Selects a field of the pod: only annotations, labels, name and namespace are supported.' + properties: + apiVersion: + description: Version of the schema the FieldPath is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the specified API version. + type: string + required: + - fieldPath + type: object + mode: + description: 'Optional: mode bits used to set permissions on this file, must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. If not specified, the volume defaultMode will be used. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.' + format: int32 + type: integer + path: + description: 'Required: Path is the relative path name of the file to be created. Must not be absolute or contain the ''..'' path. Must be utf-8 encoded. The first item of the relative path must not start with ''..''' + type: string + resourceFieldRef: + description: 'Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + required: + - path + type: object + type: array + type: object + secret: + description: secret information about the secret data to project + properties: + items: + description: items if unspecified, each key-value pair in the Data field of the referenced Secret will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the Secret, the volume setup will error unless it is marked optional. Paths must be relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits used to set permissions on this file. Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. If not specified, the volume defaultMode will be used. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.' + format: int32 + type: integer + path: + description: path is the relative path of the file to map the key to. May not be an absolute path. May not contain the path element '..'. May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: optional field specify whether the Secret or its key must be defined + type: boolean + type: object + serviceAccountToken: + description: serviceAccountToken is information about the serviceAccountToken data to project + properties: + audience: + description: audience is the intended audience of the token. A recipient of a token must identify itself with an identifier specified in the audience of the token, and otherwise should reject the token. The audience defaults to the identifier of the apiserver. + type: string + expirationSeconds: + description: expirationSeconds is the requested duration of validity of the service account token. As the token approaches expiration, the kubelet volume plugin will proactively rotate the service account token. The kubelet will start trying to rotate the token if the token is older than 80 percent of its time to live or if the token is older than 24 hours.Defaults to 1 hour and must be at least 10 minutes. + format: int64 + type: integer + path: + description: path is the path relative to the mount point of the file to project the token into. + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + description: quobyte represents a Quobyte mount on the host that shares a pod's lifetime + properties: + group: + description: group to map volume access to Default is no group + type: string + readOnly: + description: readOnly here will force the Quobyte volume to be mounted with read-only permissions. Defaults to false. + type: boolean + registry: + description: registry represents a single or multiple Quobyte Registry services specified as a string as host:port pair (multiple entries are separated with commas) which acts as the central registry for volumes + type: string + tenant: + description: tenant owning the given Quobyte volume in the Backend Used with dynamically provisioned Quobyte volumes, value is set by the plugin + type: string + user: + description: user to map volume access to Defaults to serivceaccount user + type: string + volume: + description: volume is a string that references an already created Quobyte volume by name. + type: string + required: + - registry + - volume + type: object + rbd: + description: 'rbd represents a Rados Block Device mount on the host that shares a pod''s lifetime. More info: https://examples.k8s.io/volumes/rbd/README.md' + properties: + fsType: + description: 'fsType is the filesystem type of the volume that you want to mount. Tip: Ensure that the filesystem type is supported by the host operating system. Examples: "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd TODO: how do we prevent errors in the filesystem from compromising the machine' + type: string + image: + description: 'image is the rados image name. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + keyring: + description: 'keyring is the path to key ring for RBDUser. Default is /etc/ceph/keyring. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + monitors: + description: 'monitors is a collection of Ceph monitors. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + items: + type: string + type: array + pool: + description: 'pool is the rados pool name. Default is rbd. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + readOnly: + description: 'readOnly here will force the ReadOnly setting in VolumeMounts. Defaults to false. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: boolean + secretRef: + description: 'secretRef is name of the authentication secret for RBDUser. If provided overrides keyring. Default is nil. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + user: + description: 'user is the rados user name. Default is admin. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + required: + - image + - monitors + type: object + scaleIO: + description: scaleIO represents a ScaleIO persistent volume attached and mounted on Kubernetes nodes. + properties: + fsType: + description: fsType is the filesystem type to mount. Must be a filesystem type supported by the host operating system. Ex. "ext4", "xfs", "ntfs". Default is "xfs". + type: string + gateway: + description: gateway is the host address of the ScaleIO API Gateway. + type: string + protectionDomain: + description: protectionDomain is the name of the ScaleIO Protection Domain for the configured storage. + type: string + readOnly: + description: readOnly Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: secretRef references to the secret for ScaleIO user and other sensitive information. If this is not provided, Login operation will fail. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + sslEnabled: + description: sslEnabled Flag enable/disable SSL communication with Gateway, default false + type: boolean + storageMode: + description: storageMode indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned. Default is ThinProvisioned. + type: string + storagePool: + description: storagePool is the ScaleIO Storage Pool associated with the protection domain. + type: string + system: + description: system is the name of the storage system as configured in ScaleIO. + type: string + volumeName: + description: volumeName is the name of a volume already created in the ScaleIO system that is associated with this volume source. + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + description: 'secret represents a secret that should populate this volume. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + properties: + defaultMode: + description: 'defaultMode is Optional: mode bits used to set permissions on created files by default. Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. Defaults to 0644. Directories within the path are not affected by this setting. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.' + format: int32 + type: integer + items: + description: items If unspecified, each key-value pair in the Data field of the referenced Secret will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the Secret, the volume setup will error unless it is marked optional. Paths must be relative and may not contain the '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits used to set permissions on this file. Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. If not specified, the volume defaultMode will be used. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.' + format: int32 + type: integer + path: + description: path is the relative path of the file to map the key to. May not be an absolute path. May not contain the path element '..'. May not start with the string '..'. + type: string + required: + - key + - path + type: object + type: array + optional: + description: optional field specify whether the Secret or its keys must be defined + type: boolean + secretName: + description: 'secretName is the name of the secret in the pod''s namespace to use. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + type: string + type: object + storageos: + description: storageOS represents a StorageOS volume attached and mounted on Kubernetes nodes. + properties: + fsType: + description: fsType is the filesystem type to mount. Must be a filesystem type supported by the host operating system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + readOnly: + description: readOnly defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: secretRef specifies the secret to use for obtaining the StorageOS API credentials. If not specified, default values will be attempted. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + volumeName: + description: volumeName is the human-readable name of the StorageOS volume. Volume names are only unique within a namespace. + type: string + volumeNamespace: + description: volumeNamespace specifies the scope of the volume within StorageOS. If no namespace is specified then the Pod's namespace will be used. This allows the Kubernetes name scoping to be mirrored within StorageOS for tighter integration. Set VolumeName to any name to override the default behaviour. Set to "default" if you are not using namespaces within StorageOS. Namespaces that do not pre-exist within StorageOS will be created. + type: string + type: object + vsphereVolume: + description: vsphereVolume represents a vSphere volume attached and mounted on kubelets host machine + properties: + fsType: + description: fsType is filesystem type to mount. Must be a filesystem type supported by the host operating system. Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + type: string + storagePolicyID: + description: storagePolicyID is the storage Policy Based Management (SPBM) profile ID associated with the StoragePolicyName. + type: string + storagePolicyName: + description: storagePolicyName is the storage Policy Based Management (SPBM) profile name. + type: string + volumePath: + description: volumePath is the path that identifies vSphere volume vmdk + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + required: + - containers + type: object + type: object + updateStrategy: + description: updateStrategy indicates the StatefulSetUpdateStrategy that will be employed to update Pods in the StatefulSet when a revision is made to Template. + properties: + rollingUpdate: + description: RollingUpdate is used to communicate parameters when Type is RollingUpdateStatefulSetStrategyType. + properties: + maxUnavailable: + anyOf: + - type: integer + - type: string + description: 'The maximum number of pods that can be unavailable during the update. Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). Absolute number is calculated from percentage by rounding up. This can not be 0. Defaults to 1. This field is alpha-level and is only honored by servers that enable the MaxUnavailableStatefulSet feature. The field applies to all pods in the range 0 to Replicas-1. That means if there is any unavailable pod in the range 0 to Replicas-1, it will be counted towards MaxUnavailable.' + x-kubernetes-int-or-string: true + partition: + description: Partition indicates the ordinal at which the StatefulSet should be partitioned for updates. During a rolling update, all pods from ordinal Replicas-1 to Partition are updated. All pods from ordinal Partition-1 to 0 remain untouched. This is helpful in being able to do a canary based deployment. The default value is 0. + format: int32 + type: integer + type: object + type: + description: Type indicates the type of the StatefulSetUpdateStrategy. Default is RollingUpdate. + type: string + type: object + volumeClaimTemplates: + description: 'volumeClaimTemplates is a list of claims that pods are allowed to reference. The StatefulSet controller is responsible for mapping network identities to claims in a way that maintains the identity of a pod. Every claim in this list must have at least one matching (by name) volumeMount in one container in the template. A claim in this list takes precedence over any volumes in the template, with the same name. TODO: Define the behavior if a claim already exists with the same name.' + items: + description: PersistentVolumeClaim is a user's request for and claim to a persistent volume + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + description: 'Standard object''s metadata. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata' + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + description: 'spec defines the desired characteristics of a volume requested by a pod author. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + properties: + accessModes: + description: 'accessModes contains the desired access modes the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' + items: + type: string + type: array + dataSource: + description: 'dataSource field can be used to specify either: * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) * An existing PVC (PersistentVolumeClaim) If the provisioner or an external controller can support the specified data source, it will create a new volume based on the contents of the specified data source. When the AnyVolumeDataSource feature gate is enabled, dataSource contents will be copied to dataSourceRef, and dataSourceRef contents will be copied to dataSource when dataSourceRef.namespace is not specified. If the namespace is specified, then dataSourceRef will not be copied to dataSource.' + properties: + apiGroup: + description: APIGroup is the group for the resource being referenced. If APIGroup is not specified, the specified Kind must be in the core API group. For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + dataSourceRef: + description: 'dataSourceRef specifies the object from which to populate the volume with data, if a non-empty volume is desired. This may be any object from a non-empty API group (non core object) or a PersistentVolumeClaim object. When this field is specified, volume binding will only succeed if the type of the specified object matches some installed volume populator or dynamic provisioner. This field will replace the functionality of the dataSource field and as such if both fields are non-empty, they must have the same value. For backwards compatibility, when namespace isn''t specified in dataSourceRef, both fields (dataSource and dataSourceRef) will be set to the same value automatically if one of them is empty and the other is non-empty. When namespace is specified in dataSourceRef, dataSource isn''t set to the same value and must be empty. There are three important differences between dataSource and dataSourceRef: * While dataSource only allows two specific types of objects, dataSourceRef allows any non-core object, as well as PersistentVolumeClaim objects. * While dataSource ignores disallowed values (dropping them), dataSourceRef preserves all values, and generates an error if a disallowed value is specified. * While dataSource only allows local objects, dataSourceRef allows objects in any namespaces. (Beta) Using this field requires the AnyVolumeDataSource feature gate to be enabled. (Alpha) Using the namespace field of dataSourceRef requires the CrossNamespaceVolumeDataSource feature gate to be enabled.' + properties: + apiGroup: + description: APIGroup is the group for the resource being referenced. If APIGroup is not specified, the specified Kind must be in the core API group. For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + namespace: + description: Namespace is the namespace of resource being referenced Note that when a namespace is specified, a gateway.networking.k8s.io/ReferenceGrant object is required in the referent namespace to allow that namespace's owner to accept the reference. See the ReferenceGrant documentation for details. (Alpha) This field requires the CrossNamespaceVolumeDataSource feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: 'resources represents the minimum resources the volume should have. If RecoverVolumeExpansionFailure feature is enabled users are allowed to specify resource requirements that are lower than previous value but must still be higher than capacity recorded in the status field of the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources' + properties: + claims: + description: "Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container. \n This is an alpha field and requires enabling the DynamicResourceAllocation feature gate. \n This field is immutable." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. It makes that resource available inside a container. + type: string + required: + - name + type: object + type: array + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + selector: + description: selector is a label query over volumes to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + storageClassName: + description: 'storageClassName is the name of the StorageClass required by the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' + type: string + volumeMode: + description: volumeMode defines what type of volume is required by the claim. Value of Filesystem is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference to the PersistentVolume backing this claim. + type: string + type: object + status: + description: 'status represents the current information/status of a persistent volume claim. Read-only. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + properties: + accessModes: + description: 'accessModes contains the actual access modes the volume backing the PVC has. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' + items: + type: string + type: array + allocatedResources: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: allocatedResources is the storage resource within AllocatedResources tracks the capacity allocated to a PVC. It may be larger than the actual capacity when a volume expansion operation is requested. For storage quota, the larger value from allocatedResources and PVC.spec.resources is used. If allocatedResources is not set, PVC.spec.resources alone is used for quota calculation. If a volume expansion capacity request is lowered, allocatedResources is only lowered if there are no expansion operations in progress and if the actual volume capacity is equal or lower than the requested capacity. This is an alpha field and requires enabling RecoverVolumeExpansionFailure feature. + type: object + capacity: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: capacity represents the actual resources of the underlying volume. + type: object + conditions: + description: conditions is the current Condition of persistent volume claim. If underlying persistent volume is being resized then the Condition will be set to 'ResizeStarted'. + items: + description: PersistentVolumeClaimCondition contails details about state of pvc + properties: + lastProbeTime: + description: lastProbeTime is the time we probed the condition. + format: date-time + type: string + lastTransitionTime: + description: lastTransitionTime is the time the condition transitioned from one status to another. + format: date-time + type: string + message: + description: message is the human-readable message indicating details about last transition. + type: string + reason: + description: reason is a unique, this should be a short, machine understandable string that gives the reason for condition's last transition. If it reports "ResizeStarted" that means the underlying persistent volume is being resized. + type: string + status: + type: string + type: + description: PersistentVolumeClaimConditionType is a valid value of PersistentVolumeClaimCondition.Type + type: string + required: + - status + - type + type: object + type: array + phase: + description: phase represents the current phase of PersistentVolumeClaim. + type: string + resizeStatus: + description: resizeStatus stores status of resize operation. ResizeStatus is not set by default but when expansion is complete resizeStatus is set to empty string by resize controller or kubelet. This is an alpha field and requires enabling RecoverVolumeExpansionFailure feature. + type: string + type: object + type: object + type: array + volumeSizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + volumeStorageMedium: + type: string + workDir: + type: string + workVolumeClaimTemplate: + properties: + accessModes: + items: + type: string + type: array + resources: + description: ResourceRequirements describes the compute resource requirements. + properties: + claims: + description: "Claims lists the names of resources, defined in spec.resourceClaims, that are used by this container. \n This is an alpha field and requires enabling the DynamicResourceAllocation feature gate. \n This field is immutable." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in pod.spec.resourceClaims of the Pod where this field is used. It makes that resource available inside a container. + type: string + required: + - name + type: object + type: array + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + storageClassName: + type: string + required: + - accessModes + - resources + - storageClassName + type: object + required: + - selector + - serviceName + - template + type: object + status: + properties: + availableReplicas: + description: AvailableReplicas is the total number of available runners which have been successfully registered to GitHub and still running. This corresponds to the sum of status.availableReplicas of all the runner replica sets. + type: integer + desiredReplicas: + description: DesiredReplicas is the total number of desired, non-terminated and latest pods to be set for the primary RunnerSet This doesn't include outdated pods while upgrading the deployment and replacing the runnerset. + type: integer + readyReplicas: + description: ReadyReplicas is the total number of available runners which have been successfully registered to GitHub and still running. This corresponds to the sum of status.readyReplicas of all the runner replica sets. + type: integer + replicas: + description: Replicas is the total number of replicas + type: integer + updatedReplicas: + description: ReadyReplicas is the total number of available runners which have been successfully registered to GitHub and still running. This corresponds to status.replicas of the runner replica set that has the desired template hash. + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} + preserveUnknownFields: false +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/helm/actions-runner-controller/runner-deployment/dsk-agent-group.yaml b/helm/actions-runner-controller/runner-deployment/dsk-agent-group.yaml new file mode 100644 index 0000000..a9181d2 --- /dev/null +++ b/helm/actions-runner-controller/runner-deployment/dsk-agent-group.yaml @@ -0,0 +1,13 @@ +apiVersion: actions.summerwind.dev/v1alpha1 +kind: RunnerDeployment +metadata: + name: dsk-agent-group + namespace: actions-runner-system +spec: + replicas: 1 + template: + spec: + organization: cloudmoa + group: dsk-agent-group + labels: + - dsk-agent-group diff --git a/helm/actions-runner-controller/runner-deployment/dsk-devops-group.yaml b/helm/actions-runner-controller/runner-deployment/dsk-devops-group.yaml new file mode 100644 index 0000000..a4b46d0 --- /dev/null +++ b/helm/actions-runner-controller/runner-deployment/dsk-devops-group.yaml @@ -0,0 +1,13 @@ +apiVersion: actions.summerwind.dev/v1alpha1 +kind: RunnerDeployment +metadata: + name: dsk-devops-group + namespace: actions-runner-system +spec: + replicas: 1 + template: + spec: + organization: cloudmoa + group: dsk-devops-group + labels: + - dsk-devops-group diff --git a/helm/actions-runner-controller/runner-deployment/dsk-front-group.yaml b/helm/actions-runner-controller/runner-deployment/dsk-front-group.yaml new file mode 100644 index 0000000..5fe016b --- /dev/null +++ b/helm/actions-runner-controller/runner-deployment/dsk-front-group.yaml @@ -0,0 +1,13 @@ +apiVersion: actions.summerwind.dev/v1alpha1 +kind: RunnerDeployment +metadata: + name: dsk-front-group + namespace: actions-runner-system +spec: + replicas: 4 + template: + spec: + organization: cloudmoa + group: dsk-front-group + labels: + - dsk-front-group diff --git a/helm/actions-runner-controller/templates/NOTES.txt b/helm/actions-runner-controller/templates/NOTES.txt new file mode 100644 index 0000000..faf893f --- /dev/null +++ b/helm/actions-runner-controller/templates/NOTES.txt @@ -0,0 +1,22 @@ +1. Get the application URL by running these commands: +{{- if .Values.githubWebhookServer.ingress.enabled }} +{{- range $host := .Values.githubWebhookServer.ingress.hosts }} + {{- range .paths }} + http{{ if $.Values.githubWebhookServer.ingress.tls }}s{{ end }}://{{ $host.host }}{{ . }} + {{- 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 "actions-runner-controller.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 "actions-runner-controller.fullname" . }}' + export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "actions-runner-controller.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 "actions-runner-controller.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/helm/actions-runner-controller/templates/_actions_metrics_server_helpers.tpl b/helm/actions-runner-controller/templates/_actions_metrics_server_helpers.tpl new file mode 100644 index 0000000..13e8048 --- /dev/null +++ b/helm/actions-runner-controller/templates/_actions_metrics_server_helpers.tpl @@ -0,0 +1,60 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "actions-runner-controller-actions-metrics-server.name" -}} +{{- default .Chart.Name .Values.actionsMetricsServer.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{- define "actions-runner-controller-actions-metrics-server.instance" -}} +{{- printf "%s-%s" .Release.Name "actions-metrics-server" }} +{{- 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 "actions-runner-controller-actions-metrics-server.fullname" -}} +{{- if .Values.actionsMetricsServer.fullnameOverride }} +{{- .Values.actionsMetricsServer.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.actionsMetricsServer.nameOverride }} +{{- $instance := include "actions-runner-controller-actions-metrics-server.instance" . }} +{{- if contains $name $instance }} +{{- $instance | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s-%s" .Release.Name $name "actions-metrics-server" | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "actions-runner-controller-actions-metrics-server.selectorLabels" -}} +app.kubernetes.io/name: {{ include "actions-runner-controller-actions-metrics-server.name" . }} +app.kubernetes.io/instance: {{ include "actions-runner-controller-actions-metrics-server.instance" . }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "actions-runner-controller-actions-metrics-server.serviceAccountName" -}} +{{- if .Values.actionsMetricsServer.serviceAccount.create }} +{{- default (include "actions-runner-controller-actions-metrics-server.fullname" .) .Values.actionsMetricsServer.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.actionsMetricsServer.serviceAccount.name }} +{{- end }} +{{- end }} + +{{- define "actions-runner-controller-actions-metrics-server.secretName" -}} +{{- default (include "actions-runner-controller-actions-metrics-server.fullname" .) .Values.actionsMetricsServer.secret.name }} +{{- end }} + +{{- define "actions-runner-controller-actions-metrics-server.roleName" -}} +{{- include "actions-runner-controller-actions-metrics-server.fullname" . }} +{{- end }} + +{{- define "actions-runner-controller-actions-metrics-server.serviceMonitorName" -}} +{{- include "actions-runner-controller-actions-metrics-server.fullname" . | trunc 47 }}-service-monitor +{{- end }} diff --git a/helm/actions-runner-controller/templates/_github_webhook_server_helpers.tpl b/helm/actions-runner-controller/templates/_github_webhook_server_helpers.tpl new file mode 100644 index 0000000..3255b00 --- /dev/null +++ b/helm/actions-runner-controller/templates/_github_webhook_server_helpers.tpl @@ -0,0 +1,64 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "actions-runner-controller-github-webhook-server.name" -}} +{{- default .Chart.Name .Values.githubWebhookServer.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{- define "actions-runner-controller-github-webhook-server.instance" -}} +{{- printf "%s-%s" .Release.Name "github-webhook-server" }} +{{- 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 "actions-runner-controller-github-webhook-server.fullname" -}} +{{- if .Values.githubWebhookServer.fullnameOverride }} +{{- .Values.githubWebhookServer.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.githubWebhookServer.nameOverride }} +{{- $instance := include "actions-runner-controller-github-webhook-server.instance" . }} +{{- if contains $name $instance }} +{{- $instance | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s-%s" .Release.Name $name "github-webhook-server" | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "actions-runner-controller-github-webhook-server.selectorLabels" -}} +app.kubernetes.io/name: {{ include "actions-runner-controller-github-webhook-server.name" . }} +app.kubernetes.io/instance: {{ include "actions-runner-controller-github-webhook-server.instance" . }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "actions-runner-controller-github-webhook-server.serviceAccountName" -}} +{{- if .Values.githubWebhookServer.serviceAccount.create }} +{{- default (include "actions-runner-controller-github-webhook-server.fullname" .) .Values.githubWebhookServer.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.githubWebhookServer.serviceAccount.name }} +{{- end }} +{{- end }} + +{{- define "actions-runner-controller-github-webhook-server.secretName" -}} +{{- default (include "actions-runner-controller-github-webhook-server.fullname" .) .Values.githubWebhookServer.secret.name }} +{{- end }} + +{{- define "actions-runner-controller-github-webhook-server.roleName" -}} +{{- include "actions-runner-controller-github-webhook-server.fullname" . }} +{{- end }} + +{{- define "actions-runner-controller-github-webhook-server.serviceMonitorName" -}} +{{- include "actions-runner-controller-github-webhook-server.fullname" . | trunc 47 }}-service-monitor +{{- end }} + +{{- define "actions-runner-controller-github-webhook-server.pdbName" -}} +{{- include "actions-runner-controller-github-webhook-server.fullname" . | trunc 59 }}-pdb +{{- end }} \ No newline at end of file diff --git a/helm/actions-runner-controller/templates/_helpers.tpl b/helm/actions-runner-controller/templates/_helpers.tpl new file mode 100644 index 0000000..68570f0 --- /dev/null +++ b/helm/actions-runner-controller/templates/_helpers.tpl @@ -0,0 +1,117 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "actions-runner-controller.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 "actions-runner-controller.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 "actions-runner-controller.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "actions-runner-controller.labels" -}} +helm.sh/chart: {{ include "actions-runner-controller.chart" . }} +{{ include "actions-runner-controller.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- range $k, $v := .Values.labels }} +{{ $k }}: {{ $v }} +{{- end }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "actions-runner-controller.selectorLabels" -}} +app.kubernetes.io/name: {{ include "actions-runner-controller.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "actions-runner-controller.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "actions-runner-controller.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} + +{{- define "actions-runner-controller.secretName" -}} +{{- default (include "actions-runner-controller.fullname" .) .Values.authSecret.name -}} +{{- end }} + +{{- define "actions-runner-controller.githubWebhookServerSecretName" -}} +{{- default (include "actions-runner-controller.fullname" .) .Values.githubWebhookServer.secret.name -}} +{{- end }} + +{{- define "actions-runner-controller.leaderElectionRoleName" -}} +{{- include "actions-runner-controller.fullname" . }}-leader-election +{{- end }} + +{{- define "actions-runner-controller.authProxyRoleName" -}} +{{- include "actions-runner-controller.fullname" . }}-proxy +{{- end }} + +{{- define "actions-runner-controller.managerRoleName" -}} +{{- include "actions-runner-controller.fullname" . }}-manager +{{- end }} + +{{- define "actions-runner-controller.runnerEditorRoleName" -}} +{{- include "actions-runner-controller.fullname" . }}-runner-editor +{{- end }} + +{{- define "actions-runner-controller.runnerViewerRoleName" -}} +{{- include "actions-runner-controller.fullname" . }}-runner-viewer +{{- end }} + +{{- define "actions-runner-controller.webhookServiceName" -}} +{{- include "actions-runner-controller.fullname" . | trunc 55 }}-webhook +{{- end }} + +{{- define "actions-runner-controller.metricsServiceName" -}} +{{- include "actions-runner-controller.fullname" . | trunc 47 }}-metrics-service +{{- end }} + +{{- define "actions-runner-controller.serviceMonitorName" -}} +{{- include "actions-runner-controller.fullname" . | trunc 47 }}-service-monitor +{{- end }} + +{{- define "actions-runner-controller.selfsignedIssuerName" -}} +{{- include "actions-runner-controller.fullname" . }}-selfsigned-issuer +{{- end }} + +{{- define "actions-runner-controller.servingCertName" -}} +{{- include "actions-runner-controller.fullname" . }}-serving-cert +{{- end }} + +{{- define "actions-runner-controller.pdbName" -}} +{{- include "actions-runner-controller.fullname" . | trunc 59 }}-pdb +{{- end }} diff --git a/helm/actions-runner-controller/templates/actionsmetrics.deployment.yaml b/helm/actions-runner-controller/templates/actionsmetrics.deployment.yaml new file mode 100644 index 0000000..d7cb67b --- /dev/null +++ b/helm/actions-runner-controller/templates/actionsmetrics.deployment.yaml @@ -0,0 +1,168 @@ +{{- if .Values.actionsMetricsServer.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "actions-runner-controller-actions-metrics-server.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "actions-runner-controller.labels" . | nindent 4 }} +spec: + replicas: {{ .Values.actionsMetricsServer.replicaCount }} + selector: + matchLabels: + {{- include "actions-runner-controller-actions-metrics-server.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.actionsMetricsServer.podAnnotations }} + annotations: + kubectl.kubernetes.io/default-container: "actions-metrics-server" + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "actions-runner-controller-actions-metrics-server.selectorLabels" . | nindent 8 }} + {{- with .Values.actionsMetricsServer.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- with .Values.actionsMetricsServer.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "actions-runner-controller-actions-metrics-server.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.actionsMetricsServer.podSecurityContext | nindent 8 }} + {{- with .Values.actionsMetricsServer.priorityClassName }} + priorityClassName: "{{ . }}" + {{- end }} + containers: + - args: + {{- $metricsHost := .Values.metrics.proxy.enabled | ternary "127.0.0.1" "0.0.0.0" }} + {{- $metricsPort := .Values.metrics.proxy.enabled | ternary "8080" .Values.metrics.port }} + - "--metrics-addr={{ $metricsHost }}:{{ $metricsPort }}" + {{- if .Values.actionsMetricsServer.logLevel }} + - "--log-level={{ .Values.actionsMetricsServer.logLevel }}" + {{- end }} + {{- if .Values.runnerGithubURL }} + - "--runner-github-url={{ .Values.runnerGithubURL }}" + {{- end }} + {{- if .Values.actionsMetricsServer.logFormat }} + - "--log-format={{ .Values.actionsMetricsServer.logFormat }}" + {{- end }} + command: + - "/actions-metrics-server" + {{- if .Values.actionsMetricsServer.lifecycle }} + {{- with .Values.actionsMetricsServer.lifecycle }} + lifecycle: + {{- toYaml . | nindent 10 }} + {{- end }} + {{- end }} + env: + - name: GITHUB_WEBHOOK_SECRET_TOKEN + valueFrom: + secretKeyRef: + key: github_webhook_secret_token + name: {{ include "actions-runner-controller-actions-metrics-server.secretName" . }} + optional: true + {{- if .Values.githubEnterpriseServerURL }} + - name: GITHUB_ENTERPRISE_URL + value: {{ .Values.githubEnterpriseServerURL }} + {{- end }} + {{- if .Values.githubURL }} + - name: GITHUB_URL + value: {{ .Values.githubURL }} + {{- end }} + {{- if .Values.githubUploadURL }} + - name: GITHUB_UPLOAD_URL + value: {{ .Values.githubUploadURL }} + {{- end }} + {{- if .Values.actionsMetricsServer.secret.enabled }} + - name: GITHUB_TOKEN + valueFrom: + secretKeyRef: + key: github_token + name: {{ include "actions-runner-controller-actions-metrics-server.secretName" . }} + optional: true + - name: GITHUB_APP_ID + valueFrom: + secretKeyRef: + key: github_app_id + name: {{ include "actions-runner-controller-actions-metrics-server.secretName" . }} + optional: true + - name: GITHUB_APP_INSTALLATION_ID + valueFrom: + secretKeyRef: + key: github_app_installation_id + name: {{ include "actions-runner-controller-actions-metrics-server.secretName" . }} + optional: true + - name: GITHUB_APP_PRIVATE_KEY + valueFrom: + secretKeyRef: + key: github_app_private_key + name: {{ include "actions-runner-controller-actions-metrics-server.secretName" . }} + optional: true + {{- if .Values.authSecret.github_basicauth_username }} + - name: GITHUB_BASICAUTH_USERNAME + value: {{ .Values.authSecret.github_basicauth_username }} + {{- end }} + - name: GITHUB_BASICAUTH_PASSWORD + valueFrom: + secretKeyRef: + key: github_basicauth_password + name: {{ include "actions-runner-controller.secretName" . }} + optional: true + {{- end }} + {{- range $key, $val := .Values.actionsMetricsServer.env }} + - name: {{ $key }} + value: {{ $val | quote }} + {{- end }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default (cat "v" .Chart.AppVersion | replace " " "") }}" + name: actions-metrics-server + imagePullPolicy: {{ .Values.image.pullPolicy }} + ports: + - containerPort: 8000 + name: http + protocol: TCP + {{- if not .Values.metrics.proxy.enabled }} + - containerPort: {{ .Values.metrics.port }} + name: metrics-port + protocol: TCP + {{- end }} + resources: + {{- toYaml .Values.actionsMetricsServer.resources | nindent 12 }} + securityContext: + {{- toYaml .Values.actionsMetricsServer.securityContext | nindent 12 }} + {{- if .Values.metrics.proxy.enabled }} + - args: + - "--secure-listen-address=0.0.0.0:{{ .Values.metrics.port }}" + - "--upstream=http://127.0.0.1:8080/" + - "--logtostderr=true" + - "--v=10" + image: "{{ .Values.metrics.proxy.image.repository }}:{{ .Values.metrics.proxy.image.tag }}" + name: kube-rbac-proxy + imagePullPolicy: {{ .Values.image.pullPolicy }} + ports: + - containerPort: {{ .Values.metrics.port }} + name: metrics-port + resources: + {{- toYaml .Values.resources | nindent 12 }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + {{- end }} + terminationGracePeriodSeconds: {{ .Values.actionsMetricsServer.terminationGracePeriodSeconds }} + {{- with .Values.actionsMetricsServer.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.actionsMetricsServer.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.actionsMetricsServer.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.actionsMetricsServer.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} +{{- end }} diff --git a/helm/actions-runner-controller/templates/actionsmetrics.ingress.yaml.yml b/helm/actions-runner-controller/templates/actionsmetrics.ingress.yaml.yml new file mode 100644 index 0000000..5b54993 --- /dev/null +++ b/helm/actions-runner-controller/templates/actionsmetrics.ingress.yaml.yml @@ -0,0 +1,47 @@ +{{- if .Values.actionsMetricsServer.ingress.enabled -}} +{{- $fullName := include "actions-runner-controller-actions-metrics-server.fullname" . -}} +{{- $svcPort := (index .Values.actionsMetricsServer.service.ports 0).port -}} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ $fullName }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "actions-runner-controller.labels" . | nindent 4 }} + {{- with .Values.actionsMetricsServer.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if .Values.actionsMetricsServer.ingress.tls }} + tls: + {{- range .Values.actionsMetricsServer.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ . | quote }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} + {{- end }} + {{- with .Values.actionsMetricsServer.ingress.ingressClassName }} + ingressClassName: {{ . }} + {{- end }} + rules: + {{- range .Values.actionsMetricsServer.ingress.hosts }} + - host: {{ .host | quote }} + http: + paths: + {{- if .extraPaths }} + {{- toYaml .extraPaths | nindent 10 }} + {{- end }} + {{- range .paths }} + - path: {{ .path }} + pathType: {{ .pathType }} + backend: + service: + name: {{ $fullName }} + port: + number: {{ $svcPort }} + {{- end }} + {{- end }} + {{- end }} diff --git a/helm/actions-runner-controller/templates/actionsmetrics.role.yaml b/helm/actions-runner-controller/templates/actionsmetrics.role.yaml new file mode 100644 index 0000000..829bcf3 --- /dev/null +++ b/helm/actions-runner-controller/templates/actionsmetrics.role.yaml @@ -0,0 +1,90 @@ +{{- if .Values.actionsMetricsServer.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + creationTimestamp: null + name: {{ include "actions-runner-controller-actions-metrics-server.roleName" . }} +rules: +- apiGroups: + - actions.summerwind.dev + resources: + - horizontalrunnerautoscalers + verbs: + - get + - list + - patch + - update + - watch +- apiGroups: + - actions.summerwind.dev + resources: + - horizontalrunnerautoscalers/finalizers + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - actions.summerwind.dev + resources: + - horizontalrunnerautoscalers/status + verbs: + - get + - patch + - update +- apiGroups: + - actions.summerwind.dev + resources: + - runnersets + verbs: + - get + - list + - watch +- apiGroups: + - actions.summerwind.dev + resources: + - runnerdeployments + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - actions.summerwind.dev + resources: + - runnerdeployments/finalizers + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - actions.summerwind.dev + resources: + - runnerdeployments/status + verbs: + - get + - patch + - update +- apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create +- apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create +{{- end }} diff --git a/helm/actions-runner-controller/templates/actionsmetrics.role_binding.yaml b/helm/actions-runner-controller/templates/actionsmetrics.role_binding.yaml new file mode 100644 index 0000000..0b64ed5 --- /dev/null +++ b/helm/actions-runner-controller/templates/actionsmetrics.role_binding.yaml @@ -0,0 +1,14 @@ +{{- if .Values.actionsMetricsServer.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "actions-runner-controller-actions-metrics-server.roleName" . }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ include "actions-runner-controller-actions-metrics-server.roleName" . }} +subjects: + - kind: ServiceAccount + name: {{ include "actions-runner-controller-actions-metrics-server.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +{{- end }} diff --git a/helm/actions-runner-controller/templates/actionsmetrics.secrets.yaml b/helm/actions-runner-controller/templates/actionsmetrics.secrets.yaml new file mode 100644 index 0000000..a7128b4 --- /dev/null +++ b/helm/actions-runner-controller/templates/actionsmetrics.secrets.yaml @@ -0,0 +1,28 @@ +{{- if .Values.actionsMetricsServer.enabled }} +{{- if .Values.actionsMetricsServer.secret.create }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "actions-runner-controller-actions-metrics-server.secretName" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "actions-runner-controller.labels" . | nindent 4 }} +type: Opaque +data: +{{- if .Values.actionsMetricsServer.secret.github_webhook_secret_token }} + github_webhook_secret_token: {{ .Values.actionsMetricsServer.secret.github_webhook_secret_token | toString | b64enc }} +{{- end }} +{{- if .Values.actionsMetricsServer.secret.github_app_id }} + github_app_id: {{ .Values.actionsMetricsServer.secret.github_app_id | toString | b64enc }} +{{- end }} +{{- if .Values.actionsMetricsServer.secret.github_app_installation_id }} + github_app_installation_id: {{ .Values.actionsMetricsServer.secret.github_app_installation_id | toString | b64enc }} +{{- end }} +{{- if .Values.actionsMetricsServer.secret.github_app_private_key }} + github_app_private_key: {{ .Values.actionsMetricsServer.secret.github_app_private_key | toString | b64enc }} +{{- end }} +{{- if .Values.actionsMetricsServer.secret.github_token }} + github_token: {{ .Values.actionsMetricsServer.secret.github_token | toString | b64enc }} +{{- end }} +{{- end }} +{{- end }} diff --git a/helm/actions-runner-controller/templates/actionsmetrics.service.yaml b/helm/actions-runner-controller/templates/actionsmetrics.service.yaml new file mode 100644 index 0000000..0cfae32 --- /dev/null +++ b/helm/actions-runner-controller/templates/actionsmetrics.service.yaml @@ -0,0 +1,32 @@ +{{- if .Values.actionsMetricsServer.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "actions-runner-controller-actions-metrics-server.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "actions-runner-controller-actions-metrics-server.selectorLabels" . | nindent 4 }} +{{- if .Values.actionsMetricsServer.service.annotations }} + annotations: + {{ toYaml .Values.actionsMetricsServer.service.annotations | nindent 4 }} +{{- end }} +spec: + type: {{ .Values.actionsMetricsServer.service.type }} + ports: + {{ range $_, $port := .Values.actionsMetricsServer.service.ports -}} + - {{ $port | toYaml | nindent 6 }} + {{- end }} + {{- if .Values.metrics.serviceMonitor }} + - name: metrics-port + port: {{ .Values.metrics.port }} + targetPort: metrics-port + {{- end }} + selector: + {{- include "actions-runner-controller-actions-metrics-server.selectorLabels" . | nindent 4 }} + {{- if .Values.actionsMetricsServer.service.loadBalancerSourceRanges }} + loadBalancerSourceRanges: + {{- range $ip := .Values.actionsMetricsServer.service.loadBalancerSourceRanges }} + - {{ $ip -}} + {{- end }} + {{- end }} +{{- end }} diff --git a/helm/actions-runner-controller/templates/actionsmetrics.serviceaccount.yaml.yml b/helm/actions-runner-controller/templates/actionsmetrics.serviceaccount.yaml.yml new file mode 100644 index 0000000..9ab1afc --- /dev/null +++ b/helm/actions-runner-controller/templates/actionsmetrics.serviceaccount.yaml.yml @@ -0,0 +1,15 @@ +{{- if .Values.actionsMetricsServer.enabled -}} +{{- if .Values.actionsMetricsServer.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "actions-runner-controller-actions-metrics-server.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "actions-runner-controller.labels" . | nindent 4 }} + {{- with .Values.actionsMetricsServer.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} +{{- end }} diff --git a/helm/actions-runner-controller/templates/actionsmetrics.servicemonitor.yaml.yml b/helm/actions-runner-controller/templates/actionsmetrics.servicemonitor.yaml.yml new file mode 100644 index 0000000..25e72f1 --- /dev/null +++ b/helm/actions-runner-controller/templates/actionsmetrics.servicemonitor.yaml.yml @@ -0,0 +1,25 @@ +{{- if and .Values.actionsMetricsServer.enabled .Values.actionsMetrics.serviceMonitor }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + labels: + {{- include "actions-runner-controller.labels" . | nindent 4 }} + {{- with .Values.actionsMetricsServer.serviceMonitorLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ include "actions-runner-controller-actions-metrics-server.serviceMonitorName" . }} + namespace: {{ .Release.Namespace }} +spec: + endpoints: + - path: /metrics + port: metrics-port + {{- if .Values.actionsMetrics.proxy.enabled }} + bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token + scheme: https + tlsConfig: + insecureSkipVerify: true + {{- end }} + selector: + matchLabels: + {{- include "actions-runner-controller-actions-metrics-server.selectorLabels" . | nindent 6 }} +{{- end }} diff --git a/helm/actions-runner-controller/templates/auth_proxy_role.yaml b/helm/actions-runner-controller/templates/auth_proxy_role.yaml new file mode 100644 index 0000000..24f0ce5 --- /dev/null +++ b/helm/actions-runner-controller/templates/auth_proxy_role.yaml @@ -0,0 +1,15 @@ +{{- if .Values.metrics.proxy.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "actions-runner-controller.authProxyRoleName" . }} +rules: +- apiGroups: ["authentication.k8s.io"] + resources: + - tokenreviews + verbs: ["create"] +- apiGroups: ["authorization.k8s.io"] + resources: + - subjectaccessreviews + verbs: ["create"] +{{- end }} diff --git a/helm/actions-runner-controller/templates/auth_proxy_role_binding.yaml b/helm/actions-runner-controller/templates/auth_proxy_role_binding.yaml new file mode 100644 index 0000000..b3061f7 --- /dev/null +++ b/helm/actions-runner-controller/templates/auth_proxy_role_binding.yaml @@ -0,0 +1,14 @@ +{{- if .Values.metrics.proxy.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "actions-runner-controller.authProxyRoleName" . }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ include "actions-runner-controller.authProxyRoleName" . }} +subjects: +- kind: ServiceAccount + name: {{ include "actions-runner-controller.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +{{- end }} diff --git a/helm/actions-runner-controller/templates/certificate.yaml b/helm/actions-runner-controller/templates/certificate.yaml new file mode 100644 index 0000000..25ddfa0 --- /dev/null +++ b/helm/actions-runner-controller/templates/certificate.yaml @@ -0,0 +1,26 @@ +{{- if .Values.certManagerEnabled }} +# The following manifests contain a self-signed issuer CR and a certificate CR. +# More document can be found at https://docs.cert-manager.io +# WARNING: Targets CertManager 0.11 check https://docs.cert-manager.io/en/latest/tasks/upgrading/index.html for breaking changes +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: {{ include "actions-runner-controller.selfsignedIssuerName" . }} + namespace: {{ .Release.Namespace }} +spec: + selfSigned: {} +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: {{ include "actions-runner-controller.servingCertName" . }} + namespace: {{ .Release.Namespace }} +spec: + dnsNames: + - {{ include "actions-runner-controller.webhookServiceName" . }}.{{ .Release.Namespace }}.svc + - {{ include "actions-runner-controller.webhookServiceName" . }}.{{ .Release.Namespace }}.svc.cluster.local + issuerRef: + kind: Issuer + name: {{ include "actions-runner-controller.selfsignedIssuerName" . }} + secretName: {{ include "actions-runner-controller.servingCertName" . }} +{{- end }} diff --git a/helm/actions-runner-controller/templates/ci-secret.yaml b/helm/actions-runner-controller/templates/ci-secret.yaml new file mode 100644 index 0000000..2e3154c --- /dev/null +++ b/helm/actions-runner-controller/templates/ci-secret.yaml @@ -0,0 +1,14 @@ +# This template only exists to facilitate CI testing of the chart, since +# a secret is expected to be found in the namespace by the controller manager +{{ if .Values.createDummySecret -}} +apiVersion: v1 +data: + github_token: dGVzdA== +kind: Secret +metadata: + name: controller-manager + {{- if .Values.authSecret.annotations }} + annotations: + {{ toYaml .Values.authSecret.annotations | nindent 4 }} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/helm/actions-runner-controller/templates/controller.metrics.service.yaml b/helm/actions-runner-controller/templates/controller.metrics.service.yaml new file mode 100644 index 0000000..1dc422b --- /dev/null +++ b/helm/actions-runner-controller/templates/controller.metrics.service.yaml @@ -0,0 +1,18 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + {{- include "actions-runner-controller.labels" . | nindent 4 }} + name: {{ include "actions-runner-controller.metricsServiceName" . }} + namespace: {{ .Release.Namespace }} + {{- with .Values.metrics.serviceAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + ports: + - name: metrics-port + port: {{ .Values.metrics.port }} + targetPort: metrics-port + selector: + {{- include "actions-runner-controller.selectorLabels" . | nindent 4 }} diff --git a/helm/actions-runner-controller/templates/controller.metrics.serviceMonitor.yaml b/helm/actions-runner-controller/templates/controller.metrics.serviceMonitor.yaml new file mode 100644 index 0000000..07b2f3b --- /dev/null +++ b/helm/actions-runner-controller/templates/controller.metrics.serviceMonitor.yaml @@ -0,0 +1,25 @@ +{{- if .Values.metrics.serviceMonitor }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + labels: + {{- include "actions-runner-controller.labels" . | nindent 4 }} + {{- with .Values.metrics.serviceMonitorLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ include "actions-runner-controller.serviceMonitorName" . }} + namespace: {{ .Release.Namespace }} +spec: + endpoints: + - path: /metrics + port: metrics-port + {{- if .Values.metrics.proxy.enabled }} + bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token + scheme: https + tlsConfig: + insecureSkipVerify: true + {{- end }} + selector: + matchLabels: + {{- include "actions-runner-controller.selectorLabels" . | nindent 6 }} +{{- end }} diff --git a/helm/actions-runner-controller/templates/controller.pdb.yaml b/helm/actions-runner-controller/templates/controller.pdb.yaml new file mode 100644 index 0000000..6831c4d --- /dev/null +++ b/helm/actions-runner-controller/templates/controller.pdb.yaml @@ -0,0 +1,19 @@ +{{- if .Values.podDisruptionBudget.enabled }} +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + labels: + {{- include "actions-runner-controller.labels" . | nindent 4 }} + name: {{ include "actions-runner-controller.pdbName" . }} + namespace: {{ .Release.Namespace }} +spec: + {{- if .Values.podDisruptionBudget.minAvailable }} + minAvailable: {{ .Values.podDisruptionBudget.minAvailable }} + {{- end }} + {{- if .Values.podDisruptionBudget.maxUnavailable }} + maxUnavailable: {{ .Values.podDisruptionBudget.maxUnavailable }} + {{- end }} + selector: + matchLabels: + {{- include "actions-runner-controller.selectorLabels" . | nindent 6 }} +{{- end -}} diff --git a/helm/actions-runner-controller/templates/deployment.yaml b/helm/actions-runner-controller/templates/deployment.yaml new file mode 100644 index 0000000..020e966 --- /dev/null +++ b/helm/actions-runner-controller/templates/deployment.yaml @@ -0,0 +1,213 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "actions-runner-controller.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "actions-runner-controller.labels" . | nindent 4 }} +spec: + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: + {{- include "actions-runner-controller.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + kubectl.kubernetes.io/default-logs-container: "manager" + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "actions-runner-controller.selectorLabels" . | nindent 8 }} + {{- with .Values.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "actions-runner-controller.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + {{- with .Values.priorityClassName }} + priorityClassName: "{{ . }}" + {{- end }} + containers: + - args: + {{- $metricsHost := .Values.metrics.proxy.enabled | ternary "127.0.0.1" "0.0.0.0" }} + {{- $metricsPort := .Values.metrics.proxy.enabled | ternary "8080" .Values.metrics.port }} + - "--metrics-addr={{ $metricsHost }}:{{ $metricsPort }}" + {{- if .Values.enableLeaderElection }} + - "--enable-leader-election" + {{- end }} + {{- if .Values.leaderElectionId }} + - "--leader-election-id={{ .Values.leaderElectionId }}" + {{- end }} + - "--port={{ .Values.webhookPort }}" + - "--sync-period={{ .Values.syncPeriod }}" + - "--default-scale-down-delay={{ .Values.defaultScaleDownDelay }}" + - "--docker-image={{ .Values.image.dindSidecarRepositoryAndTag }}" + - "--runner-image={{ .Values.image.actionsRunnerRepositoryAndTag }}" + {{- range .Values.image.actionsRunnerImagePullSecrets }} + - "--runner-image-pull-secret={{ . }}" + {{- end }} + {{- if .Values.dockerRegistryMirror }} + - "--docker-registry-mirror={{ .Values.dockerRegistryMirror }}" + {{- end }} + {{- if .Values.scope.singleNamespace }} + - "--watch-namespace={{ default .Release.Namespace .Values.scope.watchNamespace }}" + {{- end }} + {{- if .Values.logLevel }} + - "--log-level={{ .Values.logLevel }}" + {{- end }} + {{- if .Values.runnerGithubURL }} + - "--runner-github-url={{ .Values.runnerGithubURL }}" + {{- end }} + {{- if .Values.runner.statusUpdateHook.enabled }} + - "--runner-status-update-hook" + {{- end }} + {{- if .Values.logFormat }} + - "--log-format={{ .Values.logFormat }}" + {{- end }} + command: + - "/manager" + env: + {{- if .Values.githubEnterpriseServerURL }} + - name: GITHUB_ENTERPRISE_URL + value: {{ .Values.githubEnterpriseServerURL }} + {{- end }} + {{- if .Values.githubURL }} + - name: GITHUB_URL + value: {{ .Values.githubURL }} + {{- end }} + {{- if .Values.githubUploadURL }} + - name: GITHUB_UPLOAD_URL + value: {{ .Values.githubUploadURL }} + {{- end }} + {{- if .Values.authSecret.enabled }} + - name: GITHUB_TOKEN + valueFrom: + secretKeyRef: + key: github_token + name: {{ include "actions-runner-controller.secretName" . }} + optional: true + - name: GITHUB_APP_ID + valueFrom: + secretKeyRef: + key: github_app_id + name: {{ include "actions-runner-controller.secretName" . }} + optional: true + - name: GITHUB_APP_INSTALLATION_ID + valueFrom: + secretKeyRef: + key: github_app_installation_id + name: {{ include "actions-runner-controller.secretName" . }} + optional: true + - name: GITHUB_APP_PRIVATE_KEY + valueFrom: + secretKeyRef: + key: github_app_private_key + name: {{ include "actions-runner-controller.secretName" . }} + optional: true + {{- if .Values.authSecret.github_basicauth_username }} + - name: GITHUB_BASICAUTH_USERNAME + value: {{ .Values.authSecret.github_basicauth_username }} + {{- end }} + - name: GITHUB_BASICAUTH_PASSWORD + valueFrom: + secretKeyRef: + key: github_basicauth_password + name: {{ include "actions-runner-controller.secretName" . }} + optional: true + {{- end }} + {{- if kindIs "slice" .Values.env }} + {{- toYaml .Values.env | nindent 8 }} + {{- else }} + {{- range $key, $val := .Values.env }} + - name: {{ $key }} + value: {{ $val | quote }} + {{- end }} + {{- end }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default (cat "v" .Chart.AppVersion | replace " " "") }}" + name: manager + imagePullPolicy: {{ .Values.image.pullPolicy }} + ports: + - containerPort: {{ .Values.webhookPort }} + name: webhook-server + protocol: TCP + {{- if not .Values.metrics.proxy.enabled }} + - containerPort: {{ .Values.metrics.port }} + name: metrics-port + protocol: TCP + {{- end }} + resources: + {{- toYaml .Values.resources | nindent 12 }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + volumeMounts: + {{- if .Values.authSecret.enabled }} + - mountPath: "/etc/actions-runner-controller" + name: secret + readOnly: true + {{- end }} + - mountPath: /tmp + name: tmp + - mountPath: /tmp/k8s-webhook-server/serving-certs + name: cert + readOnly: true + {{- if .Values.additionalVolumeMounts }} + {{- toYaml .Values.additionalVolumeMounts | nindent 8 }} + {{- end }} + {{- if .Values.metrics.proxy.enabled }} + - args: + - "--secure-listen-address=0.0.0.0:{{ .Values.metrics.port }}" + - "--upstream=http://127.0.0.1:8080/" + - "--logtostderr=true" + - "--v=10" + image: "{{ .Values.metrics.proxy.image.repository }}:{{ .Values.metrics.proxy.image.tag }}" + name: kube-rbac-proxy + imagePullPolicy: {{ .Values.image.pullPolicy }} + ports: + - containerPort: {{ .Values.metrics.port }} + name: metrics-port + resources: + {{- toYaml .Values.resources | nindent 12 }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + {{- end }} + terminationGracePeriodSeconds: 10 + volumes: + {{- if .Values.authSecret.enabled }} + - name: secret + secret: + secretName: {{ include "actions-runner-controller.secretName" . }} + {{- end }} + - name: cert + secret: + defaultMode: 420 + secretName: {{ include "actions-runner-controller.servingCertName" . }} + - name: tmp + emptyDir: {} + {{- if .Values.additionalVolumes }} + {{- toYaml .Values.additionalVolumes | nindent 6}} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.hostNetwork }} + hostNetwork: {{ .Values.hostNetwork }} + {{- end }} diff --git a/helm/actions-runner-controller/templates/githubwebhook.deployment.yaml b/helm/actions-runner-controller/templates/githubwebhook.deployment.yaml new file mode 100644 index 0000000..d778cba --- /dev/null +++ b/helm/actions-runner-controller/templates/githubwebhook.deployment.yaml @@ -0,0 +1,178 @@ +{{- if .Values.githubWebhookServer.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "actions-runner-controller-github-webhook-server.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "actions-runner-controller.labels" . | nindent 4 }} +spec: + replicas: {{ .Values.githubWebhookServer.replicaCount }} + selector: + matchLabels: + {{- include "actions-runner-controller-github-webhook-server.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.githubWebhookServer.podAnnotations }} + annotations: + kubectl.kubernetes.io/default-logs-container: "github-webhook-server" + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "actions-runner-controller-github-webhook-server.selectorLabels" . | nindent 8 }} + {{- with .Values.githubWebhookServer.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- with .Values.githubWebhookServer.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "actions-runner-controller-github-webhook-server.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.githubWebhookServer.podSecurityContext | nindent 8 }} + {{- with .Values.githubWebhookServer.priorityClassName }} + priorityClassName: "{{ . }}" + {{- end }} + containers: + - args: + {{- $metricsHost := .Values.metrics.proxy.enabled | ternary "127.0.0.1" "0.0.0.0" }} + {{- $metricsPort := .Values.metrics.proxy.enabled | ternary "8080" .Values.metrics.port }} + - "--metrics-addr={{ $metricsHost }}:{{ $metricsPort }}" + {{- if .Values.githubWebhookServer.logLevel }} + - "--log-level={{ .Values.githubWebhookServer.logLevel }}" + {{- end }} + {{- if .Values.scope.singleNamespace }} + - "--watch-namespace={{ default .Release.Namespace .Values.scope.watchNamespace }}" + {{- end }} + {{- if .Values.runnerGithubURL }} + - "--runner-github-url={{ .Values.runnerGithubURL }}" + {{- end }} + {{- if .Values.githubWebhookServer.queueLimit }} + - "--queue-limit={{ .Values.githubWebhookServer.queueLimit }}" + {{- end }} + {{- if .Values.githubWebhookServer.logFormat }} + - "--log-format={{ .Values.githubWebhookServer.logFormat }}" + {{- end }} + command: + - "/github-webhook-server" + {{- if .Values.githubWebhookServer.lifecycle }} + {{- with .Values.githubWebhookServer.lifecycle }} + lifecycle: + {{- toYaml . | nindent 10 }} + {{- end }} + {{- end }} + env: + - name: GITHUB_WEBHOOK_SECRET_TOKEN + valueFrom: + secretKeyRef: + key: github_webhook_secret_token + name: {{ include "actions-runner-controller-github-webhook-server.secretName" . }} + optional: true + {{- if .Values.githubEnterpriseServerURL }} + - name: GITHUB_ENTERPRISE_URL + value: {{ .Values.githubEnterpriseServerURL }} + {{- end }} + {{- if .Values.githubURL }} + - name: GITHUB_URL + value: {{ .Values.githubURL }} + {{- end }} + {{- if .Values.githubUploadURL }} + - name: GITHUB_UPLOAD_URL + value: {{ .Values.githubUploadURL }} + {{- end }} + {{- if and .Values.githubWebhookServer.useRunnerGroupsVisibility .Values.githubWebhookServer.secret.enabled }} + - name: GITHUB_TOKEN + valueFrom: + secretKeyRef: + key: github_token + name: {{ include "actions-runner-controller.githubWebhookServerSecretName" . }} + optional: true + - name: GITHUB_APP_ID + valueFrom: + secretKeyRef: + key: github_app_id + name: {{ include "actions-runner-controller.githubWebhookServerSecretName" . }} + optional: true + - name: GITHUB_APP_INSTALLATION_ID + valueFrom: + secretKeyRef: + key: github_app_installation_id + name: {{ include "actions-runner-controller.githubWebhookServerSecretName" . }} + optional: true + - name: GITHUB_APP_PRIVATE_KEY + valueFrom: + secretKeyRef: + key: github_app_private_key + name: {{ include "actions-runner-controller.githubWebhookServerSecretName" . }} + optional: true + {{- if .Values.authSecret.github_basicauth_username }} + - name: GITHUB_BASICAUTH_USERNAME + value: {{ .Values.authSecret.github_basicauth_username }} + {{- end }} + - name: GITHUB_BASICAUTH_PASSWORD + valueFrom: + secretKeyRef: + key: github_basicauth_password + name: {{ include "actions-runner-controller.secretName" . }} + optional: true + {{- end }} + {{- if kindIs "slice" .Values.githubWebhookServer.env }} + {{- toYaml .Values.githubWebhookServer.env | nindent 8 }} + {{- else }} + {{- range $key, $val := .Values.githubWebhookServer.env }} + - name: {{ $key }} + value: {{ $val | quote }} + {{- end }} + {{- end }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default (cat "v" .Chart.AppVersion | replace " " "") }}" + name: github-webhook-server + imagePullPolicy: {{ .Values.image.pullPolicy }} + ports: + - containerPort: 8000 + name: http + protocol: TCP + {{- if not .Values.metrics.proxy.enabled }} + - containerPort: {{ .Values.metrics.port }} + name: metrics-port + protocol: TCP + {{- end }} + resources: + {{- toYaml .Values.githubWebhookServer.resources | nindent 12 }} + securityContext: + {{- toYaml .Values.githubWebhookServer.securityContext | nindent 12 }} + {{- if .Values.metrics.proxy.enabled }} + - args: + - "--secure-listen-address=0.0.0.0:{{ .Values.metrics.port }}" + - "--upstream=http://127.0.0.1:8080/" + - "--logtostderr=true" + - "--v=10" + image: "{{ .Values.metrics.proxy.image.repository }}:{{ .Values.metrics.proxy.image.tag }}" + name: kube-rbac-proxy + imagePullPolicy: {{ .Values.image.pullPolicy }} + ports: + - containerPort: {{ .Values.metrics.port }} + name: metrics-port + resources: + {{- toYaml .Values.resources | nindent 12 }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + {{- end }} + terminationGracePeriodSeconds: {{ .Values.githubWebhookServer.terminationGracePeriodSeconds }} + {{- with .Values.githubWebhookServer.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.githubWebhookServer.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.githubWebhookServer.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.githubWebhookServer.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} +{{- end }} diff --git a/helm/actions-runner-controller/templates/githubwebhook.ingress.yaml b/helm/actions-runner-controller/templates/githubwebhook.ingress.yaml new file mode 100644 index 0000000..48baa76 --- /dev/null +++ b/helm/actions-runner-controller/templates/githubwebhook.ingress.yaml @@ -0,0 +1,47 @@ +{{- if .Values.githubWebhookServer.ingress.enabled -}} +{{- $fullName := include "actions-runner-controller-github-webhook-server.fullname" . -}} +{{- $svcPort := (index .Values.githubWebhookServer.service.ports 0).port -}} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ $fullName }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "actions-runner-controller.labels" . | nindent 4 }} + {{- with .Values.githubWebhookServer.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if .Values.githubWebhookServer.ingress.tls }} + tls: + {{- range .Values.githubWebhookServer.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ . | quote }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} + {{- end }} + {{- with .Values.githubWebhookServer.ingress.ingressClassName }} + ingressClassName: {{ . }} + {{- end }} + rules: + {{- range .Values.githubWebhookServer.ingress.hosts }} + - host: {{ .host | quote }} + http: + paths: + {{- if .extraPaths }} + {{- toYaml .extraPaths | nindent 10 }} + {{- end }} + {{- range .paths }} + - path: {{ .path }} + pathType: {{ .pathType }} + backend: + service: + name: {{ $fullName }} + port: + number: {{ $svcPort }} + {{- end }} + {{- end }} + {{- end }} diff --git a/helm/actions-runner-controller/templates/githubwebhook.pdb.yaml b/helm/actions-runner-controller/templates/githubwebhook.pdb.yaml new file mode 100644 index 0000000..cb8d530 --- /dev/null +++ b/helm/actions-runner-controller/templates/githubwebhook.pdb.yaml @@ -0,0 +1,19 @@ +{{- if .Values.githubWebhookServer.podDisruptionBudget.enabled }} +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + labels: + {{- include "actions-runner-controller.labels" . | nindent 4 }} + name: {{ include "actions-runner-controller-github-webhook-server.pdbName" . }} + namespace: {{ .Release.Namespace }} +spec: + {{- if .Values.githubWebhookServer.podDisruptionBudget.minAvailable }} + minAvailable: {{ .Values.githubWebhookServer.podDisruptionBudget.minAvailable }} + {{- end }} + {{- if .Values.githubWebhookServer.podDisruptionBudget.maxUnavailable }} + maxUnavailable: {{ .Values.githubWebhookServer.podDisruptionBudget.maxUnavailable }} + {{- end }} + selector: + matchLabels: + {{- include "actions-runner-controller-github-webhook-server.selectorLabels" . | nindent 6 }} +{{- end -}} diff --git a/helm/actions-runner-controller/templates/githubwebhook.role.yaml b/helm/actions-runner-controller/templates/githubwebhook.role.yaml new file mode 100644 index 0000000..e175a45 --- /dev/null +++ b/helm/actions-runner-controller/templates/githubwebhook.role.yaml @@ -0,0 +1,90 @@ +{{- if .Values.githubWebhookServer.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + creationTimestamp: null + name: {{ include "actions-runner-controller-github-webhook-server.roleName" . }} +rules: +- apiGroups: + - actions.summerwind.dev + resources: + - horizontalrunnerautoscalers + verbs: + - get + - list + - patch + - update + - watch +- apiGroups: + - actions.summerwind.dev + resources: + - horizontalrunnerautoscalers/finalizers + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - actions.summerwind.dev + resources: + - horizontalrunnerautoscalers/status + verbs: + - get + - patch + - update +- apiGroups: + - actions.summerwind.dev + resources: + - runnersets + verbs: + - get + - list + - watch +- apiGroups: + - actions.summerwind.dev + resources: + - runnerdeployments + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - actions.summerwind.dev + resources: + - runnerdeployments/finalizers + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - actions.summerwind.dev + resources: + - runnerdeployments/status + verbs: + - get + - patch + - update +- apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create +- apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create +{{- end }} diff --git a/helm/actions-runner-controller/templates/githubwebhook.role_binding.yaml b/helm/actions-runner-controller/templates/githubwebhook.role_binding.yaml new file mode 100644 index 0000000..24a6945 --- /dev/null +++ b/helm/actions-runner-controller/templates/githubwebhook.role_binding.yaml @@ -0,0 +1,14 @@ +{{- if .Values.githubWebhookServer.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "actions-runner-controller-github-webhook-server.roleName" . }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ include "actions-runner-controller-github-webhook-server.roleName" . }} +subjects: + - kind: ServiceAccount + name: {{ include "actions-runner-controller-github-webhook-server.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +{{- end }} diff --git a/helm/actions-runner-controller/templates/githubwebhook.secrets.yaml b/helm/actions-runner-controller/templates/githubwebhook.secrets.yaml new file mode 100644 index 0000000..e1fbc28 --- /dev/null +++ b/helm/actions-runner-controller/templates/githubwebhook.secrets.yaml @@ -0,0 +1,28 @@ +{{- if .Values.githubWebhookServer.enabled }} +{{- if .Values.githubWebhookServer.secret.create }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "actions-runner-controller-github-webhook-server.secretName" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "actions-runner-controller.labels" . | nindent 4 }} +type: Opaque +data: +{{- if .Values.githubWebhookServer.secret.github_webhook_secret_token }} + github_webhook_secret_token: {{ .Values.githubWebhookServer.secret.github_webhook_secret_token | toString | b64enc }} +{{- end }} +{{- if .Values.githubWebhookServer.secret.github_app_id }} + github_app_id: {{ .Values.githubWebhookServer.secret.github_app_id | toString | b64enc }} +{{- end }} +{{- if .Values.githubWebhookServer.secret.github_app_installation_id }} + github_app_installation_id: {{ .Values.githubWebhookServer.secret.github_app_installation_id | toString | b64enc }} +{{- end }} +{{- if .Values.githubWebhookServer.secret.github_app_private_key }} + github_app_private_key: {{ .Values.githubWebhookServer.secret.github_app_private_key | toString | b64enc }} +{{- end }} +{{- if .Values.githubWebhookServer.secret.github_token }} + github_token: {{ .Values.githubWebhookServer.secret.github_token | toString | b64enc }} +{{- end }} +{{- end }} +{{- end }} diff --git a/helm/actions-runner-controller/templates/githubwebhook.service.yaml b/helm/actions-runner-controller/templates/githubwebhook.service.yaml new file mode 100644 index 0000000..99a7ea2 --- /dev/null +++ b/helm/actions-runner-controller/templates/githubwebhook.service.yaml @@ -0,0 +1,32 @@ +{{- if .Values.githubWebhookServer.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "actions-runner-controller-github-webhook-server.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "actions-runner-controller.labels" . | nindent 4 }} +{{- if .Values.githubWebhookServer.service.annotations }} + annotations: + {{ toYaml .Values.githubWebhookServer.service.annotations | nindent 4 }} +{{- end }} +spec: + type: {{ .Values.githubWebhookServer.service.type }} + ports: + {{ range $_, $port := .Values.githubWebhookServer.service.ports -}} + - {{ $port | toYaml | nindent 6 }} + {{- end }} + {{- if .Values.metrics.serviceMonitor }} + - name: metrics-port + port: {{ .Values.metrics.port }} + targetPort: metrics-port + {{- end }} + selector: + {{- include "actions-runner-controller-github-webhook-server.selectorLabels" . | nindent 4 }} + {{- if .Values.githubWebhookServer.service.loadBalancerSourceRanges }} + loadBalancerSourceRanges: + {{- range $ip := .Values.githubWebhookServer.service.loadBalancerSourceRanges }} + - {{ $ip -}} + {{- end }} + {{- end }} +{{- end }} diff --git a/helm/actions-runner-controller/templates/githubwebhook.serviceMonitor.yaml b/helm/actions-runner-controller/templates/githubwebhook.serviceMonitor.yaml new file mode 100644 index 0000000..f659cc4 --- /dev/null +++ b/helm/actions-runner-controller/templates/githubwebhook.serviceMonitor.yaml @@ -0,0 +1,25 @@ +{{- if and .Values.githubWebhookServer.enabled .Values.metrics.serviceMonitor }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + labels: + {{- include "actions-runner-controller.labels" . | nindent 4 }} + {{- with .Values.metrics.serviceMonitorLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ include "actions-runner-controller-github-webhook-server.serviceMonitorName" . }} + namespace: {{ .Release.Namespace }} +spec: + endpoints: + - path: /metrics + port: metrics-port + {{- if .Values.metrics.proxy.enabled }} + bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token + scheme: https + tlsConfig: + insecureSkipVerify: true + {{- end }} + selector: + matchLabels: + {{- include "actions-runner-controller-github-webhook-server.selectorLabels" . | nindent 6 }} +{{- end }} diff --git a/helm/actions-runner-controller/templates/githubwebhook.serviceaccount.yaml b/helm/actions-runner-controller/templates/githubwebhook.serviceaccount.yaml new file mode 100644 index 0000000..e7db91a --- /dev/null +++ b/helm/actions-runner-controller/templates/githubwebhook.serviceaccount.yaml @@ -0,0 +1,15 @@ +{{- if .Values.githubWebhookServer.enabled -}} +{{- if .Values.githubWebhookServer.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "actions-runner-controller-github-webhook-server.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "actions-runner-controller.labels" . | nindent 4 }} + {{- with .Values.githubWebhookServer.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} +{{- end }} diff --git a/helm/actions-runner-controller/templates/leader_election_role.yaml b/helm/actions-runner-controller/templates/leader_election_role.yaml new file mode 100644 index 0000000..9a2890c --- /dev/null +++ b/helm/actions-runner-controller/templates/leader_election_role.yaml @@ -0,0 +1,33 @@ +# permissions to do leader election. +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ include "actions-runner-controller.leaderElectionRoleName" . }} + namespace: {{ .Release.Namespace }} +rules: +- apiGroups: + - "" + resources: + - configmaps + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - "" + resources: + - configmaps/status + verbs: + - get + - update + - patch +- apiGroups: + - "" + resources: + - events + verbs: + - create diff --git a/helm/actions-runner-controller/templates/leader_election_role_binding.yaml b/helm/actions-runner-controller/templates/leader_election_role_binding.yaml new file mode 100644 index 0000000..328e9da --- /dev/null +++ b/helm/actions-runner-controller/templates/leader_election_role_binding.yaml @@ -0,0 +1,13 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ include "actions-runner-controller.leaderElectionRoleName" . }} + namespace: {{ .Release.Namespace }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ include "actions-runner-controller.leaderElectionRoleName" . }} +subjects: +- kind: ServiceAccount + name: {{ include "actions-runner-controller.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} diff --git a/helm/actions-runner-controller/templates/manager_role.yaml b/helm/actions-runner-controller/templates/manager_role.yaml new file mode 100644 index 0000000..bd21390 --- /dev/null +++ b/helm/actions-runner-controller/templates/manager_role.yaml @@ -0,0 +1,306 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + creationTimestamp: null + name: {{ include "actions-runner-controller.managerRoleName" . }} +rules: +- apiGroups: + - actions.summerwind.dev + resources: + - horizontalrunnerautoscalers + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - actions.summerwind.dev + resources: + - horizontalrunnerautoscalers/finalizers + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - actions.summerwind.dev + resources: + - horizontalrunnerautoscalers/status + verbs: + - get + - patch + - update +- apiGroups: + - actions.summerwind.dev + resources: + - runnerdeployments + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - actions.summerwind.dev + resources: + - runnerdeployments/finalizers + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - actions.summerwind.dev + resources: + - runnerdeployments/status + verbs: + - get + - patch + - update +- apiGroups: + - actions.summerwind.dev + resources: + - runnerreplicasets + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - actions.summerwind.dev + resources: + - runnerreplicasets/finalizers + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - actions.summerwind.dev + resources: + - runnerreplicasets/status + verbs: + - get + - patch + - update +- apiGroups: + - actions.summerwind.dev + resources: + - runners + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - actions.summerwind.dev + resources: + - runners/finalizers + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - actions.summerwind.dev + resources: + - runners/status + verbs: + - get + - patch + - update +- apiGroups: + - actions.summerwind.dev + resources: + - runnersets + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - actions.summerwind.dev + resources: + - runnersets/finalizers + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - actions.summerwind.dev + resources: + - runnersets/status + verbs: + - get + - patch + - update +- apiGroups: + - "apps" + resources: + - statefulsets + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - "apps" + resources: + - statefulsets/finalizers + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - "" + resources: + - events + verbs: + - create + - patch +- apiGroups: + - "" + resources: + - persistentvolumeclaims + verbs: + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - "" + resources: + - persistentvolumes + verbs: + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - create + - get + - list + - update +- apiGroups: + - "" + resources: + - pods + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - "" + resources: + - pods/finalizers + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +{{- if .Values.runner.statusUpdateHook.enabled }} +- apiGroups: + - "" + resources: + - serviceaccounts + verbs: + - create + - delete + - get +- apiGroups: + - rbac.authorization.k8s.io + resources: + - rolebindings + verbs: + - create + - delete + - get +- apiGroups: + - rbac.authorization.k8s.io + resources: + - roles + verbs: + - create + - delete + - get +{{- end }} +{{- if .Values.rbac.allowGrantingKubernetesContainerModePermissions }} +{{/* These permissions are required by ARC to create RBAC resources for the runner pod to use the kubernetes container mode. */}} +{{/* See https://github.com/actions/actions-runner-controller/pull/1268/files#r917331632 */}} +- apiGroups: + - "" + resources: + - pods/exec + verbs: + - create + - get +- apiGroups: + - "" + resources: + - pods/log + verbs: + - get + - list + - watch +- apiGroups: + - "batch" + resources: + - jobs + verbs: + - get + - list + - create + - delete +{{- end }} diff --git a/helm/actions-runner-controller/templates/manager_role_binding.yaml b/helm/actions-runner-controller/templates/manager_role_binding.yaml new file mode 100644 index 0000000..c51b4d9 --- /dev/null +++ b/helm/actions-runner-controller/templates/manager_role_binding.yaml @@ -0,0 +1,12 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "actions-runner-controller.managerRoleName" . }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ include "actions-runner-controller.managerRoleName" . }} +subjects: +- kind: ServiceAccount + name: {{ include "actions-runner-controller.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} diff --git a/helm/actions-runner-controller/templates/manager_role_binding_secrets.yaml b/helm/actions-runner-controller/templates/manager_role_binding_secrets.yaml new file mode 100644 index 0000000..9b7132c --- /dev/null +++ b/helm/actions-runner-controller/templates/manager_role_binding_secrets.yaml @@ -0,0 +1,21 @@ +apiVersion: rbac.authorization.k8s.io/v1 +{{- if .Values.scope.singleNamespace }} +kind: RoleBinding +{{- else }} +kind: ClusterRoleBinding +{{- end }} +metadata: + name: {{ include "actions-runner-controller.managerRoleName" . }}-secrets + namespace: {{ .Release.Namespace }} +roleRef: + apiGroup: rbac.authorization.k8s.io + {{- if .Values.scope.singleNamespace }} + kind: Role + {{- else }} + kind: ClusterRole + {{- end }} + name: {{ include "actions-runner-controller.managerRoleName" . }}-secrets +subjects: +- kind: ServiceAccount + name: {{ include "actions-runner-controller.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} diff --git a/helm/actions-runner-controller/templates/manager_role_secrets.yaml b/helm/actions-runner-controller/templates/manager_role_secrets.yaml new file mode 100644 index 0000000..38037c8 --- /dev/null +++ b/helm/actions-runner-controller/templates/manager_role_secrets.yaml @@ -0,0 +1,24 @@ +apiVersion: rbac.authorization.k8s.io/v1 +{{- if .Values.scope.singleNamespace }} +kind: Role +{{- else }} +kind: ClusterRole +{{- end }} +metadata: + creationTimestamp: null + name: {{ include "actions-runner-controller.managerRoleName" . }}-secrets +rules: +- apiGroups: + - "" + resources: + - secrets + verbs: + - get + - list + - watch +{{- if .Values.rbac.allowGrantingKubernetesContainerModePermissions }} +{{/* These permissions are required by ARC to create RBAC resources for the runner pod to use the kubernetes container mode. */}} +{{/* See https://github.com/actions/actions-runner-controller/pull/1268/files#r917331632 */}} + - create + - delete +{{- end }} \ No newline at end of file diff --git a/helm/actions-runner-controller/templates/manager_secrets.yaml b/helm/actions-runner-controller/templates/manager_secrets.yaml new file mode 100644 index 0000000..7d95c5c --- /dev/null +++ b/helm/actions-runner-controller/templates/manager_secrets.yaml @@ -0,0 +1,32 @@ +{{- if .Values.authSecret.create }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "actions-runner-controller.secretName" . }} + namespace: {{ .Release.Namespace }} + {{- if .Values.authSecret.annotations }} + annotations: + {{ toYaml .Values.authSecret.annotations | nindent 4 }} + {{- end }} + labels: + {{- include "actions-runner-controller.labels" . | nindent 4 }} +type: Opaque +data: +{{- if .Values.authSecret.github_app_id }} + # Keep this as a string as strings integrate better with things like AWS Parameter Store, see PR #882 for an example + github_app_id: {{ .Values.authSecret.github_app_id | toString | b64enc }} +{{- end }} +{{- if .Values.authSecret.github_app_installation_id }} + # Keep this as a string as strings integrate better with things like AWS Parameter Store, see PR #882 for an example + github_app_installation_id: {{ .Values.authSecret.github_app_installation_id | toString | b64enc }} +{{- end }} +{{- if .Values.authSecret.github_app_private_key }} + github_app_private_key: {{ .Values.authSecret.github_app_private_key | toString | b64enc }} +{{- end }} +{{- if .Values.authSecret.github_token }} + github_token: {{ .Values.authSecret.github_token | toString | b64enc }} +{{- end }} +{{- if .Values.authSecret.github_basicauth_password }} + github_basicauth_password: {{ .Values.authSecret.github_basicauth_password | toString | b64enc }} +{{- end }} +{{- end }} diff --git a/helm/actions-runner-controller/templates/runner_editor_role.yaml b/helm/actions-runner-controller/templates/runner_editor_role.yaml new file mode 100644 index 0000000..b10f616 --- /dev/null +++ b/helm/actions-runner-controller/templates/runner_editor_role.yaml @@ -0,0 +1,26 @@ +# permissions to do edit runners. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "actions-runner-controller.runnerEditorRoleName" . }} +rules: +- apiGroups: + - actions.summerwind.dev + resources: + - runners + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - actions.summerwind.dev + resources: + - runners/status + verbs: + - get + - patch + - update diff --git a/helm/actions-runner-controller/templates/runner_viewer_role.yaml b/helm/actions-runner-controller/templates/runner_viewer_role.yaml new file mode 100644 index 0000000..485996c --- /dev/null +++ b/helm/actions-runner-controller/templates/runner_viewer_role.yaml @@ -0,0 +1,20 @@ +# permissions to do viewer runners. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "actions-runner-controller.runnerViewerRoleName" . }} +rules: +- apiGroups: + - actions.summerwind.dev + resources: + - runners + verbs: + - get + - list + - watch +- apiGroups: + - actions.summerwind.dev + resources: + - runners/status + verbs: + - get diff --git a/helm/actions-runner-controller/templates/serviceaccount.yaml b/helm/actions-runner-controller/templates/serviceaccount.yaml new file mode 100644 index 0000000..221ac16 --- /dev/null +++ b/helm/actions-runner-controller/templates/serviceaccount.yaml @@ -0,0 +1,13 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "actions-runner-controller.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "actions-runner-controller.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/helm/actions-runner-controller/templates/webhook_configs.yaml b/helm/actions-runner-controller/templates/webhook_configs.yaml new file mode 100644 index 0000000..89cb273 --- /dev/null +++ b/helm/actions-runner-controller/templates/webhook_configs.yaml @@ -0,0 +1,261 @@ +{{/* +We will use a self managed CA if one is not provided by cert-manager +*/}} +{{- $ca := genCA "actions-runner-ca" 3650 }} +{{- $cert := genSignedCert (printf "%s.%s.svc" (include "actions-runner-controller.webhookServiceName" .) .Release.Namespace) nil (list (printf "%s.%s.svc" (include "actions-runner-controller.webhookServiceName" .) .Release.Namespace)) 3650 $ca }} +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + creationTimestamp: null + name: {{ include "actions-runner-controller.fullname" . }}-mutating-webhook-configuration + {{- if .Values.certManagerEnabled }} + annotations: + cert-manager.io/inject-ca-from: {{ .Release.Namespace }}/{{ include "actions-runner-controller.servingCertName" . }} + {{- end }} +webhooks: +- admissionReviewVersions: + - v1beta1 + {{- if .Values.scope.singleNamespace }} + namespaceSelector: + matchLabels: + name: {{ default .Release.Namespace .Values.scope.watchNamespace }} + {{- end }} + clientConfig: + {{- if .Values.admissionWebHooks.caBundle }} + caBundle: {{ quote .Values.admissionWebHooks.caBundle }} + {{- else if not .Values.certManagerEnabled }} + caBundle: {{ $ca.Cert | b64enc | quote }} + {{- end }} + service: + name: {{ include "actions-runner-controller.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /mutate-actions-summerwind-dev-v1alpha1-runner + failurePolicy: Fail + name: mutate.runner.actions.summerwind.dev + rules: + - apiGroups: + - actions.summerwind.dev + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - runners + sideEffects: None + timeoutSeconds: {{ .Values.admissionWebHooks.timeoutSeconds | default 10}} +- admissionReviewVersions: + - v1beta1 + {{- if .Values.scope.singleNamespace }} + namespaceSelector: + matchLabels: + name: {{ default .Release.Namespace .Values.scope.watchNamespace }} + {{- end }} + clientConfig: + {{- if .Values.admissionWebHooks.caBundle }} + caBundle: {{ quote .Values.admissionWebHooks.caBundle }} + {{- else if not .Values.certManagerEnabled }} + caBundle: {{ $ca.Cert | b64enc | quote }} + {{- end }} + service: + name: {{ include "actions-runner-controller.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /mutate-actions-summerwind-dev-v1alpha1-runnerdeployment + failurePolicy: Fail + name: mutate.runnerdeployment.actions.summerwind.dev + rules: + - apiGroups: + - actions.summerwind.dev + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - runnerdeployments + sideEffects: None + timeoutSeconds: {{ .Values.admissionWebHooks.timeoutSeconds | default 10}} +- admissionReviewVersions: + - v1beta1 + {{- if .Values.scope.singleNamespace }} + namespaceSelector: + matchLabels: + name: {{ default .Release.Namespace .Values.scope.watchNamespace }} + {{- end }} + clientConfig: + {{- if .Values.admissionWebHooks.caBundle }} + caBundle: {{ quote .Values.admissionWebHooks.caBundle }} + {{- else if not .Values.certManagerEnabled }} + caBundle: {{ $ca.Cert | b64enc | quote }} + {{- end }} + service: + name: {{ include "actions-runner-controller.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /mutate-actions-summerwind-dev-v1alpha1-runnerreplicaset + failurePolicy: Fail + name: mutate.runnerreplicaset.actions.summerwind.dev + rules: + - apiGroups: + - actions.summerwind.dev + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - runnerreplicasets + sideEffects: None + timeoutSeconds: {{ .Values.admissionWebHooks.timeoutSeconds | default 10}} +- admissionReviewVersions: + - v1beta1 + {{- if .Values.scope.singleNamespace }} + namespaceSelector: + matchLabels: + name: {{ default .Release.Namespace .Values.scope.watchNamespace }} + {{- end }} + clientConfig: + {{- if .Values.admissionWebHooks.caBundle }} + caBundle: {{ quote .Values.admissionWebHooks.caBundle }} + {{- else if not .Values.certManagerEnabled }} + caBundle: {{ $ca.Cert | b64enc | quote }} + {{- end }} + service: + name: {{ include "actions-runner-controller.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /mutate-runner-set-pod + failurePolicy: Fail + name: mutate-runner-pod.webhook.actions.summerwind.dev + rules: + - apiGroups: + - "" + apiVersions: + - v1 + operations: + - CREATE + resources: + - pods + sideEffects: None + objectSelector: + matchLabels: + "actions-runner-controller/inject-registration-token": "true" + timeoutSeconds: {{ .Values.admissionWebHooks.timeoutSeconds | default 10}} +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + creationTimestamp: null + name: {{ include "actions-runner-controller.fullname" . }}-validating-webhook-configuration + {{- if .Values.certManagerEnabled }} + annotations: + cert-manager.io/inject-ca-from: {{ .Release.Namespace }}/{{ include "actions-runner-controller.servingCertName" . }} + {{- end }} +webhooks: +- admissionReviewVersions: + - v1beta1 + {{- if .Values.scope.singleNamespace }} + namespaceSelector: + matchLabels: + name: {{ default .Release.Namespace .Values.scope.watchNamespace }} + {{- end }} + clientConfig: + {{- if .Values.admissionWebHooks.caBundle }} + caBundle: {{ quote .Values.admissionWebHooks.caBundle }} + {{- else if not .Values.certManagerEnabled }} + caBundle: {{ $ca.Cert | b64enc | quote }} + {{- end }} + service: + name: {{ include "actions-runner-controller.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /validate-actions-summerwind-dev-v1alpha1-runner + failurePolicy: Fail + name: validate.runner.actions.summerwind.dev + rules: + - apiGroups: + - actions.summerwind.dev + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - runners + sideEffects: None + timeoutSeconds: {{ .Values.admissionWebHooks.timeoutSeconds | default 10}} +- admissionReviewVersions: + - v1beta1 + {{- if .Values.scope.singleNamespace }} + namespaceSelector: + matchLabels: + name: {{ default .Release.Namespace .Values.scope.watchNamespace }} + {{- end }} + clientConfig: + {{- if .Values.admissionWebHooks.caBundle }} + caBundle: {{ quote .Values.admissionWebHooks.caBundle }} + {{- else if not .Values.certManagerEnabled }} + caBundle: {{ $ca.Cert | b64enc | quote }} + {{- end }} + service: + name: {{ include "actions-runner-controller.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /validate-actions-summerwind-dev-v1alpha1-runnerdeployment + failurePolicy: Fail + name: validate.runnerdeployment.actions.summerwind.dev + rules: + - apiGroups: + - actions.summerwind.dev + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - runnerdeployments + sideEffects: None + timeoutSeconds: {{ .Values.admissionWebHooks.timeoutSeconds | default 10}} +- admissionReviewVersions: + - v1beta1 + {{- if .Values.scope.singleNamespace }} + namespaceSelector: + matchLabels: + name: {{ default .Release.Namespace .Values.scope.watchNamespace }} + {{- end }} + clientConfig: + {{- if .Values.admissionWebHooks.caBundle }} + caBundle: {{ quote .Values.admissionWebHooks.caBundle }} + {{- else if not .Values.certManagerEnabled }} + caBundle: {{ $ca.Cert | b64enc | quote }} + {{- end }} + service: + name: {{ include "actions-runner-controller.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + path: /validate-actions-summerwind-dev-v1alpha1-runnerreplicaset + failurePolicy: Fail + name: validate.runnerreplicaset.actions.summerwind.dev + rules: + - apiGroups: + - actions.summerwind.dev + apiVersions: + - v1alpha1 + operations: + - CREATE + - UPDATE + resources: + - runnerreplicasets + sideEffects: None +{{ if not (or (hasKey .Values.admissionWebHooks "caBundle") .Values.certManagerEnabled) }} + timeoutSeconds: {{ .Values.admissionWebHooks.timeoutSeconds | default 10}} +--- +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "actions-runner-controller.servingCertName" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "actions-runner-controller.labels" . | nindent 4 }} +type: kubernetes.io/tls +data: + tls.crt: {{ $cert.Cert | b64enc | quote }} + tls.key: {{ $cert.Key | b64enc | quote }} + ca.crt: {{ $ca.Cert | b64enc | quote }} +{{- end }} diff --git a/helm/actions-runner-controller/templates/webhook_service.yaml b/helm/actions-runner-controller/templates/webhook_service.yaml new file mode 100644 index 0000000..41425f4 --- /dev/null +++ b/helm/actions-runner-controller/templates/webhook_service.yaml @@ -0,0 +1,20 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "actions-runner-controller.webhookServiceName" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "actions-runner-controller.labels" . | nindent 4 }} + {{- with .Values.service.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + type: {{ .Values.service.type }} + ports: + - port: 443 + targetPort: {{ .Values.webhookPort }} + protocol: TCP + name: https + selector: + {{- include "actions-runner-controller.selectorLabels" . | nindent 4 }} diff --git a/helm/actions-runner-controller/values.yaml b/helm/actions-runner-controller/values.yaml new file mode 100644 index 0000000..9d4dab8 --- /dev/null +++ b/helm/actions-runner-controller/values.yaml @@ -0,0 +1,394 @@ +# Default values for actions-runner-controller. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +labels: {} + +replicaCount: 1 + +webhookPort: 9443 +syncPeriod: 1m +defaultScaleDownDelay: 10m + +enableLeaderElection: true +# Specifies the controller id for leader election. +# Must be unique if more than one controller installed onto the same namespace. +#leaderElectionId: "actions-runner-controller" + +# The URL of your GitHub Enterprise server, if you're using one. +#githubEnterpriseServerURL: https://github.example.com + +# Override GitHub URLs in case of using proxy APIs +#githubURL: "" +#githubUploadURL: "" +#runnerGithubURL: "" + +# Only 1 authentication method can be deployed at a time +# Uncomment the configuration you are applying and fill in the details +# +# If authSecret.enabled=true these values are inherited to actions-runner-controller's controller-manager container's env. +# +# Do set authSecret.enabled=false and set env if you want full control over +# the GitHub authn related envvars of the container. +# See https://github.com/actions/actions-runner-controller/pull/937 for more details. +authSecret: + enabled: true + create: false + name: "controller-manager" + annotations: {} + ### GitHub Apps Configuration + ## NOTE: IDs MUST be strings, use quotes + #github_app_id: "" + #github_app_installation_id: "" + #github_app_private_key: | + ### GitHub PAT Configuration + #github_token: "" + ### Basic auth for github API proxy + #github_basicauth_username: "" + #github_basicauth_password: "" + +# http(s) should be specified for dockerRegistryMirror, e.g.: dockerRegistryMirror="https://" +dockerRegistryMirror: "" +image: + repository: "summerwind/actions-runner-controller" + actionsRunnerRepositoryAndTag: "summerwind/actions-runner:latest" + dindSidecarRepositoryAndTag: "docker:dind" + pullPolicy: IfNotPresent + # The default image-pull secrets name for self-hosted runner container. + # It's added to spec.ImagePullSecrets of self-hosted runner pods. + actionsRunnerImagePullSecrets: [] + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" + +runner: + statusUpdateHook: + enabled: false + +rbac: + {} + # # This allows ARC to dynamically create a ServiceAccount and a Role for each Runner pod that uses "kubernetes" container mode, + # # by extending ARC's manager role to have the same permissions required by the pod runs the runner agent in "kubernetes" container mode. + # # Without this, Kubernetes blocks ARC to create the role to prevent a priviledge escalation. + # # See https://github.com/actions/actions-runner-controller/pull/1268/files#r917327010 + # allowGrantingKubernetesContainerModePermissions: true + +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: {} + +podLabels: {} + +podSecurityContext: + {} + # fsGroup: 2000 + +securityContext: + {} + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + +# Webhook service resource +service: + type: ClusterIP + port: 443 + annotations: {} + +# Metrics service resource +metrics: + serviceAnnotations: {} + serviceMonitor: false + serviceMonitorLabels: {} + port: 8443 + proxy: + enabled: true + image: + repository: quay.io/brancz/kube-rbac-proxy + tag: v0.13.1 + +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 + +nodeSelector: {} + +tolerations: [] + +affinity: {} + +# Only one of minAvailable or maxUnavailable can be set +podDisruptionBudget: + enabled: false + # minAvailable: 1 + # maxUnavailable: 3 + +# Leverage a PriorityClass to ensure your pods survive resource shortages +# ref: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/ +# PriorityClass: system-cluster-critical +priorityClassName: "" + +env: + {} + # specify additional environment variables for the controller pod. + # It's possible to specify either key vale pairs e.g.: + # http_proxy: "proxy.com:8080" + # https_proxy: "proxy.com:8080" + # no_proxy: "" + + # or a list of complete environment variable definitions e.g.: + # - name: GITHUB_APP_INSTALLATION_ID + # valueFrom: + # secretKeyRef: + # key: some_key_in_the_secret + # name: some-secret-name + # optional: true + +## specify additional volumes to mount in the manager container, this can be used +## to specify additional storage of material or to inject files from ConfigMaps +## into the running container +additionalVolumes: [] + +## specify where the additional volumes are mounted in the manager container +additionalVolumeMounts: [] + +scope: + # If true, the controller will only watch custom resources in a single namespace + singleNamespace: false + # If `scope.singleNamespace=true`, the controller will only watch custom resources in this namespace + # The default value is "", which means the namespace of the controller + watchNamespace: "" + +certManagerEnabled: true + +admissionWebHooks: + {} + #caBundle: "Ci0tLS0tQk......tLS0K" + +# There may be alternatives to setting `hostNetwork: true`, see +# https://github.com/actions/actions-runner-controller/issues/1005#issuecomment-993097155 +#hostNetwork: true + +## specify log format for actions runner controller. Valid options are "text" and "json" +logFormat: text + +githubWebhookServer: + enabled: false + replicaCount: 1 + useRunnerGroupsVisibility: false + ## specify log format for github webhook server. Valid options are "text" and "json" + logFormat: text + secret: + enabled: false + create: false + name: "github-webhook-server" + ### GitHub Webhook Configuration + github_webhook_secret_token: "" + ### GitHub Apps Configuration + ## NOTE: IDs MUST be strings, use quotes + #github_app_id: "" + #github_app_installation_id: "" + #github_app_private_key: | + ### GitHub PAT Configuration + #github_token: "" + imagePullSecrets: [] + nameOverride: "" + fullnameOverride: "" + 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: {} + podLabels: {} + podSecurityContext: {} + # fsGroup: 2000 + securityContext: {} + resources: {} + nodeSelector: {} + tolerations: [] + affinity: {} + priorityClassName: "" + service: + type: ClusterIP + annotations: {} + ports: + - port: 80 + targetPort: http + protocol: TCP + name: http + #nodePort: someFixedPortForUseWithTerraformCdkCfnEtc + loadBalancerSourceRanges: [] + ingress: + enabled: false + ingressClassName: "" + annotations: {} + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: "true" + hosts: + - host: chart-example.local + paths: [] + # - path: /* + # pathType: ImplementationSpecific + # Extra paths that are not automatically connected to the server. This is useful when working with annotation based services. + extraPaths: [] + # - path: /* + # backend: + # serviceName: ssl-redirect + # servicePort: use-annotation + ## for Kubernetes >=1.19 (when "networking.k8s.io/v1" is used) + # - path: /* + # pathType: Prefix + # backend: + # service: + # name: ssl-redirect + # port: + # name: use-annotation + tls: [] + # - secretName: chart-example-tls + # hosts: + # - chart-example.local + + # Only one of minAvailable or maxUnavailable can be set + podDisruptionBudget: + enabled: false + # minAvailable: 1 + # maxUnavailable: 3 + # queueLimit: 100 + terminationGracePeriodSeconds: 10 + lifecycle: {} + # specify additional environment variables for the webhook server pod. + # It's possible to specify either key vale pairs e.g.: + # my_env_var: "some value" + # my_other_env_var: "other value" + + # or a list of complete environment variable definitions e.g.: + # - name: GITHUB_WEBHOOK_SECRET_TOKEN + # valueFrom: + # secretKeyRef: + # key: GITHUB_WEBHOOK_SECRET_TOKEN + # name: prod-gha-controller-webhook-token + # optional: true + env: {} + +actionsMetrics: + serviceAnnotations: {} + # Set serviceMonitor=true to create a service monitor + # as a part of the helm release. + # Do note that you also need actionsMetricsServer.enabled=true + # to deploy the actions-metrics-server whose k8s service is referenced by the service monitor. + serviceMonitor: false + serviceMonitorLabels: {} + port: 8443 + proxy: + enabled: true + image: + repository: quay.io/brancz/kube-rbac-proxy + tag: v0.13.1 + +actionsMetricsServer: + enabled: false + # DO NOT CHANGE THIS! + # See the thread below for more context. + # https://github.com/actions/actions-runner-controller/pull/1814#discussion_r974758924 + replicaCount: 1 + ## specify log format for actions metrics server. Valid options are "text" and "json" + logFormat: text + secret: + enabled: false + create: false + name: "actions-metrics-server" + ### GitHub Webhook Configuration + github_webhook_secret_token: "" + ### GitHub Apps Configuration + ## NOTE: IDs MUST be strings, use quotes + #github_app_id: "" + #github_app_installation_id: "" + #github_app_private_key: | + ### GitHub PAT Configuration + #github_token: "" + imagePullSecrets: [] + nameOverride: "" + fullnameOverride: "" + 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: {} + podLabels: {} + podSecurityContext: {} + # fsGroup: 2000 + securityContext: {} + resources: {} + nodeSelector: {} + tolerations: [] + affinity: {} + priorityClassName: "" + service: + type: ClusterIP + annotations: {} + ports: + - port: 80 + targetPort: http + protocol: TCP + name: http + #nodePort: someFixedPortForUseWithTerraformCdkCfnEtc + loadBalancerSourceRanges: [] + ingress: + enabled: false + ingressClassName: "" + annotations: {} + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: "true" + hosts: + - host: chart-example.local + paths: [] + # - path: /* + # pathType: ImplementationSpecific + # Extra paths that are not automatically connected to the server. This is useful when working with annotation based services. + extraPaths: [] + # - path: /* + # backend: + # serviceName: ssl-redirect + # servicePort: use-annotation + ## for Kubernetes >=1.19 (when "networking.k8s.io/v1" is used) + # - path: /* + # pathType: Prefix + # backend: + # service: + # name: ssl-redirect + # port: + # name: use-annotation + tls: [] + # - secretName: chart-example-tls + # hosts: + # - chart-example.local + terminationGracePeriodSeconds: 10 + lifecycle: {} diff --git a/helm/airflow/.gitignore b/helm/airflow/.gitignore new file mode 100644 index 0000000..77eb66a --- /dev/null +++ b/helm/airflow/.gitignore @@ -0,0 +1,9 @@ +# User overrides +config.yaml +config.yml + +# Build dir +repository + +# Never check in tmpcharts +tmpcharts diff --git a/helm/airflow/.helmignore b/helm/airflow/.helmignore new file mode 100644 index 0000000..6d231e1 --- /dev/null +++ b/helm/airflow/.helmignore @@ -0,0 +1,42 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*~ +# Various IDEs +.project +.idea/ +*.tmproj +bin + +# We do not want to include our Python Helm Chart Unit test files +tests diff --git a/helm/airflow/Chart.lock b/helm/airflow/Chart.lock new file mode 100644 index 0000000..8e99c4b --- /dev/null +++ b/helm/airflow/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: postgresql + repository: https://charts.bitnami.com/bitnami + version: 12.10.0 +digest: sha256:731562ef1f62ee687121df2d44ff8131a73aa63841f6cac858c30748ad349d55 +generated: "2023-08-25T13:23:48.02337-06:00" diff --git a/helm/airflow/Chart.yaml b/helm/airflow/Chart.yaml new file mode 100644 index 0000000..b9e9eda --- /dev/null +++ b/helm/airflow/Chart.yaml @@ -0,0 +1,137 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +# apiVersion v2 is Helm 3 +--- +apiVersion: v2 +name: airflow +version: 1.11.0-dev +appVersion: 2.7.1 +description: The official Helm chart to deploy Apache Airflow, a platform to + programmatically author, schedule, and monitor workflows +home: https://airflow.apache.org/ +sources: + - https://github.com/apache/airflow +icon: https://airflow.apache.org/images/airflow_dark_bg.png +keywords: + - apache + - airflow + - workflow + - scheduler +dependencies: + - name: postgresql + version: 12.10.0 + repository: https://charts.bitnami.com/bitnami + condition: postgresql.enabled +maintainers: + - email: dev@airflow.apache.org + name: Apache Airflow PMC +type: application +annotations: + artifacthub.io/links: | + - name: Documentation + url: https://airflow.apache.org/docs/helm-chart/1.8.0/ + artifacthub.io/screenshots: | + - title: DAGs View + url: https://airflow.apache.org/docs/apache-airflow/2.7.1/_images/dags.png + - title: Datasets View + url: https://airflow.apache.org/docs/apache-airflow/2.7.1/_images/datasets.png + - title: Grid View + url: https://airflow.apache.org/docs/apache-airflow/2.7.1/_images/grid.png + - title: Graph View + url: https://airflow.apache.org/docs/apache-airflow/2.7.1/_images/graph.png + - title: Calendar View + url: https://airflow.apache.org/docs/apache-airflow/2.7.1/_images/calendar.png + - title: Variable View + url: https://airflow.apache.org/docs/apache-airflow/2.7.1/_images/variable_hidden.png + - title: Gantt Chart + url: https://airflow.apache.org/docs/apache-airflow/2.7.1/_images/gantt.png + - title: Task Duration + url: https://airflow.apache.org/docs/apache-airflow/2.7.1/_images/duration.png + - title: Code View + url: https://airflow.apache.org/docs/apache-airflow/2.7.1/_images/code.png + artifacthub.io/changes: | + - description: Add support for container security context + kind: added + links: + - name: '#31043' + url: https://github.com/apache/airflow/pull/31043 + - description: Validate ``executor`` and ``config.core.executor`` match + kind: changed + links: + - name: '#30693' + url: https://github.com/apache/airflow/pull/30693 + - description: Support ``minAvailable`` property for PodDisruptionBudget + kind: changed + links: + - name: '#30603' + url: https://github.com/apache/airflow/pull/30603 + - description: Add ``volumeMounts`` to dag processor ``waitForMigrations`` + kind: changed + links: + - name: '#30990' + url: https://github.com/apache/airflow/pull/30990 + - description: Template extra volumes + kind: changed + links: + - name: '#30773' + url: https://github.com/apache/airflow/pull/30773 + - description: Fix webserver probes timeout and period + kind: fixed + links: + - name: '#30609' + url: https://github.com/apache/airflow/pull/30609 + - description: Add missing ``waitForMigrations`` for workers + kind: fixed + links: + - name: '#31625' + url: https://github.com/apache/airflow/pull/31625 + - description: Add missing ``priorityClassName`` to K8S worker pod template + kind: fixed + links: + - name: '#31328' + url: https://github.com/apache/airflow/pull/31328 + - description: Adding log groomer sidecar to dag processor + kind: fixed + links: + - name: '#30726' + url: https://github.com/apache/airflow/pull/30726 + - description: Do not propagate global security context to statsd and redis + kind: fixed + links: + - name: '#31865' + url: https://github.com/apache/airflow/pull/31865 + - description: 'Misc: Default Airflow version to 2.6.3' + kind: changed + links: + - name: '#31979' + url: https://github.com/apache/airflow/pull/31979 + - description: 'Misc: Use template comments for the chart license header' + kind: changed + links: + - name: '#30569' + url: https://github.com/apache/airflow/pull/30569 + - description: 'Misc: Align ``apiVersion`` and ``kind`` order in chart templates' + kind: changed + links: + - name: '#31850' + url: https://github.com/apache/airflow/pull/31850 + - description: 'Misc: Cleanup Kubernetes < 1.23 support' + kind: changed + links: + - name: '#31847' + url: https://github.com/apache/airflow/pull/31847 diff --git a/helm/airflow/INSTALL b/helm/airflow/INSTALL new file mode 100644 index 0000000..86f4cdf --- /dev/null +++ b/helm/airflow/INSTALL @@ -0,0 +1,14 @@ +## INSTALL / BUILD instructions for Apache Airflow Chart + +# The Assumption here is that you have a running Kubernetes cluster +# and helm installed & configured to talk with the cluster + +# Run `helm install` Command +helm install airflow . + +# If you want to install in a particular namespace +## Create that namespace (example 'airflow' here, change it as needed) +kubectl create namespace airflow + +## Install the chart in that namespace +helm install airflow -n airflow . diff --git a/helm/airflow/LICENSE b/helm/airflow/LICENSE new file mode 100644 index 0000000..11069ed --- /dev/null +++ b/helm/airflow/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/helm/airflow/NOTICE b/helm/airflow/NOTICE new file mode 100644 index 0000000..3f68897 --- /dev/null +++ b/helm/airflow/NOTICE @@ -0,0 +1,17 @@ +Apache Airflow +Copyright 2016-2021 The Apache Software Foundation + +This product includes software developed at The Apache Software +Foundation (http://www.apache.org/). +======================================================================= + +postgresql: +----- +This product contains vendored-in postgresql Helm chart. + +Copyright © 2022 Bitnami + +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. diff --git a/helm/airflow/README.md b/helm/airflow/README.md new file mode 100644 index 0000000..af613c8 --- /dev/null +++ b/helm/airflow/README.md @@ -0,0 +1,63 @@ + + +# Helm Chart for Apache Airflow + +[![Artifact HUB](https://img.shields.io/endpoint?url=https://artifacthub.io/badge/repository/apache-airflow)](https://artifacthub.io/packages/search?repo=apache-airflow) + +[Apache Airflow](https://airflow.apache.org/) is a platform to programmatically author, schedule and monitor workflows. + +## Introduction + +This chart will bootstrap an [Airflow](https://airflow.apache.org) deployment on a [Kubernetes](http://kubernetes.io) +cluster using the [Helm](https://helm.sh) package manager. + +## Requirements + +- Kubernetes 1.24+ cluster +- Helm 3.0+ +- PV provisioner support in the underlying infrastructure (optionally) + +## Features + +* Supported executors: ``LocalExecutor``, ``CeleryExecutor``, ``KubernetesExecutor``, ``LocalKubernetesExecutor``, ``CeleryKubernetesExecutor`` +* Supported Airflow version: ``1.10+``, ``2.0+`` +* Supported database backend: ``PostgresSQL``, ``MySQL`` +* Autoscaling for ``CeleryExecutor`` provided by KEDA +* PostgreSQL and PgBouncer with a battle-tested configuration +* Monitoring: + * StatsD/Prometheus metrics for Airflow + * Prometheus metrics for PgBouncer + * Flower +* Automatic database migration after a new deployment +* Administrator account creation during deployment +* Kerberos secure configuration +* One-command deployment for any type of executor. You don't need to provide other services e.g. Redis/Database to test the Airflow. + +## Documentation + +Full documentation for Helm Chart (latest **stable** release) lives [on the website](https://airflow.apache.org/docs/helm-chart/). + +> Note: If you're looking for documentation for main branch (latest development branch): you can find it on [s.apache.org/airflow-docs/](http://apache-airflow-docs.s3-website.eu-central-1.amazonaws.com/docs/helm-chart/latest/index.html). +> Source code for documentation is in [../docs/helm-chart](https://github.com/apache/airflow/tree/main/docs/helm-chart) +> + +## Contributing + +Want to help build Apache Airflow? Check out our [contributing documentation](https://github.com/apache/airflow/blob/main/CONTRIBUTING.rst). diff --git a/helm/airflow/RELEASE_NOTES.rst b/helm/airflow/RELEASE_NOTES.rst new file mode 100644 index 0000000..94276da --- /dev/null +++ b/helm/airflow/RELEASE_NOTES.rst @@ -0,0 +1,749 @@ + .. Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + .. http://www.apache.org/licenses/LICENSE-2.0 + + .. Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. + +.. contents:: Apache Airflow Helm Chart Releases + :local: + :depth: 1 + +Run ``helm repo update`` before upgrading the chart to the latest version. + +.. towncrier release notes start + + +Airflow Helm Chart 1.10.0 (2023-06-26) +-------------------------------------- + +Significant Changes +^^^^^^^^^^^^^^^^^^^ + +Default Airflow image is updated to ``2.6.2`` (#31979) +"""""""""""""""""""""""""""""""""""""""""""""""""""""" + +The default Airflow image that is used with the Chart is now ``2.6.2``, previously it was ``2.5.3``. + +New Features +^^^^^^^^^^^^ + +- Add support for container security context (#31043) + +Improvements +^^^^^^^^^^^^ + +- Validate ``executor`` and ``config.core.executor`` match (#30693) +- Support ``minAvailable`` property for PodDisruptionBudget (#30603) +- Add ``volumeMounts`` to dag processor ``waitForMigrations`` (#30990) +- Template extra volumes (#30773) + +Bug Fixes +^^^^^^^^^ + +- Fix webserver probes timeout and period (#30609) +- Add missing ``waitForMigrations`` for workers (#31625) +- Add missing ``priorityClassName`` to K8S worker pod template (#31328) +- Adding log groomer sidecar to dag processor (#30726) +- Do not propagate global security context to statsd and redis (#31865) + +Misc +^^^^ + +- Default Airflow version to 2.6.2 (#31979) +- Use template comments for the chart license header (#30569) +- Align ``apiVersion`` and ``kind`` order in chart templates (#31850) +- Cleanup Kubernetes < 1.23 support (#31847) + +Airflow Helm Chart 1.9.0 (2023-04-14) +------------------------------------- + +Significant Changes +^^^^^^^^^^^^^^^^^^^ + +Default PgBouncer and PgBouncer Exporter images have been updated (#29919) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +The PgBouncer and PgBouncer Exporter images are based on newer software/os. They are also multi-platform AMD/ARM images: + + * ``pgbouncer``: 1.16.1 based on alpine 3.14 (``airflow-pgbouncer-2023.02.24-1.16.1``) + * ``pgbouncer-exporter``: 0.14.0 based on alpine 3.17 (``apache/airflow:airflow-pgbouncer-exporter-2023.02.21-0.14.0``) + +Default Airflow image is updated to ``2.5.3`` (#30411) +"""""""""""""""""""""""""""""""""""""""""""""""""""""" + +The default Airflow image that is used with the Chart is now ``2.5.3``, previously it was ``2.5.1``. + +New Features +^^^^^^^^^^^^ + +- Add support for ``hostAliases`` for Airflow webserver and scheduler (#30051) +- Add support for annotations on StatsD Deployment and cleanup CronJob (#30126) +- Add support for annotations in logs PVC (#29270) +- Add support for annotations in extra ConfigMap and Secrets (#30303) +- Add support for pod annotations to PgBouncer (#30168) +- Add support for ``ttlSecondsAfterFinished`` on ``migrateDatabaseJob`` and ``createUserJob`` (#29314) +- Add support for using SHA digest of Docker images (#30214) + +Improvements +^^^^^^^^^^^^ + +- Template extra volumes in Helm Chart (#29357) +- Make Liveness/Readiness Probe timeouts configurable for PgBouncer Exporter (#29752) +- Enable individual trigger logging (#29482) + +Bug Fixes +^^^^^^^^^ + +- Add ``config.kubernetes_executor`` to values (#29818) +- Block extra properties in image config (#30217) +- Remove replicas if KEDA is enabled (#29838) +- Mount ``kerberos.keytab`` to worker when enabled (#29526) +- Fix adding annotations for dag persistence PVC (#29622) +- Fix ``bitnami/postgresql`` default username and password (#29478) +- Add global volumes in pod template file (#29295) +- Add log groomer sidecar to triggerer service (#29392) +- Helm deployment fails when ``postgresql.nameOverride`` is used (#29214) + +Doc only changes +^^^^^^^^^^^^^^^^ + +- Add gitSync optional env description (#29378) +- Add webserver NodePort example (#29460) +- Include Rancher in Helm chart install instructions (#28416) +- Change RSA SSH host key to reflect update from Github (#30286) + +Misc +^^^^ + +- Update Airflow version to 2.5.3 (#30411) +- Switch to newer versions of PgBouncer and PgBouncer Exporter in chart (#29919) +- Reformat chart templates (#29917) +- Reformat chart templates part 2 (#29941) +- Reformat chart templates part 3 (#30312) +- Replace deprecated k8s registry references (#29938) +- Fix ``airflow_dags_mount`` formatting (#29296) +- Fix ``webserver.service.ports`` formatting (#29297) + +Airflow Helm Chart 1.8.0 (2023-02-06) +------------------------------------- + +Significant Changes +^^^^^^^^^^^^^^^^^^^ + +``bitnami/postgresql`` subchart updated to ``12.1.9`` (#29071) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +The version of postgresql installed is still version 11. + +If you are upgrading an existing helm release with the built-in postgres database, you will either need to delete your release and reinstall fresh, or manually delete these 2 objects: + +.. code-block:: + + kubectl delete secret {RELEASE_NAME}-postgresql + kubectl delete statefulset {RELEASE_NAME}-postgresql + +As a reminder, it is recommended to `set up an external database `_ in production. + +This version of the chart uses different variable names for setting usernames and passwords in the postgres database. + +- ``postgresql.auth.enablePostgresUser`` is used to determine if the "postgres" admin account will be created. +- ``postgresql.auth.postgresPassword`` sets the password for the "postgres" user. +- ``postgresql.auth.username`` and ``postrgesql.auth.password`` are used to set credentials for a non-admin account if desired. +- ``postgresql.postgresqlUsername`` and ``postgresql.postresqlPassword``, which were used in the previous version of the chart, are no longer used. + +Users will need to make those changes in their values files if they are changing the Postgres configuration. + +Previously the subchart version was ``10.5.3``. + +Default ``dags.gitSync.wait`` reduced to ``5`` seconds (#27625) +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +The default for ``dags.gitSync.wait`` has been reduced from ``60`` seconds to ``5`` seconds to reduce the likelihood of DAGs +becoming inconsistent between Airflow components. This will, however, increase traffic to the remote git repository. + +Default Airflow image is updated to ``2.5.1`` (#29074) +"""""""""""""""""""""""""""""""""""""""""""""""""""""" + +The default Airflow image that is used with the Chart is now ``2.5.1``, previously it was ``2.4.1``. + +Default git-sync image is updated to ``3.6.3`` (#27848) +""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +The default git-sync image that is used with the Chart is now ``3.6.3``, previously it was ``3.4.0``. + +Default redis image is updated to ``7-bullseye`` (#27443) +""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +The default redis image that is used with the Chart is now ``7-bullseye``, previously it was ``6-bullseye``. + +New Features +^^^^^^^^^^^^ + +- Add annotations on deployments (#28688) +- Add global volume & volumeMounts to the chart (#27781) + +Improvements +^^^^^^^^^^^^ + +- Add support for ``webserverConfigConfigMapName`` (#27419) +- Enhance chart to allow overriding command-line args to statsd exporter (#28041) +- Add support for NodePort in Services (#26945) +- Add worker log-groomer-sidecar enable option (#27178) +- Add HostAliases to Pod template file (#27544) +- Allow PgBouncer replicas to be configurable (#27439) + +Bug Fixes +^^^^^^^^^ + +- Create scheduler service to serve task logs for LocalKubernetesExecutor (#28828) +- Fix NOTES.txt to show correct URL (#28264) +- Add worker service account for LocalKubernetesExecutor (#28813) +- Remove checks for 1.19 api checks (#28461) +- Add airflow_local_settings to all airflow containers (#27779) +- Make custom env vars optional for job templates (#27148) +- Decrease default gitSync wait (#27625) +- Add ``extraVolumeMounts`` to sidecars too (#27420) +- Fix PgBouncer after PostgreSQL subchart upgrade (#29207) + +Doc only changes +^^^^^^^^^^^^^^^^ + +- Enhance production guide with a few Argo specific guidelines (#29078) +- Add doc note about Pod template images (#29032) +- Update production guide db section (#28610) +- Fix to LoadBalancer snippet (#28014) +- Fix gitSync example code (#28083) +- Correct repo example for cloning via ssh (#27671) + +Misc +^^^^ + +- Update Airflow version to 2.5.1 (#29074) +- Update git-sync to 3.6.3 (#27848) +- Upgrade ``bitnami/postgresql`` subchart to 12.1.9 (#29071) +- Update redis to 7 (#27443) +- Replace helm chart icon (#27704) + +Airflow Helm Chart 1.7.0 (2022-10-14) +------------------------------------- + +Significant Changes +^^^^^^^^^^^^^^^^^^^ + +Default Airflow image is updated to ``2.4.1`` (#26485) +"""""""""""""""""""""""""""""""""""""""""""""""""""""" + +The default Airflow image that is used with the Chart is now ``2.4.1``, previously it was ``2.3.2``. + +New Features +^^^^^^^^^^^^ + +- Make cleanup job history configurable (#26838) +- Added labels to specific Airflow components (#25031) +- Add StatsD ``overrideMappings`` in Helm chart values (#26598) +- Adding ``podAnnotations`` to StatsD deployment template (#25732) +- Container specific extra environment variables (#24784) +- Custom labels for extra Secrets and ConfigMaps (#25283) +- Add ``revisionHistoryLimit`` to all deployments (#25059) +- Adding ``podAnnotations`` to Redis StatefulSet (#23708) +- Provision Standalone Dag Processor (#23711) +- Add configurable scheme for webserver probes (#22815) +- Add support for KEDA HPA config to Helm chart (#24220) + +Improvements +^^^^^^^^^^^^ + +- Add 'executor' label to Airflow scheduler deployment (#25684) +- Add default ``flower_url_prefix`` in Helm chart values (#26415) +- Add liveness probe to Celery workers (#25561) +- Use ``sql_alchemy_conn`` for celery result backend when ``result_backend`` is not set (#24496) + +Bug Fixes +^^^^^^^^^ + +- Fix pod template ``imagePullPolicy`` (#26423) +- Do not declare a volume for ``sshKeySecret`` if dag persistence is enabled (#22913) +- Pass worker annotations to generated pod template (#24647) +- Fix semver compare number for ``jobs check`` command (#24480) +- Use ``--local`` flag for liveness probes in Airflow 2.5+ (#24999) + +Doc only changes +^^^^^^^^^^^^^^^^ + +- Improve documentation on helm hooks disabling (#26747) +- Remove ``ssh://`` prefix from git repo value (#26632) +- Fix ``defaultAirflowRepository`` comment (#26428) +- Baking DAGs into Docker image (#26401) +- Reload pods when using the same DAG tag (#24576) +- Minor clarifications about ``result_backend``, dag processor, and ``helm uninstall`` (#24929) +- Add hyperlinks to GitHub PRs for Release Notes (#24532) +- Terraform should not use Helm hooks for starting jobs (#26604) +- Flux should not use Helm hooks for starting jobs (#24288) +- Provide details on how to pull Airflow image from a private repository (#24394) +- Helm logo no longer a link (#23977) +- Document LocalKubernetesExecutor support in chart (#23876) +- Update Production Guide (#23836) + +Misc +^^^^ + +- Default Airflow version to 2.4.1 (#26485) +- Vendor in the Bitnami chart (#24395) +- Remove kubernetes 1.20 support (#25871) + + +Airflow Helm Chart 1.6.0 (2022-05-20) +------------------------------------- + +Significant Changes +^^^^^^^^^^^^^^^^^^^ + +Default Airflow image is updated to ``2.3.0`` (#23386) +"""""""""""""""""""""""""""""""""""""""""""""""""""""" + +The default Airflow image that is used with the Chart is now ``2.3.0``, previously it was ``2.2.4``. + +``ingress.enabled`` is deprecated +""""""""""""""""""""""""""""""""" + +Instead of having a single flag to control ingress resources for both the webserver and flower, there +are now separate flags to control them individually, ``ingress.web.enabled`` and ``ingress.flower.enabled``. +``ingress.enabled`` is now deprecated, but will still continue to control them both. + +Flower disabled by default +"""""""""""""""""""""""""" + +Flower is no longer enabled by default when using CeleryExecutor. If you'd like to deploy it, set +``flower.enabed`` to true in your values file. + +New Features +^^^^^^^^^^^^ + +- Support ``annotations`` on ``volumeClaimTemplates`` (#23433) +- Add support for ``topologySpreadConstraints`` to Helm Chart (#22712) +- Helm support for LocalKubernetesExecutor (#22388) +- Add ``securityContext`` config for Redis to Helm chart (#22182) +- Allow ``annotations`` on Helm DAG PVC (#22261) +- enable optional ``subPath`` for DAGs volume mount (#22323) +- Added support to override ``auth_type`` in ``auth_file`` in PgBouncer Helm configuration (#21999) +- Add ``extraVolumeMounts`` to Flower (#22414) +- Add webserver ``PodDisruptionBudget`` (#21735) + +Improvements +^^^^^^^^^^^^ + +- Ensure the messages from migration job show up early (#23479) +- Allow migration jobs and init containers to be optional (#22195) +- Use jobs check command for liveness probe check in Airflow 2 (#22143) + +Doc only changes +^^^^^^^^^^^^^^^^ + +- Adds ``resultBackendSecretName`` warning in Helm production docs (#23307) + +Misc +^^^^ + +- Update default Airflow version to ``2.3.0`` (#23386) +- Move the database configuration to a new section (#22284) +- Disable flower in chart by default (#23737) + + +Airflow Helm Chart 1.5.0, (2022-03-07) +-------------------------------------- + +Significant changes +^^^^^^^^^^^^^^^^^^^ + +Default Airflow image is updated to ``2.2.4`` +""""""""""""""""""""""""""""""""""""""""""""" + +The default Airflow image that is used with the Chart is now ``2.2.4``, previously it was ``2.2.3``. + +Removed ``config.api`` +"""""""""""""""""""""" + +This section configured the authentication backend for the Airflow API but used the same values as the Airflow default setting, which made it unnecessary to +declare the same again. + +New Features +^^^^^^^^^^^^ + +- Add support for custom command and args in jobs (#20864) +- Support for ``priorityClassName`` (#20794) +- Add ``envFrom`` to the Flower deployment (#21401) +- Add annotations to cleanup pods (#21484) + +Improvements +^^^^^^^^^^^^ + +- Speedup liveness probe for scheduler and triggerer (#20833, #21108) +- Update git-sync to v3.4.0 (#21309) +- Remove default auth backend setting (#21640) + +Bug Fixes +^^^^^^^^^ + +- Fix elasticsearch URL when username/password are empty (#21222) +- Mount ``airflow.cfg`` in wait-for-airflow-migrations containers (#20609) +- Grant pod log reader to triggerer ServiceAccount (#21111) + +Doc only changes +^^^^^^^^^^^^^^^^ + +- Simplify chart docs for configuring Airflow (#21747) +- Add extra information about time synchronization needed (#21685) +- Fix extra containers docs (#20787) + +Misc +^^^^ + +- Use ``2.2.4`` as default Airflow version (#21745) +- Change Redis image to bullseye (#21875) + +Airflow Helm Chart 1.4.0, (2022-01-10) +-------------------------------------- + +Significant changes +^^^^^^^^^^^^^^^^^^^ + +Default Airflow image is updated to ``2.2.3`` +""""""""""""""""""""""""""""""""""""""""""""" + +The default Airflow image that is used with the Chart is now ``2.2.3``, previously it was ``2.2.1``. + +``ingress.web.hosts`` and ``ingress.flower.hosts`` parameters data type has changed and ``ingress.web.tls`` and ``ingress.flower.tls`` have moved +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +``ingress.web.hosts`` and ``ingress.flower.hosts`` have had their types have been changed from an array of strings to an array of objects. ``ingress.web.tls`` and ``ingress.flower.tls`` can now be specified per host in ``ingress.web.hosts`` and ``ingress.flower.hosts`` respectively. + +The old parameter names will continue to work, however support for them will be removed in a future release so please update your values file. + +Fixed precedence of ``nodeSelector``, ``affinity`` and ``tolerations`` params +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +``nodeSelector``, ``affinity`` and ``tolerations`` params precedence has been fixed on all components. Now component-specific params +(e.g. ``webserver.affinity``) takes precedence over the global param (e.g. ``affinity``). + +Default ``KubernetesExecutor`` worker affinity removed +"""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Previously a default affinity was added to ``KubernetesExecutor`` workers to spread the workers out across nodes. This default affinity is no +longer set because, in general, there is no reason to spread task-specific workers across nodes. + +Changes in webserver and flower ``NetworkPolicy`` default ports +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +The defaults for ``webserver.networkPolicy.ingress.ports`` and ``flower.networkPolicy.ingress.ports`` moved away from using named ports to numerical ports to avoid issues with OpenShift. + +Increase default ``livenessProbe`` ``timeoutSeconds`` for scheduler and triggerer +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +The default timeout for the scheduler and triggerer ``livenessProbe`` has been increased from 10 seconds to 20 seconds. + +New Features +^^^^^^^^^^^^ + +- Add ``type`` to extra secrets param (#20599) +- Support elasticsearch connection ``scheme`` (#20564) +- Allows to disable built-in secret variables individually (#18974) +- Add support for ``securityContext`` (#18249) +- Add extra containers, volumes and volume mounts for jobs (#18808) +- Allow ingress multiple hostnames w/diff secrets (#18542) +- PgBouncer extra volumes, volume mounts, and ``sslmode`` (#19749) +- Allow specifying kerberos keytab (#19054) +- Allow disabling the Helm hooks (#18776, #20018) +- Add ``migration-wait-timeout`` (#20069) + +Improvements +^^^^^^^^^^^^ + +- Increase default ``livenessProbe`` timeout (#20698) +- Strict schema for k8s objects for values.yaml (#19181) +- Remove unnecessary ``pod_template_file`` defaults (#19690) +- Use built-in ``check-migrations`` command for Airflow>=2 (#19676) + +Bug Fixes +^^^^^^^^^ + +- Fix precedence of ``affinity``, ``nodeSelector``, and ``tolerations`` (#20641) +- Fix chart elasticsearch default port 80 to 9200. (#20616) +- Fix network policy issue for webserver and flower ui (#20199) +- Use local definitions for k8s schema validation (#20544) +- Add custom labels for ingresses/PVCs (#20535) +- Fix extra secrets/configmaps labels (#20464) +- Fix flower restarts on update (#20316) +- Properly quote namespace names (#20266) + +Doc only changes +^^^^^^^^^^^^^^^^ + +- Add ``helm dependency update`` step to chart INSTALL (#20702) +- Reword section covering the envvar secrets (#20566) +- Add "Customizing Workers" page (#20331) +- Include Datadog example in production guide (#17996) +- Update production Helm guide database section to use k8s secret (#19892) +- Fix ``multiNamespaceMode`` docs to also cover KPO (#19879) +- Clarify Helm behaviour when it comes to loading default connections (#19708) + +Misc +^^^^ + +- Use ``2.2.3`` as default Airflow version (#20450) +- Add ArtifactHUB annotations for docs and screenshots (#20558) +- Add kubernetes 1.21 support (#19557) + +Airflow Helm Chart 1.3.0 (2021-11-08) +------------------------------------- + +Significant changes +^^^^^^^^^^^^^^^^^^^ + +Default Airflow image is updated to ``2.2.1`` +""""""""""""""""""""""""""""""""""""""""""""" + +The default Airflow image that is used with the Chart is now ``2.2.1`` (which is Python ``3.7``), previously it was ``2.1.4`` (which is Python ``3.6``). + +The triggerer component requires Python ``3.7``. If you require Python ``3.6`` and Airflow ``2.2.0`` or later, use a ``3.6`` based image and set ``triggerer.enabled=False`` in your values. + +Resources made configurable for ``airflow-run-airflow-migrations`` job +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +Now it's possible to set resources requests and limits for migration job through ``migrateDatabaseJob.resources`` value. + +New Features +^^^^^^^^^^^^ + +- Chart: Add resources for ``cleanup`` and ``createuser`` jobs (#19263) +- Chart: Add labels to jobs created by cleanup pods (#19225) +- Add migration job resources (#19175) +- Allow custom pod annotations to all components (#18481) +- Chart: Make PgBouncer cmd/args configurable (#18910) +- Chart: Use python 3.7 by default; support disabling triggerer (#18920) + +Improvements +^^^^^^^^^^^^ + +- Chart: Increase default liveness probe timeout (#19003) +- Chart: Mount DAGs in triggerer (#18753) + +Bug Fixes +^^^^^^^^^ + +- Allow Airflow UI to create worker pod via Clear > Run (#18272) +- Allow Airflow standard images to run in OpenShift utilizing the official Helm chart #18136 (#18147) + +Doc only changes +^^^^^^^^^^^^^^^^ + +- Chart: Fix ``extraEnvFrom`` examples (#19144) +- Chart docs: Update webserver secret key reference configuration (#18595) +- Fix helm chart links in source install guide (#18588) + +Misc +^^^^ + +- Chart: Update default Airflow version to ``2.2.1`` (#19326) +- Modernize dockerfiles builds (#19327) +- Chart: Use strict k8s schemas for template validation (#19379) + +Airflow Helm Chart 1.2.0 (2021-09-28) +------------------------------------- + +Significant Changes +^^^^^^^^^^^^^^^^^^^ + +``ingress.web.host`` and ``ingress.flower.host`` parameters have been renamed and data type changed +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +``ingress.web.host`` and ``ingress.flower.host`` parameters have been renamed to ``ingress.web.hosts`` and ``ingress.flower.hosts``, respectively. Their types have been changed from a string to an array of strings. + +The old parameter names will continue to work, however support for them will be removed in a future release so please update your values file. + +Default Airflow version is updated to ``2.1.4`` +""""""""""""""""""""""""""""""""""""""""""""""" + +The default Airflow version that is installed with the Chart is now ``2.1.4``, previously it was ``2.1.2``. + +Removed ``ingress.flower.precedingPaths`` and ``ingress.flower.succeedingPaths`` parameters +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +``ingress.flower.precedingPaths`` and ``ingress.flower.succeedingPaths`` parameters have been removed as they had previously had no effect on rendered YAML output. + +Change of default ``path`` on Ingress +""""""""""""""""""""""""""""""""""""" + +With the move to support the stable Kubernetes Ingress API the default path has been changed from being unset to ``/``. For most Ingress controllers this should not change the behavior of the resulting Ingress resource. + +New Features +^^^^^^^^^^^^ + +- Add Triggerer to Helm Chart (#17743) +- Chart: warn when webserver secret key isn't set (#18306) +- add ``extraContainers`` for ``migrateDatabaseJob`` (#18379) +- Labels on job templates (#18403) +- Chart: Allow running and waiting for DB Migrations using default image (#18218) +- Chart: Make cleanup cronjob cmd/args configurable (#17970) +- Chart: configurable number of retention days for log groomers (#17764) +- Chart: Add ``loadBalancerSourceRanges`` in webserver and flower services (#17666) +- Chart: Support ``extraContainers`` in k8s workers (#17562) + + +Improvements +^^^^^^^^^^^^ + +- Switch to latest version of PGBouncer-Exporter (#18429) +- Chart: Ability to access http k8s via multiple hostnames (#18257) +- Chart: Use stable API versions where available (#17211) +- Chart: Allow ``podTemplate`` to be templated (#17560) + +Bug Fixes +^^^^^^^^^ + +- Chart: Fix applying ``labels`` on Triggerer (#18299) +- Fixes warm shutdown for celery worker. (#18068) +- Chart: Fix minor Triggerer issues (#18105) +- Chart: fix webserver secret key update (#18079) +- Chart: fix running with ``uid`` ``0`` (#17688) +- Chart: use ServiceAccount template for log reader RoleBinding (#17645) +- Chart: Fix elasticsearch-secret template port default function (#17428) +- KEDA task count query should ignore k8s queue (#17433) + +Doc only changes +^^^^^^^^^^^^^^^^ + +- Chart Doc: Delete extra space in adding connections doc (#18424) +- Improves installing from sources pages for all components (#18251) +- Chart docs: Format ``loadBalancerSourceRanges`` using code-block (#17763) +- Doc: Fix a broken link in an ssh-related warning message (#17294) +- Chart: Add instructions to Update Helm Repo before upgrade (#17282) +- Chart docs: better note for logs existing PVC permissions (#17177) + +Misc +^^^^ + +- Chart: Update the default Airflow version to ``2.1.4`` (#18354) + +Airflow Helm Chart 1.1.0 (2021-07-26) +------------------------------------- + +Significant Changes +^^^^^^^^^^^^^^^^^^^ + +Run ``helm repo update`` before upgrading the chart to the latest version. + +Default Airflow version is updated to ``2.1.2`` +""""""""""""""""""""""""""""""""""""""""""""""" + +The default Airflow version that is installed with the Chart is now ``2.1.2``, previously it was ``2.0.2``. + +Helm 2 no longer supported +"""""""""""""""""""""""""" + +This chart has dropped support for `Helm 2 as it has been deprecated `__ and no longer receiving security updates since November 2020. + +``webserver.extraNetworkPolicies`` and ``flower.extraNetworkPolicies`` parameters have been renamed +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +``webserver.extraNetworkPolicies`` and ``flower.extraNetworkPolicies`` have been renamed to ``webserver.networkPolicy.ingress.from`` and ``flower.networkPolicy.ingress.from``, respectively. Their values and behavior are the same. + +The old parameter names will continue to work, however support for them will be removed in a future release so please update your values file. + +Removed ``dags.gitSync.root``, ``dags.gitSync.dest``, and ``dags.gitSync.excludeWebserver`` parameters +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +The ``dags.gitSync.root`` and ``dags.gitSync.dest`` parameters did not provide any useful behaviors to chart users so they have been removed. +If you have them set in your values file you can safely remove them. + +The ``dags.gitSync.excludeWebserver`` parameter was mistakenly included in the charts ``values.schema.json``. If you have it set in your values file, +you can safely remove it. + +``nodeSelector``, ``affinity`` and ``tolerations`` on ``migrateDatabaseJob`` and ``createUserJob`` jobs +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +The ``migrateDatabaseJob`` and ``createUserJob`` jobs were incorrectly using the ``webserver``'s ``nodeSelector``, ``affinity`` +and ``tolerations`` (if set). Each job is now configured separately. + +New Features +^^^^^^^^^^^^ + +- Chart: Allow using ``krb5.conf`` with ``CeleryExecutor`` (#16822) +- Chart: Refactor webserver and flower NetworkPolicy (#16619) +- Chart: Apply worker's node assigning settings to Pod Template File (#16663) +- Chart: Support for overriding webserver and flower service ports (#16572) +- Chart: Support ``extraContainers`` and ``extraVolumes`` in flower (#16515) +- Chart: Allow configuration of pod resources in helm chart (#16425) +- Chart: Support job level annotations; fix jobs scheduling config (#16331) +- feat: Helm chart adding ``minReplicaCount`` to the KEDA ``worker-kedaautoscaler.yaml`` (#16262) +- Chart: Adds support for custom command and args (#16153) +- Chart: Add extra ini config to ``pgbouncer`` (#16120) +- Chart: Add ``extraInitContainers`` to scheduler/webserver/workers (#16098) +- Configurable resources for git-sync sidecar (#16080) +- Chart: Template ``airflowLocalSettings`` and ``webserver.webserverConfig`` (#16074) +- Support ``strategy``/``updateStrategy`` on scheduler (#16069) +- Chart: Add both airflow and extra annotations to jobs (#16058) +- ``loadBalancerIP`` and ``annotations`` for both Flower and Webserver (#15972) + +Improvements +^^^^^^^^^^^^ + +- Chart: Update Postgres subchart to 10.5.3 (#17041) +- Chart: Update the default Airflow version to ``2.1.2`` (#17013) +- Update default image as ``2.1.1`` for Helm Chart (#16785) +- Chart: warn when using default logging with ``KubernetesExecutor`` (#16784) +- Drop support for Helm 2 (#16575) +- Chart: ``podAntiAffinity`` for scheduler, webserver, and workers (#16315) +- Chart: Update the default Airflow Version to ``2.1.0`` (#16273) +- Chart: Only mount DAGs in webserver when required (#16229) +- Chart: Remove ``git-sync``: ``root`` and ``dest`` params (#15955) +- Chart: Add warning about missing ``knownHosts`` (#15950) + +Bug Fixes +^^^^^^^^^ + +- Chart: Create a random secret for Webserver's flask secret key (#17142) +- Chart: fix labels on cleanup ServiceAccount (#16722) +- Chart: Fix overriding node assigning settings on Worker Deployment (#16670) +- Chart: Always deploy a ``gitsync`` init container (#16339) +- Chart: Fix updating from ``KubernetesExecutor`` to ``CeleryExecutor`` (#16242) +- Chart: Adds labels to Kubernetes worker pods (#16203) +- Chart: Allow ``webserver.base_url`` to be templated (#16126) +- Chart: Fix ``PgBouncer`` exporter sidecar (#16099) +- Remove ``dags.gitSync.excludeWebserver`` from chart ``values.schema.json`` (#16070) +- Chart: Fix Elasticsearch secret created without Elasticsearch enabled (#16015) +- Handle special characters in passwords for Helm Chart (#16004) +- Fix flower ServiceAccount created without flower enable (#16011) +- Chart: ``gitsync`` Clean Up for ``KubernetesExecutor`` (#15925) +- Mount DAGs read only when using ``gitsync`` (#15953) + +Doc only changes +^^^^^^^^^^^^^^^^ + +- Chart docs: note uid write permissions for existing PVC (#17170) +- Chart Docs: Add single-line description for ``multiNamespaceMode`` (#17147) +- Chart: Update description for Helm chart to include 'official' (#17040) +- Chart: Better comment and example for ``podTemplate`` (#16859) +- Chart: Add more clear docs for setting ``pod_template_file.yaml`` (#16632) +- Fix description on ``scheduler.livenessprobe.periodSeconds`` (#16486) +- Chart docs: Fix ``extrasecrets`` example (#16305) +- Small improvements for ``README.md`` files (#16244) + +Misc +^^^^ + +- Removes pylint from our toolchain (#16682) +- Update link to match what is in pre-commit (#16408) +- Chart: Update the ``appVersion`` to 2.1.0 in ``Chart.yaml`` (#16337) +- Rename the main branch of the Airflow repo to be ``main`` (#16149) +- Update Chart version to ``1.1.0-rc1`` (#16124) diff --git a/helm/airflow/charts/postgresql-12.10.0.tgz b/helm/airflow/charts/postgresql-12.10.0.tgz new file mode 100644 index 0000000000000000000000000000000000000000..0946bad2f049f1cbf11c85d304e4ab41a847fb5f GIT binary patch literal 61605 zcmV)5K*_%!iwG0|00000|0w_~VMtOiV@ORlOnEsqVl!4SWK%V1T2nbTPgYhoO;>Dc zVQyr3R8em|NM&qo0POwycH20zFpAILehU1Q?l1OiQ?eZ=>CyUn|30_uB;M_dw&kSv zoS9h;L_!kU6u|}{JL+`a;5^cKr}GMD;YI=^NKqF%Nl(0HIyMMY6$*typ-?EKgz+&& z?6PvID` zF8E^$0007zz$xki!U8ryaV!gUr7nm_c#CKolg<$H1Ws|s)a&l=2N4=#m<0R#0X=-? zKr?a}pbsgb9MMH!OAWev?fqx%0~^P|b1#nH7Sf#8?Cw8rAGY^wsQY_c0K_;%2@_m7 zN?|xb!9ja(3#RxTq70Ly3+@iKV47xsDll6SN>LJ_B*chyw+vw+nNCTv1pq}UVVKJS zAR+E{IuwmD<8&VEw@YM(V#2a505}}W(F=h75@ZnX3;_r25A6?I5n>_5DVIfk)yu(u zpMh=tJKF)60hj=iq69E9qagxh_$vx|Kv66O1;!xK!U1j*axc(~2n7_y7!Gla`5eF` zl9d2XI2u#T=WTG*J3SVJr7?yH-vyWhHcQ3eG0`63aRP49ob7^N2~OCqpdO=pwhK7L z<1wO4f@Pdg6oHhI5JfYJSbJ+i1Q#cqr>xsC+-Zkox`jj0QO}nSWDIfEVH}3H%o^|x zo{p_Q16d(BIN1Ae@a(XiCgZJJG`}Y_lH+HIRQ|_SkTGa00O}h>X^cb3zpVg-@r(%> zpF*5)h!aFDX?S;j4=LIOr%Bk}0$@htya!{ikWtdU%W&?*cY~2hU%05BFcd=-}lK@Q1&>8113I4WI8v&!6o*AEMFo=!cij!?|qL!q#1!0VU{ zVGL48;S_O1nfTg|5oBl=B!nZtCy)a^!3^BvI0obnQHmo`j;v<804HHQi*Paqwtm_L zAxTDfJQMaGCt$`@%dx^M<#+4JlP&ePFo*?p60WY(mKOh&R$+$VW2wi~ZU7klCR>}$ zk7>~btyU%2{w$6MD5Qw90%QXdF!@<3Sq7jqv>~NXAp@vAZmZvl@N{2NMm+GaZjkqtnz#o9H= z4OR(hUZD+Ve3Jd$hl~l68f3o+>|$tJrb-LIXo?dt<`irj!C~ON7ts5iW&{XmVlaSU zp+pKnIAfel6(UYRND<_yjM6l1iYl$_V?%`Ll6}keXyv|TpK8#VI!)1`514VBjFsFe zq+|q4u@QYeZKZVO+s}|9sb65s%9OZ}-|w`W5u_0QjOMH@MaS^{XEe{KyG3(=lT8p= zgYErJ8(b#wT)>RL{RAc8eIq8m7khDr`0^bVvh-;EEg<_0-L*E?kJf8H&W&|m{v+yj zwXdqE;+w@25czKvAr%>WYM_Z+=c?Rq6(sA$o^H)Rs;n z>w`UDx(*O^oDr*PoN2Tz)m2$5XEWtir>!MT(Ce5xJ-JD8%^g)kb?0_AMB4ucE{&!0 z^K6J{f;eJklO$SMRVAJrh#1$b@qkkyznlo9LPXxT# zmll_CILU>FB59jR96N#x8(D!41JFZ@_|%vVfu;znfJ!^Zj)@@FW>`;s0P2f?Q|J~5 zgW@EC!x(`G!*N0w$03-K2mviCj6;q_vzQ?+pyajANrYTe+x^x?5^hule_N27QZht( zQ!o^Dm}&!)NSR1vIu*a03R>7Alw|g(M$-i&7&BBykO9`y|8kNGuOKEQ#wY9Ryhf*i zboBuPixEoekU~0U;7I&uC3K>>!G)6%PB5Rl+Q?qQsua^t%1vX}Rhyn%6#x;r|Je|(C6goj8 zfK`vXr}~8xv9#)bh#d#dpI|aEC}1}c3W?8%?=l{ob$T?kHo6J>)G#eI4)6; z&f>UFVjOx{AijZAe)P68ThBp?LOhz=t<-YP${j|-**I@70;)hcf&iP4SsaP!rYF5R zE|XqCvmMS{fCXQn=M+I6Q<;OX(s`P35t{wAAqwU@TE!Uk`52AhELM8^=}~+S=j^HI zKtB4Ifu}-CGyZfJpqR;C$m*w~3&Q&pF_iG93Y;VKx7mu*#-tOGkadK46O3m#LLGG& z+If;v6bR;fB?LUoy{GqiXPnCYYT0*FM!z}VseNrDlkj0bd9R<&zjlrkVt z!oV2$kBUpqjsn6hvv zfq#2fAgQsx%786w4U0Wo&L_2E&uV+Ll$R=-*X~xf0MgoTzIFITM%u2=zB`iPY1fs7 zH(9MJJk=snM7A0aJ*fPB-;@`wUFBHaEqWt&rIG%=iX-o{S&4POMfDWR2|7!`h?1$A zq>8jQxE2<$B6BK_C1A{mv67i&>Mfds_i+T%Ot-!l>^wU@>I?4atw3AVX%BG{-K0(E zDH5YrRm?yLnO;%1D!e9zad=4QW7)&Bz@Jo2+ot`58zk+4e0nQTxK;Ltm3?7ZIGPc( zEw5Y5`C8=|v&wC7<+Z@HdWB=ez&V*E-0@#Zcg0A4#0ldFMuK%SCKv`2fRZ~*NiszV z2X~NSF>9=a!+~yDQHBT_PB2FypHXBp+bQ3E&p1pX7?T9O2ZVz6R_ESJ4~kvC3-am$ z)s>|^jghKisGdA=6{!V8j-HKIV6o7;R*ChY&E`osp(G(Q)+5s?=F$$eO6ArXbLqKg zgQGYm_bAf)r7n0+5}_ZJQE~&*G@e_3-&4$y_*;6X-Yd09Mx*zYg zws%4nwPP}VLl~C^)fpLsFvdc4OmrFZHRzEfQ64JgtJG~`G7hkeGNrlWQY`H;8B2}j zgLRBqSPhQMI9mo_I+olM9TAY+mZFu?lQJ|xRTUdflrVREi@ z?MS&$g!&ZPfFZu)gLjRm=y#GJko{szTLDqbaK_;@WopkCVJ>9Vl9b#b>q>)D?v8B! zDQBw*F(~pmR}UpNb^)T4P=z69i-u%%&740-`?0jlXog5rvf#^>4Rj2%sCsN6UHQ>~cADsZP9H4uzuVxigvsq!2OljW&yfuEYSx`>=1dWR@D?E@G^RBU(& zmFmlEY!o@NR=e0(o{kA!BGjl{K9XV^xzAFg05~ZDP-0^pK~Wi+W9FIMDoSdkSv4Yb zYNpTeg{UOV@KTp%BNr%4SAtn&yx1HbUo6Rc(I`qB_Ltz|Bw8LWPND{Ivn|RB;M4m` zsZqTGSA=lGG&D8`4M^Bc*@Twt#wDRw^oz#QcvONS3dO%detZqm`|@76s%?=QimV&R zIbD($s^t;q6c1+{)$&|p8R1x%1gqeAC7agFSBDso|HcWJLLN>49E&|IF9^FcI)11M zwcabMK~yDr10?55MAXhmeE$#0bm%xhOQ6FEnj+(Sm78bw-ar(CHSqC~tBnRza~Lxa zp_HN!auof)|IhzjVjYi}QKOZdv+95W${fL*=&e1tJ{tg(gmj+jer$<$UEeXF(rsCU z8Z{gC)Lsmf9@2lP8DsvC!f*YN-kUb=@H(YxcubLGtNw$>dJ9=|UTIbWrJUbhovA6C zNd79>5UNm(&_CF}x}A=&!T!+|-TPNZ(f_^;PDhy|X*W9+CVYaZf}H!mi%t=3?_Vur z?+e)qBy6O*RV)*_f)&`QVB29o_9a7dlg#FRwa zY)6`KWX3^^r`R0Zi!H`v3Z`gE=v*$|Kh1%$(9|KD+%RS~d<3?og3vz8x3Rc(>U3Lq4FXqGAaj3rN*9&iOY3j)>*$w=yg{nt3# zAm^oOS_xfPG+MW`n#p@=tJITRiE;`@BOGQ%?BZYw0SL}Gd2Q}s0P~wzUC0!Q)kU6e zqIeWAJWf!gXhf9bkyv{2qf!S@6*i%%5gkZ9-oxoc=&N5QND90a1+EnRQ>Ku~dO$Tr zNr)JrP_>vqHGpcr@H9WREu-;Bj3CJFNx{($Jub-!r~aQSPAK8H1`6#MRPAet9~WS-cb(nsG3A~ak8eaT!}0@MapSsFgVi##=vk6 zDEe)N6qoq~O#!s|w}h|iZ|xUq-I^jkArW(yF1I)S4%0a6t@y=^vvjaJoxehNMEjD? zFw4V;ascH3LyIeYil>my3o$*ZDs^YNE^L?1z4V9tTx}bTP2nz>LM8)NVgw`cZ@b;j z6sW#is;YXCISR-}xQyjW=n1x%PBH4X@k>DUsx^y;JJn_p2uIU<=!DX%ho#@hqodDa)0iy0V z$vH!4W(PV|cRcd7j?*`e$$elv$pI(95Cy`zMNu%KWE#k0q(GXPfmlOje2bo& zbGCVyu}~^boK~w#hr!-JOuU3Hl!g+adDl)8%%kB#eXvfHk%}FY(Pt7_0O@!(6$@l` z6-<^FuVR@#tFJ09)s8h(l&jDx8)SYdfsUCcc)tKQC-oN?3#&a3=+ogHu~`p|d&r`K zQ7EzZS+OJi%C%#FBmw+5}=R`GBO?29}NUUW#rT~5Y&oAX9<8D$Y>`pB!rvB z+H_aOyK0jC4Zw7MBXHiRFKsq43034*@$dhyGsH=UO`K8`P6%in6TpZtQgAYEx19S6 z8WH&TsSz9UiBp(D4Lhl(&UN_?=X*cC_a0(1%#8<6o7wuGCiH@BVQ`4G3tQ$lLkYti z-yu6}aL3cP5GLTB&|3gwl8h@mCy%rjFxtm~!i}5C?#o5j2xVcCWWiu!qxu1b(z7^0 ze#y?l5gJTg;LuBIOlW3TI5R0SodgyB( z3Un@-a!msvC5)Lm&Y`Y!pr}1aq1FVCCjj0-9P5NO8us7GOo2|2TB5VaS&#jb1+Kz` zTh0XOTNoiI<0GUbD_hM+p^0SjE|{7f*|y%=6Khn}yp;}HhnsSJb@(Zdmk6)Lt^a-_ z%*E>o0`iwUGC_seYMk12>ELJrT%KB8OBtlg1D98oCAAy=jEuue5J7Vw^=Vm?^w|TSME}QnBI9KzE%Y?>hjIeQ{i;UcM|HdP# zGRn2f)l}J@sbCU$2BVJtwaKII3G5W_5LFF}w9RS|%I}S_DZ9;}$`!D_2bU^GbOqaT zv-By5@f}JKW4nMN7-8|NPRs={+W>lsC?=7C+n0Z> z1(4$@A~S9vUaLRX0y%;>o>6o?p@>aL9D!G=0Pw726|ih3BmQ%+168mPtjyeJ6&BV6 z?e0~3r^3i}!LvQJG}wIaf_+u$GOr6%>cL|FyWoW~0}CDKf_-ndGjaC{towB}i7jAQ zPGsH2P2evS+T}qu5ZmQ}HWb|D0XGy~4`6u@z%E@%c%MJI>}mz=m0bJVYI5s9UruW6 zri)=Ol-T9KHIUZj05+7=<$yMn(h^W*ZD(bbCinXKb-zMJ_n$8%q{>!0b5{PIc2GHm z@)$4AE}<^iD~pUI`6*c$oc7FAp}ul;xW--3?8_i`0WQEku;-!1?aa+(Fx$W?@y2+B z!g&~@H-y|WpYyMz0OY1goh_q+zkG;Bgd(w1g(IymItrs+)HmerXTIu%QU{@hl0z!<0qn1NV=1DwUe7sBxE8MMGO?)3zAQh`pv{mIC$P)8mZIDX}h?7MoR> z4;q@#ynFlEZc$Ig&&R&3{sJcEYNHW5E5XuPa-=RO%l}wh&6=zLuwtOr0eL|Z8QnWT z95@AQ0+;U7KE-!9Mq_lsLa6e8OGK3)*F?%tD3oWPk`azko6l1fkm@U66IBRP<=w@I zwIfPWiKtxaN23A?ypXFVRwhx|)Y4^ozU}2DdI+t?RSdVSDwjz{F$!LF!IcV((1|nT zC%dbrvgmQ1{we@RXJ=lnP6*>iF@_8|$A`upo05o`Km%Dx0jW_DAxT1%a@Nraxmb`O zeoyEvPR1P=MFC1U#Yi4a3-y6`7zhL`xW{}Ve+@LQju{|}$Vw-hsB@t(*_luz?V18B z6N=F_<#8D(|)fGzs^u~4pTrzcD|}8yOLq$ zCaT32=jp4wu1!0ImGyhEPnI}ke#}DZs){x8Y;j+tkk)k~15<~{CSPMKCgfTUWidBb z72c6b10}P|@CvR0sB3{#R&&!2WTT-gW%r)TS6dkwadp}`fi!yGY}wD}bT~oLOyq0SSWa75+bhMoW>Q2-N;vl5$4PXDXpxdcNwZpbYg*PoDOB}R0C zpt5pPB(M}k=pp(c{#zng6c(thIJhp?R0e`)lzlytE93@;IXm}OD{tj_yNB#sG_Ryu z>M$9bo82F3M6$ttqS8yt-*06CPIuhU0Se&nK?0}9i7>hKChM%}gw7vU-w$2MbfqEt zeSOg*kw?u0Ky_umTy$V}%nV`G@tctn)4jUY2`HJKW_i9EPY}nUQJxwLCbqtKP`NJb z)+@qY9RyJ|mZfYd@|Y3xr*b&5C0VzrT&@J*0g6$`2?ZCK5Y(>sOLNrnzes(;BtpSd zTca2kr8jvRVlKZq$DQe`5>hTMm>@+P6bTS6ZHkC zPr&{rdL~!DtQUZ(T2O_>%*iZ|3V~CSjE&t z31FqQqE|~qCEB+P$>e}BM>K&Pf$a0Hd@KO87$@|$wN$b{nY#vyp$znpT8^3NEao_k zQIKKEcT)~+l|A5yPH`gT^fiSc>O03L*)fXW{z?#vROSW^1%a^uB2x@6Ikn27)OlhN z7m$%FCUtaI_I8#=kfQ;okfZUuWOW!j%HB0GU0GTOO@LA&vrN8~rHi2J%0R&=c+0KZ zBdhWy$9$#;AuA zLYRK@V2JoVLJ9ca&-V8A_JU^zFJHX;&jq9lOSqJfDnnbabq%cMdw!1#SC@632p-G5 zO_4PjO+NNi?mtbBLNjP!AaBuuyg=?bbmF23f>DeZGXunYmp8JeUD?nk()zTJq$Qo4 zx|ws=rsN8&!zWhgpI{7=Pba*^kPFVp0mS#92Dw_uP;Nn(F=n{pyw zcBMiAl0@2O8x#=(T3$d4Oc!j%xLs{97U+Wld95zI>m=*u$WYzp)BymeedQOTcShBi zt~D^OWzFod{$lljCYtvYkGA}LTL1vs@k@9j&bww4f*frNeqlQELZ z8bypDolOu@q|Thorr(S|W{zAKbZfCD+kb>HnMHxVltF_Lrsy8Vapws|j8h!)K!Xvx zJkb@yz`!$mo;(3nz0Ib20QUFV>VJEkgTpErbK0tva)Gpo#Z4&i6S+JVl)1UC&`b;D z&>Em-h%ro(%x5)Ff4fdBYbn(2cIAzyAp$L-@mfM>wt7+qPy5;2IvrVs@-;q&!kN5I zrKeC9Jd;1=LDltcbABYZ( zn9PjU_hvKmr_dt173c$Gc`ifE+^&5Euo(IFY;UioLmH;FTD&PNc_5`EMU)p9V^&79 z`c|{U)N~iPoE!T70W2(e+0wf}>NAQe&iZ_&rFp2Z%1*Q@RN0DFm10PV2ct|>WTRDA zFZ%C#&de>v04%_3E}F*>Prdh^`|o<%{p4y0t6j}%XyclS4QwCsi44<9q0TF*v+J1o zD{G+$!2ANJbU0VuIw`(e;>cKr)0@Mo0nuzW%t&Ulq0%ly-O{zF=R~0boEV@w!z)fe zgzoIiSt`&^*oXahQcjHztY{+YxYD7bzY&j}S2o4a=_fXU^~Pp}Y^k1Dnm0ltoS(3eAXczn2D>^xG!+Au zLwf!5$*%Ye{uj7RQ8M5#ymcRWD?e7cXy}xkaZVznM(#+(KZ}CmxH&_m?Do8|QKtd8 zLNNM;Vva78u!%B|iKJ|yxl)VkV)UYA7yR%VH|b~1CPkVku10INBe4U{ne7#l(EoSQ2PregS^{!jCTI-{tT+$>K9TQ@&(J)QBU^*Ap zt-CfmhfRw*CMLeJG)*kF7=Eb^)JDLDomZ}18p~Wzi^~-fWh%W*{;tv{J;GVfxRTIN z;0>t3TUwgAqEC{SQKvUIi z5DE(473mqG3B1FEs&&?SPekREGpnAVQS93>0~AHG5Jfh*Ig+jzd5DvBNj^p~;fo-Iai9+J`e_I1p#S-E4>-MFF#*AHa{Ul_2&xgRo{XRx<~kV(s-do%mY^E) zpFTH%YePPMf&vfz$IepVA>r{-6%>qvMfnOm`r<(|7TEjl$IDqzSXWj|T(GRoux|c> zwedAhV^E3d&y&c&;nkYi3>LxqQ>Qd2I0-hI*Pt2fWs@5$0d=Vi2TQUtgT3WkS_pVe)5A-e>Rf=!N-lJIS@)DeU3y3uI0C6HiX*V zSL8!*y|&HbgHGP{g-FiiAa&>yjjt&{y95cUbxFn=7F_ zUUdl*3QYT!GQo3X^aUqPa1XE-XHKZ^*kk8TSVVmxfkJ`!FDr$@qP~>#D0sW`$jspIaNYC_el~vj2^z}cy-t>fT3N2k z(_pE<6*4urvtgs@8oZ#tqMQw0`oI3f4c=~j0ofb8bS>?YT{?+_7wxx94htCcZ=23x zp}2g@>9C=k4pnluY+{F6-B6p_!Arrn{0{5qcWA=cf43wLUY=|)(}RB+fabX#ECY3o zY!9ygsZq*@9P#=|AF9zmQ09k9gkOC6hf2!7;2aRuG%uA1q9AeKQb9akDu~JveB68x z)q=F~q!86T-ehKoN-XQ8hp6V$pCLy?W$!kbDB>zpHh;=g5q=(SK3_zxvscL&u{@Pu zM%swg=ziqf5l-@mpI~@9OYKvbCr`ljL`FrZ8hDz9yL4IfRKhjs=^A6iTW@mO0{VmGDc?;MP0kivu`#4;EHZc53R!f6f%GmsDtAYchh z*@SQ)@I>;6Mo8T~q)}%G!&~tSpeQ7Fh|a-K_ECaabC!yp2EURa>uf2YZZZsws4!zh ze;j@l_yk%Mjb|~W@mwswrHP^0Tb#)nnf{s`-DW;6Gb-88W+$jh&+0$Ap!I(uh!yS{ z_<}PtO2v3-_fj>YQeEY3ES7dv1XMlV5yUZy{)-IR8!U{K`5B&KUW44*RG_+-$EOJ-ftdTus{aqv95bG z;)uS&31$-%)sRuqLY-aszbz(%BH4q5GU?P)2fKDj7hER#N~Xc55aowuPnqv-Orynr z$=fkc7~;}TTKpn?f-tZzA=FRVWv{yw`@9ZF=Mbgw*;wa%vL0! z>PAize!Fe$1IuNp@ZZyELWA8>@JTc_>ru_k9sf-o-(8)`+d9qe>!?%$Ws!0K`7ia< zT?vOD$uIZRj)}_2Q^9canG?YW%~^e#pKb0tL!5NjB>OuEvtL{3_(qsTFpfbG zgfW5%2m(9`D8xBjx+dfTSg^4{g3be9(+FyzK??M-vr;EKiz4kV^OEI zRnH#1V=t~eseMmZ_w8Zc>r`^( zEOI|8Csa%l^nNEN!}igMo%wXeI2ek~A?Zt)!el1HGxTlng4cCOW=T}^kNZ8n4SH>E zALkZ>>?&6Nz*~gUmb`*glRF8Whf^Qdm#r@Cpcs`gDa@v0Vw!s{Sy zFc7YT)b@{-PI}7TP_H|*$>`U)Ll=y@>96A#ZPHOoYYEgvO;vlQ)d)j=HY5L&pJe2x z8<2w{GUs$f0`4e<-k6#CU}ezYPzCZF>Y}rgvWOK9P$ZOBI6;8VWOhCQ<}TO2*V^k^ z;;*kxzSuA9u&;UUIX=?&Ykr#{!G}9Uvsh40lshL9+iya_5GRqKds{|{Tc=_%3G)!r z9h$zss%8`oxA<^!CvQyTFNy`g1h}-ia1omEEcW^ zafoAPq0WAF{MwESPTvC7>yhJ$lNFDm$Xq;@4pxlhr^IgN`k|apMR%0B!<@m=WS0C+ zRq&>WQyj8Ia1~cnU9g=}8PJJlCZMzybONV{r7+Cz^ZbJhe?=kx7dR&g=0vW;S*?t@ z+SF=;>j`4n{U2jT$kex-0BtMI)&1Ixu%|h|b^{t^x{Vs@QkjZsWxDzqUGmaT+YFON zUzx6{5dBx;q;&=($>@Sl_iM*P{xlm$ND9eft zP1wnOPg0M)^g81qGSqWhGmY!Sqv#4 z6pwMzUYE`q>A$EDc||{FSv;GtU`-mZ%9p>}%B`*-R7fKhe@*g0xs14NwzGCmy>qBf zBKFz3r@SU>cT8vX5;e?`q@y3b*_j;Lo%!O!VHS3e4shpaogQ#!tL|9Qtf*E69z-Q| z;G$5YR>V+N2)dogz-vuaR)yK(xq~^7Gu0^q*+qqFo|vD~`E}uY)-{w}k#PEElT{9C ztdT7HFmY{7ChsifDV!fdnbpwypc<{vwMSHHH9g+EX4^nFmsV~y9b8Gn75iW-xoTYB zG+hC6?`zR?m0J=^#v+u=dn8HJZiroz6MX@|Xg5?;ZV^hv{({W-m`GQSx+x$E#4b^} z*Hqm7El3pY7C{_%?Zq<($s)dvT~_u7YEf$QzrcgDN^+b+PTl zHH2iELN3*@43m(aSj~$(s6s%kxMTMe!=$7AlIC7A#Jj;H?^=su!un0%h(d z6@X_H)iqFbVV1ej@-UKFNB|qd|J`9jVU@Q+XwcjT# zMn7${9pwT_2~N29ixcoPKRVK>7M}u=s5|>Y@d*mc=pBJ9eJ-#0cJI{02q)^E%Q78k zu>CL7B4e4`6pbx)-SlTPR~0Ux8+&ax%?yRY;6G+E=dx^;GCD67&5U51#s&zo z{w;yRv{^EvvgK>DQ9Z55`K#`>sKZKfpV)DWU_{~wQ5kkh5~O|f3!;s-vf~k9?a1RO z6q9=ocbdYgWbX>0Pws-c7W|6Hrww8-fluDdznj71i~Fg|!t24hFg>mnVq@jKt;vMD zQkq-aa=hddL_xn~ENcGfGrFJD5mRn-^`!pQYmRzPL0>G)PNPmfq=@1vN;r&nwu%|3 zbah=@=qT&bro0K<5u_CGcgu#^mRu$jZWyWn_QGWsbuF$@ymQk>qYSYcqfP6PDss(N z_gh;nU)hCp@s}73GBRB`^7q8bZmvN1%+mrc`3T{)UL>>Feix15kcl%8`iLPeb(5wQ zGZ}xi3!nmo8ORO?^?9QT_?u2iq8wc9(JYQ-WhWI`_MBlMdsBgK`9OmB&8794+@eGU zN;CP0faY}MUg>Pl^SOsf+AiVn-(GeAkK)K#ISb$??BLnEwu%3p~_LN3HF zKbgrcmQ+klvgJWvu;iZ5TlHGz5Qg1ak(GF;?Nhk=>8Pi62keV&IHnU)g zrJgM27BWHxK*21q>SP(mm~r-B`PDz%NHv7pE7myX9}{u1rc%XiRD=Kfv97`(PhP z@2uQI%@TMAajdu8^7HfTvl#4@rRA}9mYj2a23}Zntb^RVpT)Cv`7jHB)+x2jtU!6b z!q#lu4Ya~`-FX%{gL|Uk*6r1c0J9x>Ly+F>xeHWmv>QQNdPnZ!(HraH1?@-LaJ#fv z+w4YNui9gmp_&b4mN|aY`)6}sJ+Q=5Z>0Cy`_I}3_GbFv`M1sV<7}o20-;t>qlk`W zOr@O_POq}Mx@UWBy*_+T$qcas#o5^3n6ZB%KqliLLHB`%CF8c`jg=7|%Sh}k%g=o7 z=s*C{@r`kGTMLqm3G0H^;NP&3D1m-sQ!`N$>jU4!ABfwkWw__;;(>4mdd*oPa%Wa&asu5MOVGbFp~5 zy1G2C00Lx+Au4yzl6GNC;RI|yHMZj3(_N7Lu`m8G{C&D(t?APO%W_|QcdOuDpD~$i zuXT3x)5%$@_%%W-q&U^@Hruau8=6}#j=ZClm|h>feSNY3(*XZo!X!8$A!pApyYf-Y zx|uDL_LI^l%f2JsuUJ$8LuhHyx9|oT-l`Oo-Z!dE=EVN%o0I?PUtV3GT-_X>4vv00 zJGnVNd3E&m?E2>XpSi|OZ+HLKrM60&7;v8J`=Teubbk{ z9ZLiEeTZez0>6)|83D@Yv=IsggL%jd)g}wUI?_O~0y!!41xbB1RUZ9`lt@r&$eCyqHSUu`9?=I@ce&OB4 z{&^#flHQ*J{iK zsIvaK53J{CSHibKbkJahhbuC53bPe~*gK*=nL0!oH?0>gLu$wHIw z-0-O>N31z!c+#=^*dz~mv9I=_e|Cqa^z1|~Pn^gYgdoC9X8x1?HX?|UNQP+JMA@+d z=6*&7PR8hj6sER+wOl2Y&-AoDegtjB!*=~t`1DEp$1TDyWeSlzFhSoUuAP9o&VqTU zYZc>|3V5!Jij~HL=rc~n8Rv9X?=rbID{IqvRuGln-_9?A6@oiT6mIKfE_=D?3aJCx z41|;3I76{`Y8k5J8y$Br2B+p1$aUfp!;$>WZ6zR)|K!j*IS2_wgmrS!35aH5XBd-V zXA0#j5yvE)$p|v_R%eRa)98s$at)EqyQL^KcCGnW<)cx(lUhR7l9_&!2>G8ac))Hs zL^ki6zE5w34Vg#0<*f)6?_H?{)3D!#IaIJZk0kb;vjVnsfbz&597LJ~rC%5D>BVV7Ac zF!ecPKGl5Fz-qgcLj9EtWvf#7qq-%kV*@#)W5n}kk5n)pRJ({@$xz2TCiX&SQ)jT` z0gWcZJyBaFV<}6bvB_biUsAO@SGDZAwTjCwEV8Izz^uHm7SPr$tOW`la$zk{ zwUm}FkhxJUU7$-vT^10!5+I?R!&?NHbm6FsMCwsrl~CM7ZpxTondO*U@4lJImfH!X z3zjfO!jOD38zX%SS|C4zG+1`Rc>N9{;1*qDD2Rb;)IVt>w9K`a9Us+ zCt*B`5NLS=mRq2`BP`QTpaY)0*xLjD3HEKgBe6W}Pwk@Ecd3)1J4B^|eh9e91rglmTV2o+Mnt#M5u+byNg#CGQNKQE?TYGro+43Kc_>s_{@hrr3qDF6(6SSyW~Ekp z#wkw5vb`$DJeD6UUF5*XYK{n#)3HCEuw~m#0chST*~y3*FRfk zp8vB2d0QjME8B zW>Z9Q2oym8XLqlb>vtBSx>A4h`J@A%GjMf1v_oVI?et#91eWVO!J^{6yh|WY)$s4x zt+$+l<+?3KL0UYU>Gr}w^>kUZS-rbD;fVwy^8igC1NIeXQhG47c8C_vkB!cY0t;0C zzo1!R>F~E3k`&wcZ7eR5K_(Z~6ejxej{(%K?3GhK!BK>gLI(h7$t6tn!7O18KsoGk z$#R!mtIDTE?Ax3^U6q#)COMyh$6NNl#;mX&aBE^+RG9`0|GuJ-m!5YU2vCjKMo|(; z8>Gcz92G}Wm7Qb3*L~j?_@O0ZSv}w0CYTGjuW@Su|FTovrEIe+b8+=5YhGnC=Ao;l zBly*a21HIgC)OB(Uj16sk~kQ>c(~P*t*O-mjsw3>*b1$Ana9rmeO#rclbj^ z1tSvYxaCy%RG5%qI{S>g==I-jh!J~L6$~S$1wJgHbSxFzWZL+o+nP$bIzLv4zZa`3 z?ap0m`(hzp);`EnELKr~6OP73jh0a$pLNVYeCbO}Dci|93(YDcSH+X!h{}9Cy)3e_ z)-Wg~sdF>CnWqWzq;$f9xGE;3TeP|u&+#KOELSJl;*$k%=xCt^BJcKSOZ@*+GtaB# z|1;-NtaEXBeKKhC4}3E|rUm}LmwV5@`TsuGPw&mq)it;{IzQ=xk014+Vq5NOK7HC! zU*DZv4NfmF>I5&hVr#}8Mbvl!TPyS^*9h_V2FfO zAE7iRa}1r#&LK~qWr}1)2FTL43OAl4-raoKsW(;Lok)e z(vRX;-y;GOc!zWg^;Sa)ir~;rSFNhz;`>~50Ky_65Kl!eFgy1G219w0k9V5)@%J%S1i;o(V29H zbAUdeaK>>mmMpoQ4N=HrFh*R}2!i~aRtSndaBb&jwx2$MAOCo2XaehLBCRwoVg3Xr%lq#z;ejCl$?QHw{;JLZ{&{5~p5kTau0i zwdpKr3nGP7p_nN)i$A_o9wB+{xBFu*ae3Qz=CYHAl&V$HYwNVt(yG&Qv|~bUXK5y@ zs<_#KZtE7!bFqdqKG9HrMswDdeqBSs&uA_T4e4@tr>4WU%qUFfE`Sp0?pIR^w$X16 zcQTf=c6Qv^6d0}u2q#*7b$^r!XFDMrY!jMc8OLM@_LiPt;^r}AL9G`Zh)b|k#= z5V&nh=M7*xr$@c*X7x@0O;BZjcg(DTOzWhB+BjM{S!Sa#I} z&`G4N^f%J~lu{DSR3aiPMFDFoVNMhQw!2luVW^`D6oESoWgND13~%w@j&jup@!E$w zB5_Ra#rk!8p%Qg4^~`|i22O-xq9*oPPumI{`u&T-fq%P7J+;|gXhOi->QN~5o?1sf zsAeVO&Q??OTP^_BX2abuN>G68Ce^%|?ow*TOH;kFNLm89NbUu?Ya&-IxuV#< z%^V`2vqX=fveQBTa&Z0n>SSAc%GxzE?8h<41?p0!TGS zzDQn(b*d37^!m36@%i{MyR~GA(pSVtVAja|pvhX9>m_Xmth1(oT0t$ytX3n!wvtLW zJGP{=qN>i!D5dA*7?;*7@y#$?fM^(@73k|JK|rS<2sodE0E@rWL+n33y+C(}K5b}% zsuWvQ11LY5u?tXg_hYO7I+vG{2(`dJwbvjB%tj*!K+1lLK@dy`t6Tv6ixUXmf+pe( zg2=Gh2Ru9VR6r|8aBEq!Gz&q@1p)+V^QAnKg3Rju%7%W^gZgz0R+3NC{{$D8*C$uI5UU!^Yih<(_ud^k!6xlSOLZOk^Swc_Tk1+cZbQ|~GZ0uZIrhG4(NUHx{a zJUEtbpPU{8>q?awjt1G6K7INGB7&4LEN%Z*y$+Nnspsh!YkTQYkgS_oVVWogS{Ecj zeKj5h!p&&OWItwX^m2A_d3Y1))^TA!4Fh^7NkG+4j8Hao(HhS{LA(CbK zk58?g5()jwtLp+0tDt8o3e}xAfiKZ4`P9lTSuQu{cIs9l@ySx_EuUVuXZv@W*B}UF zzrV{m{>AF+k_r}oH|^7Bqt!A)bb9H0mYfk7{RCr}gorkpDO!VZFoko#g@S@$gzmu< zCo^u{i?#uS)4q;U%JTQNvjc)(AUF5j!)ADmphJMDSq ze`EYhu3&*V*O2D7_&=5BN!vJy&<9|YMr`rYya@;PcBBYsNzkJ#w#BW@&eEJIMyQ)R zAHLpsyjHKj$eG?V7uy>yh(`WJ$AS@|_mD=-CIPz(JIhUk#=Pw|ABF$5$yu;}@Up$v z-fQoFu_C?RR-!2XR)4>aew4P_w(Xs{bgw7KcHw3Y5EBHB#|aT1NCFacudWBjI$tGD zKqyR9`Nn-p(H$nU!mF<85b+)|5TO`x`QRrdv$0ynN7dhc9^l6t|8X-xu@LDtPvZ^XsE_}6c6fOBq7eV_VsC%{Tl~jk{Cxb_`Ri7X zq;rbL6As>;-$ROa!D$kPCJkWvqHFUWH?^ ztzQt}be70-bI8GqXEOMMfguXvj3L0t6xlDGD3}<kbJ!O)(*Dyk9E1RR?7%*0uaDSarR5R^2F{K`xv9qJ?hx*~)ZE!mcef@u|^Vs^mt z)SKYihP`ke7+SkG4z#skN#cSV zK2=|7tK&P|K2{W6kdz+x}_j>2Io#t}@jyQMY{~8Y=cS1HEth?8-)Ph2=IhTtG~CD6Hm}{%7h__oAv^@9 z9Czzi#5L!bU=7w8d&_ey;AAe;PdT1LbzalV*RLQp27|6Uhdi~tQKsd^+ zW;E92K;-g^{4U%nCXb!IvjQ6tqEJbtFWK1 z>+%U$=hgP37RJJXVMt~wzr~E9EzrO$JW@?6wVGQ^GsNmhc5c2*Ttfk9qVsilG+G|( ztAA-V0$8D+SW4|8g(^EcKI+>^4(b>yx05_( zW*b^IyoOxnkG{(UO(vv!p-Rsm z9POzVYk9o_@Q2~IS4^y!`yCZ2FEa|I;~UHbHS=aS8U6sj%?L;OMnfwa3L1WF6z5;` z<=X83^a(H)hluhjSUhGulwIavEWSna1$C8!+1xPD_o0G`eVHM(FR~V%S+zE*wxn%@ zclE3goP9ucv_4w5E7oC0ezU^4S!8Y@7eb@j6s3e=PUu`Q@gE=7#t&Y%OVsNM-a#L zi%aoBL^hc11n)pRyQa_68z4?EH}M33zX+ zzn6r*x7xf1kmt|aay-?ye06fgl#)9fAppTF!N1KAxQBE7dY8^FDl8Dy4=n_^DLG7=!?R@Ii6 zrDl8M?0@MHhWbN!`0_@(z^W+OSV1x_^({*ZA@{Tcd0qRS(A%2PsC$VyB{2@?os>iY z)5#$MUG_wb5~28aoQzc&Myz?*Tnfd$T0iZEsJhTmucx!6(_{OKg&58_d5sc8<)+?e zm{+Y?f&kVLFhU!C$-t*3&wEP{f=4Q!qM%&8?#S{Q@^+y#&J&Q?);6^Q=PT3lkA@_E z&z3pf^|ARD&6~5j81k@bZr|GQ9mj>A(?4tCSL622X#Thi?;R~8+D8v6+#y^b+s*k= z~1PMtDDU!F@V9YiUUU40>VuVFu%_$3s zv-Ft3(o;!8Tjv0IEomRr2k$nM`0rUDWqPSd*Md_pS2RavnDmASCu22`7S}424y#r= zF2C!%il6(I=EMDX@Ba>AcsolwAtlMLWZ0g==~~x-7ry`aVy|%j_vOLi^KbWmALBPg^j>I*WW43?UCEoxA<5Tbx8)(4!>zFEZSkA`Tl)n2;Kk3~45lj)a?)7L6m^q}Y<$fTc4E1a2 z5?J<#v*#YJ`qozOhRBqgK!w#Qekw4nj20`V3wRR715bkWkW5pOpoGiEmUD*4E?UnR zFYKpX*X`_)^(AAUOdC`DU_YDOG_gH!GTS>a>(l33UM-fQP)HFACn%c5N(j_=SM=7@ zRG`GxOm36Id0%eCy0+`D(6m%p!5Bdtqv*fLkiEf-6FNV`Q_SlC`CBMxY$nqmj%M*P z5UX1`16S3WL&|Y7K1MK#ae@XYBuS))w&G(gHFfYl+6kI|CBtjIhN*O}WU*D1(}>c4(FIJqi({Ma~S zH7NW@{&us>Q69Kzd|G5_XP$~G3U1z!Y!It0`T;Ii6PE= z|K@UVT{BM2r&~3DFR$t_EIyvAl;9l4@!RwM&GBh*7W(j%mN-J;7^!%YzSy@fnh);b zX7wx>49>1DFRyzip6)l^*L(URj}mR~l^6O#C1Lr1a)1r|SYBjRYQ*!wN&0TrRjENM zO*WNLy8tWzIzwm)ng_GG?td-@niZ$)Dq}2JR^mq{NL|qJ)mS(uh0PIRS_gP7aTccO zuqhl}wFrf|DY3oWT-KtfHrBmqxGRm0Lzh^c^?mWKz^UlM(1``hGTTgK%*axBAK1>X z0@viJ<}s%B6mKHei}nO+B(vDH7~*Lag?`z~Q!J{-izSHiq8Ezd3$yA~hLSa+ue_L7 zDYXY6eQg`l6RzR$WY+or(z|eN-``&r`v3M0UhW?h^Zz}2`SP3p?=gNh?EkY*JqkWR z=g6bU{8I-5wg)it{q=n_>YFFK-*7HxQM^L6Y^nQoGV%( zOSmsf3v#oC*vDre^BlL?q+`D7c#VYShzTQ*7rw(=RJcl}2n zIE6us8GnrRfA8Ss^Wyq{c)0g%{eO&~O|Jj$l$AnsEZ<)i;u!>iFQ?wZH;P^Tw+WH| z_GA5c=YN9uJ)yTs`v*vTXKQGJMfU&mgF^oAgT3d6hu`M^WBfdz{ja4+Sp?o(8ig8C z&aP%LV(kbe^ImpMid~bF4>GSy+@P&8h2`%%#TWvQ1`1&chd9O@m!Re?wR>6ZJ}&G^ z{#}QCJz0|0ED}l@5ev5-o7yFKw;&6)3v?Ky&;XoBA=v^zNlVvf%C9n8GNV}L3CVpNuX}xsf)g8lCdC=+!N(>WmPYe>$=#J#vYH`UV)yk`8YbTLU;9To z*{$jIwgHRQ|Gk5v|L^6?7YE(>fKkiI-4>5=+6}3=1I`&W*&J@l2I4@5v=ZGtH;;88~R}&Hwi(Kaaoud(tdz z#12?L5!yF{;EON_$Q_~-N9X|-d4ImHS`z={D`Tzxce6vSyb3JR|Ido|zYd=5?LYgb z{~zP$0sX)JbY1?egB2;gHnA?On(piCSq;8ACBK&6u0pJG652Ke2mb~-e4U?K{jXmv zThshssQ(Y1zbxAShtIyn|2@jj1L}YC-kmx5E0!z8cdj2~Twl>^xZiaA7op>~fPQn& zjEmGAlEs|-9Zur~@?bIjoBDpZpGNwhtrrNs==|q!?^!Yao2a*ma(hz)bSXu^3K$%0z4aBHRorLD4xF+o)pr?K9{jOZn2klxW?ZA+Yzp;L zyZ$?IpsQN|3)cUad;3NI-`>k--{Lw2E|E$_Cy0vg(MQUk5J(AZzE|Ylvijt`T z@FfI)YHI&2?Ut|e6v|i-Y86yn=x=5*e8@P|GN}uKP?s1!EyPYxY7<9K{q$a}2udNO z3+h|^-N_?gM^5sT+Gx{i#MXUpUudgy@p|E?t`?zMO@KV_04w0L;&#tx32xHV%Sl|< z*^~i2qpgA|IN^xiB01XfslBYJRk-G)Y=E`GT79v0*HrP9uY;ve57W&u1rOHQ2}uYo?)a?2 zCX(fa;m}jziIJK@u8U?*7A!ur__p=buN(5GG|L^ZTKRnzop8r03 z`R)G4qx@{r{$KBTpGBv$wlG$l%?@;x0pc6q39OX@)ZqAfEcw#mZKI$w)6W%x&3sM2 z@E|ko&}Ch)FHLy4oHk0}%hlu>tMcJOZ;cf*cJvg&d7_ESg)UI$wyYu4ukE zmBGeCzczo={Qzg&?$bNPXLnXpAYem}^(^l154JPCVUK~6Nq6bQEi2#j_Q;YaZ>}fp zuSM`GX=V(FaDu{HHk)>wd*Ui^2Zy&g>}?sx1HNmUN2S_7L5Ac@1g(k`Nv$23dUiy~ zR7}Pl&=OMA0)Lp<`3GPVc<}rMn@yXY39fUYzSLv?75P=WUXdMQ^E_xOF`G)H;(~89 z=e+witDxp3GV5+Sg?$nYQWO^Ue{0^9bRe&=2h}UvQ5ce0!fO|}a#cqgI=v~rc-5c9 zv3iPCu8Ebjd3ZM=j331qGUV)kv%<~XIJL11znM@mR^W_G?__r>}}ngh^OripvQ|%FsY7dpO=QU7HA(uoLt(0WTx0 z?{1^hey_5@X}?!uiP*Q$ca41m1ZmQ~x?aUoPzbRtqSrsc0#lur5C zWUAigu~7L^c=WQzR_zlyyS%jfTeHjM@X{^_NjeXTkDb-O(ppB~f44QWZ9T8QRlsPc zS#|%zlND1Ud)maUoxgZe=P1e>FZFmX08hX#2t*`#%H?A!m?8j$y1c_N8lxzGP8Z+= z@CjxhgbXe2P1U1&{ul0=Pxb1@{OTrrBUX6dl?*^U**AWJ)6NVsEcXfO*V%h;rY%t<|qoHhf0Vet^>dj-UaQ6Vw!59TVIQx!B4S z^u6q00AO}kR(FO@p~+K32&O_GqZ1XNGV;A){-Xgt+@ zz#nbmH=WG2A1rlVTBob#R&WJgzI+Kf5xVQJ$#g|@wXb%sWzc<=rKW*cE#Hf}1?DkD zZ3W7!Rr6|=b|v6P9PPzhr{>r|D?`_O8&whqFGVX5v+6#sdjGS!t!TdyUcI|n&+1t~ zS;a&8{>S*20#GqGYKoW9&>8E>YT4cx`V@CF3f6x&|Fds+D>~c!RK3a>x1m$@0{D%b zs)O9O#ENf^*^F+y>t243y_Uc3EA(&`dJTJSS1b{58AvwN8Nwh&0T~Np)ba!)TP;`8}RLonBuYouA$upZxUp zbwOK8VpMKhL=#Bopv9>muQh@(LoLU-s8mLThO_a4@!auilbojh<>31D)yd$$&u;pc zSJyWeZ_j@^xvC^?@%8xT_}*Qfy*)pi+SKDR&bEMN$n@rjm`zJ{Z> zK?_^W80tgD?g@=v;kf9Z67OX_L2L_Nx5Nu6n#IV`4t+Kzb*&@R*g#mZ}!hEnpZaWbbSe1x{e`7 zXJ?nc+?<^Eum4`llde`-o4}b3!rMWOHnQhJGbQjvOYe*!`tK>c<({v$4}4UW_Eqb) zuTxIeRC3F@7rf&TK@NwIAs_!sd=}QjPe+4lu~>{^Sxe$7PZCvQMr5*IlVGY89>!r3 z4d;ve99ieDPWor3y`$^X%Zr=y%j0S$WF{|*;hnH~r;u@BsV}0Sp|R;uQoEu!D#7B$ zTYc;BL6;eu%12TvRu?y=T713uIZ>}ycF5eDrdY9+tr`Pq9sTuC3Gw0&%xkG^--N91mli75TQ(zL$EveZ` zr1j3;4z5qGZjSo>n~S6K~}Xxww8t`;8eaD)?}ZlUl%L8Dm+~|y*Rx-{^{oE z>h)sA`rt3e$$EnG3GoYz#a6Z<@xL6MEwh!c!nVn-%sjTAm;6ER>a>5Yb{maEsR5$Z zn6LHDQdHM(%4&FTkS%Ls4Ae5*q+iS04ChC3PQSSvTsQ8H!J+?tLl|$0XBnSY1-d?= zmFl#TgJ;J_{YCzjo9uQBW!GmFt5|Elk#ne$pI0ZZPXDJNM=2WN4@>j( z?W@KZ*le@{2C*5uIlfp@?!{*C_@Z1EC5`c(UL3E07bj5(FHWK;snibY4u$qcmm1!f zHD_n1zG8a6(^%eQ-@eeThUidWI=znY4^ED*dT(xyuCJ?gm46T!5}W)R$T{_WIO3e* z;cSUXq9}QFdUjo-H*0Ab;g};YHLui{wY)b^Kv4r#udbE4s(x{`!#$dHh)zNI9iRcqY4Hz4=f64yezF(XR8r=b+)!o^$9qdMVK$t zC6}+Incrx?1qH-*Ovb{vuXDszAnILST%7c-PcJVPZ?H35J(46SRQI5lLw9^SSPA1X zX5nI_C1;~v_jq>^Hrm>!Veu=s^zSYGR&%OD>j@MWpo3 zPERhbZ_ZCIZq82zgQM3cO(#VdW0df7oSY-Z;214469;dOu1=1HfS+9+9p9Xt{&aP8 zb=m-Rt`i3nNKw?MC?+sE!$S%wuBM^F2O_iQoFsSeAT7B9HxaSqz;772R39YfxyWcE z>7CbpRw;N&K~ZHZyaB&@=jDM8&4cbT?L~MWQM^PM}*>~xiL>pFxxXKuh0f&^&(mo}_Vx+(IWkb=HWsDn$ zS+wb_2+v)+C)?g&Ugq?~ICOTJs|xfX&pnn)iRT6_sJun1z64>ZaMh!B1yE21((w&u z6v1c?g17dY3weB8MW~RxgcJ?Mr1-JID7I)&HyUdbNYrjJ0AsNztU~4Nl|PvHfY2s?f!`0bS@&>Q{yv=!{<*#%^c6sl#vT@S8gPYSrNtf)TFJht&DDNrhOz zx&e*o(&|@z=C>Jo+CB21DS70S1kyg zb5)pxw}=KP;dCyan+i0RsI!J&!KJjyvrtKIpnMLik?m<)PrTntWMvZ92~<3_FylBG zm-3ERb=A7@T*w(--PL7t&&dC*HhN2i`&xbRo(ng+xorY_S3FQ!a1i-`7tGZvcA3QU zF5q;AR_MUzzwG}lXTw5nEu}TWT5XYz-wa_hg|dty*|h#x*PHy#S^yvHl)yo<&QZZf z|EqGISzuW2KD`JQW>PR9m(Qr+v|Ki`f@!?z%nFO({@Z3&_~McbWFsZ*t8?|2kLG{0 z0&R}8f14pX4^qe{tzFR4_Jp#}3^@6+$-fqjVJUflsP&!kx`6JFCPQunTBivhG(r?` z0@Uc5Ne1R*1`>oK@rk7<#G^TYAOo}QST0$yrJBbv8N#@2-@UV|?o`|-YH~U5_~`oR zW^noTs&{hp_Ug3qG}c^h%G?dz@1xH5?ElYLJS7qOF~UsrSyEDw%uhciBI9cXNjnxR zH)zt?J?b9~24DU?;UdL8V!yl#S}R`@_KIHJJ;26(yE+-l7R3iT|M$XQ@BF{!%-HjO zviYe#F)poo$~8FkDb>v!8@t;3F^-LEFm7NKdi-N!ALf-@f;>zIB)mnus3$5PUlQ5 zDj!{gEl9}^>|dH~I!j)P<(+XAbgp#%QEt4{es{4`B8z{*5enf0WTeahua=8a$!_^| znn(ALHSvyRL6`0S$q|&Z8m~OEICb`f8@SlumMck#EYD z-?uF_dg~w8H9M+XWwZ*koi9B=O;7NaI=yQ!Ts$qGD0^x6u33K;of9?4X1t=1@mQ1U zk+bF}Q}RCPF{WMcah2h-yyTl-FC5^jtr@@{nh=YolJRAI&rIVApOs;O z^~Cwkauclf*stQqFB1lb`YDR=Y}y6qXi8{p7KVX5JiI!#_NJrFsuJG<)NW{4Ht9gGudj?-&{Iq>h^i?B@sNlFiA z3%hQU&t`kEtu@;U1Zgg{!x*ysiE|5WElr@Mjz#}J_TK%waU0na&(HcRu=NRZ+K)XR?;XU?QekpMm@ zpiosPRJC)*qy^%e)t|4PcCjp8-0Ty(dhmAHjn|nV=m&_Y6Y#~_*xTFNd;9ve{O{i0 zUjDzY4qoklwg39{yMz6My?3wQezkY7_j>QuS72||V2eu3IHX_gE!|cg+#@Msrtf~! zIwH}G;_-xopWfd>igv(h=yhBDi{pQE&aj6L*gFtN65f~yIj>QHaAy0_)jF1ovV=lhP)Q1@uQgV%C#~7I+aHEz917rmLp3IX& z{ndo?h#l_kjxnFaLowRB>14A1i5ZI#+kNx5w{H(xYA;vRgF!Tbxf#ewfGFgs6NmDC zQwN2<^dDzQ*ncAv@>zrq!BG%1j_Bz{ODK!_--qCwgaV$-_22-Ln8i7_ykdKk={U(O`sbTf*~3a zD(jrRq)48C%yt07Vt*G8Wqqny0)_}kzbY{gU~nxxt)Ms2^<&EcYlu8S8(CdfXow|q zB{^xaTrDcEXj=xBEIHGrRzC;rI3@!#;PSi%_ygk zdlSPIi+QEhpVe^4``#G;B&AONTSDwhN{#&Y=HOjU{@Z{1_TX9m+emqs@}FgAeu}c+ zyr?%XRh0>6bJnxw@?8V5ZV{v0!V;b(-({tdqA<=Hi+CYp9nNLQD15(tMxg&43}EOX zDzk6ZeQ-{EBzEJrKK4LgWW>hcio($ddj;1R^7Ryck)5_>2MEpa6vSrDe;8PwC_C3B z49AF>z^!G!SAs12NM4HgKa7O;i}UoN2%QjY9Wk9=R8y*~jzolZz?g{MX0BQCcSSeT zCQ5r)_9;U$k8*D`!Xf4}BN%2LR<>PO!4f@C&IN`2P(Q84URm9`Gq1W|WdLLkmA9Pu zpT*9aE;_eW7wQJ=I1+Y9X!CpJv?{73t-?NlY_O<``Vhu}J(QM>p=RDnmjKzthE@=# zd1=+&$Tae-A3hh?QlkHnDdH0pGa3hIX%(Ssog;GC3t7=7i#K-1P`WL^7$}M8&+wR8pg9YOW=f$vPd=+#xH_HEV!`#Y(B< z%0UTBE~zT0W6vwlbpJB%O0WQ1PMyzkTjtsn%kl)i4JO-8BGs~} z>rn(1zqPlJNZML#M zitgs_Q%&K*GC`gG_xkO-od4JU-n0IURd5T#fKqzXre;I6Z{lbPvOW*!z_ zMy>4UQ{2kR`M=gimuLUA{QuRfS9$;6w{H)g`Tr)$J=*`W_ZsbUC`i2t=E&o*&>F48 z@9kCW5!F{6pTMT@7}e~LVMou!`tFYg3cXa9Ts?jV2u^Jf3u zGymU2*&zR4mcv(i6aJa_yW3GrCoB9rIU6Ry;}&-|tg7NsI2+nmAF7<7@<2lOh)z3AZS(~}b~%J=_J8NJov z$x;$P&Hn%Tb>9EuU~m8Jo9F$16J?G2zn(z3035DTKyfWN6q8k+i)VRCPevm65C*gF zDVdfzlN222WlkQmjiq1eb3P@9oZBzeN+Y_*e_Cne5t<;4Jh1XTEh2v3Y-=rbj+X3S z8`$Tpyjd-JEfCH(pie%OZTdZWi`sX`*FEac-?WknyuSyx7R)qP%zJ#rfJ)j@4f7iviPt zm18Ti<>p7%?nDEh`6nmVJC}0#U+aR}|8^M#picguyZ?Kz_v+x;{Y@cp4!y!lX23pq* z%@Y^8&3`>7#JP2Yc@#$I3QrMwjQqN8bn2_C8FKi zrJo;%a?ti|0_3Zz(k+Nd>-$`~iE7{J;cld2-&Ol4#Zeq)~=WmH6 z--=eZ7LB0JVqYoXXROPQN337K>mY-40hfc)?;p6ofnF2YeKrF|zi~w3kQ=#QZoieO zIP4i(7)doJ9%Pz~BOh|q=M-`@)?N(RXNBpYs_Li?p0YmAfro#@Vzyk})m(u6#n}+3 zi9GMh5$XYF@}0Oq2ANQ|%iR|#n<53#X$u1GT0L3%+KQ>qn;`F+#nb%lDSf{{9S&pf zI&E=Fo)v??bWNIu?st$OnVPuC zLI#qZKFg%zR~ek-Mp4?gvQeB6#(M#V3}v**4Cvq7wd1V#ka6FWe8Y17 zTT%a$MjShzNd=ztCs_w#?NoMBeisgnjnqp}85eXTm5QjX2spOTFA}s61 zit$Di6N>rlD1eNKeb92B$p2KXepS@cs5i`;AU_Te&DN25T;7Z9*K^5#n#}`5r#O^z z><0=xbb%F4jxgFJ%mos;^Ejj^>6*s7>}cyPfKD%TC3o;-p*%qR6WW$!pu&*&0e;%y{W# z$FL%a;aslA?GjZ@>^(=uSBcqYZT9myZEZ>L^WJucz$4L2<|MV#XG*cSRMwtvK)#<# zeX45_!gWEA=#o0RQSy3Gvajj|vrsngk{TMN^wxPnd=kFoGR+yL2tX@>4@msdRJst% zfCm|J#Fczp%MKP`31yX6GX|$Y5&IUT&g406fr69k17)#nM$*H<+N zS$lzw7`##TSHy8->S#%iPA&)PGuye}6;>&YRA;r#RDga1TY!^3r#Kvgt%}hvWo=0m zF|fT2+A!v%J>Q%+A-5qIU>|hi!J+)`58w`XF$WzVv_TtmMhAm(A=iSGEU98pSwlp& z{j%yEu>JAJVQJ^)r9U0L4E*uON+9JYlPJ?`A5+kY8aJ>jmU5+0S-zc#IU}>xZ!ZF8 z*CXMm9ED=`?-a9tyf8*M^c&X+I#aTW%#;OLJU?wMeR);=v0Bn{n0yS!Az>VQ?}=Zsrj2P}sUxghL%Pn=Gvcz%sGJ`rYZ(dGGz{=i`&_KK_v7 z>as^V(;N*Uo#`y!pe=*4w=;%K#ZY`SjK?*U-7e-eX`e1W^sj!nJn8@6v(FbFF0VeH ze|-Pl$z^HhQXkH;`|9rP{q*7N#|zMl`2>YryWSUp(Fp@>XZ&P?lKBB;qCe~B?V3@6F`wueV^X+lg{t6y~F z3P+(x8!hc~QFp)3L>nb=0qt^)W~HAOKyM&@R}Dz-?CitO zpHJRjT>Z0hOb#{kT1A@)5kB@S_>#RA+&IC5p1m4)>r?>`)uOn^2E;7yJ-R#sKX_c9aLy0Q0B-@;of zGqiiTp{Z{{T-5?7Lh(4(KmiwSE)E_ahM#snZKX>bKzFXS6z+}9-{oHC%9|qutdxN z^cL$_uVet+4c{IOn)dbbY_ZN>o-MtD3)R`jysn#PAAXQb$BDr~QDZkC;~xp*RU2wa zLq{LZ&rgoT-cr7T=Gr;T0F+gt8a8pXwYAu;SgO=G{RpTyLonc zej?e-=|9~2XtmPJq*B)HD?CO2CZX%tUY))_`F|hI8_b!cffe*O8q3LjM#e6dydQcW zk58{ew;g+HRo|?$)vbR%>Rt5~>BSM`FevZL3-E!9t)#9iM`x!e=U1QKpPqkyf70*w zemHSm6kdQ)$lv4eJz@-wQInO}|FL&@ax5nJ*@xco=d;uAE_;`!4o#;#u|I(n`41+#?fUxqeP<7pIETR#5(P5={EZN)Q%1enl_b?X~7g&pldr_zGXcpM# zxfhM2=w?RGzI)?L!E6tC64k?eL3rdE0PZsN!Rh|&eH@m8HHoM0q$IMG(+A2Sk zW*JQ8AbQ)Kxu7p;D1mh56u6y(QrC0!OUIjgSmkHyLk@?Kp(2}vs!;R{MB~qx3B)td z`Dn)?O;2)cqjt*prSqLX6zk;M5_#I{g7WUIyn|J#p8&=J@vy9^jG850zDBc}cN1kP zWeRQ3nSlL+cip}2UUxs|#_hPMbJKcdBX8}w%Z;R<+Zso+ZF@Gaax|TIc|C7D!#5~I zj1@4)!2W6F+%enms@P+u&&B+41+Xd@WRQjRr{|F1nMJORMLu)LO>oFd1btk>B5CHg zmGj74)2m{V*hAzplRsI){_AHG1$XPWd4WW`}^&7%c$c{%=z}UzAzXMVWac-A@*W zS+CtU)6z1=-`|U4;1|pdGcU4 zLMbV3zt5*>PW$``v^#nW?EV%bI_pG`Pue@6t+y{(fyt1fV#Zq8zk|5ssi&25W z;kPFCj}O|XAt2O86mS9*bCT&Nv`L7<6qf zKKs?}5}&Usdx2pD$GxlG=l+L}mq#a`KVF`ep0pVUv_$zk{Mz6Bn*DFaf+_LQw?1Y9 zv+PMpyn&oE(Dt@9lq>YIvk_hN`u&IRah&gQQD+~X6WziN$Awd`%2(6bic&R)l1*_< z$GU~}FL$C_an4te?a7q#Q@*)f@1i*OJy_XMUzU4s;*_tV#TD#An?KttYIz}J4ELfw z@vafi^NG^*VWso3lE|AmuBd8r1$4fTLyE$-7b3Nwo-FWSvy7k36`pXc$TD zi^aiEvv@uh?_$Qx1wlvk6%R)(&j^=tveaA~I z%?<%)7VIkzv^QTtcinB<^4|F|rib8n7qm?>PnR;ST833O7meopH8UTVUOg*J-?ZI~ zw3Rma68n2Ht{DVVj!0%s39mM*+ms!a0yV@<_hr3W)qJJ0U#rC|Tw_DmjWR@5NtIyhfh1 z73U_0Hzg=?93pE`ayo~x;a?*00FzLe;cN|M%z_szb^$E^-S7t6(6nCZA#KJFEy%uW4%t+d1| z$*4V-zxMa)yN%{#Ia$LEGGpsQefO-}%Qv>p+}m@z?hEjdA(eqBtp(r^K;Osm-<$wG zK>&I@h5?A;VSw4>obXEo{aMfVDPl~UD_(#RMu888C?L0Bh&&j}%8_07Ee-;)dq-f1 za5xrweuO+B+A~5zFpRnQB2yn`U`WX|k{x4YiolIpF$|Cq_7GXn{1tY!?R61m-59PD+S6aVUNGJ1F!cqVfXjxNJsh zQn{9^Pc@J0?Irh+JH zxD6eU4@QK_+QgR(UL!Fi;@^Z%5Cs>ho4srT-JlQ*(TGr4=j9+~A(~D|Al@%otw=3>M zTsITalG*EeoiT$-zLh6^}l4X z4x!ieD1u5DRqEX(2~bAyvv(l9EIk;(Ar3Idrk3;ry#rNihq@lA{5?{gFgKQK)33@K zaOj}sVK0E-69Eo6(6`+HjRSP3K2UM)#RDmpC>GD6-VMZoeE0BMu*J~y2GJujjUYv! z{h#~YgEyT$+i$LDZU`=$&Wr7BeF$vH9od!)*oZ~e#1w)OjIhkznH;ruz{^PLQ!iVE z$Mf=c-(0AbuVTd1%QuJ)?H6N)vbD&mmcHOVbt@%Wu~6hNTR$)C?Uq(nHV+P}=7GNG zIX4X+*v|J{zN*^)hdA_cI9`PqP_zHvn@~HLX}$ zis$o_)NT*T=KE=A&Q*P{(8gD7Y8%#sJ)P@+kR9Rc$X|C_Fp;Mp|XxIZ3eD8|9ic+m%sn}>doG>{dW^( zP3M2v^A+nPu{uEr@y%h3)9g}84J@awV*iy^RsqWspy1LJ) zUVE+U`YjovGqN^JtF#@K!?)6RcJwcF18G=ZoP$@VDWn;9?FqQb^b3iRc82YyWmWFg zRhB6F?fDTKSqXuRImw*)IHk3*1C&>ZeW5q~2ymOQh(`*{LlOxB4jE6^#!b>jtHXUC z2s&od@sP|{T4VcdRF1o)bpxH%mET=lA; zyzPU`iYXY)$iJWsP0%XIzuYLP()XPtskH6z*zb3?vp#=tz1}Que4e}@<54sALmmR> z<3Z&E3VXRz@J2aroj9RTA8Plo8|*J2+cOQJG=URYr2%q^C;?7_VS?L5LwlakiU7e_ zhxq792fpxv9dA%!Hg(X1R+8`jtMK;&^vCG804l zj#*f-8mwJO2I1R9CBm2VMs<(q*V+&NXpfPv41smI_AGU_kZm_$ zASx1yjqjpao6<$rHHv;)@7cZ8(%bQuO%I5GP?Xek|Jfa^jT@=7pBRCITSMG#t#@3a z0bvn~Rn6B_()QhZ()E&o8(zxA*YZZs=V$ll&F)s!$-6%u_1CKacMej3(vs4Bn!Crv z*ADC4*@s5eW=!g`36kK_5)0)U1Q?|`P4ZCZ*_4IZHA7U67w z_MrhA@g0Nb={G>L_wTTkC}_=s5?+W3heiBkAuVit-yBIHOkLr}$AdnmRzm)sI(j@m zJ*~J4khpelS?ejC7Eu?kUMjkXv+N7|rk*G4=A>gFYGdij#lwP9YLY9^fT>`V;k;5X z;NrxfV7NtkPuP`P@2|rR$M>Ubo2Z9U_g?DxR52$!${pM}B zOI#Hu`R#BjOK>v7SC<1D!IZX)xNJC%&x@;?d`zJiAuPmklsXzaU{@shF>WGmCk5Q6ih*B~*Rj%uIGPR3-HJ6>q7>OFfI$K<@A5x;y510vxN_!F=Z^K0+D$nx^e^;@Z zS#IwOvGx?fNBNk1?iX4ei6aCT!Z_zuRv7gdSSWBl!Z@tebj8}O`X$n^uj`A@-_8v%s<9P(o%?dJPwAFV%cdcUn8jShf;p+hlw`vT zR2t`uDJiSX{o`DcK0z{8v)oBCfrh5AY?=n4T%{$4QXz-Dz|O&`dm{~~9w!r3QwdlX zC4;N`4#=2K6PO}l_;}WT?K|c%5QVCcQA{%GFcu!h+4aX~0}>TjwB+7schSdZ$T(U^ z2w#}hhUgor%(ZL2z;=9GLW>-FxgadkE9w)yWz+TRz`4u|sYg8d!`h?y8(yte(-NMK zW;vLv)szLXK9%17eW0kYk^hJQWre>CWG^5|kB0WXTb!4HA~G2siqC4v{tXnX7xc51 z%ddqncI#`;y~m-@3?2hl5pz8VlxHd3Ic|u&6QBgbf{oiknk%X`v0PVFP$R~XJiDD8 zVL|9Q7L?W#{fO=WG`rQy=Se1B_)_P{@6TfGLZ4yU%H^nEAW63TY;cB-Mg2<^d${St zdxRwU6Rh24EAaOqB;DUTKFmc2SpR&z5i|2EnHfar*rM{2#fHOdn!q1SK({MV-S*8u zp)NjeFR+egGs^0k4dzBLL?yQc(c}2oK5yjE2GAb@a6~SFNVYG& z7dq5fdStL_0h8s8Bdx25lRW^XzH0*Yf%wh9;R7W@OoUD6ndBcU#Y5O@BtIgQFG-=G zMp7JH9d&o{B-)}f^4kzW@y{;};20lTa zei@ydi+_uBDg^UUe&m}0!Fr*fPWuA`2Q4&2NouIi!E12gnh0M?6DX133K;;JMVO@f zb7Sj0)WGS=oeBC2cP2!=DM+c@dPTD{#gAX8fc1(A9O3TT_}0ba3hM8Y0sMzgQSQ1#Onhb)smL2jg_>)w9I_|Nv9=<)#?)* zw`p(Xg7g}#tIRrmIUHKQKSUd^$eGuzR>BqpS|e*zon~X^M2A$1*F=B4^Hl8gqKPmr z=+i-2S%nH#F_~hc4P~?mOHpJNZ?jYEx~hMamiok9Zbx`*{%o9HGu3s0db+?2be+@8 z|D04;TuAK#y)$G|>`B^R_+X7a9^2_&9A(=NBA)$2xF#-1cRK|w1?K1rsvIoouU{BeD zGti&f_RG7d3blu8f!#TgfpR|SL3AuVGeaJA7{!5!BkvELAeHsSnaUELNW1GLNp@VPr%5u0i&6o%sM!Jjt#{d4-Rg;r3&Re}`TRuM+G!HS6vH8m zL#5?7AZMRZ68AL~P1E57|K`MRck_kRZ(LEF)DiD-Q=60cT!Qd|A>84U-;fI@luOLL zD<~efu)L2YvnT-}Xb@Gv?J4-dXx3hEiFxOpp`pr(Tm~7bjH#ySqkv|WvqCq50>T6Y zGq#PEj9)W`UfO2*I&J>V?Krrj%RDh+8L07f;BEp?^{|mPLKQ3Tb$IlKxFmP;KP3F3EtgyFaUabl;^=A0$``dC#wG7yyX zSXFk5zg?V_X?%DVKO%#C=+n3~Dd<)2QJ#ay!OZ_YM@gOTzXI!dr?NSzz2RSeJ_bKo zg_h000bS9{rL*b?mW#iNKTD(aAk3u6_k|~`XT7d7Sls8)1o_dr+~5q^&(b>6&Yrbk z;nHt~qG3`J{C>NKm{Sb-ZnJpK9U+;9(LbBeb`^KpVtS)X3!^oWvg8=&I+b6LB31t= zW<)w(;HiZ7780~isJogCHxv{m_NG=jw!jt}n0|XtHI5zL`Qs%oZEDKq+#UM>nAF4A z<(dq+YtBRJnRuwxBIJxK6A^{%Ti7|Z8B})8?#D|m$kJovqy*vzk)HWchDeL*ez4?Jw| zg$ZWgU&IVgFDK|6Ro^3ApVo1wqBW|VS(bYvu$F5-J+#V%KNIe+{26AZ@UgqSKF{;- zeMZN+@#62|LhhoH0(cz7NBiOHZ6DZ=jjv^g62@CPQs<q%RZ;uWPhhV^^ng>K z?=jM8-k~(?93tFsqtUl1!&~nB6)^Mt^8hVOp3ch*?C?EC2tO4LBcSKX>tOMC3fU%^ z2o`}*ZC0)~E7aRdh^`nz@o$|{#n7DKl>oQ!$`Q4)>){+;-7wUYasbWI>qE0+R@|l`F#ndE*z01{GGb6}qY`h#qE*0Q*aB(TsCuooai=fXDGIu%c&upEZ7CwF}J+-?vzagibr zI+sIpl2f)~AE3_lbSgnW`qZ8T=2fZqwUmvA_DBA)&XqY>2w<7FLo_?~Vatnb7IoUP zAX7MZlD}g*4rO`5m-NF_ji;6c0g3=wayRT7qpv#vsp8461kl~8RUM1D<<>e04!BsX z9d}iZ^XJcflWGtq{6fS(B!175tLRc6$SEH6P#o|KMZN_gB4|OtU(}WTRp{hY4uh`# zElf&9dSr?_^;Nk#u&hOxKUdUrA}KTzRpdrd+Wvd_Lf-C{ka0G78d&)N;USFu<%*3u>A$`V=7p6Vn+T7~BgM-+NEuO?S(6RNh5Sxwbys1)TG2H9pM5ax zhBfsjdRlGQ1WugnHc!D6liI^jF}~YeBl?m^A>$u}@}Yqu0Od4qk2n-iCSmCz_=!aF z2nI8aXDBn8e8EIk$|un~{c`8St)e$P7k7jzn}FVtkB}v+w)UPGL%{_pxEL`T%MAJB zp0#4@^4s~4CRh5J^_{3CRAu{wRy{ueElxIi**Qf}fR9WcH%FhY{v-suLxmaE82v{F zGh8-*`bt&PxOBscWSmiZMwT+l`CoQ37kLho@v$)@A0e9S6*N@x8m(k=x|>*4k|k6) z6d?%5kP6!^eL8@?;+S~yPVzKumLVHsB!&f5j8ydf9^w*40$uc%kA+_@5%qyJh6;}1 zFePIKN#qAw`K010F%*@mfo%T1>!jGp5$lNV6HZ3|M&_~EYS!XLK>aR7zU;aA4z`~@ z7yF1^9_r8wACjWlX$FsDGE(b993s|i;*&0};_;28x>PouS?&B~2Dc1`$0YEvQey_6 z^PG<{YZ*ggaxOnMBanwkpE)bCyC<7?iM*5e&o-k<5P#aavPgzcz#Dv2S^RJHH21&! z!7FJa9tI34$G+k}8Ev#T)&X~&?1AS|;gd+u#kA5QPId(iUhUwe@e`*5ph3Ma4s9EH zqmxPQ-9+P6fyq*Wmtj}6miki=G#Qi08u0ylb>oW@(y@m(H%846#e-sLfq)o);9!w> zI~?)ZPnC|LIl9rKU+82--{uGv>}8co%{obHB1Tz2fj&VVDH%gi)(@g3e9n2oWe*>j z*G^&sE>gpcraq>N)wL?nfNJKG$iKdaH~qJGH=%P%aLd94%FfU zPa0OYx(c?y@D z$+`%0*7!Jzv_^w!+C|oH3;l)JDPnT?!f!ORn@N9pOvEU005F=#42S@$RT9w!l0q}M zwfejT_ zH`toC9VR$0+F2246!F<1CBr$h;B?{El{#;^9C^E)`bCWamLTu=oJhV;XDZlc#9%y* zD95FCx_Tssns0zQ^(@>~rEm3&CWSVSp;Jq2MdjkZdV7cR0-QM`Zf1HL3acALk( z#bsV*F=n!HjLZ^JI#uAo07lz{hU-c?H2y)nMW44eK2bDM?p#i}UE4Y+_RHk{hy4f* zchWS+)ttdgg#UM?%=<2pKlccq&CwHt2C@jDNBrR)X-|j6NasEfU0(}E8N@1wZ3#hK`Z$+1#3M(;R4CL<62=OmWc zHXO-EV4Rbr7myw0PC3@XzY7(0cKs<{*ct7PhD#sn==@hwbXwpc**=C#H@k@x@v=)d z0vRQ0UC4nQgv#HR?*l2$-G~8+6JB^q6H>#pN1k{=sxssyf_dv`7Crbkl6f>{hpK0v zR*lfK&k99jNseOJIY=ge;;HFW<*8xz;!W{pP+3Hx#~Q8!!-s`<7FIiSQRiU5F6zCx zet;j@;h#r9{qBpiy+cZ?`q6BhGxTo}HWC1+FeuO|nQl-`s4yZS-8;hVCuM@zr~WPKR53H&yMtb<_7| z8-@Vf%0atkSzH+;iu$;T6wUb|bQP|yVy#jjxkuc9V^{jDxExCmw}Fr??kPrfQdn%ZLn(34%R3KuzQR7Y3V>}iWmJ<@vI2uvX> z9>mdPy5k6~pqr8ampmcsCL_z!HrS?Y@!!F2KB6E%0CWB+bccvEhn>TO4E0AtL5Swv zx8^n*@Te?_;6;!D2WlSzzI4mJZhd4GDEnw}Uj2*%L|JsJDsF-lEoD^}ebnR6e9Em)Xg0xDaV51jbc z06m-%AE|Q}$M#B|#fl-7VEq(iNIp!W6!?}xoFMfnovfLlPW)YN+A@VQWmpn3@=Jf? zzh#pv$YVIlAmLP&?xlXv+e0w%sERw<@>KWy^x?pm{Q%-#wjdJ8$H`FHRY)1u7QpI; zj6h~lXiuxUem0TVuz-zZxiyUx9WAATh-6P#h%}KFU>k+OLb3=Ii8)VCaTur@A)Ub) z&`E+ak=e-AmXuLzAl;Px+YHy#bXZM%9Cn)9xl@l6Rdv4|w%S>ecr2%7zw?_^PZT;V zp~c&Jd4MFflthV+!d?SNLQjDs(kp_~ktQdbU_A8QCkraUBUo*uB4d|V!z{FxJb#Bs zq0Imib8*&@tNp;HVTDS`LNi5(OK~`zj6xqnFWQg*z4w%YN-6Z7MNd?9XrYxjf{0A& zKP+-iBdA@7<3OtL+jl}s2#B`$j37BBOo(@abJ8@E!i-;%5cGwto+T5Vm{;MH?SbTz z#{Sl8l;y5CN)Iy6Nx0$X$r2-JVP!`=!aSBp!n8}}9zakRrc2H+21L)4VA2P=76^dd z)A9^)25p;?vv_DNGSuE|L%cc#l;Z&nqxC_;K%jv0iqZPYQ%HhaPFT%2lnKZFXyNtu0<-B+B)(7DUfNJM>% zI3~R{6wG>A$pooEiXdl+5THn7gl2uvNb#2Q&~n6Q(gBq`9{T2xSb8wZeCTQV&oqNM zvgSAalQ;d)IHH1~=L_6j_uI(zoebczQ<&a%V9~OT_gBd_jSIS@I z)U4wAe13){`lOi+GlY;OM`uPKS@kG)#1lC?zd#XjjeFuIYKYD@dcOmmF9Q$p1gSWG zOdwFgynz}|qd2BuPKw9lYU<@w*O&{}wz3%`g9iTdU-{z1cZ>gWggN z5WPZ}8#1kqwJKLtUo(K1UG%Y)HCL_0g6ju+Sb+OB3~6ra4K ziJgurUrO`s4lzzW9!`Hy3I+;BEzQ&4FFy*1Fi!`_Riy|zqeLjvMAD~mkJqpO z5keD>Du`wbNCp!hST1xmV~CiCu_=sZ2cRfa1z(+4Ud*ogIv4PF2T%}DE#ckQFnt<) z$tW+*#C|GCo``vw>Je33OqdG6-Ha^qUz&)h`CsWLpG3?Y^+oScAmu?#GP1X6=U^TfS4}b z0up8k=D<`S4Sskp9fm*x$=h*qUb7Z(PRc+*B<6QnK=BN6-M@?G6!907A1l~38mu@m zUR6k0+a3Uk-2gB^imI#Bj+Q2mzc0u;I%9$j)?#U2p`J_qAT}3=CloxFW0D|D5ff|mp|j$uc_=nqk61W=YmBCz0rLz_ zMIuLZz4?{WjKHu}L^>d_`Dwg=rYMG3t^MP|Nr=90K5L+*(Q^c{UY)SBT^V)!;E!!| zFW?JI>5T@_p`@Jyx7>l)=hwWA%lsQAc_vRSC7_Wp_yTt1YHC+oSMa$qh_dy%haPpK5qiN4{aQ8n zm`?hsw&y*)_pj2C?>OBbN7n}KqmAIM{?D;??1huW7wy<%y9h|?f%m2p$dnV`wPC_`9Gh<`FOQs zSQ>MPs|WB5r(qX&V%XEW+8on{G-|dabNTOFmwdyxbhsE}=oZh9k0D@4=8ttP;`q8j zY-a7i$7Ho|g6Wzz3@i^_n<#;HYhn5z8#^Hw4dhy!S~C(<^W&{QCa9h767+bnOyM>& zps=(C zzLS*)fLg5YN1_HztINYM=JgUnf@%I-=N3w@`-|-8H*%ih<=`c+t`f*l^=3mYO4xOK zYK(FE{<JN^)-dea=il}L4knN?Wz5pXQ{X5!2-ke2Sf!uKL*&<#IA2oqrLdxJS4!#mZ`e7D!} zuO|L5a_PN;AR+p1zY&Vf*`uThaq7IyBPgmy?^@=8H<%Kto+IDrTtsL)2MVDRWK-h+ z*SvKQS*fqSP5LmDpSJ>~vN3h71OY<>V3jm3Lo?RKED+sg%FgWW6?5ouyofS&@xm!w zk*;j@Aht*|>LLMJg)T2Vj;HW{MyWSouf7@6mdg5{okm@M&qme1Z`@8Gl00&g?}0C| zBD5sEPZIPV9sON*c1jlUzxzj)3G@leXlNc&o`KMTmqJh{JpB|?3D-=JT`N-s572ZCt#3=?nH2YZ zTQPz71PL$yhKAu|L{;e^XQP4t0cR9b-Q}GlUB+_~?HeODPqJRGh=L;nK*J2?)5P4@$Y13Y(2xG;202sYtyCc%h! zZx^!RFi>&t!M_qgRUqfwOp7?H3FIg4?!Xym$^-Jhz9qKC5Pf5y#;l|Bs_SM7S_~+l z#|V(5R$8fHM>GAe=!yk2m1ET4>A?|9VI_Q#AjN(Po=Hy#vD42sa5cB8my+;fL{58> z>)b0&4JA}W6X1+7<%(F$BcX8a_{JmS{WMj5fZ*LURNBa9jjNq9a(uXQJ^9I>NqlXAxqbR|bB4FMBTs@4vo15^4UI zrFQQB8p&^d_IzBdeqH+TUHM#j^!{u3`}m%=v1LiOjf!3x0S7PkW5UMnZT~JzWxm$QT?U(NY{kshDBh?A}jfsdD zm(FMAykac@0YkQ12|74Y7vA}>!L`8FfE3VTR-Ai#-rxgqrNxQlYp`6<;!z)C?=^YdV=b$*1+;IM|PX6iX ztm^on1DOejv%36~#w@lPxm&ds@&}`i;+a*~`m*A&`+L94k+!9?zmnpf-(jJxKyG&Q zp=S{|70oyv{seyb!}gGNt#k6TNqyDaB~8w$lVWiqX~&iTsI<6qyMLo!5bwa&D@Dp( zT{9&&ty5?pI3K>yRU0-e%O+7K#J^n#PcqXr2~~Rx5#XCJ%2pz3SoKl?=-q-RF+4Rw zTq>y)qcJ|eMjm3_X2u%Zlb}x&E4dq!e$1@>{?9iMJ@ZBRiX*H)rUsGW)v!f$Hw?Qi z+4^j!$y~=&AUtB(#&Psuoxti{=1${!3?&vZpP>B_lQp*UWbicByzqq?VX^k%IXhGw0y;!1=~ zhNKxQc1Gz~u(CMvPIsK{DTYp*r4bENoPsRp z)|rDg$sK96HtL`3J7bXoGPb)>bcD&KY;p${Bu*y1@%1>fkTqK{59 z$4ss}0lcaX#=PChsJ4u*-Yu04TM}RM-CX-~(5}&3Y$k_nnn`D;(aoRi$Ig>KXM;CYdwyXYW_*8+sQn7pfC zMJBc~RiCLZ0Inio*he;GctA~%=1%am`kYsEB;XI|>924SvpZh?n_zmJzgII=T>KXZ ztv)k<45!xYt$Ie1OYl0g)fOs}8_m`i~dG>#8_e_1(J3~FcoAh@7e_YUTTMOrMN{k z!sieQg#D=+7CV&qVhLY#;E2$A>x%2*=7bZQ5q&3-AW^CUcpEpEqj7?UdVj|!L}W(b z`QE<0sUdQI*9%>wg%6_Smn{q5wgz$jLwX)x5r=Hqx4|=jLEwN9?-`?yV0!E*IZ?mH zCPv9B8*9a3Hwl|~lXp@ffu+%MU!RJ`nD6M?ednPT=ehP+Y^2Jilz-L6@kUt(F>;8G zsix3M{2&Z$fY58wonSbXjiCs?uawyX6`|)&(rSM@*9Uhk9sDV}dMUp0VOG7_+8e0s z328~}`kEyVnU>9g1uMH7Q!21*+u?+}%8;!W~XsR&vRLjQM<|#ML#KIy4?}{iEDSrbgrI~>%70Qa}2BVF`PX{j| zR-jim^GCeUY?p+L=~%S0)wIh~tTv&0pQ5OdiAaBufyqTR;RX!toM;xOIO>qLP}zH{ z9!08TCrbwA1WdZ7;*hSv6{aV1*~q_2c(4Qp_Izk2QxObU3UT}niP{O31Txak5clwF8h=VS@jy5p372& z?xn-S%g_7Y(B6jwO|_wD0wop#(v{=wk8cI7FVQS&@d{q}E!4hXR?Fe6Lt-8)TY}El z&#U43>Ek@;ZXu<7Zp+<7in*9cu;rMF$hKr!nLLq6(B^Iy)87!2tBHYq`+uCEq*;?n zYq$QK(4YK54>nH`pAiN(X9xUvH)Ex$syEbLkw!1=F){DYhl#3cXoO8(PNxke`LpG} z%vV2?1nm$FKh6u#m^$Q5{@EZ>s+SSIZyjbUoU)8f0v{9Wrl@Nh+xgTh-`8sY*El1T z`Exm}kW9QMt`o|ETbvX~!efw&$s41xCtaZWLTmAy!k9gnbbCzsoE=7ij11?%L{4*b zjaaN%ZO>!mcgJSi4$592oe@~-b3-TXrM$GtRN}h^n6PvO zQ9|;f3Qk2nkfRPJhNFO=uPW+j4N^iPys)6SNkUm;9Ha)>u7xSBwKbxsJ2DYkG)xCx zGTyEupAx0WWUqKGTtf$LR(m}OtB$Hb4o?2RDP7lT!4#&0>9&B7>sy+OSrI2aS}iKh zVc^g%Hl(9EZog_yrx6w7ApC?CWOFeRFTBop zGK!%%d{4q$H|h*syJVBq-^ipUPSbe2974iDEOb}c0nQCVxqIC682J4!Y=ak?cS^j- ze=s?C>V&1jAZBG%qzdA;PstaDF_>q zLyLUQNW&B$U9dey$w1?*pcC4__Y{-Nbg&~*5VU)SHiM0)+TS~+xz@D%VW^Ha+ksI@ zFzS;7D^MfL`y}+m7OiBOH(+&f2~GD!4>vzjJ&*QoXx)JEj*-C%79v%>Hc9Jf))@_9 zi5rqDK_$$|z3e}%>BnG`r=zuzm2ica-&19U9BR{6VP4sP7Brlc{qw!&UM*DoXY%E6 zvl;S1p+DRCM4Qp54j=`)x^&mFsXls-&K8DXaRUU=L1hNf)n~!Iu8>{@KOj( z3|P+*x}Z)|H2T^0>K*f6({A#>@p?AE8|pv|?_Opd27c+#H)nWj=Pkowprm7gs02H1 z5GMQpA}k8tEbt%EK}KR`%Z{kQgs@a?hDJbx!|=%m@`<9|nO$NAwMS&~4`F4o7zwez zEynq~@uc1=?u37q{3>_A;)6F}pC~5QnqVWr2@w)V;P2DieDr`(=K(7c)^?*b(KTSC z8XX_n$E!%6%bYC?NF(G-UZZDf5*s_W| zeN7u<#0N~-aXPA8*oc$+id2bw1AFb#ZGEZ^_z8|7V^N?IN=!+=>l|?*BLcrkKvBx# ztq=eWhbSQ6@ud-MF2|kT4Lao88}W-Ph5^Y;SXg+r5=-{n%e2SNqGwT`ftpa$(55+` zuD$LzwSVV$u5>p4tB0%gstK1(+=6@eVBgxqjuMsNPX`xLf0EFd^jB5$>3FQyf=pUY}|? z?gp$j(?ki{9^U7Z_Qv>YICsW0Jiwmm`x87E+xL&uzt<@cLGIWR7XnH{qN3-i92OWT zy<5Hl5Z{Dp&$4A)1SkSn99YFEKV(@8{K~RFecFX8m3-KLrB+|i4NkLZcWC-#lY+#0 z<#~PDyKK4}dEU2%>%29($fu$~=$z#L(WCfUwLpvoi8z19((DL#9qp3ff7d|-eMKlI zKuDP^ezKjmYJWlg7SPQB1|bXU#>;onkOy|!p~mCfdw`_+hm&PZ$&5fL38j$Wz)MX> zrA-gp-cuzOq#5?RgZ%1=+$~@hQFR6{fXj@n$Cn!X;(G!BU|eXYuHkGNeKgV+Cy{)Vm2?FBigB-=bLMlx37qT>g+=r z77T%~iz<1Yw~kW>uw6>@SPdEn{#!7 zKFvra8=GUF(sqz~Nd!l#LlrDSz4ycd{vsH6Of(x}+%P6En0M_z+F``0!YJ|Yqd-?LpF^^!rVuGHZGfVDG(G=A zD1R_F#!f$^)YQ=?&yt)mv5F=eY9mdl8o}a@>((NJHS>(STmXwMW?i87uyDks`%N6$huHwB_HCl$`g2k~hOEsf@H%J~sWY9kq z!ff+emSWexkz<{mi;3Q61*g{`o9>+JF(QOY8NH<tnn^k&Y#duLSmT$k9s|lL7fdn;*u^ z74UrvPY{qAOgC2`VPnJuM#y1O{S*^}yisO-19HHSh*GN~)53zJrha z2&hqCNz;ri;*(Cx3Xqnwxy&`{3SuWGWMH73LIbfcNzzGz%CJO31_>6?M9SH77mQY7 zP>hs5EUU!mE($d)gat54zE&V#I!^=5Fw~RmmTFb|_s8}3T4bPaFHr9d`K`Isih6fB z37WF4(_0ub%nvc?5bgvtq)}Ud)+#S}94!^fc|Oy;;VNhM5=OEW6DW7HazQt3aBoo3 zQXc0Wl%C#DBdLw-)6$Zz+6oH^U-D9$h$S==ZVk?L1{IlNw z^g5)e8ediJFDr1b0`7_ts{6@wD3HF3=We=zitzd?NK~cMA)C1FQ4+R@MHGyL0L3qD|?w#FBbsDejzp2qXZFOuZerAZZ zVhT+tb65<|ZPTf|Yxt(>Vs|n)jZ&ji)JS7NT&Bgu@?@0Zxj~f0)|pXo>%ZYLDSf9t z$dV%u^nJLzqF!4z8m1Y^w zObd8TyI3@&uCdM(-qmxSk`W=+h7j98F;{f~ts#JTMu~eZ1D`ZSoYp-1m`>v44Q^0w z#~)gmX;v6K_cSA^U%SE*u70&BfOd8PvPN)-?h< zM;TVZ8E(o|>0ur*`h*PPv0O~61NYyPb;G2N&l%GR3iZy)wf%`P`Gl~CE1+M6QELQ?ppd@Uy+g?xZerU<4eDivbMw3w5C z_(!kh-F?m4P1PY9_IZvoK|2q|jEmjadaCkuP9#|-A(xc(Bb83|oo z`!%%^@PzP+9b<~!Hg6>Tx^jx`N!2BV>uQ_N3n0Ba&bUpS#s=Nh&1)j5NZyL|u^bXM)^yS#fUq$YJ59Jg>OWtdbm2^}&HXqBKp>Vw^l ztiSAJ>_TW;I^bhXtfE4MEw9S!_a}o?+Xb{q%IJM*@D{Q>zMO8YbtG%!Cl!UxXfw7a zdH2w*hOvG*?K-k*IsLJkZZ{(QJO8cj+DR6N4X{Vaxr;mIdnS2!;JDh z6q?kgZ;_yqqjyQ;XD2&tJ~mde;!oi`?2l$vGJ^{)(2H|YAp(3Oh%j?l7>qa0F!#|5 zjlah!Ycx<1lZvQqdb(F_%Eqt0Rc zl8}laI#Bn5c|z9jVYqJPsI5<>KNINxEyG|4sh~^}_$Mpng9OoBd3RCB11*pGpp~+D zR^hBbwbQ&NNlmtO*`4pisl*xVW9;9~wq4c%tWuNWRLPn0AB34kDMY4H0^&+fGMJ@V zW&aVQ#E9KDhiPoBX4gT}w8Oqz0CapNsgZ%WH*P7|BxTRYx`fA@EN_t?;JzHt`8jJO z7}lji)!CFazw6}Nnd{>2{M^jiDw~{;GB@Hn{dGrY0+DMqkF_)LVF3BIGw0aVWSU6ULQ&i{8$dk zmb+^m&kt;OLkYzC&EgYe2)cJhAKk}C9SD_nz~_g9RgZ_- zBW7!Y7j*@bUE}eusBq-ZUs;8Wa0J`U|FoIt{BsDaIwWdH;11tiHEtz+EbTBR!aqIN z?xun5Q+(WWgbXXjew9J5XITU3vOR}OnF_;TN*3yd5n#?$X;F7=k@+lEQ`_ein~(yD zI>b;{AehLHWABN1!0}K^gvH!R*`!~!;5hAKLhacM?;sK7AMet^6-G=tJ6Y~$ zGLw0ZjLxX!K&dc#t2)9lvIHeh{r|kcuXWFd?5tyHci{unCmMq8;y>Pr4ze-uKb+n(B={C<`D(DH<{$% zk9;?|*3hv4erUWaehft1558)=-x}D#FZccN|Cm?jeX(dDG?NfPzLPh$`mw30Z>#F^ zuEAVL)3<%00i6k4878*MQsXB( z-%ghY)goDN(}AQW@SQFM`K>&YHT)fm!nngc@ZBf@)0YcVHyikso{Jax`oyRp{^~?? z;llggo@sI$1|l1SFe5B1ldS!E`i-W0>@q0)a9mh3NTeYoWU6-HY8s0k{VOKBAQLN+ zPpgwdTL3dGdvm^N9R}-9pJIj*nNSqC+WDx;^SDpnW4a>5|6;5B|E&phY)XCc{`>uQ zP`G;Y^|5!q=I!e3=k4~fb+Ubg{P|iY@ccVgf$=Ea;KOmV>)cI9fpAWVOtYn#57S+* z^PS3qf7TYqO!UgSG8s(|H)#-wT$F(IETziA&3GbJSA8yYR6CCNkDNt+W2&JWOzFpP z`b0*Wc3(<=zRO94$pi|5W5jF1dM%XRToN>`2%r%4_?&dwd2Bsh%TIjxhcF4#C#VQn zDt9PBnxDFJow0ESJpS|#cjLs!nro9$YJyQ|ki^d{!Sk{dxZ^SEVdE;;TXrx)62KFs z=kSOmym=xoh!YvE*Vfj~254Zn>44qCO8ccLF3M25$;bhKkMPVhRSUUiZ`xYE+Z+P> z$UG!@oy*BuZdBkAoU6Gz0dA<2hNI1-Lqt_vYq>6s@NfCfcNe1Kq07G=#6DYF8c`Pz zag@SB90%#WBpR}xnr`Uf3dyoK^nY=Ae#SyfT8K_VE1WYus z2v~NO?Swg@kcsHt>I-#GI5a7dU%)0uE48+a76|H5hTwOo<{m8jH^Qa6+|l)YJ~Vo` zKi#K=o)q(sXc(_R-WjlfJjOWHz~RQxY&40=DsMCm`xtlmeH;*eoemz}dlgoVtIq70 z6l@>%Ebqn-^R7k?qdDa4rC?{nlj+BW5JYiKdF2U>-f~`w4&T6BnLUSE)qsoifs4fQ z98b8nEuS-c#iv@oYx%<`@u^v|@z$Bc6{ysT>+QtqXQ`u0S7PEzDV5Q*ZbR^wM9sQt z8=KF1EzMqto$CZ+!k>wEbsCh2v(Jo?f0FEHy@0a7aT8t^3xoh?KPAiG^ztV@E!Q=Y zU);r{=vqHuiH)CHwAGq~f6~3dKv|zCYl0LeD>kG-E5Z+GV|z{<;sfF}1NtdDX76pQ z41p$uYMei4&N!I#ub)ov8y2b1RV48FXpzNlnQ>K4Wn_)L^ib>l=e91c&oJ0S`_M8y zlm0|{#aJ^_j*katf39vZg6;jwx=v$w(T{?#c8(XVg-`iglKzvrd}Bjr<4NRHlRobA zM_0p{wZ~vtAa9aJoZ^Bqn6UmRbFN&Z|5Z?J1x{lo1^IL_?A3va8{)vk<5KUQh%h3K zm4}LB7#{#m-cz&?XXF4D`fHJN{?b1%xF=X+x9qtsz7XFL*LzD{rtcEmYePu*T5K+h zNM#1;MQZUezYDr`7~bwv<>$M9OYt_mg|diZDok~^k!+@`7oj08q~`XUyeplamx3*IHUpk5#!HG5OHx`1SMKjM%E#dw-EYQm96+7V$0{Z-R2#r zoyWJb&zzOnG7SO07f(pPYd!s^-*xf|Z@WX}oNtbPKHhF`d)>(VKFHoDUl9HRd;;5` zFjKsur!r)Vi|91;v^O{liQX;8`!0^127GA} zTDEbnEpnAHrW(2T<4rdu8~+c4{rxBOyTMhT-{-aAm*LIUMVrCZRo|9>(-+2?4(wni z8Y|M7#!s2H6zFHkC=BV-?~oIk3m2W62cj(Fst7V*FF8DO2wr|Y2zBM-6J-RP>DG&Ks(hyHyVFU+k{7{M(G=$0(q(y)k8j)EP>{uzlVG(~{ zf$Ww`)bZC5ipk>JETDtVA{O3%nYtprKA3x|IKbG&-+>4Y=G%%F&unzu_8YKpVGoGa zS+%6-iAL7J-`Y`^pjt;QtU=nf#D!h2S_UoROiq-jG9hXXd8xR1*mpTfOkP(8jj)P; zs#eXmt8j3Gb_HQmviM9BUgm}fBoVuykg0#qjh{6uDoOs*`K>V3sxwbq43p+^FHUSzK86#tWo+^mAhw8iR9RL{CK^rUEU ztH=ajM$qyZm7KsB;hXsU)wj+b8*P&_{j%nLS7`QShn=&)ke9JEDSh_#;~jhBGy9K3 zC$Dw@-ct3K$Bll^RP8s%I(YRaclC>6@}}<_eotcr%7Cz&wI%S+vPG1B7fJ!Sq(k=f zW+9sgBltpYj#$#bMvug+8?mGi!FDJeBe3l8{RSjlALSjUc{%!0dr|RC(^U-8uKvg* zF8GN(vqk9r9hvY?e$7)Y#~K{dLH?)SO(XrkudkN2HldR^0o5}9uO1WLM;mRFy#Eum zE=tiv(r1Gr|5)Dd>U$I9#{mwwcEX%O?oCdVhHhkT zRXX4r%?`ouzXN$C=Z`-u*IA-NTnVY%daPg`W_)Y~Dk{S}boIUTOiiL4(FC{yzr}>3 z{IBA36#C}zEfTZh5bU?i51n~B$}_WN=qM^!FCA42;uEtexsy@U(AUuhuMnLk_X!>m zEi0(E1mO~ziN)RqZM9m~LP145g$a)U`VFW&Y`RU2T>k3DHM&-XC}1dCtC}xOYE@rk zYSrUiG4`B9Bp~D2-%*31w?0Y^!`gPgQ?`{Se%x4nElvr3qp3CQZ8zreyTi z(aHbM-uHjEZ6gof&-^QJwEMA@nzUsn&aQX8pL3mb*RO5jv-9QcYxY`*ge2A!!4i}l zZR7jf?_uzT;CD)vWarl0_qwqN4hDn4U}i9w*)N=ybRT<6{esx{=p?2QiBipSvW@`c zrn8azLD(@d^<`p58_J;m#20U|QSnU`VR@Hu_-Lc;&O|owR*y)iA9XI#TEnGjr^{1Lnw7@@HTvWADLse z=q;{2tWG%ObcwG>IAj{iV;2sKYfw(L5O_Ed@F#O+bYB1WU;Pzpf60~KdEFPfTK$9&E;AQZ@udmFY}nAsF`B_THvU!{ zsC#bW`9t=#tDvY3Y9X78S@yD;9y-~kGBsdA<0OD2?E0KnMez9nOQvwHJDB<-lDggI zES8rmG`!r*F*2EvxN9Qs2LN#0%TNFdd^hB#`EmdzSo84z@<4o#Gy@h}Wq-SMCA-Eq~fvy#o~iE5kP z;;+6tJI@Muc3f4-0DB9_oBOLpqQhxArisi{x)2GQK3^Rv&#zu}C7_r13()WWtcT+u zWBY|jSM%lSsCIUFA&cO3q#cd}^+9(M9;||dGWGc4{8#(!>d5#H&e}9e;SRWu&Za44 z9u7&;k*ebuFQB*|ElN)52JYo{SWdaa60IcWK{VQ*9YT{9;+8(BBWvr&tDBAwBoPHN zmYR&&(_}0%84RV#l&A_SkoE@R+trP>fT1Jz=v&u1L$`P?3QQ62rl$2R77^`1ltPsk zxIL5xp>A;G9=QkNDpcMJ#KA}^@5v%0I&pG7^QryE-JOk)4)1r>)mDyHz|6iOA9+GX zPYBeMEqlF`j zCK$Np)`LMA`;Xn(&j-$*|J8f;^Z&W~*R#93Z5!?8$b-J1lwLz}cO=i2I2>S~CT?4w z|F?_(U)(8OF81?(w8wuQ9X>C{e;zzPdh-8o#PA&iAAgL+{)|n;uKbA z^UoF7fh0*>7z~JL=UUc#hDYQ?9Ba>T82F&&yyhJo9H5ia(pg&8h{?!07ZTbL7eMMW zMtCPq_hX!n-IVHFat8-CvSs>l^^Z3Y3}p`k68i9oXzCms*x6oJ!mz(C4EqaU*w+}A zP?4)&-V)Z}Ss4>^So-|6Vn)g&=;Z?^I7?lr+XK3&Al#RiNurCrAqPpZ>LB%{i+-=reah?xu<2M>a5DZeLf_Y+%BfsK%rG2@wu&jH*-pkwO=K0e$;3#Q&a*FIvkxF`W zjb2|}y}c5(_+UNC>VYZ+MgmmG)^A~vi>ybYbGyFNQ>m8aezZT8%SUGwNXU#tGB;g9 z%mRO+Af%bQaf0WZ0U|wXjp5>k{`kyF- zwl@9mMgMufsQ(?kIDXRqHt}p+|1F0O=lj!In=1PUm5NSIk*hIq)hn~H%Gp}kTvt2PA27m|o0KN7 z)t(srrX-mJk=Pyba8f)n%}LXjQXTjrV_5_Qg|iA3ED!Ru<_o7TO2zm$?=HjC4@QKg zCOXD|Pm%q<3VV$?=FBiE>F$REwcqpTr4)nzkp9Vkgh%35k4?Tu#GKe8rT5r`NC;fasq>eg(RC7Z*_P@#?A`4R&3I8BQy!{ifr?aEvLCXE~&VO#3q6yX?Z z0OWpkE0<0FFDuuztUl_Lk%~8jNH9dZW>mBRrU&y;B+E$w(_F`2&@>8u7c^FhFW~lC z0i7H+t6K(yTgswXo^&U0onPrV4ZL1jAS>tig5}%7U-I20P15Y0{Hy4nzBIhi22AaUc58~-imLq* zw)r*hM}NJ45v4AIpSajXyEKtCeR{gOj0{3S7pX2AkR~`{I`eB*VSkP%p{xYNvC!^r zRcRWD;&wrlk`XDnx?gd^nSSnfvO)=etqydRywI8!jp`lXrODCut`Wy@a@rDAP!(KR z8C*aUv`c=^0j~y=y8$IOWijF}f(qsa={dr@7|cn>pMG$G|XNIFpmP}H4mPZSF0180IkIkX@~)k_nz$ZGQfGoAJc1J` zd7x>e+yvNfPMPN{{c8e{eYnWG$NyGRIG)=3*n5S3my$$P40mfE8-k%#!Glm((C7e}cNW5>afpRNBwx4qmO*_n=`nUF+QDCf`O zo}iYD7CrO@$^-lpPr_c-4Tq7-0#=c$LTsxgjG&^ME4OUbOCHvkgcFyIg{Y_nA>Y=( zDB}Z>8j)votAkVC=t}MNp9_)gJA-)z02!*UVF+Ztpp%|m_xa*PC?0Jr;GkC7;I_vzg7Q#c~FY~I_$rA(*HN{Y&`z!_2-!HKdRKQ zt||`YW@>jdQ^q-26PXGJz6EKfR0iJi?TjQz;1e!nlWF9k<0JTIFu9%%hrwrLJ9Vi` z&l7@ERSX}{G6t|SzZ!UIatJ8-ty|-o`*mRii(Ht4Ci-23*_y45RwfjuR3!4| zUnMWryHW)=X2UZWQ&~T}8+jC&wUcrAQt5?1KFAD*ihGKUJI53?;AAcqqtk{J)7WYS z%SMwY-&NP8Q>Bd?$XC6+_fo2ay6Po$rt4ms+$(DHi)&6)kjE#o_T)571IH}juPs_x zZ*c&(PgK3F_Dvb!RP4;=xJ6&4z=L1zzf0rVjSQ|l%Ns}Lb)X%Vk*MqTQ8muObk`V= z*_v{DO-7~!?)DZU#Xa@EF8aT?JGid+pZ@WSe#!s;;`k~4XCu$X^?x1yBe+U#n+^M> z;=bHgsRC-Q<^9&GW5;|OzNLax;<8ArCmY$5x&CKUfKLIGgI?!;*w=SY-^L=tf{2mf z*eFk<5dx&*>_t8Ktj-!51v3&UvjTj92y!-SZNo^uV3tRw5pmI(s7MYu%2FlxMRbU| z8@v14l%>+|sfpi%PX^e#xy6Z}1z-hXkji5A-v-f;cBn~MUt(L0Ui1qzElr1chc~06 zs3j)7)8U-&?6(As@r(~*MiLwrDayFyHTeOt)IENQK)f@$_mcrSs)@aJAUu{zp(ToCW_|>XHQR>`~ zc_*QBViB* z@RVD&6{{v+WT3Qe@?Yem{mT$}k3Zo!R@dK*3ke*TQxrr#`P}r?wnn=CPC@HpQy|*c znoi(A6O@oN3CN6a&Vr+;Fd^8VBM(%0ztft`(j|zqPb0K9m+V5B%=tBlY?-aV|B$Z} zP|TmvugIx!X!npEl4z8UZPY)2Ii!3JA%-k(!RP+n7(6VOeu-m|lVjN(F_SwwT_U<2 zlSG^+Y8nR&v6OOlZ(0il$Q6r0l&>=hg&fGI@mB%tZ+U1%p`>p4tLs)3LTL{XcXYy4 zF!p<>DQvswV-SW2juwYO!cvj3Odw-JO1WW)*nBdeAyY$c0iAg-D%709dDJ3Z3pA2yjzK!0H+qz-DlA8e^XEG%&x)_3*pHjj0 zdq|XT73mzL$sLhf&Q?I3;tu6noLy+*L-q@qsSJE`s$#ZG%mU-f3lY9%`g~6kazleI zEe;_UcQ1wrSF9Y~7oA2vnnoN8eHx)yUQOx_lV4^`sQic;S8<$y(~54g^lPxjfPb^T zFk?FR2->+J^TuvcmETM(C}5R<6^WZk0_CO@q$GaNLg>&%mpYw}8tN>-#kH9ckIU&y zN-%}AB2QjKG~y4}4L~kvNr6qtW9loMq+={Un3BEXxQP@Eny9j2<)DvTbOkFioEwX@ zKrT7rGhke~fXft>(Au*WC?__j``R!^jfu!@@}X1<86)E$tkjJ zq_YV~kx=+KTj+*Y6(UsK?3HSqiK}7(D*Zw=Rai(#YqaklAXm~#He*zgCTMiuw^ zX&Qvg9g*}0GXFlI6Tb79B|@2v+`{%`Y_gd_RoCqYRb{ERV`#y}S!YPga)dalnw8fg!Vj!d;vM)a7k&BCO4UQ!BVsdcWp zlzC@lJI6k#kO-k7an!raQ21nj!#>%_r$l7EloC^`CF1?3$X0_^xHKgVQg~I*x^Y`N z8*@!tBh|zgG&p`vBG075A4YW+BcDLwb~K6bAS8Z10ft(mr{-F#yVkp{E)QH9E54Wk zu9`2EQmn|QlD`2NZH0zyU{t}%<`wfIDv-u$sT_9YQ90$g`B0GnO(d49M#QkUR+Y%E z9+%2hpTCanN}aMW`PXTpN3t8zTaut%zU`ca@ff3iuP6R|Go6qm@KC>pcBgS%ZuLcG zgZss;LxHODr7T(34#h%+{O+pW<#Xa85PjeYgzCqP~ zUgc!w+QUqPEUo|itM=QLx6*TfQJj!jK&Py1iD1*DWnC7#XxX;dA8hq5$lYzstwvkm z_XRaJ3yQKKYm%f|IzOsJ%5t_n|K~T{zpDZv}<3Soal2B9d{FxWQ=1b zj3?&NSZ6Dde=x2}Gl=i0*OV)+BBK0V#EM;`Wc4Dc7Oo4t4MVcgHjd-w#2Doc&CNzo z#+2=)P=i_K0hLN^9HLzhr^wcEJKOFR32_?C$Ta|T?(X!LqM2}!*gdoh7ebW*lKae- z`1DZDA71UY>59d!L_=Mh?5zx;Lh;ANi70w+Prvu{LFDQ%nmAgbt% z{1v`&)Q=tS%hYsi_}dZ{^;wNG^!JXwj%FWlV#^3e@;RnSivIW`18{eDy1jcd9S|=K zfjG)jV_e&4yb50Ma2RfGnUqcXHjqQnZ;VEKhdQ$_SX{$uoyY=F#4M_rnamySWo@6D0w}{D2yY-JHVy;u z8ZrJ4C=tZXA30#-3pj5%$BcYm`V@|BoMIN?Vjre)Rtqgl99-987m1S}7xgOaBlt5r z1geEn6RMYHniw2XNR36zVC&2^o|Eh7Iq}y*ORNMq^ZN18$fyBh23E}g3B##$t z8JAgmv|Vs)?FJ^$`kxvPNy~4p%6XnmV*!)k3!|5Lr=b$ukz`l|KH*y3Zl`{ zCP1tIzhCnIzkKrlZ06ax{{K-h6T$;JO=ZE)goYv9)5W7EwO{k0Z2u0A8p=OiQJOZ1 z_eyA{&m7WZY0s3cE}q!PDB;wTd5k+J_>cw+J>0=O`h3 zm?V<1%y>ovzf5geXE}yq&k&_cqFIp8NL-wQ>pArm2qkSu!c-ALh^B_zW{&K|;k`IU zOUv+WJnb0|{&bN4MjYS%FCJzLM}C4A*bG|a|BL=%@&5PG(ecyy??#@D%YPX|Nzl3C zq%1RbRx%bRqU3w2#B-M@(~L(oz&huUD*T|sVAVygyot~)W+s2bP_`3sGTC5N^{Ir& zU>Oxrrm@!k4(3Q~MZYROx9XaXt1l;IJ*jKcm}TG6gp<`(cY035cx(5_uEaHr&cgM_ z3KJ%SAVHQc*5=^J;OS0)MB4%cfAF4>UpYquem zIljv8sw2a*5Q=sg06A{rQoVEqw<7qwIu)rgcMTbMrk{f_z{%XWttEWgkd+4{tMswa zq;TiEQMk1(6_q)vL0mn6*l0yN=TUPr6b+6kUZTiginUd|XRRFEg-DbpkevaoYU1U} z&4#kr+$-r;J?Y&iL&51V3#M+jW7Ua>dK64N)b6#9!RnwV&^Z!X4?0@RBsQov=Nr3&qLax9T`|st;qobnzcX0G% z|83-XIQ#D>&PlJnTe+2|2x*#*>rKZ39KO-=4{FTDD@xNE(=jn#*|}aT;PCBN zg_#&Irt;_3@7vAS=I^ga90ne+NZoMCEy_?IsYzU%rCPH%*Rb9+mOSF{DPFO4oWmeL z8bH!ylw}eflo+ncLe5`pFpE#;aOjmUIIP+Up(tG@@=Dzh#rqcK@I?VpQ~KD(TCf|4 zP_wA&xv!#q2PVwES_7G?aB8O5e~Kfg%MQ3QU(O1Zfi8G2;mlEBE8s2T$ms}X#cmum zhy~_-Nf%BXlzTdG6xc`ZzA?q=B5N$C)UDBZv&Q9?8^V3onYkk^vao8tTd`w~uiph` zHdC{|%300OZ<$e3N>cG#b&B`hWTdFP<0g{~aAX-T&Ck^ML*z&PlJn z`>%wI{<3-}kYv-x;{-BCTki=HXy4NpWOlVChftZki#dek_bYJ-rN`zFdWBOwz^wSaFMr;YL+P5RiydWGl6cn&>1>*gUuV2xz|nkBiz@VV&VgHk=>_P4X5212MM_HLoVR5exF=n zM|)I0IY!bBF1buBwK?Nt%MMI0+B=M-jxH;(LJyoo<4`)M?P`^w6x>&Z!+ko14a1P)oRJ*6I>% zGD*JPsky&jR886X{h|-;;Awdl_WwcN+r=(|w#9!PKQG3A9UdP%-T&Ok^ML-p`St() zarKVBTwdmfcl*I0*Bbc+J*>&iS0v_QPCod0B`!V_(vlHhIb@cO_cEb8MSDF(dzCGG zSkeChPOXQI^~y=kN99#|;7BjQfKPE=594cU-SbxGXQ%ROx-izWyzcF}5bNqIkLRjZqrbY@?Cv7e(r{gIT+2R- z`hT+a-JL)!@n8LyCI8RS@zedk%{&k1|G5;Lv<@eb!K9DI6O`dp?+(h^+|MUu^tB$x zP&I)U@(vjw?wJOr0#c=mNL!b>y=i{6L*>$5{mL>&M@t`ut<(@*RNY&pW5vyHHV^1c zDL1R6Y`vLZZeDNKR;-N`rI;yWk$1013KkvTif zz z*J{dbx(HHgZj*?2a;1txTm1}f{tkyi}JfgKokF4o? zeIVK{K|oh7FUZX=aEo+x{q3RyjAW2MRbvaRzS9iZ+F0LHU z>ZF@V=mjNR5o!yl70Wxbw|IGxS83aR#q3f$rWTf|VTrh~%uRl1YPYEWcv1gvLi}LS zLJ%$Sf5*=ciuKl$bK@`2#ugV{g-z$fvT!VG)_FBEVOB`6ySzH|jRt^&M17I>}3f(7?Fh}ir52_wJ z$6s|V^}f8z&WJxNa9cy{oY}J8x1ATkwH+@UCujEl^*gTH+)zTmHtp5bo5Etwr)n7Y zw9Ew1N9l4BJDw;WsSGhO`p%RFkBrI~>_r>OtD*Lfx?)sB1ceAJm z97r{}rnmlTd+Y1ox~P10nx3e0TuGa%A(U$#7p4Kl#%8ZZS?%O_Hru(z&aX9 zP(fs9DDE6j!rX1g%-E~(r(|kHtv{u@Uxr2`A_-23zu*0ur7Zj2*1u>b$0m{Saf++E zsE>Q-px0+xl_(MIYVTOiU~1MPM$jJ{+HH8AW#`p|JG9O_K7RbD_6+MAqkK8Ytt{7M zMAGwVl8`8KD%y6@af2gYOAaY93jPz-Qytadqj&UmH2Z)PGf1)qjm(BY?=o}Q6HNqb zpL~iwMJgKc8}=!xuyjP{0&_ldk^*k8CeSPI0TAGKzF|9Mv8D?&W8X(Rj>FX=Zf>1! z^X5_ta4c}-yW9%PSRzpUdAEdpCGQm}_mJcjJH|HjQJNqzth!2}6ih zK@*&M;~*OCp@f7u4Q6t~%YMg^Z*8H7j6{6%u5c>II8yXKdoFq#g>ytB_>!Z9Vv?XR zh=^;sudaW&=G&9Ch0cLN(TDSE)HRcw$KNh1a!*K#jDrMa^r;lM!eK=1E1i1 z(JrCCS?-K^)F=C2kw2k!{a?L4d-c<6cjDi_kCyviFJAUv7S{iZ7l%*w|3;oI^qr{a zuU5m4!64!K#yRH(%Q{0p|AT~+{LlZ|9j9r`PWJctCgHO2zE3^2pVBz+*nTLQ{v!El zi?`{4=X#XTY0O26;4u`^QQ)BgNpA^>G$P_V*Rr;@(7PZ1^6JX6e*N`Vt`l26iAm&> z$P0+nyZNqoBH_UfEuEkz=+OP_epc}^lm#hG<|l}H!O8x9LPh~gleyD(ed^ti#0}{F zK=d!V=Uqa-9*r0ciN!~ObpLZSjk%(!n*n+_4nC;vXMO7?i2M`8P4Hm!6OOG3NikP{ zIpzZI3Y&+&VD4}lh9Z~|j-=IBley4sko^x5h7^6IN$A@GiLEVk5v2+Br*Mv7Ss<&0 zCJ`re7WjlAtVpliduU9;m?R9{jstIuJRETy2K@JMQ(;Cz8l#BZ%4tDUt{DraD6v6L z?Gek`jjc zZvW5UT8LaG>163aQ7fE(;;@8BgMnoFKifEX!Db zEnQvdmN3l%K3@kWWJ&z}XcR=BEi1*NHn0Ltibp1xzS}=``;Jcr0gjyhfs-5`Syns^ z!%G?lUMsFZ?BN_?0sc~ds86{-rP?_QZ}FV%a6?Js!D+Sw-t}~6Pn=hA3xPMk7`~zD zWkMK<(j9@1IO%5@LO4nA+(IZwiSR!(W2(&OaE_QlIubxQXKM6iKWI0*3rcAh6G6Ylffrirw zLDvEh0!Vx4VyJk}cI-W5cJl@{DchEtgC8)CCqw=mHcGLr@a-;$Mmdaa$F?l&d4#c_ zs88C^J%g5LLj5e%xEAkRM^^;J~DQ-9kuv5qTpORPzIwYf^Gr!hktqQ!c4Ka?|-%MtCAdA{Kx#3~Ldx z-k7>f5FsoP-$RT}2ugzqVI06Mj$l!a_}4;zNkk|@Oc@IXK^UZS(Jg2=V-h5+NDZz7 zsoCAiB>BFi75wfvPPO7Hsj|G*icp9LB$PW8j^pm1iYa^>vKPQo=FKgc2S-C;`ahQ$RbzSLTB+=|dUt3lN#pT)c^~bkYuk;Hfyo%o^baG<+ zh$NvQ)NGi4(?BjYJ7UDrMO?~%P<^+scq);q{1@`9cyVuul`Z>*6WA`{3J~-Iy;qXC!iR0m}*>2lH0`GlL z40CfakCA(IAS$5OM7nP3H2n2VCTZ zi8{6Iy#g&yZ5ud#r_i*c55CyJwp!@Fa1aH*eEr#irB@yK9MdF42AI?BU2ed7X$T*y zvpNUlT#P-UZxLs_fEIIEo!WmuNzh*n z3HoawLBB`><@0zSj}q*2O$9{AJBs@5fqP(CKfjI88#*JC0ZCB*Xb&A893Jcm6MA;2 zoY?3VGXy3GH;;xv6tFSzGfRIIq~qxT41LbL(n-3-Qk+hiLx)Z}CXVz6gZ&>cG{L{o zL^-0ksV8C!86U7zVDyo`H^$M3FyWREP8a?@b7{ym1_nY(xlo` zBsiTW9F*@9ICT|6JrWueK;i39s=VNQ(OteK<~5RE(XNylK!?E`4QM(R zA05K@jui0?KzwS2n-0dGhk00rDZDF)M&Z2YqM!dk64LDHR31*w12_)kpd1kEJurJc z9C4=d(S!nxGGiAH=v1sL1Fv7jk-2L*=sl-`P=lmH_16+kvm-Z$))4=`za?8cfSe=Q zyagNH;k!IHaXc7`h54(L?Pow(*zTXffe9L8h6Y@Dr-@HEL*phd+LB^R zG)(9OVLmj$i!>r?Pf|`vxpMXZ9vgF$A=*jNkc%!H%~8PEl(6ny3LRapBgv@DBN0vl z$^`_M*>a|&)5ZMSr-bqDmB>=-5l3@Akr^7FO4%>8^(j>qk+fN9i;fy#Oy+io#krPvvIvFZr zruYA5LhLe{$`1x19qo%Y#Ni`>KAqX2lT!K5qy4|ZwkE?aEh9GbzdRbx|H8MiqkNpE zB^&!_8u>Dm{Vc}bm?$uNNZmR*bPv!jZ(z$;cJD71=bZ_j0~>Pb3p@bJn|$_249nl6 zlQ;~739Ysc3BtAhDFM(yiebfbRMlQ5TOpiU7Lep*fB*LO*2RFLOOw%lD4MYSA1}^d zzqy9c(!W{O`zR!gWt-(-uH5%rVu$z^aX~Ulh!F5Wgl>}{h0|t6hbbqKQYjHj!*Rc&gXgE`>3Mn{{P}+Y00960IYEPk0OAG! D4%VBG literal 0 HcmV?d00001 diff --git a/helm/airflow/dockerfiles/README.md b/helm/airflow/dockerfiles/README.md new file mode 100644 index 0000000..8e663a0 --- /dev/null +++ b/helm/airflow/dockerfiles/README.md @@ -0,0 +1,28 @@ + + +Those are images that are needed for the Helm Chart. + +In each of the images you can find "build_and_push.sh" script that builds and pushes the image. + +You need to be a PMC with direct push access to "apache/airflow" DockerHub registry +to be able to push to the Airflow DockerHub registry. + +You can set the DOCKERHUB_USER variable to push to your own DockerHub user if you want + to test the image or build your own image. diff --git a/helm/airflow/dockerfiles/pgbouncer-exporter/Dockerfile b/helm/airflow/dockerfiles/pgbouncer-exporter/Dockerfile new file mode 100644 index 0000000..b2a3926 --- /dev/null +++ b/helm/airflow/dockerfiles/pgbouncer-exporter/Dockerfile @@ -0,0 +1,57 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +ARG ALPINE_VERSION="3.17" +ARG GO_VERSION + +FROM golang:${GO_VERSION} AS builder + +ARG PGBOUNCER_EXPORTER_VERSION + +WORKDIR /usr/src/myapp + +SHELL ["/bin/bash", "-o", "pipefail", "-e", "-u", "-x", "-c"] + +RUN URL="https://github.com/jbub/pgbouncer_exporter/archive/v${PGBOUNCER_EXPORTER_VERSION}.tar.gz" \ + && curl -L "${URL}" | tar -zx --strip-components 1 \ + && PLATFORM=$([ "$(uname -m)" = "aarch64" ] && echo "arm64" || echo "amd64" )\ + && GOOS=linux GOARCH="${PLATFORM}" CGO_ENABLED=0 go build -v + +FROM alpine:${ALPINE_VERSION} AS final + +# We want to make sure this one includes latest security fixes. +# "Pin versions in apk add" https://github.com/hadolint/hadolint/wiki/DL3018 +# hadolint ignore=DL3018 +RUN apk --no-cache add libressl libressl-dev openssl + +COPY --from=builder /usr/src/myapp/pgbouncer_exporter /bin + +ARG PGBOUNCER_EXPORTER_VERSION +ARG AIRFLOW_PGBOUNCER_EXPORTER_VERSION +ARG GO_VERSION +ARG COMMIT_SHA + +LABEL org.apache.airflow.component="pgbouncer-exporter" \ + org.apache.airflow.pgbouncer-exporter.version="${PGBOUNCER_EXPORTER_VERSION}" \ + org.apache.airflow.go.version="${GO_VERSION}" \ + org.apache.airflow.airflow-pgbouncer-exporter.version="${AIRFLOW_PGBOUNCER_EXPORTER_VERSION}" \ + org.apache.airflow.commit-sha="${COMMIT_SHA}" \ + maintainer="Apache Airflow Community " + +HEALTHCHECK CMD ["/bin/pgbouncer_exporter", "health"] + +USER nobody + +ENTRYPOINT ["/bin/pgbouncer_exporter"] +CMD ["server"] diff --git a/helm/airflow/dockerfiles/pgbouncer-exporter/build_and_push.sh b/helm/airflow/dockerfiles/pgbouncer-exporter/build_and_push.sh new file mode 100755 index 0000000..1c5955c --- /dev/null +++ b/helm/airflow/dockerfiles/pgbouncer-exporter/build_and_push.sh @@ -0,0 +1,68 @@ +#!/usr/bin/env bash +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +set -euo pipefail +DOCKERHUB_USER=${DOCKERHUB_USER:="apache"} +readonly DOCKERHUB_USER +DOCKERHUB_REPO=${DOCKERHUB_REPO:="airflow"} +readonly DOCKERHUB_REPO + +PGBOUNCER_EXPORTER_VERSION="0.14.0" +readonly PGBOUNCER_EXPORTER_VERSION + +AIRFLOW_PGBOUNCER_EXPORTER_VERSION="2023.02.21" +readonly AIRFLOW_PGBOUNCER_EXPORTER_VERSION + +EXPECTED_GO_VERSION="1.19.6" +readonly EXPECTED_GO_VERSION + +COMMIT_SHA=$(git rev-parse HEAD) +readonly COMMIT_SHA + +TAG="${DOCKERHUB_USER}/${DOCKERHUB_REPO}:airflow-pgbouncer-exporter-${AIRFLOW_PGBOUNCER_EXPORTER_VERSION}-${PGBOUNCER_EXPORTER_VERSION}" +readonly TAG + +function center_text() { + columns=$(tput cols || echo 80) + printf "%*s\n" $(( (${#1} + columns) / 2)) "$1" +} + +cd "$( dirname "${BASH_SOURCE[0]}" )" || exit 1 + +center_text "Building image" + +# Note, you need buildx and qemu installed for your docker. They come pre-installed with docker-desktop, but +# as described in: +# * https://docs.docker.com/build/install-buildx/ +# * https://docs.docker.com/build/building/multi-platform/ +# You can also install them easily on all docker-based systems +# You might also need to create a different builder to build multi-platform images +# For example by running `docker buildx create --use` + +docker buildx build . \ + --platform linux/amd64,linux/arm64 \ + --pull \ + --push \ + --build-arg "PGBOUNCER_EXPORTER_VERSION=${PGBOUNCER_EXPORTER_VERSION}" \ + --build-arg "AIRFLOW_PGBOUNCER_EXPORTER_VERSION=${AIRFLOW_PGBOUNCER_EXPORTER_VERSION}"\ + --build-arg "COMMIT_SHA=${COMMIT_SHA}" \ + --build-arg "GO_VERSION=${EXPECTED_GO_VERSION}" \ + --tag "${TAG}" + +center_text "Checking image" + +docker run --rm "${TAG}" --version diff --git a/helm/airflow/dockerfiles/pgbouncer/Dockerfile b/helm/airflow/dockerfiles/pgbouncer/Dockerfile new file mode 100644 index 0000000..f561fad --- /dev/null +++ b/helm/airflow/dockerfiles/pgbouncer/Dockerfile @@ -0,0 +1,77 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +ARG ALPINE_VERSION="3.14" +FROM alpine:${ALPINE_VERSION} AS builder +SHELL ["/bin/ash", "-e", "-x", "-c", "-o", "pipefail"] + +ARG PGBOUNCER_VERSION +ARG AIRFLOW_PGBOUNCER_VERSION + +ARG PGBOUNCER_SHA256 + +# Those are build deps only but still we want the latest versions of those +# "Pin versions in apk add" https://github.com/hadolint/hadolint/wiki/DL3018 +# hadolint ignore=DL3018 +RUN apk --no-cache add make pkgconfig build-base libtool wget gcc g++ libevent-dev libressl-dev c-ares-dev ca-certificates +# We are not using Dash so we can safely ignore the "Dash warning" +# "In dash, something is not supported." https://github.com/koalaman/shellcheck/wiki/SC2169 +# hadolint ignore=SC2169,SC3060 +RUN wget --progress=dot:giga "https://github.com/pgbouncer/pgbouncer/releases/download/pgbouncer_${PGBOUNCER_VERSION//\./_}/pgbouncer-${PGBOUNCER_VERSION}.tar.gz" \ + && echo "${PGBOUNCER_SHA256} pgbouncer-${PGBOUNCER_VERSION}.tar.gz" | sha256sum -c - \ + && tar -xzvf pgbouncer-$PGBOUNCER_VERSION.tar.gz + +WORKDIR /pgbouncer-$PGBOUNCER_VERSION +RUN ./configure --prefix=/usr --disable-debug && make && make install \ + && mkdir /etc/pgbouncer \ + && cp ./etc/pgbouncer.ini /etc/pgbouncer/ \ + && touch /etc/pgbouncer/userlist.txt \ + && sed -i -e "s|logfile = |#logfile = |" \ + -e "s|pidfile = |#pidfile = |" \ + -e "s|listen_addr = .*|listen_addr = 0.0.0.0|" \ + -e "s|auth_type = .*|auth_type = md5|" \ + /etc/pgbouncer/pgbouncer.ini + +FROM alpine:${ALPINE_VERSION} + +ARG PGBOUNCER_VERSION +ARG AIRFLOW_PGBOUNCER_VERSION +ARG COMMIT_SHA + + +# We want to make sure this one includes latest security fixes. +# "Pin versions in apk add" https://github.com/hadolint/hadolint/wiki/DL3018 +# hadolint ignore=DL3018 +RUN apk --no-cache add libevent libressl c-ares + +COPY --from=builder /etc/pgbouncer /etc/pgbouncer +COPY --from=builder /usr/bin/pgbouncer /usr/bin/pgbouncer + +LABEL org.apache.airflow.component="pgbouncer" \ + org.apache.airflow.pgbouncer.version="${PGBOUNCER_VERSION}" \ + org.apache.airflow.airflow-pgbouncer.version="${AIRFLOW_PGBOUNCER_VERSION}" \ + org.apache.airflow.commit-sha="${COMMIT_SHA}" \ + maintainer="Apache Airflow Community " + +# Healthcheck +HEALTHCHECK --interval=10s --timeout=3s CMD stat /tmp/.s.PGSQL.* + +EXPOSE 6432 + +USER nobody + +# pgbouncer can't run as root, so let's drop to 'nobody' +ENTRYPOINT ["/usr/bin/pgbouncer", "-u", "nobody", "/etc/pgbouncer/pgbouncer.ini" ] diff --git a/helm/airflow/dockerfiles/pgbouncer/build_and_push.sh b/helm/airflow/dockerfiles/pgbouncer/build_and_push.sh new file mode 100755 index 0000000..59c6114 --- /dev/null +++ b/helm/airflow/dockerfiles/pgbouncer/build_and_push.sh @@ -0,0 +1,69 @@ +#!/usr/bin/env bash +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +set -euo pipefail +DOCKERHUB_USER=${DOCKERHUB_USER:="apache"} +readonly DOCKERHUB_USER + +DOCKERHUB_REPO=${DOCKERHUB_REPO:="airflow"} +readonly DOCKERHUB_REPO + +PGBOUNCER_VERSION="1.16.1" +readonly PGBOUNCER_VERSION + +PGBOUNCER_SHA256="087477e9e4766d032b04b7b006c0c8d64160a54141a7bfc2c6e5ae7ae11bf7fc" +readonly PGBOUNCER_SHA256 + +AIRFLOW_PGBOUNCER_VERSION="2023.02.24" +readonly AIRFLOW_PGBOUNCER_VERSION + +COMMIT_SHA=$(git rev-parse HEAD) +readonly COMMIT_SHA + +TAG="${DOCKERHUB_USER}/${DOCKERHUB_REPO}:airflow-pgbouncer-${AIRFLOW_PGBOUNCER_VERSION}-${PGBOUNCER_VERSION}" +readonly TAG + +function center_text() { + columns=$(tput cols || echo 80) + printf "%*s\n" $(( (${#1} + columns) / 2)) "$1" +} + +cd "$( dirname "${BASH_SOURCE[0]}" )" || exit 1 + +center_text "Building image" + +# Note, you need buildx and qemu installed for your docker. They come pre-installed with docker-desktop, but +# as described in: +# * https://docs.docker.com/build/install-buildx/ +# * https://docs.docker.com/build/building/multi-platform/ +# You can also install them easily on all docker-based systems +# You might also need to create a different builder to build multi-platform images +# For example by running `docker buildx create --use` + +docker buildx build . \ + --platform linux/amd64,linux/arm64 \ + --pull \ + --push \ + --build-arg "PGBOUNCER_VERSION=${PGBOUNCER_VERSION}" \ + --build-arg "AIRFLOW_PGBOUNCER_VERSION=${AIRFLOW_PGBOUNCER_VERSION}"\ + --build-arg "PGBOUNCER_SHA256=${PGBOUNCER_SHA256}"\ + --build-arg "COMMIT_SHA=${COMMIT_SHA}" \ + --tag "${TAG}" + +center_text "Checking image" + +docker run --rm "${TAG}" pgbouncer --version diff --git a/helm/airflow/files/pod-template-file.kubernetes-helm-yaml b/helm/airflow/files/pod-template-file.kubernetes-helm-yaml new file mode 100644 index 0000000..a748dda --- /dev/null +++ b/helm/airflow/files/pod-template-file.kubernetes-helm-yaml @@ -0,0 +1,141 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} +--- +{{- $nodeSelector := or .Values.workers.nodeSelector .Values.nodeSelector }} +{{- $affinity := or .Values.workers.affinity .Values.affinity }} +{{- $tolerations := or .Values.workers.tolerations .Values.tolerations }} +{{- $topologySpreadConstraints := or .Values.workers.topologySpreadConstraints .Values.topologySpreadConstraints }} +{{- $securityContext := include "airflowPodSecurityContext" (list . .Values.workers) }} +{{- $containerSecurityContext := include "containerSecurityContext" (list . .Values.workers) }} +{{- $containerLifecycleHooks := or .Values.workers.containerLifecycleHooks .Values.containerLifecycleHooks }} +apiVersion: v1 +kind: Pod +metadata: + name: placeholder-name + labels: + tier: airflow + component: worker + release: {{ .Release.Name }} + {{- if or (.Values.labels) (.Values.workers.labels) }} + {{- mustMerge .Values.workers.labels .Values.labels | toYaml | nindent 4 }} + {{- end }} + {{- if or .Values.airflowPodAnnotations .Values.workers.podAnnotations }} + annotations: + {{- if .Values.airflowPodAnnotations }} + {{- toYaml .Values.airflowPodAnnotations | nindent 4 }} + {{- end }} + {{- if .Values.workers.podAnnotations }} + {{- toYaml .Values.workers.podAnnotations | nindent 4 }} + {{- end }} + {{- end }} +spec: + {{- if or (and .Values.dags.gitSync.enabled (not .Values.dags.persistence.enabled)) .Values.workers.extraInitContainers }} + initContainers: + {{- if and .Values.dags.gitSync.enabled (not .Values.dags.persistence.enabled) }} + {{- include "git_sync_container" (dict "Values" .Values "is_init" "true" "Template" .Template) | nindent 4 }} + {{- end }} + {{- if .Values.workers.extraInitContainers }} + {{- toYaml .Values.workers.extraInitContainers | nindent 4 }} + {{- end }} + {{- end }} + containers: + - envFrom: {{- include "custom_airflow_environment_from" . | default "\n []" | indent 6 }} + env: + - name: AIRFLOW__CORE__EXECUTOR + value: LocalExecutor + {{- include "standard_airflow_environment" . | indent 6}} + {{- include "custom_airflow_environment" . | indent 6 }} + {{- include "container_extra_envs" (list . .Values.workers.env) | indent 6 }} + image: {{ template "pod_template_image" . }} + imagePullPolicy: {{ .Values.images.pod_template.pullPolicy }} + securityContext: {{ $containerSecurityContext | nindent 8 }} + {{- if $containerLifecycleHooks }} + lifecycle: {{- tpl (toYaml $containerLifecycleHooks) . | nindent 8 }} + {{- end }} + name: base + resources: {{- toYaml .Values.workers.resources | nindent 8 }} + volumeMounts: + - mountPath: {{ template "airflow_logs" . }} + name: logs + {{- include "airflow_config_mount" . | nindent 8 }} + {{- if or .Values.dags.gitSync.enabled .Values.dags.persistence.enabled }} + {{- include "airflow_dags_mount" . | nindent 8 }} + {{- end }} + {{- if .Values.volumeMounts }} + {{- toYaml .Values.volumeMounts | nindent 8 }} + {{- end }} + {{- if .Values.workers.extraVolumeMounts }} + {{- tpl (toYaml .Values.workers.extraVolumeMounts) . | nindent 8 }} + {{- end }} + {{- if .Values.workers.extraContainers }} + {{- toYaml .Values.workers.extraContainers | nindent 4 }} + {{- end }} + {{- if .Values.workers.priorityClassName }} + priorityClassName: {{ .Values.workers.priorityClassName }} + {{- end }} + {{- if .Values.workers.runtimeClassName }} + priorityClassName: {{ .Values.workers.runtimeClassName }} + {{- end }} + {{- if or .Values.registry.secretName .Values.registry.connection }} + imagePullSecrets: + - name: {{ template "registry_secret" . }} + {{- end }} + {{- if .Values.workers.hostAliases }} + hostAliases: {{- toYaml .Values.workers.hostAliases | nindent 4 }} + {{- end }} + restartPolicy: Never + securityContext: {{ $securityContext | nindent 4 }} + nodeSelector: {{- toYaml $nodeSelector | nindent 4 }} + affinity: {{- toYaml $affinity | nindent 4 }} + {{- if .Values.schedulerName }} + schedulerName: {{ .Values.schedulerName }} + {{- end }} + terminationGracePeriodSeconds: {{ .Values.workers.terminationGracePeriodSeconds }} + tolerations: {{- toYaml $tolerations | nindent 4 }} + topologySpreadConstraints: {{- toYaml $topologySpreadConstraints | nindent 4 }} + serviceAccountName: {{ include "worker.serviceAccountName" . }} + volumes: + {{- if .Values.dags.persistence.enabled }} + - name: dags + persistentVolumeClaim: + claimName: {{ template "airflow_dags_volume_claim" . }} + {{- else if .Values.dags.gitSync.enabled }} + - name: dags + emptyDir: {} + {{- end }} + {{- if .Values.logs.persistence.enabled }} + - name: logs + persistentVolumeClaim: + claimName: {{ template "airflow_logs_volume_claim" . }} + {{- else }} + - emptyDir: {} + name: logs + {{- end }} + {{- if and .Values.dags.gitSync.enabled .Values.dags.gitSync.sshKeySecret }} + {{- include "git_sync_ssh_key_volume" . | nindent 2 }} + {{- end }} + - configMap: + name: {{ include "airflow_config" . }} + name: config + {{- if .Values.volumes }} + {{- toYaml .Values.volumes | nindent 2 }} + {{- end }} + {{- if .Values.workers.extraVolumes }} + {{- tpl (toYaml .Values.workers.extraVolumes) . | nindent 2 }} + {{- end }} diff --git a/helm/airflow/files/statsd-mappings.yml b/helm/airflow/files/statsd-mappings.yml new file mode 100644 index 0000000..f10ab00 --- /dev/null +++ b/helm/airflow/files/statsd-mappings.yml @@ -0,0 +1,87 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +--- +mappings: + # Map dot separated stats to labels + - match: airflow.dagrun.dependency-check.*.* + name: "airflow_dagrun_dependency_check" + labels: + dag_id: "$1" + + - match: airflow.operator_successes_(.*) + match_type: regex + name: "airflow_operator_successes" + labels: + operator: "$1" + + - match: airflow.operator_failures_(.*) + match_type: regex + name: "airflow_operator_failures" + labels: + operator: "$1" + + - match: airflow.scheduler_heartbeat + match_type: regex + name: "airflow_scheduler_heartbeat" + labels: + type: counter + + - match: airflow.dag.*.*.duration + name: "airflow_task_duration" + labels: + dag_id: "$1" + task_id: "$2" + + - match: airflow.dagrun.duration.success.* + name: "airflow_dagrun_duration" + labels: + dag_id: "$1" + + - match: airflow.dagrun.duration.failed.* + name: "airflow_dagrun_failed" + labels: + dag_id: "$1" + + - match: airflow.dagrun.schedule_delay.* + name: "airflow_dagrun_schedule_delay" + labels: + dag_id: "$1" + + - match: airflow.dag_processing.last_runtime.* + name: "airflow_dag_processing_last_runtime" + labels: + dag_file: "$1" + + - match: airflow.dag_processing.last_run.seconds_ago.* + name: "airflow_dag_processing_last_run_seconds_ago" + labels: + dag_file: "$1" + + - match: airflow.pool.open_slots.* + name: "airflow_pool_open_slots" + labels: + pool: "$1" + + - match: airflow.pool.used_slots.* + name: "airflow_pool_used_slots" + labels: + pool: "$1" + + - match: airflow.pool.starving_tasks.* + name: "airflow_pool_starving_tasks" + labels: + pool: "$1" diff --git a/helm/airflow/newsfragments/31066.significant.rst b/helm/airflow/newsfragments/31066.significant.rst new file mode 100644 index 0000000..c2fca5f --- /dev/null +++ b/helm/airflow/newsfragments/31066.significant.rst @@ -0,0 +1,23 @@ +Support naming customization on helm chart resources, some resources may be renamed during upgrade + +This is a new opt-in switch ``useStandardNaming``, for backwards compatibility, to leverage the standard naming convention, which allows full use of fullnameOverride and nameOverride in all resources. + +Only the following resources will be renamed using default of ``useStandardNaming=false``: +- ConfigMap {release}-airflow-config to {release}-config +- Secret {release}-airflow-metadata to {release}-metadata +- Secret {release}-airflow-result-backend to {release}-result-backend + +For existing installations, all your resources will be recreated with a new name and helm will delete previous resources. + +This won't delete existing PVCs for logs used by statefulset/deployments, but it will recreate them with brand new PVCs. +If you do want to preserve logs history you'll need to manually copy the data of these volumes into the new volumes after +deployment. Depending on what storage backend/class you're using this procedure may vary. If you don't mind starting +with fresh logs/redis volumes, you can just delete the old pvcs that will be names, for example: + +.. code-block:: bash + + kubectl delete pvc -n airflow logs-gta-triggerer-0 + kubectl delete pvc -n airflow logs-gta-worker-0 + kubectl delete pvc -n airflow redis-db-gta-redis-0 + +If you do not change ``useStandardNaming`` or ``fullnameOverride`` after upgrade, you can proceed as usual and no unexpected behaviours will be presented. diff --git a/helm/airflow/newsfragments/33747.significant.rst b/helm/airflow/newsfragments/33747.significant.rst new file mode 100644 index 0000000..f0ac317 --- /dev/null +++ b/helm/airflow/newsfragments/33747.significant.rst @@ -0,0 +1,3 @@ +``bitnami/postgresql`` subchart updated to ``12.10.0`` + +The PostgreSQL subchart that is used with the Chart is now ``12.10.0``, previously it was ``12.1.9``. diff --git a/helm/airflow/newsfragments/33748.significant.rst b/helm/airflow/newsfragments/33748.significant.rst new file mode 100644 index 0000000..025e872 --- /dev/null +++ b/helm/airflow/newsfragments/33748.significant.rst @@ -0,0 +1,3 @@ +Default git-sync image is updated to ``3.6.9`` + +The default git-sync image that is used with the Chart is now ``3.6.9``, previously it was ``3.6.3``. diff --git a/helm/airflow/newsfragments/34186.significant.rst b/helm/airflow/newsfragments/34186.significant.rst new file mode 100644 index 0000000..82713b2 --- /dev/null +++ b/helm/airflow/newsfragments/34186.significant.rst @@ -0,0 +1,3 @@ +Default Airflow image is updated to ``2.7.1`` + +The default Airflow image that is used with the Chart is now ``2.7.1``, previously it was ``2.6.2``. diff --git a/helm/airflow/newsfragments/config.toml b/helm/airflow/newsfragments/config.toml new file mode 100644 index 0000000..b00560d --- /dev/null +++ b/helm/airflow/newsfragments/config.toml @@ -0,0 +1,50 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +[tool.towncrier] +name = "Airflow Helm Chart" +filename = "RELEASE_NOTES.rst" +underlines = ["-", '^'] + +[[tool.towncrier.type]] +directory = "significant" +name = "Significant Changes" +showcontent = true + +[[tool.towncrier.type]] +directory = "feature" +name = "Features" +showcontent = true + +[[tool.towncrier.type]] +directory = "improvement" +name = "Improvements" +showcontent = true + +[[tool.towncrier.type]] +directory = "bugfix" +name = "Bug Fixes" +showcontent = true + +[[tool.towncrier.type]] +directory = "doc" +name = "Doc only Changes" +showcontent = true + +[[tool.towncrier.type]] +directory = "misc" +name = "Misc" +showcontent = true diff --git a/helm/airflow/override_values.yaml b/helm/airflow/override_values.yaml new file mode 100644 index 0000000..a142614 --- /dev/null +++ b/helm/airflow/override_values.yaml @@ -0,0 +1,197 @@ +## Prerequirements + +## Airflow Namespace 생성 +# kubectl create namespace airflow + +## Web Server Secret Key 생성 +# kubectl create secret -n airflow generic webserver-secret --from-literal="webserver-secret-key=$(python3 -c 'import secrets; print(secrets.token_hex(16))')" + +## GitHub 연동을 위한 Secret Key 생성 +# kubectl create secret generic airflow-git-ssh-secret \ +# --from-file=gitSshKey=[사용할 SSH Private key] \ +# -n airflow + +## keda 활용 시 설치 +# helm repo add kedacore https://kedacore.github.io/charts +# helm repo update +# kubectl create namespace keda +# helm install keda kedacore/keda --namespace keda --version "v2.0.0" + +--- + +webserverSecretKeySecretName: webserver-secret + +executor: "CeleryKubernetesExecutor" + +workers: + replicas: 1 + resources: + limits: + cpu: 1 + memory: 3Gi + requests: + cpu: 1 + memory: 2Gi + keda: + enabled: true + minReplicaCount: 1 + maxReplicaCount: 3 + # advanced: + # horizontalPodAutoscalerConfig: + # behavior: + # scaleDown: + # stabilizationWindowSeconds: 600 + # policies: + # - type: Percent + # value: 100 + # periodSeconds: 15 + +scheduler: + replicas: 1 + resources: + limits: + cpu: 1 + memory: 1Gi + requests: + cpu: 500m + memory: 1Gi + +webserver: + replicas: 1 + resources: + limits: + cpu: 1 + memory: 2Gi + requests: + cpu: 500m + memory: 1Gi + service: + type: NodePort + ports: + - name: airflow-ui + port: 8080 + targetPort: 8080 + nodePort: 30180 + defaultUser: + email: minchulahn@ex-em.com + +triggerer: + replicas: 1 + resources: + limits: + cpu: 1 + memory: 1Gi + requests: + cpu: 500m + memory: 1Gi + +statsd: + resources: + limits: + cpu: 100m + memory: 128Mi + requests: + cpu: 100m + memory: 128Mi + +redis: + resources: + limits: + cpu: 100m + memory: 128Mi + requests: + cpu: 100m + memory: 128Mi + +dags: + gitSync: + enabled: true + repo: git@github.com:cloudmoa/dsk-airflow-pipeline.git + branch: main + subPath: dags + sshKeySecret: airflow-git-ssh-secret + +postgresql: + primary: + service: + type: NodePort + nodePorts: + postgresql: 30185 + +logs: + persistence: + enabled: true + +config: + core: + dags_folder: '{{ include "airflow_dags" . }}' + # This is ignored when used with the official Docker image + load_examples: 'False' + executor: '{{ .Values.executor }}' + # For Airflow 1.10, backward compatibility; moved to [logging] in 2.0 + colored_console_log: 'False' + remote_logging: '{{- ternary "True" "False" .Values.elasticsearch.enabled }}' + logging: + remote_logging: '{{- ternary "True" "False" .Values.elasticsearch.enabled }}' + colored_console_log: 'False' + metrics: + statsd_on: '{{ ternary "True" "False" .Values.statsd.enabled }}' + statsd_port: 9125 + statsd_prefix: airflow + statsd_host: '{{ printf "%s-statsd" .Release.Name }}' + webserver: + enable_proxy_fix: 'True' + # For Airflow 1.10 + rbac: 'True' + celery: + flower_url_prefix: '{{ .Values.ingress.flower.path }}' + worker_concurrency: 16 + scheduler: + standalone_dag_processor: '{{ ternary "True" "False" .Values.dagProcessor.enabled }}' + # statsd params included for Airflow 1.10 backward compatibility; moved to [metrics] in 2.0 + statsd_on: '{{ ternary "True" "False" .Values.statsd.enabled }}' + statsd_port: 9125 + statsd_prefix: airflow + statsd_host: '{{ printf "%s-statsd" .Release.Name }}' + # `run_duration` included for Airflow 1.10 backward compatibility; removed in 2.0. + run_duration: 41460 + elasticsearch: + json_format: 'True' + log_id_template: "{dag_id}_{task_id}_{execution_date}_{try_number}" + elasticsearch_configs: + max_retries: 3 + timeout: 30 + retry_timeout: 'True' + kerberos: + keytab: '{{ .Values.kerberos.keytabPath }}' + reinit_frequency: '{{ .Values.kerberos.reinitFrequency }}' + principal: '{{ .Values.kerberos.principal }}' + ccache: '{{ .Values.kerberos.ccacheMountPath }}/{{ .Values.kerberos.ccacheFileName }}' + celery_kubernetes_executor: + kubernetes_queue: 'kubernetes' + # The `kubernetes` section is deprecated in Airflow >= 2.5.0 due to an airflow.cfg schema change. + # The `kubernetes` section can be removed once the helm chart no longer supports Airflow < 2.5.0. + kubernetes: + namespace: '{{ .Release.Namespace }}' + # The following `airflow_` entries are for Airflow 1, and can be removed when it is no longer supported. + airflow_configmap: '{{ include "airflow_config" . }}' + airflow_local_settings_configmap: '{{ include "airflow_config" . }}' + pod_template_file: '{{ include "airflow_pod_template_file" . }}/pod_template_file.yaml' + worker_container_repository: '{{ .Values.images.airflow.repository | default .Values.defaultAirflowRepository }}' + worker_container_tag: '{{ .Values.images.airflow.tag | default .Values.defaultAirflowTag }}' + multi_namespace_mode: '{{ ternary "True" "False" .Values.multiNamespaceMode }}' + # The `kubernetes_executor` section duplicates the `kubernetes` section in Airflow >= 2.5.0 due to an airflow.cfg schema change. + kubernetes_executor: + namespace: '{{ .Release.Namespace }}' + pod_template_file: '{{ include "airflow_pod_template_file" . }}/pod_template_file.yaml' + worker_container_repository: '{{ .Values.images.airflow.repository | default .Values.defaultAirflowRepository }}' + worker_container_tag: '{{ .Values.images.airflow.tag | default .Values.defaultAirflowTag }}' + multi_namespace_mode: '{{ ternary "True" "False" .Values.multiNamespaceMode }}' + email: + email_backend: airflow.providers.amazon.aws.utils.emailer.send_email + email_conn_id: aws_ses + default_email_on_retry: True + default_email_on_failure: True + from_email: DataSaker + api: + auth_backends: airflow.api.auth.backend.basic_auth \ No newline at end of file diff --git a/helm/airflow/templates/NOTES.txt b/helm/airflow/templates/NOTES.txt new file mode 100644 index 0000000..2e96cfa --- /dev/null +++ b/helm/airflow/templates/NOTES.txt @@ -0,0 +1,206 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + + +Thank you for installing Apache {{ title .Chart.Name }} {{ .Values.airflowVersion }}! + +Your release is named {{ .Release.Name }}. + +{{- if or .Values.ingress.web.enabled .Values.ingress.flower.enabled .Values.ingress.enabled }} +You can now access your service(s) by following defined Ingress urls: + +{{- if .Values.ingress.web.host }} + +DEPRECATION WARNING: + `ingress.web.host` has been renamed to `ingress.web.hosts` and is now an array. + Please change your values as support for the old name will be dropped in a future release. + +{{- end }} + +{{- if .Values.ingress.web.tls }} + +DEPRECATION WARNING: + `ingress.web.tls` has been renamed to `ingress.web.hosts[*].tls` and can be set per host. + Please change your values as support for the old name will be dropped in a future release. + +{{- end }} + +{{- if .Values.ingress.flower.host }} + +DEPRECATION WARNING: + `ingress.flower.host` has been renamed to `ingress.flower.hosts` and is now an array. + Please change your values as support for the old name will be dropped in a future release. + +{{- end }} + + +{{- if .Values.ingress.flower.tls }} + +DEPRECATION WARNING: + `ingress.flower.tls` has been renamed to `ingress.flower.hosts[*].tls` and can be set per host. + Please change your values as support for the old name will be dropped in a future release. + +{{- end }} + +{{- if .Values.ingress.enabled }} + +DEPRECATION WARNING: + `ingress.enabled` has been deprecated. There are now separate flags to control the webserver and + flower individually, ``ingress.web.enabled`` and ``ingress.flower.enabled``. + Please change your values as support for the old name will be dropped in a future release. + +{{- end }} + +{{- if or .Values.ingress.web.enabled .Values.ingress.enabled }} +Airflow Webserver: +{{- range .Values.ingress.web.hosts | default (list .Values.ingress.web.host) }} + {{- $tlsEnabled := $.Values.ingress.web.tls.enabled -}} + {{- $hostname := $.Values.ingress.web.host -}} + {{- if . | kindIs "string" | not }} + {{- if .tls }} + {{- $tlsEnabled = .tls.enabled -}} + {{- $hostname = .name -}} + {{- end }} + {{- end }} + http{{ if $tlsEnabled }}s{{ end }}://{{ $hostname }}{{ $.Values.ingress.web.path }}/ +{{- end }} +{{- end }} +{{- if and (or .Values.ingress.flower.enabled .Values.ingress.enabled) (or (eq .Values.executor "CeleryExecutor") (eq .Values.executor "CeleryKubernetesExecutor")) }} +Flower dashboard: +{{- range .Values.ingress.flower.hosts | default (list .Values.ingress.flower.host) }} + {{- $tlsEnabled := $.Values.ingress.flower.tls.enabled -}} + {{- $hostname := $.Values.ingress.flower.host -}} + {{- if . | kindIs "string" | not }} + {{- if .tls }} + {{- $tlsEnabled = .tls.enabled -}} + {{- $hostname = .name -}} + {{- end }} + {{- end }} + http{{ if $tlsEnabled }}s{{ end }}://{{ $hostname }}{{ $.Values.ingress.flower.path }}/ +{{- end }} +{{- end }} +{{- else }} +You can now access your dashboard(s) by executing the following command(s) and visiting the corresponding port at localhost in your browser: + +Airflow Webserver: kubectl port-forward svc/{{ include "airflow.fullname" . }}-webserver {{ .Values.ports.airflowUI }}:{{ .Values.ports.airflowUI }} --namespace {{ .Release.Namespace }} + +{{- if .Values.flower.enabled }} +{{- if or (eq .Values.executor "CeleryExecutor") (eq .Values.executor "CeleryKubernetesExecutor")}} +Flower dashboard: kubectl port-forward svc/{{ include "airflow.fullname" . }}-flower {{ .Values.ports.flowerUI }}:{{ .Values.ports.flowerUI }} --namespace {{ .Release.Namespace }} + +{{- end }} +{{- end }} +{{- end }} + + +{{- if .Values.webserver.defaultUser.enabled}} +Default Webserver (Airflow UI) Login credentials: + username: {{ .Values.webserver.defaultUser.username }} + password: {{ .Values.webserver.defaultUser.password }} +{{- end }} + +{{- if .Values.postgresql.enabled }} +Default Postgres connection credentials: + username: {{ .Values.data.metadataConnection.user }} + password: {{ .Values.data.metadataConnection.pass }} + port: {{ .Values.data.metadataConnection.port }} + +{{- end }} + +{{- if not .Values.fernetKeySecretName }} + +You can get Fernet Key value by running the following: + + echo Fernet Key: $(kubectl get secret --namespace {{ .Release.Namespace }} {{ .Release.Name }}-fernet-key -o jsonpath="{.data.fernet-key}" | base64 --decode) + +{{- end }} + +{{- if or (eq .Values.executor "KubernetesExecutor") (eq .Values.executor "CeleryKubernetesExecutor") }} +{{- if and (not .Values.logs.persistence.enabled) (eq (lower (tpl .Values.config.logging.remote_logging .)) "false") }} + +WARNING: + Kubernetes workers task logs may not persist unless you configure log persistence or remote logging! + Logging options can be found at: https://airflow.apache.org/docs/helm-chart/stable/manage-logs.html + (This warning can be ignored if logging is configured with environment variables or secrets backend) + +{{- end }} +{{- end }} + +{{- if and .Values.dags.gitSync.enabled .Values.dags.gitSync.sshKeySecret (not .Values.dags.gitSync.knownHosts)}} + +##################################################### +# WARNING: You should set dags.gitSync.knownHosts # +##################################################### + +You are using ssh authentication for your gitsync repo, however you currently have SSH known_hosts verification disabled, +making you susceptible to man-in-the-middle attacks! + +Information on how to set knownHosts can be found here: +https://airflow.apache.org/docs/helm-chart/stable/production-guide.html#knownhosts + +{{- end }} + +{{- if .Values.flower.extraNetworkPolicies }} + +DEPRECATION WARNING: + `flower.extraNetworkPolicies` has been renamed to `flower.networkPolicy.peers`. + Please change your values as support for the old name will be dropped in a future release. + +{{- end }} + + +{{- if .Values.webserver.extraNetworkPolicies }} + +DEPRECATION WARNING: + `webserver.extraNetworkPolicies` has been renamed to `webserver.networkPolicy.peers`. + Please change your values as support for the old name will be dropped in a future release. + +{{- end }} + +{{- if not (or .Values.webserverSecretKey .Values.webserverSecretKeySecretName) }} + +{{- if .Values.securityContext }} + + DEPRECATION WARNING: + `securityContext` has been renamed to `securityContexts`, to be enabled on container and pod level. + Please change your values as support for the old name will be dropped in a future release. + +{{- end }} + +########################################################### +# WARNING: You should set a static webserver secret key # +########################################################### + +You are using a dynamically generated webserver secret key, which can lead to +unnecessary restarts of your Airflow components. + +Information on how to set a static webserver secret key can be found here: +https://airflow.apache.org/docs/helm-chart/stable/production-guide.html#webserver-secret-key + +{{- end }} + +{{- if or .Values.postgresql.postgresqlUsername .Values.postgresql.postgresqlPassword }} + + {{ fail "postgresql.postgresqlUsername and postgresql.postgresqlPassword are no longer supported. If you wish to use the 'postgres' user, set its password with postgresql.auth.postgresPassword. If you wish to create a different user, do so with postgresql.auth.username and postgresql.auth.password." }} + +{{- end }} + +{{- if ne .Values.executor (tpl .Values.config.core.executor $) }} + {{ fail "Please configure the executor with `executor`, not `config.core.executor`." }} +{{- end }} diff --git a/helm/airflow/templates/_helpers.yaml b/helm/airflow/templates/_helpers.yaml new file mode 100644 index 0000000..efeace9 --- /dev/null +++ b/helm/airflow/templates/_helpers.yaml @@ -0,0 +1,985 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +{{/* +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 "airflow.fullname" -}} + {{- if not .Values.useStandardNaming }} + {{- .Release.Name }} + {{- else 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 "airflow.serviceAccountName" -}} + {{ 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 }} + +{{/* Standard Airflow environment variables */}} +{{- define "standard_airflow_environment" }} + # Hard Coded Airflow Envs + {{- if .Values.enableBuiltInSecretEnvVars.AIRFLOW__CORE__FERNET_KEY }} + - name: AIRFLOW__CORE__FERNET_KEY + valueFrom: + secretKeyRef: + name: {{ template "fernet_key_secret" . }} + key: fernet-key + {{- end }} + # For Airflow <2.3, backward compatibility; moved to [database] in 2.3 + {{- if .Values.enableBuiltInSecretEnvVars.AIRFLOW__CORE__SQL_ALCHEMY_CONN }} + - name: AIRFLOW__CORE__SQL_ALCHEMY_CONN + valueFrom: + secretKeyRef: + name: {{ template "airflow_metadata_secret" . }} + key: connection + {{- end }} + {{- if .Values.enableBuiltInSecretEnvVars.AIRFLOW__DATABASE__SQL_ALCHEMY_CONN }} + - name: AIRFLOW__DATABASE__SQL_ALCHEMY_CONN + valueFrom: + secretKeyRef: + name: {{ template "airflow_metadata_secret" . }} + key: connection + {{- end }} + {{- if .Values.enableBuiltInSecretEnvVars.AIRFLOW_CONN_AIRFLOW_DB }} + - name: AIRFLOW_CONN_AIRFLOW_DB + valueFrom: + secretKeyRef: + name: {{ template "airflow_metadata_secret" . }} + key: connection + {{- end }} + {{- if and .Values.workers.keda.enabled .Values.pgbouncer.enabled (not .Values.workers.keda.usePgbouncer) }} + - name: KEDA_DB_CONN + valueFrom: + secretKeyRef: + name: {{ template "airflow_metadata_secret" . }} + key: kedaConnection + {{- end }} + {{- if .Values.enableBuiltInSecretEnvVars.AIRFLOW__WEBSERVER__SECRET_KEY }} + - name: AIRFLOW__WEBSERVER__SECRET_KEY + valueFrom: + secretKeyRef: + name: {{ template "webserver_secret_key_secret" . }} + key: webserver-secret-key + {{- end }} + {{- if or (eq .Values.executor "CeleryExecutor") (eq .Values.executor "CeleryKubernetesExecutor") }} + {{- if or (semverCompare "<2.4.0" .Values.airflowVersion) (.Values.data.resultBackendSecretName) (.Values.data.resultBackendConnection) }} + {{- if .Values.enableBuiltInSecretEnvVars.AIRFLOW__CELERY__CELERY_RESULT_BACKEND }} + # (Airflow 1.10.* variant) + - name: AIRFLOW__CELERY__CELERY_RESULT_BACKEND + valueFrom: + secretKeyRef: + name: {{ template "airflow_result_backend_secret" . }} + key: connection + {{- end }} + {{- if .Values.enableBuiltInSecretEnvVars.AIRFLOW__CELERY__RESULT_BACKEND }} + - name: AIRFLOW__CELERY__RESULT_BACKEND + valueFrom: + secretKeyRef: + name: {{ template "airflow_result_backend_secret" . }} + key: connection + {{- end }} + {{- end }} + {{- if .Values.enableBuiltInSecretEnvVars.AIRFLOW__CELERY__BROKER_URL }} + - name: AIRFLOW__CELERY__BROKER_URL + valueFrom: + secretKeyRef: + name: {{ default (printf "%s-broker-url" .Release.Name) .Values.data.brokerUrlSecretName }} + key: connection + {{- end }} + {{- end }} + {{- if .Values.elasticsearch.enabled }} + # The elasticsearch variables were updated to the shorter names in v1.10.4 + {{- if .Values.enableBuiltInSecretEnvVars.AIRFLOW__ELASTICSEARCH__HOST }} + - name: AIRFLOW__ELASTICSEARCH__HOST + valueFrom: + secretKeyRef: + name: {{ template "elasticsearch_secret" . }} + key: connection + {{- end }} + {{- if .Values.enableBuiltInSecretEnvVars.AIRFLOW__ELASTICSEARCH__ELASTICSEARCH_HOST }} + # This is the older format for these variable names, kept here for backward compatibility + - name: AIRFLOW__ELASTICSEARCH__ELASTICSEARCH_HOST + valueFrom: + secretKeyRef: + name: {{ template "elasticsearch_secret" . }} + key: connection + {{- end }} + {{- end }} +{{- end }} + +{{/* User defined Airflow environment variables */}} +{{- define "custom_airflow_environment" }} + # Dynamically created environment variables + {{- range $i, $config := .Values.env }} + - name: {{ $config.name }} + value: {{ $config.value | quote }} + {{- if or (eq $.Values.executor "KubernetesExecutor") (eq $.Values.executor "LocalKubernetesExecutor") (eq $.Values.executor "CeleryKubernetesExecutor") }} + - name: AIRFLOW__KUBERNETES_ENVIRONMENT_VARIABLES__{{ $config.name }} + value: {{ $config.value | quote }} + {{- end }} + {{- end }} + # Dynamically created secret envs + {{- range $i, $config := .Values.secret }} + - name: {{ $config.envName }} + valueFrom: + secretKeyRef: + name: {{ $config.secretName }} + key: {{ default "value" $config.secretKey }} + {{- end }} + {{- if or (eq $.Values.executor "LocalKubernetesExecutor") (eq $.Values.executor "KubernetesExecutor") (eq $.Values.executor "CeleryKubernetesExecutor") }} + {{- range $i, $config := .Values.secret }} + - name: AIRFLOW__KUBERNETES_SECRETS__{{ $config.envName }} + value: {{ printf "%s=%s" $config.secretName $config.secretKey }} + {{- end }} + {{ end }} + # Extra env + {{- $Global := . }} + {{- with .Values.extraEnv }} + {{- tpl . $Global | nindent 2 }} + {{- end }} +{{- end }} + +{{/* User defined Airflow environment from */}} +{{- define "custom_airflow_environment_from" }} + {{- $Global := . }} + {{- with .Values.extraEnvFrom }} + {{- tpl . $Global | nindent 2 }} + {{- end }} +{{- end }} + +{{/* Git ssh key volume */}} +{{- define "git_sync_ssh_key_volume" }} +- name: git-sync-ssh-key + secret: + secretName: {{ .Values.dags.gitSync.sshKeySecret }} + defaultMode: 288 +{{- end }} + +{{/* Git sync container */}} +{{- define "git_sync_container" }} +- name: {{ .Values.dags.gitSync.containerName }}{{ if .is_init }}-init{{ end }} + image: {{ template "git_sync_image" . }} + imagePullPolicy: {{ .Values.images.gitSync.pullPolicy }} + securityContext: {{- include "localContainerSecurityContext" .Values.dags.gitSync | nindent 4 }} + env: + {{- if .Values.dags.gitSync.sshKeySecret }} + - name: GIT_SSH_KEY_FILE + value: "/etc/git-secret/ssh" + - name: GIT_SYNC_SSH + value: "true" + {{- if .Values.dags.gitSync.knownHosts }} + - name: GIT_KNOWN_HOSTS + value: "true" + - name: GIT_SSH_KNOWN_HOSTS_FILE + value: "/etc/git-secret/known_hosts" + {{- else }} + - name: GIT_KNOWN_HOSTS + value: "false" + {{- end }} + {{ else if .Values.dags.gitSync.credentialsSecret }} + - name: GIT_SYNC_USERNAME + valueFrom: + secretKeyRef: + name: {{ .Values.dags.gitSync.credentialsSecret | quote }} + key: GIT_SYNC_USERNAME + - name: GIT_SYNC_PASSWORD + valueFrom: + secretKeyRef: + name: {{ .Values.dags.gitSync.credentialsSecret | quote }} + key: GIT_SYNC_PASSWORD + {{- end }} + - name: GIT_SYNC_REV + value: {{ .Values.dags.gitSync.rev | quote }} + - name: GIT_SYNC_BRANCH + value: {{ .Values.dags.gitSync.branch | quote }} + - name: GIT_SYNC_REPO + value: {{ .Values.dags.gitSync.repo | quote }} + - name: GIT_SYNC_DEPTH + value: {{ .Values.dags.gitSync.depth | quote }} + - name: GIT_SYNC_ROOT + value: "/git" + - name: GIT_SYNC_DEST + value: "repo" + - name: GIT_SYNC_ADD_USER + value: "true" + - name: GIT_SYNC_WAIT + value: {{ .Values.dags.gitSync.wait | quote }} + - name: GIT_SYNC_MAX_SYNC_FAILURES + value: {{ .Values.dags.gitSync.maxFailures | quote }} + {{- if .is_init }} + - name: GIT_SYNC_ONE_TIME + value: "true" + {{- end }} + {{- with .Values.dags.gitSync.env }} + {{- toYaml . | nindent 4 }} + {{- end }} + resources: {{ toYaml .Values.dags.gitSync.resources | nindent 6 }} + volumeMounts: + - name: dags + mountPath: /git + {{- if .Values.dags.gitSync.sshKeySecret }} + - name: git-sync-ssh-key + mountPath: /etc/git-secret/ssh + readOnly: true + subPath: gitSshKey + {{- if .Values.dags.gitSync.knownHosts }} + - name: config + mountPath: /etc/git-secret/known_hosts + readOnly: true + subPath: known_hosts + {{- end }} + {{- end }} + {{- if .Values.dags.gitSync.extraVolumeMounts }} + {{- tpl (toYaml .Values.dags.gitSync.extraVolumeMounts) . | nindent 2 }} + {{- end }} +{{- end }} + +{{/* This helper will change when customers deploy a new image */}} +{{- define "airflow_image" -}} + {{- $repository := .Values.images.airflow.repository | default .Values.defaultAirflowRepository -}} + {{- $tag := .Values.images.airflow.tag | default .Values.defaultAirflowTag -}} + {{- $digest := .Values.images.airflow.digest | default .Values.defaultAirflowDigest -}} + {{- if $digest }} + {{- printf "%s@%s" $repository $digest -}} + {{- else }} + {{- printf "%s:%s" $repository $tag -}} + {{- end }} +{{- end }} + +{{- define "pod_template_image" -}} + {{- printf "%s:%s" (.Values.images.pod_template.repository | default .Values.defaultAirflowRepository) (.Values.images.pod_template.tag | default .Values.defaultAirflowTag) }} +{{- end }} + +{{/* This helper is used for airflow containers that do not need the users code */}} +{{ define "default_airflow_image" -}} + {{- $repository := .Values.defaultAirflowRepository -}} + {{- $tag := .Values.defaultAirflowTag -}} + {{- $digest := .Values.defaultAirflowDigest -}} + {{- if $digest }} + {{- printf "%s@%s" $repository $digest -}} + {{- else }} + {{- printf "%s:%s" $repository $tag -}} + {{- end }} +{{- end }} + +{{ define "airflow_image_for_migrations" -}} + {{- if .Values.images.useDefaultImageForMigration }} + {{- template "default_airflow_image" . }} + {{- else }} + {{- template "airflow_image" . }} + {{- end }} +{{- end }} + +{{- define "flower_image" -}} + {{- printf "%s:%s" (.Values.images.flower.repository | default .Values.defaultAirflowRepository) (.Values.images.flower.tag | default .Values.defaultAirflowTag) }} +{{- end }} + +{{- define "statsd_image" -}} + {{- printf "%s:%s" .Values.images.statsd.repository .Values.images.statsd.tag }} +{{- end }} + +{{- define "redis_image" -}} + {{- printf "%s:%s" .Values.images.redis.repository .Values.images.redis.tag }} +{{- end }} + +{{- define "pgbouncer_image" -}} + {{- printf "%s:%s" .Values.images.pgbouncer.repository .Values.images.pgbouncer.tag }} +{{- end }} + +{{- define "pgbouncer_exporter_image" -}} + {{- printf "%s:%s" .Values.images.pgbouncerExporter.repository .Values.images.pgbouncerExporter.tag }} +{{- end }} + +{{- define "git_sync_image" -}} + {{- printf "%s:%s" .Values.images.gitSync.repository .Values.images.gitSync.tag }} +{{- end }} + +{{- define "fernet_key_secret" -}} + {{- default (printf "%s-fernet-key" .Release.Name) .Values.fernetKeySecretName }} +{{- end }} + +{{- define "webserver_secret_key_secret" -}} + {{- default (printf "%s-webserver-secret-key" (include "airflow.fullname" .)) .Values.webserverSecretKeySecretName }} +{{- end }} + +{{- define "redis_password_secret" -}} + {{- default (printf "%s-redis-password" .Release.Name) .Values.redis.passwordSecretName }} +{{- end }} + +{{- define "airflow_metadata_secret" -}} + {{- default (printf "%s-metadata" (include "airflow.fullname" .)) .Values.data.metadataSecretName }} +{{- end }} + +{{- define "airflow_result_backend_secret" -}} + {{- default (printf "%s-result-backend" (include "airflow.fullname" .)) .Values.data.resultBackendSecretName }} +{{- end }} + +{{- define "airflow_pod_template_file" -}} + {{- printf "%s/pod_templates" .Values.airflowHome }} +{{- end }} + +{{- define "pgbouncer_config_secret" -}} + {{- default (printf "%s-pgbouncer-config" (include "airflow.fullname" .)) .Values.pgbouncer.configSecretName }} +{{- end }} + +{{- define "pgbouncer_certificates_secret" -}} + {{- printf "%s-pgbouncer-certificates" (include "airflow.fullname" .) }} +{{- end }} + +{{- define "pgbouncer_stats_secret" -}} + {{- default (printf "%s-pgbouncer-stats" (include "airflow.fullname" .)) .Values.pgbouncer.metricsExporterSidecar.statsSecretName }} +{{- end }} + +{{- define "registry_secret" -}} + {{- default (printf "%s-registry" (include "airflow.fullname" .)) .Values.registry.secretName }} +{{- end }} + +{{- define "elasticsearch_secret" -}} + {{- default (printf "%s-elasticsearch" (include "airflow.fullname" .)) .Values.elasticsearch.secretName }} +{{- end }} + +{{- define "flower_secret" -}} + {{- default (printf "%s-flower" (include "airflow.fullname" .)) .Values.flower.secretName }} +{{- end }} + +{{- define "kerberos_keytab_secret" -}} + {{- printf "%s-kerberos-keytab" (include "airflow.fullname" .) }} +{{- end }} + +{{- define "kerberos_ccache_path" -}} + {{- printf "%s/%s" .Values.kerberos.ccacheMountPath .Values.kerberos.ccacheFileName }} +{{- end }} + +{{- define "celery_executor_namespace" -}} + {{- if semverCompare ">=2.7.0" .Values.airflowVersion }} + {{- print "airflow.providers.celery.executors.celery_executor.app" -}} + {{- else }} + {{- print "airflow.executors.celery_executor.app" -}} + {{- end }} +{{- end }} + +{{- define "pgbouncer_config" -}} +{{ $resultBackendConnection := .Values.data.resultBackendConnection | default .Values.data.metadataConnection }} +{{ $pgMetadataHost := .Values.data.metadataConnection.host | default (printf "%s-%s.%s" .Release.Name "postgresql" .Release.Namespace) }} +{{ $pgResultBackendHost := $resultBackendConnection.host | default (printf "%s-%s.%s" .Release.Name "postgresql" .Release.Namespace) }} +[databases] +{{ .Release.Name }}-metadata = host={{ $pgMetadataHost }} dbname={{ .Values.data.metadataConnection.db }} port={{ .Values.data.metadataConnection.port }} pool_size={{ .Values.pgbouncer.metadataPoolSize }} {{ .Values.pgbouncer.extraIniMetadata | default "" }} +{{ .Release.Name }}-result-backend = host={{ $pgResultBackendHost }} dbname={{ $resultBackendConnection.db }} port={{ $resultBackendConnection.port }} pool_size={{ .Values.pgbouncer.resultBackendPoolSize }} {{ .Values.pgbouncer.extraIniResultBackend | default "" }} + +[pgbouncer] +pool_mode = transaction +listen_port = {{ .Values.ports.pgbouncer }} +listen_addr = * +auth_type = {{ .Values.pgbouncer.auth_type }} +auth_file = {{ .Values.pgbouncer.auth_file }} +stats_users = {{ .Values.data.metadataConnection.user }} +ignore_startup_parameters = extra_float_digits +max_client_conn = {{ .Values.pgbouncer.maxClientConn }} +verbose = {{ .Values.pgbouncer.verbose }} +log_disconnections = {{ .Values.pgbouncer.logDisconnections }} +log_connections = {{ .Values.pgbouncer.logConnections }} + +server_tls_sslmode = {{ .Values.pgbouncer.sslmode }} +server_tls_ciphers = {{ .Values.pgbouncer.ciphers }} + +{{- if .Values.pgbouncer.ssl.ca }} +server_tls_ca_file = /etc/pgbouncer/root.crt +{{- end }} +{{- if .Values.pgbouncer.ssl.cert }} +server_tls_cert_file = /etc/pgbouncer/server.crt +{{- end }} +{{- if .Values.pgbouncer.ssl.key }} +server_tls_key_file = /etc/pgbouncer/server.key +{{- end }} + +{{- if .Values.pgbouncer.extraIni }} +{{ .Values.pgbouncer.extraIni }} +{{- end }} +{{- end }} + +{{ define "pgbouncer_users" }} +{{- $resultBackendConnection := .Values.data.resultBackendConnection | default .Values.data.metadataConnection }} +{{ .Values.data.metadataConnection.user | quote }} {{ .Values.data.metadataConnection.pass | quote }} +{{ $resultBackendConnection.user | quote }} {{ $resultBackendConnection.pass | quote }} +{{- end }} + +{{- define "airflow_logs" -}} + {{- printf "%s/logs" .Values.airflowHome | quote }} +{{- end }} + +{{- define "airflow_logs_no_quote" -}} + {{- printf "%s/logs" .Values.airflowHome }} +{{- end }} + +{{- define "airflow_logs_volume_claim" -}} + {{- if .Values.logs.persistence.existingClaim }} + {{- .Values.logs.persistence.existingClaim }} + {{- else }} + {{- printf "%s-logs" .Release.Name }} + {{- end }} +{{- end }} + +{{- define "airflow_dags" -}} + {{- if .Values.dags.gitSync.enabled }} + {{- printf "%s/dags/repo/%s" .Values.airflowHome .Values.dags.gitSync.subPath }} + {{- else }} + {{- printf "%s/dags" .Values.airflowHome }} + {{- end }} +{{- end }} + +{{- define "airflow_dags_volume_claim" -}} + {{- if .Values.dags.persistence.existingClaim }} + {{- .Values.dags.persistence.existingClaim }} + {{- else }} + {{- printf "%s-dags" .Release.Name }} + {{- end }} +{{- end }} + +{{- define "airflow_dags_mount" -}} +- name: dags + mountPath: {{ printf "%s/dags" .Values.airflowHome }} + {{- if .Values.dags.persistence.subPath }} + subPath: {{ .Values.dags.persistence.subPath }} + {{- end }} + readOnly: {{ .Values.dags.gitSync.enabled | ternary "True" "False" }} +{{- end }} + +{{- define "airflow_config_path" -}} + {{- printf "%s/airflow.cfg" .Values.airflowHome | quote }} +{{- end }} + +{{- define "airflow_webserver_config_path" -}} + {{- printf "%s/webserver_config.py" .Values.airflowHome | quote }} +{{- end }} + +{{- define "airflow_webserver_config_configmap_name" -}} + {{- default (printf "%s-webserver-config" .Release.Name) .Values.webserver.webserverConfigConfigMapName }} +{{- end }} + +{{- define "airflow_webserver_config_mount" -}} +- name: webserver-config + mountPath: {{ template "airflow_webserver_config_path" . }} + subPath: webserver_config.py + readOnly: True +{{- end }} + +{{- define "airflow_local_setting_path" -}} + {{- printf "%s/config/airflow_local_settings.py" .Values.airflowHome | quote }} +{{- end }} + +{{- define "airflow_config" -}} + {{- printf "%s-config" (include "airflow.fullname" .) }} +{{- end }} + +{{- define "airflow_config_mount" -}} +- name: config + mountPath: {{ template "airflow_config_path" . }} + subPath: airflow.cfg + readOnly: true + {{- if .Values.airflowLocalSettings }} +- name: config + mountPath: {{ template "airflow_local_setting_path" . }} + subPath: airflow_local_settings.py + readOnly: true + {{- end }} +{{- end }} + +{{/* Create the name of the webserver service account to use */}} +{{- define "webserver.serviceAccountName" -}} + {{- if .Values.webserver.serviceAccount.create }} + {{- default (printf "%s-webserver" (include "airflow.serviceAccountName" .)) .Values.webserver.serviceAccount.name }} + {{- else }} + {{- default "default" .Values.webserver.serviceAccount.name }} + {{- end }} +{{- end }} + +{{/* Create the name of the redis service account to use */}} +{{- define "redis.serviceAccountName" -}} + {{- if .Values.redis.serviceAccount.create }} + {{- default (printf "%s-redis" (include "airflow.serviceAccountName" .)) .Values.redis.serviceAccount.name }} + {{- else }} + {{- default "default" .Values.redis.serviceAccount.name }} + {{- end }} +{{- end }} + +{{/* Create the name of the flower service account to use */}} +{{- define "flower.serviceAccountName" -}} + {{- if .Values.flower.serviceAccount.create }} + {{- default (printf "%s-flower" (include "airflow.serviceAccountName" .)) .Values.flower.serviceAccount.name }} + {{- else }} + {{- default "default" .Values.flower.serviceAccount.name }} + {{- end }} +{{- end }} + +{{/* Create the name of the scheduler service account to use */}} +{{- define "scheduler.serviceAccountName" -}} + {{- if .Values.scheduler.serviceAccount.create }} + {{- default (printf "%s-scheduler" (include "airflow.serviceAccountName" .)) .Values.scheduler.serviceAccount.name }} + {{- else }} + {{- default "default" .Values.scheduler.serviceAccount.name }} + {{- end }} +{{- end }} + +{{/* Create the name of the StatsD service account to use */}} +{{- define "statsd.serviceAccountName" -}} + {{- if .Values.statsd.serviceAccount.create }} + {{- default (printf "%s-statsd" (include "airflow.serviceAccountName" .)) .Values.statsd.serviceAccount.name }} + {{- else }} + {{- default "default" .Values.statsd.serviceAccount.name }} + {{- end }} +{{- end }} + +{{/* Create the name of the create user job service account to use */}} +{{- define "createUserJob.serviceAccountName" -}} + {{- if .Values.createUserJob.serviceAccount.create }} + {{- default (printf "%s-create-user-job" (include "airflow.serviceAccountName" .)) .Values.createUserJob.serviceAccount.name }} + {{- else }} + {{- default "default" .Values.createUserJob.serviceAccount.name }} + {{- end }} +{{- end }} + +{{/* Create the name of the migrate database job service account to use */}} +{{- define "migrateDatabaseJob.serviceAccountName" -}} + {{- if .Values.migrateDatabaseJob.serviceAccount.create }} + {{- default (printf "%s-migrate-database-job" (include "airflow.serviceAccountName" .)) .Values.migrateDatabaseJob.serviceAccount.name }} + {{- else }} + {{- default "default" .Values.migrateDatabaseJob.serviceAccount.name }} + {{- end }} +{{- end }} + +{{/* Create the name of the worker service account to use */}} +{{- define "worker.serviceAccountName" -}} + {{- if .Values.workers.serviceAccount.create }} + {{- default (printf "%s-worker" (include "airflow.serviceAccountName" .)) .Values.workers.serviceAccount.name }} + {{- else }} + {{- default "default" .Values.workers.serviceAccount.name }} + {{- end }} +{{- end }} + +{{/* Create the name of the triggerer service account to use */}} +{{- define "triggerer.serviceAccountName" -}} + {{- if .Values.triggerer.serviceAccount.create }} + {{- default (printf "%s-triggerer" (include "airflow.serviceAccountName" .)) .Values.triggerer.serviceAccount.name }} + {{- else }} + {{- default "default" .Values.triggerer.serviceAccount.name }} + {{- end }} +{{- end }} + +{{/* Create the name of the dag processor service account to use */}} +{{- define "dagProcessor.serviceAccountName" -}} + {{- if .Values.dagProcessor.serviceAccount.create }} + {{- default (printf "%s-dag-processor" (include "airflow.serviceAccountName" .)) .Values.dagProcessor.serviceAccount.name }} + {{- else }} + {{- default "default" .Values.dagProcessor.serviceAccount.name }} + {{- end }} +{{- end }} + +{{/* Create the name of the pgbouncer service account to use */}} +{{- define "pgbouncer.serviceAccountName" -}} + {{- if .Values.pgbouncer.serviceAccount.create }} + {{- default (printf "%s-pgbouncer" (include "airflow.serviceAccountName" .)) .Values.pgbouncer.serviceAccount.name }} + {{- else }} + {{- default "default" .Values.pgbouncer.serviceAccount.name }} + {{- end }} +{{- end }} + +{{/* Create the name of the cleanup service account to use */}} +{{- define "cleanup.serviceAccountName" -}} + {{- if .Values.cleanup.serviceAccount.create }} + {{- default (printf "%s-cleanup" (include "airflow.serviceAccountName" .)) .Values.cleanup.serviceAccount.name }} + {{- else }} + {{- default "default" .Values.cleanup.serviceAccount.name }} + {{- end }} +{{- end }} + +{{- define "wait-for-migrations-command" -}} + {{- if semverCompare ">=2.0.0" .Values.airflowVersion }} + - airflow + - db + - check-migrations + - --migration-wait-timeout={{ .Values.images.migrationsWaitTimeout }} + {{- else }} + - python + - -c + - | + import airflow + import logging + import os + import time + + from alembic.config import Config + from alembic.runtime.migration import MigrationContext + from alembic.script import ScriptDirectory + + from airflow import settings + + package_dir = os.path.abspath(os.path.dirname(airflow.__file__)) + directory = os.path.join(package_dir, 'migrations') + config = Config(os.path.join(package_dir, 'alembic.ini')) + config.set_main_option('script_location', directory) + config.set_main_option('sqlalchemy.url', settings.SQL_ALCHEMY_CONN.replace('%', '%%')) + script_ = ScriptDirectory.from_config(config) + + timeout=60 + + with settings.engine.connect() as connection: + context = MigrationContext.configure(connection) + ticker = 0 + while True: + source_heads = set(script_.get_heads()) + + db_heads = set(context.get_current_heads()) + if source_heads == db_heads: + break + + if ticker >= timeout: + raise TimeoutError("There are still unapplied migrations after {} seconds.".format(ticker)) + ticker += 1 + time.sleep(1) + logging.info('Waiting for migrations... %s second(s)', ticker) + {{- end }} +{{- end }} + +{{- define "scheduler_liveness_check_command" }} + {{- if semverCompare ">=2.5.0" .Values.airflowVersion }} + - sh + - -c + - | + CONNECTION_CHECK_MAX_COUNT=0 AIRFLOW__LOGGING__LOGGING_LEVEL=ERROR exec /entrypoint \ + airflow jobs check --job-type SchedulerJob --local + {{- else if semverCompare ">=2.1.0" .Values.airflowVersion }} + - sh + - -c + - | + CONNECTION_CHECK_MAX_COUNT=0 AIRFLOW__LOGGING__LOGGING_LEVEL=ERROR exec /entrypoint \ + airflow jobs check --job-type SchedulerJob --hostname $(hostname) + {{- else }} + - sh + - -c + - | + CONNECTION_CHECK_MAX_COUNT=0 exec /entrypoint python -Wignore -c " + import os + os.environ['AIRFLOW__CORE__LOGGING_LEVEL'] = 'ERROR' + os.environ['AIRFLOW__LOGGING__LOGGING_LEVEL'] = 'ERROR' + from airflow.jobs.scheduler_job import SchedulerJob + from airflow.utils.db import create_session + from airflow.utils.net import get_hostname + import sys + with create_session() as session: + job = session.query(SchedulerJob).filter_by(hostname=get_hostname()).order_by( + SchedulerJob.latest_heartbeat.desc()).limit(1).first() + sys.exit(0 if job.is_alive() else 1)" + {{- end }} +{{- end }} + + +{{- define "scheduler_startup_check_command" }} + {{- if semverCompare ">=2.5.0" .Values.airflowVersion }} + - sh + - -c + - | + CONNECTION_CHECK_MAX_COUNT=0 AIRFLOW__LOGGING__LOGGING_LEVEL=ERROR exec /entrypoint \ + airflow jobs check --job-type SchedulerJob --local + {{- else if semverCompare ">=2.1.0" .Values.airflowVersion }} + - sh + - -c + - | + CONNECTION_CHECK_MAX_COUNT=0 AIRFLOW__LOGGING__LOGGING_LEVEL=ERROR exec /entrypoint \ + airflow jobs check --job-type SchedulerJob --hostname $(hostname) + {{- else }} + - sh + - -c + - | + CONNECTION_CHECK_MAX_COUNT=0 exec /entrypoint python -Wignore -c " + import os + os.environ['AIRFLOW__CORE__LOGGING_LEVEL'] = 'ERROR' + os.environ['AIRFLOW__LOGGING__LOGGING_LEVEL'] = 'ERROR' + from airflow.jobs.scheduler_job import SchedulerJob + from airflow.utils.db import create_session + from airflow.utils.net import get_hostname + import sys + with create_session() as session: + job = session.query(SchedulerJob).filter_by(hostname=get_hostname()).order_by( + SchedulerJob.latest_heartbeat.desc()).limit(1).first() + sys.exit(0 if job.is_alive() else 1)" + {{- end }} +{{- end }} + +{{- define "triggerer_liveness_check_command" }} + {{- if semverCompare ">=2.5.0" .Values.airflowVersion }} + - sh + - -c + - | + CONNECTION_CHECK_MAX_COUNT=0 AIRFLOW__LOGGING__LOGGING_LEVEL=ERROR exec /entrypoint \ + airflow jobs check --job-type TriggererJob --local + {{- else }} + - sh + - -c + - | + CONNECTION_CHECK_MAX_COUNT=0 AIRFLOW__LOGGING__LOGGING_LEVEL=ERROR exec /entrypoint \ + airflow jobs check --job-type TriggererJob --hostname $(hostname) + {{- end }} +{{- end }} + +{{- define "dag_processor_liveness_check_command" }} + {{- $commandArgs := (list) -}} + {{- if semverCompare ">=2.5.0" .Values.airflowVersion }} + {{- $commandArgs = append $commandArgs "--local" -}} + {{- if semverCompare ">=2.5.2" .Values.airflowVersion }} + {{- $commandArgs = concat $commandArgs (list "--job-type" "DagProcessorJob") -}} + {{- end }} + {{- else }} + {{- $commandArgs = concat $commandArgs (list "--hostname" "$(hostname)") -}} + {{- end }} + - sh + - -c + - | + CONNECTION_CHECK_MAX_COUNT=0 AIRFLOW__LOGGING__LOGGING_LEVEL=ERROR exec /entrypoint \ + airflow jobs check {{ join " " $commandArgs }} +{{- end }} + +{{- define "registry_docker_config" }} + {{- $host := .Values.registry.connection.host }} + {{- $email := .Values.registry.connection.email }} + {{- $user := .Values.registry.connection.user }} + {{- $pass := .Values.registry.connection.pass }} + + {{- $config := dict "auths" }} + {{- $auth := dict }} + {{- $data := dict }} + {{- $_ := set $data "username" $user }} + {{- $_ := set $data "password" $pass }} + {{- $_ := set $data "email" $email }} + {{- $_ := set $data "auth" (printf "%v:%v" $user $pass | b64enc) }} + {{- $_ := set $auth $host $data }} + {{- $_ := set $config "auths" $auth }} + {{ $config | toJson | print }} +{{- end }} + +{{/* +Set the default value for pod securityContext +If no value is passed for securityContexts.pod or .securityContexts.pod or legacy securityContext and .securityContext, defaults to global uid and gid. + + +-----------------------------+ +------------------------+ +----------------------+ +-----------------+ +-------------------------+ + | .securityContexts.pod | -> | .securityContext | -> | securityContexts.pod | -> | securityContext | -> | Values.uid + Values.gid | + +-----------------------------+ +------------------------+ +----------------------+ +-----------------+ +-------------------------+ + +Values are not accumulated meaning that if runAsUser is set to 10 in .securityContexts.pod, +any extra values set to securityContext or uid+gid will be ignored. + +The template can be called like so: + include "airflowPodSecurityContext" (list . .Values.webserver) + +Where `.` is the global variables scope and `.Values.webserver` the local variables scope for the webserver template. +*/}} +{{- define "airflowPodSecurityContext" -}} + {{- $ := index . 0 -}} + {{- with index . 1 }} + {{- if .securityContexts.pod -}} + {{ toYaml .securityContexts.pod | print }} + {{- else if .securityContext -}} + {{ toYaml .securityContext | print }} + {{- else if $.Values.securityContexts.pod -}} + {{ toYaml $.Values.securityContexts.pod | print }} + {{- else if $.Values.securityContext -}} + {{ toYaml $.Values.securityContext | print }} + {{- else -}} +runAsUser: {{ $.Values.uid }} +fsGroup: {{ $.Values.gid }} + {{- end }} + {{- end }} +{{- end }} + +{{/* +Set the default value for pod securityContext +If no value is passed for .securityContexts.pod or .securityContext, defaults to UID in the local node. + + +-----------------------------+ +------------------------+ +-------------+ + | .securityContexts.pod | -> | .securityContext | -> | .uid | + +-----------------------------+ +------------------------+ +-------------+ + +The template can be called like so: + include "localPodSecurityContext" (list . .Values.schedule) + +It is important to pass the local variables scope to this template as it is used to determine the local node value for uid. +*/}} +{{- define "localPodSecurityContext" -}} + {{- if .securityContexts.pod -}} + {{ toYaml .securityContexts.pod | print }} + {{- else if .securityContext -}} + {{ toYaml .securityContext | print }} + {{- else -}} +runAsUser: {{ .uid }} + {{- end -}} +{{- end -}} + +{{/* +Set the default value for container securityContext +If no value is passed for .securityContexts.container or .securityContext, defaults to UID in the local node. + + +-----------------------------------+ +------------------------+ +-------------+ + | .securityContexts.container | -> | .securityContext | -> | .uid | + +-----------------------------------+ +------------------------+ +-------------+ + +The template can be called like so: + include "localContainerSecurityContext" .Values.statsd + +It is important to pass the local variables scope to this template as it is used to determine the local node value for uid. +*/}} +{{- define "localContainerSecurityContext" -}} + {{- if .securityContexts.container -}} + {{ toYaml .securityContexts.container | print }} + {{- else if .securityContext -}} + {{ toYaml .securityContext | print }} + {{- else -}} +runAsUser: {{ .uid }} + {{- end -}} +{{- end -}} + +{{/* +Set the default value for workers chown for persistent storage +If no value is passed for securityContexts.pod or .securityContexts.pod or legacy securityContext and .securityContext, defaults to global uid and gid. +The template looks for `runAsUser` and `fsGroup` specifically, any other parameter will be ignored. + + +-----------------------------+ +----------------------------------------------------+ +------------------+ +-------------------------+ + | .securityContexts.pod | -> | securityContexts.pod | .securityContexts.pod | -> | securityContexts | -> | Values.uid + Values.gid | + +-----------------------------+ +----------------------------------------------------+ +------------------+ +-------------------------+ + +Values are not accumulated meaning that if runAsUser is set to 10 in .securityContexts.pod, +any extra values set to securityContexts or uid+gid will be ignored. + +The template can be called like so: + include "airflowPodSecurityContextsIds" (list . .Values.webserver) + +Where `.` is the global variables scope and `.Values.workers` the local variables scope for the workers template. +*/}} +{{- define "airflowPodSecurityContextsIds" -}} + {{- $ := index . 0 -}} + {{- with index . 1 }} + {{- if .securityContexts.pod -}} + {{ pluck "runAsUser" .securityContexts.pod | first | default $.Values.uid }}:{{ pluck "fsGroup" .securityContexts.pod | first | default $.Values.gid }} + {{- else if $.Values.securityContext -}} + {{ pluck "runAsUser" $.Values.securityContext | first | default $.Values.uid }}:{{ pluck "fsGroup" $.Values.securityContext | first | default $.Values.gid }} + {{- else if $.Values.securityContexts.pod -}} + {{ pluck "runAsUser" $.Values.securityContexts.pod | first | default $.Values.uid }}:{{ pluck "fsGroup" $.Values.securityContexts.pod | first | default $.Values.gid }} + {{- else if $.Values.securityContext -}} + {{ pluck "runAsUser" $.Values.securityContext | first | default $.Values.uid }}:{{ pluck "fsGroup" $.Values.securityContext | first | default $.Values.gid }} + {{- else -}} +{{ $.Values.uid }}:{{ $.Values.gid }} + {{- end -}} + {{- end -}} +{{- end -}} + +{{/* +Set the default value for container securityContext +If no value is passed for securityContexts.container or .securityContexts.container, defaults to deny privileges escallation and dropping all POSIX capabilities. + + +-----------------------------------+ +----------------------------+ +-----------------------------------------------------------+ + | .securityContexts.container | -> | securityContexts.containers | -> | allowPrivilegesEscalation: false, capabilities.drop: [ALL]| + +-----------------------------------+ +----------------------------+ +-----------------------------------------------------------+ + +The template can be called like so: + include "containerSecurityContext" (list . .Values.webserver) + +Where `.` is the global variables scope and `.Values.webserver` the local variables scope for the webserver template. +*/}} +{{- define "containerSecurityContext" -}} + {{- $ := index . 0 -}} + {{- with index . 1 }} + {{- if .securityContexts.container -}} + {{ toYaml .securityContexts.container | print }} + {{- else if $.Values.securityContexts.containers -}} + {{ toYaml $.Values.securityContexts.containers | print }} + {{- else -}} +allowPrivilegeEscalation: false +capabilities: + drop: + - ALL + {{- end -}} + {{- end -}} +{{- end -}} + +{{/* +Set the default value for external container securityContext(redis and statsd). +If no value is passed for .securityContexts.container, defaults to deny privileges escallation and dropping all POSIX capabilities. + + +-----------------------------------+ +-----------------------------------------------------------+ + | .securityContexts.container | -> | allowPrivilegesEscalation: false, capabilities.drop: [ALL]| + +-----------------------------------+ +-----------------------------------------------------------+ + +The template can be called like so: + include "externalContainerSecurityContext" .Values.statsd +*/}} +{{- define "externalContainerSecurityContext" -}} + {{- if .securityContexts.container -}} + {{ toYaml .securityContexts.container | print }} + {{- else -}} +allowPrivilegeEscalation: false +capabilities: + drop: + - ALL + {{- end -}} +{{- end -}} + +{{- define "container_extra_envs" -}} + {{- $ := index . 0 -}} + {{- $env := index . 1 -}} + {{- range $i, $config := $env }} + - name: {{ $config.name }} + value: {{ $config.value | quote }} + {{- if or (eq $.Values.executor "KubernetesExecutor") (eq $.Values.executor "LocalKubernetesExecutor") (eq $.Values.executor "CeleryKubernetesExecutor") }} + - name: AIRFLOW__KUBERNETES_ENVIRONMENT_VARIABLES__{{ $config.name }} + value: {{ $config.value | quote }} + {{- end }} + {{- end }} +{{- end }} + +{{- define "kedaNetworkPolicySelector" }} + {{- if .Values.workers.keda.enabled }} + + {{- if .Values.workers.keda.namespaceLabels }} + - namespaceSelector: + matchLabels: {{- toYaml .Values.workers.keda.namespaceLabels | nindent 10 }} + podSelector: + {{- else }} + - podSelector: + {{- end }} + matchLabels: + app: keda-operator + {{- end }} +{{- end }} diff --git a/helm/airflow/templates/check-values.yaml b/helm/airflow/templates/check-values.yaml new file mode 100644 index 0000000..7e7871a --- /dev/null +++ b/helm/airflow/templates/check-values.yaml @@ -0,0 +1,64 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +{{- /* +The sole purpose of this yaml file is it to check the values file is consistent for some complexe combinations. +*/ -}} + +{{- /* +############################## + Redis related checks +############################# +*/ -}} + + {{- if or (eq .Values.executor "CeleryExecutor") (eq .Values.executor "CeleryKubernetesExecutor") }} + {{- if .Values.redis.enabled }} + + {{- if and .Values.redis.passwordSecretName (not .Values.data.brokerUrlSecretName) }} + {{ required "When using the internal redis of the chart and setting the value redis.passwordSecretName, you must also set the value data.brokerUrlSecretName." nil }} + {{- end }} + + {{- if and .Values.redis.passwordSecretName .Values.redis.password }} + {{ required "You must not set both values redis.passwordSecretName and redis.password" nil }} + {{- end }} + + {{- else }} + + {{- if not (or .Values.data.brokerUrlSecretName .Values.data.brokerUrl) }} + {{ required "You must set one of the values data.brokerUrlSecretName or data.brokerUrl when using a Celery based executor with redis.enabled set to false (we need the url to the redis instance)." nil }} + {{- end }} + + {{- end }} + + {{- if and .Values.data.brokerUrlSecretName .Values.data.brokerUrl }} + {{ required "You must not set both values data.brokerUrlSecretName and data.brokerUrl" nil }} + {{- end }} + + {{- end }} + + {{- if .Values.elasticsearch.enabled }} + {{- if and .Values.elasticsearch.secretName .Values.elasticsearch.connection }} + {{ required "You must not set both values elasticsearch.secretName and elasticsearch.connection" nil }} + {{- end }} + + {{- if not (or .Values.elasticsearch.secretName .Values.elasticsearch.connection) }} + {{ required "You must set one of the values elasticsearch.secretName or elasticsearch.connection when using a Elasticsearch" nil }} + {{- end }} + + {{- end }} diff --git a/helm/airflow/templates/cleanup/cleanup-cronjob.yaml b/helm/airflow/templates/cleanup/cleanup-cronjob.yaml new file mode 100644 index 0000000..c09e279 --- /dev/null +++ b/helm/airflow/templates/cleanup/cleanup-cronjob.yaml @@ -0,0 +1,109 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +################################ +## Airflow Cleanup Pods CronJob +################################# +{{- if .Values.cleanup.enabled }} +{{- $nodeSelector := or .Values.cleanup.nodeSelector .Values.nodeSelector }} +{{- $affinity := or .Values.cleanup.affinity .Values.affinity }} +{{- $tolerations := or .Values.cleanup.tolerations .Values.tolerations }} +{{- $topologySpreadConstraints := or .Values.cleanup.topologySpreadConstraints .Values.topologySpreadConstraints }} +{{- $securityContext := include "airflowPodSecurityContext" (list . .Values.cleanup) }} +apiVersion: batch/v1 +kind: CronJob +metadata: + name: {{ include "airflow.fullname" . }}-cleanup + labels: + tier: airflow + component: airflow-cleanup-pods + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.cleanup.jobAnnotations }} + annotations: {{- toYaml . | nindent 4 }} + {{- end }} +spec: + schedule: "{{ tpl .Values.cleanup.schedule . }}" + # The cron job does not allow concurrent runs; if it is time for a new job run and the previous job run hasn't finished yet, the cron job skips the new job run + concurrencyPolicy: Forbid + {{- if .Values.cleanup.failedJobsHistoryLimit }} + failedJobsHistoryLimit: {{ .Values.cleanup.failedJobsHistoryLimit }} + {{- end }} + {{- if .Values.cleanup.successfulJobsHistoryLimit }} + successfulJobsHistoryLimit: {{ .Values.cleanup.successfulJobsHistoryLimit }} + {{- end }} + jobTemplate: + spec: + backoffLimit: 1 + template: + metadata: + labels: + tier: airflow + component: airflow-cleanup-pods + release: {{ .Release.Name }} + {{- if or (.Values.labels) (.Values.cleanup.labels) }} + {{- mustMerge .Values.cleanup.labels .Values.labels | toYaml | nindent 12 }} + {{- end }} + annotations: + sidecar.istio.io/inject: "false" + {{- if .Values.airflowPodAnnotations }} + {{- toYaml .Values.airflowPodAnnotations | nindent 12 }} + {{- end }} + {{- if .Values.cleanup.podAnnotations }} + {{- toYaml .Values.cleanup.podAnnotations | nindent 12 }} + {{- end }} + spec: + restartPolicy: Never + nodeSelector: {{- toYaml $nodeSelector | nindent 12 }} + affinity: {{- toYaml $affinity | nindent 12 }} + {{- if .Values.schedulerName }} + schedulerName: {{ .Values.schedulerName }} + {{- end }} + tolerations: {{- toYaml $tolerations | nindent 12 }} + topologySpreadConstraints: {{- toYaml $topologySpreadConstraints | nindent 12 }} + serviceAccountName: {{ include "cleanup.serviceAccountName" . }} + {{- if or .Values.registry.secretName .Values.registry.connection }} + imagePullSecrets: + - name: {{ template "registry_secret" . }} + {{- end }} + securityContext: {{ $securityContext | nindent 12 }} + containers: + - name: airflow-cleanup-pods + image: {{ template "airflow_image" . }} + imagePullPolicy: {{ .Values.images.airflow.pullPolicy }} + {{- if .Values.cleanup.command }} + command: {{ tpl (toYaml .Values.cleanup.command) . | nindent 16 }} + {{- end }} + {{- if .Values.cleanup.args }} + args: {{ tpl (toYaml .Values.cleanup.args) . | nindent 16 }} + {{- end }} + env: + {{- include "standard_airflow_environment" . | indent 12 }} + {{- include "container_extra_envs" (list . .Values.cleanup.env) | indent 12 }} + volumeMounts: {{- include "airflow_config_mount" . | nindent 16 }} + resources: {{- toYaml .Values.cleanup.resources | nindent 16 }} + volumes: + - name: config + configMap: + name: {{ template "airflow_config" . }} +{{- end }} diff --git a/helm/airflow/templates/cleanup/cleanup-serviceaccount.yaml b/helm/airflow/templates/cleanup/cleanup-serviceaccount.yaml new file mode 100644 index 0000000..0bda299 --- /dev/null +++ b/helm/airflow/templates/cleanup/cleanup-serviceaccount.yaml @@ -0,0 +1,40 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +################################ +## Airflow Cleanup ServiceAccount +################################# +{{- if and .Values.cleanup.serviceAccount.create .Values.cleanup.enabled }} +apiVersion: v1 +kind: ServiceAccount +automountServiceAccountToken: {{ .Values.cleanup.serviceAccount.automountServiceAccountToken }} +metadata: + name: {{ include "cleanup.serviceAccountName" . }} + labels: + tier: airflow + release: {{ .Release.Name }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + {{- if or (.Values.labels) (.Values.cleanup.labels) }} + {{- mustMerge .Values.cleanup.labels .Values.labels | toYaml | nindent 4 }} + {{- end }} + {{- with .Values.cleanup.serviceAccount.annotations }} + annotations: {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/helm/airflow/templates/configmaps/configmap.yaml b/helm/airflow/templates/configmaps/configmap.yaml new file mode 100644 index 0000000..b69d144 --- /dev/null +++ b/helm/airflow/templates/configmaps/configmap.yaml @@ -0,0 +1,74 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +################################ +## Airflow ConfigMap +################################# +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "airflow_config" . }} + labels: + tier: airflow + component: config + release: {{ .Release.Name }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end -}} + {{- if .Values.airflowConfigAnnotations }} + annotations: {{- toYaml .Values.airflowConfigAnnotations | nindent 4 }} + {{- end }} +{{- $Global := . }} +data: + # These are system-specified config overrides. + airflow.cfg: |- + {{- range $section, $settings := .Values.config }} + [{{ $section }}] + {{- range $key, $val := $settings }} + {{ $key }} = {{ tpl ($val | toString) $Global }} + {{- end }} + {{ end }} + + {{- if .Values.airflowLocalSettings }} + airflow_local_settings.py: |- + {{- tpl .Values.airflowLocalSettings . | nindent 4 }} + {{- end }} + + {{- if and .Values.dags.gitSync.enabled .Values.dags.gitSync.knownHosts }} + known_hosts: |- + {{- .Values.dags.gitSync.knownHosts | nindent 4 }} + {{- end }} + +{{/* {{- if or (eq $.Values.executor "LocalKubernetesExecutor") (eq $.Values.executor "KubernetesExecutor") (eq $.Values.executor "CeleryKubernetesExecutor") }}*/}} +{{/* {{- if semverCompare ">=1.10.12" .Values.airflowVersion }}*/}} + pod_template_file.yaml: |- + {{- if .Values.podTemplate }} + {{- tpl .Values.podTemplate . | nindent 4 }} + {{- else }} + {{- tpl (.Files.Get "files/pod-template-file.kubernetes-helm-yaml") . | nindent 4 }} + {{- end }} +{{/* {{- end }}*/}} +{{/* {{- end }}*/}} + + {{- if .Values.kerberos.enabled }} + krb5.conf: |- + {{- tpl .Values.kerberos.config . | nindent 4 }} + {{- end }} diff --git a/helm/airflow/templates/configmaps/extra-configmaps.yaml b/helm/airflow/templates/configmaps/extra-configmaps.yaml new file mode 100644 index 0000000..2a50a31 --- /dev/null +++ b/helm/airflow/templates/configmaps/extra-configmaps.yaml @@ -0,0 +1,53 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +#################################################### +## Extra ConfigMaps provisioned via the chart values +#################################################### +{{- $Global := . }} +{{- range $configMapName, $configMapContent := .Values.extraConfigMaps }} +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ tpl $configMapName $Global | quote }} + labels: + release: {{ $Global.Release.Name }} + chart: "{{ $Global.Chart.Name }}-{{ $Global.Chart.Version }}" + heritage: {{ $Global.Release.Service }} + {{- with $Global.Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if $configMapContent.labels }} + {{- toYaml $configMapContent.labels | nindent 4 }} + {{- end }} + annotations: + "helm.sh/hook": "pre-install,pre-upgrade" + "helm.sh/hook-delete-policy": "before-hook-creation" + "helm.sh/hook-weight": "0" + {{- if $configMapContent.annotations }} + {{- toYaml $configMapContent.annotations | nindent 4 }} + {{- end }} +{{- if $configMapContent.data }} +data: + {{- with $configMapContent.data }} + {{- tpl . $Global | nindent 2 }} + {{- end }} +{{- end }} +{{- end }} diff --git a/helm/airflow/templates/configmaps/statsd-configmap.yaml b/helm/airflow/templates/configmaps/statsd-configmap.yaml new file mode 100644 index 0000000..c195109 --- /dev/null +++ b/helm/airflow/templates/configmaps/statsd-configmap.yaml @@ -0,0 +1,52 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +################################ +## Airflow StatsD ConfigMap +################################# +{{- if and .Values.statsd.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "airflow.fullname" . }}-statsd + labels: + tier: airflow + component: config + release: {{ .Release.Name }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.statsd.configMapAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +data: + mappings.yml: |- + {{- if .Values.statsd.overrideMappings }} + mappings: + {{- toYaml .Values.statsd.overrideMappings | nindent 6 }} + {{- else }} + {{- .Files.Get "files/statsd-mappings.yml" | nindent 4 }} + {{- if .Values.statsd.extraMappings }} + {{- toYaml .Values.statsd.extraMappings | nindent 6 }} + {{- end }} + {{- end }} +{{- end }} diff --git a/helm/airflow/templates/configmaps/webserver-configmap.yaml b/helm/airflow/templates/configmaps/webserver-configmap.yaml new file mode 100644 index 0000000..c1b25ba --- /dev/null +++ b/helm/airflow/templates/configmaps/webserver-configmap.yaml @@ -0,0 +1,44 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +################################ +## Airflow ConfigMap +################################# +{{- if and .Values.webserver.webserverConfig (not .Values.webserver.webserverConfigConfigMapName) }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "airflow_webserver_config_configmap_name" . }} + labels: + tier: airflow + component: config + release: {{ .Release.Name }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.webserver.configMapAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +data: + webserver_config.py: |- + {{- tpl .Values.webserver.webserverConfig . | nindent 4 }} +{{- end }} diff --git a/helm/airflow/templates/dag-processor/dag-processor-deployment.yaml b/helm/airflow/templates/dag-processor/dag-processor-deployment.yaml new file mode 100644 index 0000000..4e87bae --- /dev/null +++ b/helm/airflow/templates/dag-processor/dag-processor-deployment.yaml @@ -0,0 +1,261 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +################################ +## Airflow Dag Processor Deployment +################################# +{{- if semverCompare ">=2.3.0" .Values.airflowVersion }} +{{- if .Values.dagProcessor.enabled }} +{{- $nodeSelector := or .Values.dagProcessor.nodeSelector .Values.nodeSelector }} +{{- $affinity := or .Values.dagProcessor.affinity .Values.affinity }} +{{- $tolerations := or .Values.dagProcessor.tolerations .Values.tolerations }} +{{- $topologySpreadConstraints := or .Values.dagProcessor.topologySpreadConstraints .Values.topologySpreadConstraints }} +{{- $revisionHistoryLimit := or .Values.dagProcessor.revisionHistoryLimit .Values.revisionHistoryLimit }} +{{- $securityContext := include "airflowPodSecurityContext" (list . .Values.dagProcessor) }} +{{- $containerSecurityContext := include "containerSecurityContext" (list . .Values.dagProcessor) }} +{{- $containerLifecycleHooks := or .Values.dagProcessor.containerLifecycleHooks .Values.containerLifecycleHooks }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "airflow.fullname" . }}-dag-processor + labels: + tier: airflow + component: dag-processor + release: {{ .Release.Name }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if .Values.dagProcessor.annotations }} + annotations: {{- toYaml .Values.dagProcessor.annotations | nindent 4 }} + {{- end }} +spec: + replicas: {{ .Values.dagProcessor.replicas }} + {{- if $revisionHistoryLimit }} + revisionHistoryLimit: {{ $revisionHistoryLimit }} + {{- end }} + selector: + matchLabels: + tier: airflow + component: dag-processor + release: {{ .Release.Name }} + {{- if .Values.dagProcessor.strategy }} + strategy: {{- toYaml .Values.dagProcessor.strategy | nindent 4 }} + {{- end }} + template: + metadata: + labels: + tier: airflow + component: dag-processor + release: {{ .Release.Name }} + {{- with .Values.labels }} + {{- toYaml . | nindent 8 }} + {{- end }} + annotations: + checksum/metadata-secret: {{ include (print $.Template.BasePath "/secrets/metadata-connection-secret.yaml") . | sha256sum }} + checksum/pgbouncer-config-secret: {{ include (print $.Template.BasePath "/secrets/pgbouncer-config-secret.yaml") . | sha256sum }} + checksum/airflow-config: {{ include (print $.Template.BasePath "/configmaps/configmap.yaml") . | sha256sum }} + checksum/extra-configmaps: {{ include (print $.Template.BasePath "/configmaps/extra-configmaps.yaml") . | sha256sum }} + checksum/extra-secrets: {{ include (print $.Template.BasePath "/secrets/extra-secrets.yaml") . | sha256sum }} + {{- if .Values.dagProcessor.safeToEvict }} + cluster-autoscaler.kubernetes.io/safe-to-evict: "true" + {{- end }} + {{- if .Values.airflowPodAnnotations }} + {{- toYaml .Values.airflowPodAnnotations | nindent 8 }} + {{- end }} + {{- if .Values.dagProcessor.podAnnotations }} + {{- toYaml .Values.dagProcessor.podAnnotations | nindent 8 }} + {{- end }} + spec: + {{- if .Values.dagProcessor.priorityClassName }} + priorityClassName: {{ .Values.dagProcessor.priorityClassName }} + {{- end }} + nodeSelector: {{- toYaml $nodeSelector | nindent 8 }} + affinity: + {{- if $affinity }} + {{- toYaml $affinity | nindent 8 }} + {{- else }} + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchLabels: + component: dag-processor + topologyKey: kubernetes.io/hostname + weight: 100 + {{- end }} + {{- if .Values.schedulerName }} + schedulerName: {{ .Values.schedulerName }} + {{- end }} + tolerations: {{- toYaml $tolerations | nindent 8 }} + topologySpreadConstraints: {{- toYaml $topologySpreadConstraints | nindent 8 }} + terminationGracePeriodSeconds: {{ .Values.dagProcessor.terminationGracePeriodSeconds }} + restartPolicy: Always + serviceAccountName: {{ include "dagProcessor.serviceAccountName" . }} + securityContext: {{ $securityContext | nindent 8 }} + {{- if or .Values.registry.secretName .Values.registry.connection }} + imagePullSecrets: + - name: {{ template "registry_secret" . }} + {{- end }} + initContainers: + {{- if .Values.dagProcessor.waitForMigrations.enabled }} + - name: wait-for-airflow-migrations + resources: {{- toYaml .Values.dagProcessor.resources | nindent 12 }} + image: {{ template "airflow_image_for_migrations" . }} + imagePullPolicy: {{ .Values.images.airflow.pullPolicy }} + volumeMounts: + {{- if .Values.volumeMounts }} + {{- toYaml .Values.volumeMounts | nindent 12 }} + {{- end }} + {{- if .Values.dagProcessor.extraVolumeMounts }} + {{- tpl (toYaml .Values.dagProcessor.extraVolumeMounts) . | nindent 12 }} + {{- end }} + {{- include "airflow_config_mount" . | nindent 12 }} + args: {{- include "wait-for-migrations-command" . | indent 10 }} + envFrom: {{- include "custom_airflow_environment_from" . | default "\n []" | indent 10 }} + env: + {{- include "custom_airflow_environment" . | indent 10 }} + {{- include "standard_airflow_environment" . | indent 10 }} + {{- if .Values.dagProcessor.waitForMigrations.env }} + {{- tpl (toYaml .Values.dagProcessor.waitForMigrations.env) $ | nindent 12 }} + {{- end }} + {{- end }} + {{- if and (.Values.dags.gitSync.enabled) (not .Values.dags.persistence.enabled) }} + {{- include "git_sync_container" (dict "Values" .Values "is_init" "true" "Template" .Template) | nindent 8 }} + {{- end }} + {{- if .Values.dagProcessor.extraInitContainers }} + {{- toYaml .Values.dagProcessor.extraInitContainers | nindent 8 }} + {{- end }} + containers: + - name: dag-processor + image: {{ template "airflow_image" . }} + imagePullPolicy: {{ .Values.images.airflow.pullPolicy }} + securityContext: {{ $containerSecurityContext | nindent 12 }} + {{- if $containerLifecycleHooks }} + lifecycle: {{- tpl (toYaml $containerLifecycleHooks) . | nindent 12 }} + {{- end }} + {{- if .Values.dagProcessor.command }} + command: {{ tpl (toYaml .Values.dagProcessor.command) . | nindent 12 }} + {{- end }} + {{- if .Values.dagProcessor.args }} + args: {{ tpl (toYaml .Values.dagProcessor.args) . | nindent 12 }} + {{- end }} + resources: {{- toYaml .Values.dagProcessor.resources | nindent 12 }} + volumeMounts: + {{- if .Values.volumeMounts }} + {{- toYaml .Values.volumeMounts | nindent 12 }} + {{- end }} + {{- if .Values.dagProcessor.extraVolumeMounts }} + {{- tpl (toYaml .Values.dagProcessor.extraVolumeMounts) . | nindent 12 }} + {{- end }} + - name: logs + mountPath: {{ template "airflow_logs" . }} + {{- include "airflow_config_mount" . | nindent 12 }} + {{- if or .Values.dags.persistence.enabled .Values.dags.gitSync.enabled }} + {{- include "airflow_dags_mount" . | nindent 12 }} + {{- end }} + envFrom: {{- include "custom_airflow_environment_from" . | default "\n []" | indent 10 }} + env: + {{- include "custom_airflow_environment" . | indent 10 }} + {{- include "standard_airflow_environment" . | indent 10 }} + {{- include "container_extra_envs" (list . .Values.dagProcessor.env) | indent 10 }} + livenessProbe: + initialDelaySeconds: {{ .Values.dagProcessor.livenessProbe.initialDelaySeconds }} + timeoutSeconds: {{ .Values.dagProcessor.livenessProbe.timeoutSeconds }} + failureThreshold: {{ .Values.dagProcessor.livenessProbe.failureThreshold }} + periodSeconds: {{ .Values.dagProcessor.livenessProbe.periodSeconds }} + exec: + command: + {{- if .Values.dagProcessor.livenessProbe.command }} + {{- toYaml .Values.dagProcessor.livenessProbe.command | nindent 16 }} + {{- else }} + {{- include "dag_processor_liveness_check_command" . | indent 14 }} + {{- end }} + {{- if and (.Values.dags.gitSync.enabled) (not .Values.dags.persistence.enabled) }} + {{- include "git_sync_container" . | indent 8 }} + {{- end }} + {{- if .Values.dagProcessor.logGroomerSidecar.enabled }} + - name: dag-processor-log-groomer + resources: {{- toYaml .Values.dagProcessor.logGroomerSidecar.resources | nindent 12 }} + image: {{ template "airflow_image" . }} + imagePullPolicy: {{ .Values.images.airflow.pullPolicy }} + {{- if .Values.dagProcessor.logGroomerSidecar.command }} + command: {{ tpl (toYaml .Values.dagProcessor.logGroomerSidecar.command) . | nindent 12 }} + {{- end }} + {{- if .Values.dagProcessor.logGroomerSidecar.args }} + args: {{- tpl (toYaml .Values.dagProcessor.logGroomerSidecar.args) . | nindent 12 }} + {{- end }} + {{- if .Values.dagProcessor.logGroomerSidecar.retentionDays }} + env: + - name: AIRFLOW__LOG_RETENTION_DAYS + value: "{{ .Values.dagProcessor.logGroomerSidecar.retentionDays }}" + {{- end }} + volumeMounts: + - name: logs + mountPath: {{ template "airflow_logs" . }} + {{- if .Values.volumeMounts }} + {{- toYaml .Values.volumeMounts | nindent 12 }} + {{- end }} + {{- if .Values.dagProcessor.extraVolumeMounts }} + {{- tpl (toYaml .Values.dagProcessor.extraVolumeMounts) . | nindent 12 }} + {{- end }} + {{- if or .Values.webserver.webserverConfig .Values.webserver.webserverConfigConfigMapName }} + {{- include "airflow_webserver_config_mount" . | nindent 12 }} + {{- end }} + {{- end }} + {{- if .Values.dagProcessor.extraContainers }} + {{- toYaml .Values.dagProcessor.extraContainers | nindent 8 }} + {{- end }} + volumes: + - name: config + configMap: + name: {{ template "airflow_config" . }} + {{- if or .Values.webserver.webserverConfig .Values.webserver.webserverConfigConfigMapName }} + - name: webserver-config + configMap: + name: {{ template "airflow_webserver_config_configmap_name" . }} + {{- end }} + {{- if .Values.dags.persistence.enabled }} + - name: dags + persistentVolumeClaim: + claimName: {{ template "airflow_dags_volume_claim" . }} + {{- else if .Values.dags.gitSync.enabled }} + - name: dags + emptyDir: {} + {{- end }} + {{- if and .Values.dags.gitSync.enabled .Values.dags.gitSync.sshKeySecret }} + {{- include "git_sync_ssh_key_volume" . | indent 8 }} + {{- end }} + {{- if .Values.volumes }} + {{- toYaml .Values.volumes | nindent 8 }} + {{- end }} + {{- if .Values.dagProcessor.extraVolumes }} + {{- tpl (toYaml .Values.dagProcessor.extraVolumes) . | nindent 8 }} + {{- end }} + {{- if .Values.logs.persistence.enabled }} + - name: logs + persistentVolumeClaim: + claimName: {{ template "airflow_logs_volume_claim" . }} + {{- else }} + - name: logs + emptyDir: {} +{{- end }} +{{- end }} +{{- end }} diff --git a/helm/airflow/templates/dag-processor/dag-processor-serviceaccount.yaml b/helm/airflow/templates/dag-processor/dag-processor-serviceaccount.yaml new file mode 100644 index 0000000..5d386e4 --- /dev/null +++ b/helm/airflow/templates/dag-processor/dag-processor-serviceaccount.yaml @@ -0,0 +1,43 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +################################ +## Airflow Dag Processor ServiceAccount +################################# +{{- if semverCompare ">=2.3.0" .Values.airflowVersion }} +{{- if and .Values.dagProcessor.serviceAccount.create .Values.dagProcessor.enabled }} +apiVersion: v1 +kind: ServiceAccount +automountServiceAccountToken: {{ .Values.dagProcessor.serviceAccount.automountServiceAccountToken }} +metadata: + name: {{ include "dagProcessor.serviceAccountName" . }} + labels: + tier: airflow + component: dag-processor + release: {{ .Release.Name }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.dagProcessor.serviceAccount.annotations}} + annotations: {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} +{{- end }} diff --git a/helm/airflow/templates/dags-persistent-volume-claim.yaml b/helm/airflow/templates/dags-persistent-volume-claim.yaml new file mode 100644 index 0000000..15628ca --- /dev/null +++ b/helm/airflow/templates/dags-persistent-volume-claim.yaml @@ -0,0 +1,52 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +###################################### +## Airflow DAGs PersistentVolumeClaim +###################################### +{{- if and (not .Values.dags.persistence.existingClaim ) .Values.dags.persistence.enabled }} +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ template "airflow_dags_volume_claim" . }} + labels: + tier: airflow + component: dags-pvc + release: {{ .Release.Name }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.dags.persistence.annotations }} + annotations: {{- toYaml . | nindent 4 }} + {{- end }} +spec: + accessModes: [{{ .Values.dags.persistence.accessMode | quote }}] + resources: + requests: + storage: {{ .Values.dags.persistence.size | quote }} + {{- if .Values.dags.persistence.storageClassName }} + {{- if (eq "-" .Values.dags.persistence.storageClassName) }} + storageClassName: "" + {{- else }} + storageClassName: "{{ .Values.dags.persistence.storageClassName }}" + {{- end }} + {{- end }} +{{- end }} diff --git a/helm/airflow/templates/flower/flower-deployment.yaml b/helm/airflow/templates/flower/flower-deployment.yaml new file mode 100644 index 0000000..00f8f4a --- /dev/null +++ b/helm/airflow/templates/flower/flower-deployment.yaml @@ -0,0 +1,169 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +################################ +## Airflow Flower Deployment +################################# +{{- if .Values.flower.enabled }} +{{- if or (eq .Values.executor "CeleryExecutor") (eq .Values.executor "CeleryKubernetesExecutor") }} +{{- $nodeSelector := or .Values.flower.nodeSelector .Values.nodeSelector }} +{{- $affinity := or .Values.flower.affinity .Values.affinity }} +{{- $tolerations := or .Values.flower.tolerations .Values.tolerations }} +{{- $topologySpreadConstraints := or .Values.flower.topologySpreadConstraints .Values.topologySpreadConstraints }} +{{- $revisionHistoryLimit := or .Values.flower.revisionHistoryLimit .Values.revisionHistoryLimit }} +{{- $securityContext := include "airflowPodSecurityContext" (list . .Values.flower) }} +{{- $containerSecurityContext := include "containerSecurityContext" (list . .Values.flower) }} +{{- $containerLifecycleHooks := or .Values.flower.containerLifecycleHooks .Values.containerLifecycleHooks }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "airflow.fullname" . }}-flower + labels: + tier: airflow + component: flower + release: {{ .Release.Name }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if .Values.flower.annotations }} + annotations: {{- toYaml .Values.flower.annotations | nindent 4 }} + {{- end }} +spec: + replicas: 1 + {{- if $revisionHistoryLimit }} + revisionHistoryLimit: {{ $revisionHistoryLimit }} + {{- end }} + selector: + matchLabels: + tier: airflow + component: flower + release: {{ .Release.Name }} + template: + metadata: + labels: + tier: airflow + component: flower + release: {{ .Release.Name }} + {{- if or (.Values.labels) (.Values.flower.labels) }} + {{- mustMerge .Values.flower.labels .Values.labels | toYaml | nindent 8 }} + {{- end }} + annotations: + checksum/airflow-config: {{ include (print $.Template.BasePath "/configmaps/configmap.yaml") . | sha256sum }} + checksum/flower-secret: {{ include (print $.Template.BasePath "/secrets/flower-secret.yaml") . | sha256sum }} + {{- if or (.Values.airflowPodAnnotations) (.Values.flower.podAnnotations) }} + {{- mustMerge .Values.flower.podAnnotations .Values.airflowPodAnnotations | toYaml | nindent 8 }} + {{- end }} + spec: + nodeSelector: {{- toYaml $nodeSelector | nindent 8 }} + affinity: {{- toYaml $affinity | nindent 8 }} + {{- if .Values.schedulerName }} + schedulerName: {{ .Values.schedulerName }} + {{- end }} + tolerations: {{- toYaml $tolerations | nindent 8 }} + topologySpreadConstraints: {{- toYaml $topologySpreadConstraints | nindent 8 }} + serviceAccountName: {{ include "flower.serviceAccountName" . }} + {{- if .Values.flower.priorityClassName }} + priorityClassName: {{ .Values.flower.priorityClassName }} + {{- end }} + restartPolicy: Always + securityContext: {{ $securityContext | nindent 8 }} + {{- if or .Values.registry.secretName .Values.registry.connection }} + imagePullSecrets: + - name: {{ template "registry_secret" . }} + {{- end }} + containers: + - name: flower + image: {{ template "flower_image" . }} + imagePullPolicy: {{ .Values.images.flower.pullPolicy }} + securityContext: {{ $containerSecurityContext | nindent 12 }} + {{- if $containerLifecycleHooks }} + lifecycle: {{- tpl (toYaml $containerLifecycleHooks) . | nindent 12 }} + {{- end }} + {{- if .Values.flower.command }} + command: {{ tpl (toYaml .Values.flower.command) . | nindent 12 }} + {{- end }} + {{- if .Values.flower.args }} + args: {{ tpl (toYaml .Values.flower.args) . | nindent 12 }} + {{- end }} + resources: {{- toYaml .Values.flower.resources | nindent 12 }} + volumeMounts: + {{- include "airflow_config_mount" . | nindent 12 }} + {{- if .Values.volumeMounts }} + {{- toYaml .Values.volumeMounts | nindent 12 }} + {{- end }} + {{- if .Values.flower.extraVolumeMounts }} + {{- tpl (toYaml .Values.flower.extraVolumeMounts) . | nindent 12 }} + {{- end }} + ports: + - name: flower-ui + containerPort: {{ .Values.ports.flowerUI }} + livenessProbe: + failureThreshold: 10 + exec: + command: + - curl + {{- if (or .Values.flower.secretName (and .Values.flower.username .Values.flower.password))}} + - "--user" + - $AIRFLOW__CELERY__FLOWER_BASIC_AUTH + {{- end }} + - {{ printf "localhost:%s" (.Values.ports.flowerUI | toString) }} + initialDelaySeconds: 10 + periodSeconds: 5 + readinessProbe: + failureThreshold: 10 + exec: + command: + - curl + {{- if (or .Values.flower.secretName (and .Values.flower.username .Values.flower.password))}} + - "--user" + - $AIRFLOW__CELERY__FLOWER_BASIC_AUTH + {{- end }} + - {{ printf "localhost:%s" (.Values.ports.flowerUI | toString) }} + initialDelaySeconds: 10 + periodSeconds: 5 + envFrom: + {{- include "custom_airflow_environment_from" . | default "\n []" | indent 10 }} + env: + {{- if (or .Values.flower.secretName (and .Values.flower.username .Values.flower.password))}} + - name: AIRFLOW__CELERY__FLOWER_BASIC_AUTH + valueFrom: + secretKeyRef: + name: {{ template "flower_secret" . }} + key: basicAuth + {{- end }} + {{- include "standard_airflow_environment" . | indent 10 }} + {{- include "custom_airflow_environment" . | indent 10 }} + {{- include "container_extra_envs" (list . .Values.flower.env) | indent 10 }} + {{- if .Values.flower.extraContainers }} + {{- toYaml .Values.flower.extraContainers | nindent 8 }} + {{- end }} + volumes: + - name: config + configMap: + name: {{ template "airflow_config" . }} + {{- if .Values.volumes }} + {{- toYaml .Values.volumes | nindent 8 }} + {{- end }} + {{- if .Values.flower.extraVolumes }} + {{- tpl (toYaml .Values.flower.extraVolumes) . | nindent 8 }} + {{- end }} +{{- end }} +{{- end }} diff --git a/helm/airflow/templates/flower/flower-ingress.yaml b/helm/airflow/templates/flower/flower-ingress.yaml new file mode 100644 index 0000000..7c798ad --- /dev/null +++ b/helm/airflow/templates/flower/flower-ingress.yaml @@ -0,0 +1,94 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +################################ +## Airflow Flower Ingress +################################# +{{- if .Values.flower.enabled }} +{{- if and (or .Values.ingress.flower.enabled .Values.ingress.enabled) (or (eq .Values.executor "CeleryExecutor") (eq .Values.executor "CeleryKubernetesExecutor")) }} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ include "airflow.fullname" . }}-flower-ingress + labels: + tier: airflow + component: flower-ingress + release: {{ .Release.Name }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + {{- if or (.Values.labels) (.Values.flower.labels) }} + {{- mustMerge .Values.flower.labels .Values.labels | toYaml | nindent 4 }} + {{- end }} + {{- with .Values.ingress.flower.annotations }} + annotations: {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if and .Values.ingress.flower.hosts (.Values.ingress.flower.hosts | first | kindIs "string" | not) }} + {{- $anyTlsHosts := false -}} + {{- range .Values.ingress.flower.hosts }} + {{- if .tls }} + {{- if .tls.enabled }} + {{- $anyTlsHosts = true -}} + {{- end }} + {{- end }} + {{- end }} + {{- if $anyTlsHosts }} + tls: + {{- range .Values.ingress.flower.hosts }} + {{- if .tls }} + {{- if .tls.enabled }} + - hosts: + - {{ .name | quote }} + secretName: {{ .tls.secretName }} + {{- end }} + {{- end }} + {{- end }} + {{- end }} + {{- else if .Values.ingress.flower.tls.enabled }} + tls: + - hosts: + {{- .Values.ingress.flower.hosts | default (list .Values.ingress.flower.host) | toYaml | nindent 8 }} + secretName: {{ .Values.ingress.flower.tls.secretName }} + {{- end }} + rules: + {{- range .Values.ingress.flower.hosts | default (list .Values.ingress.flower.host) }} + - http: + paths: + - backend: + service: + name: {{ $.Release.Name }}-flower + port: + name: flower-ui + {{- if $.Values.ingress.flower.path }} + path: {{ $.Values.ingress.flower.path }} + pathType: {{ $.Values.ingress.flower.pathType }} + {{- end }} + {{- $hostname := . -}} + {{- if . | kindIs "string" | not }} + {{- $hostname = .name -}} + {{- end }} + {{- if $hostname }} + host: {{ tpl $hostname $ | quote }} + {{- end }} + {{- end }} + {{- if .Values.ingress.flower.ingressClassName }} + ingressClassName: {{ .Values.ingress.flower.ingressClassName }} + {{- end }} +{{- end }} +{{- end }} diff --git a/helm/airflow/templates/flower/flower-networkpolicy.yaml b/helm/airflow/templates/flower/flower-networkpolicy.yaml new file mode 100644 index 0000000..b0f9db8 --- /dev/null +++ b/helm/airflow/templates/flower/flower-networkpolicy.yaml @@ -0,0 +1,60 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +################################ +## Airflow Flower NetworkPolicy +################################# +{{- if .Values.flower.enabled }} +{{- $celery_executors := list "CeleryExecutor" "CeleryKubernetesExecutor"}} +{{- if and .Values.networkPolicies.enabled (has .Values.executor $celery_executors) }} +{{- $from := or .Values.flower.networkPolicy.ingress.from .Values.flower.extraNetworkPolicies }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "airflow.fullname" . }}-flower-policy + labels: + tier: airflow + component: airflow-flower-policy + release: {{ .Release.Name }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + {{- if or (.Values.labels) (.Values.flower.labels) }} + {{- mustMerge .Values.flower.labels .Values.labels | toYaml | nindent 4 }} + {{- end }} +spec: + podSelector: + matchLabels: + tier: airflow + component: flower + release: {{ .Release.Name }} + policyTypes: + - Ingress + {{- if $from }} + ingress: + - from: {{- toYaml $from | nindent 6 }} + ports: + {{ range .Values.flower.networkPolicy.ingress.ports }} + - + {{- range $key, $val := . }} + {{ $key }}: {{ tpl (toString $val) $ }} + {{- end }} + {{- end }} + {{- end }} +{{- end }} +{{- end }} diff --git a/helm/airflow/templates/flower/flower-service.yaml b/helm/airflow/templates/flower/flower-service.yaml new file mode 100644 index 0000000..0847ff6 --- /dev/null +++ b/helm/airflow/templates/flower/flower-service.yaml @@ -0,0 +1,61 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +################################ +## Airflow Flower Service Component +################################# +{{- if .Values.flower.enabled }} +{{- if or (eq .Values.executor "CeleryExecutor") (eq .Values.executor "CeleryKubernetesExecutor") }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "airflow.fullname" . }}-flower + labels: + tier: airflow + component: flower + release: {{ .Release.Name }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + {{- if or (.Values.labels) (.Values.flower.labels) }} + {{- mustMerge .Values.flower.labels .Values.labels | toYaml | nindent 4 }} + {{- end }} + {{- with .Values.flower.service.annotations }} + annotations: {{- toYaml . | nindent 4 }} + {{- end }} +spec: + type: {{ .Values.flower.service.type }} + selector: + tier: airflow + component: flower + release: {{ .Release.Name }} + ports: + {{ range .Values.flower.service.ports }} + - + {{- range $key, $val := . }} + {{ $key }}: {{ tpl (toString $val) $ }} + {{- end }} + {{- end }} + {{- if .Values.flower.service.loadBalancerIP }} + loadBalancerIP: {{ .Values.flower.service.loadBalancerIP }} + {{- end }} + {{- if .Values.flower.service.loadBalancerSourceRanges }} + loadBalancerSourceRanges: {{- toYaml .Values.flower.service.loadBalancerSourceRanges | nindent 4 }} + {{- end }} +{{- end }} +{{- end }} diff --git a/helm/airflow/templates/flower/flower-serviceaccount.yaml b/helm/airflow/templates/flower/flower-serviceaccount.yaml new file mode 100644 index 0000000..efe621c --- /dev/null +++ b/helm/airflow/templates/flower/flower-serviceaccount.yaml @@ -0,0 +1,41 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +###################################### +## Airflow Flower ServiceAccount +###################################### +{{- if and .Values.flower.enabled (or (eq .Values.executor "CeleryExecutor") (eq .Values.executor "CeleryKubernetesExecutor")) .Values.flower.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +automountServiceAccountToken: {{ .Values.flower.serviceAccount.automountServiceAccountToken }} +metadata: + name: {{ include "flower.serviceAccountName" . }} + labels: + tier: airflow + component: flower + release: {{ .Release.Name }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + {{- if or (.Values.labels) (.Values.flower.labels) }} + {{- mustMerge .Values.flower.labels .Values.labels | toYaml | nindent 4 }} + {{- end }} + {{- with .Values.flower.serviceAccount.annotations }} + annotations: {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/helm/airflow/templates/jobs/create-user-job-serviceaccount.yaml b/helm/airflow/templates/jobs/create-user-job-serviceaccount.yaml new file mode 100644 index 0000000..8e6f4a6 --- /dev/null +++ b/helm/airflow/templates/jobs/create-user-job-serviceaccount.yaml @@ -0,0 +1,41 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +########################################### +## Airflow Create User Job ServiceAccount +########################################### +{{- if and .Values.createUserJob.serviceAccount.create .Values.webserver.defaultUser.enabled }} +apiVersion: v1 +kind: ServiceAccount +automountServiceAccountToken: {{ .Values.createUserJob.serviceAccount.automountServiceAccountToken }} +metadata: + name: {{ include "createUserJob.serviceAccountName" . }} + labels: + tier: airflow + component: create-user-job + release: {{ .Release.Name }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + {{- if or (.Values.labels) (.Values.createUserJob.labels) }} + {{- mustMerge .Values.createUserJob.labels .Values.labels | toYaml | nindent 4 }} + {{- end }} + {{- with .Values.createUserJob.serviceAccount.annotations }} + annotations: {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/helm/airflow/templates/jobs/create-user-job.yaml b/helm/airflow/templates/jobs/create-user-job.yaml new file mode 100644 index 0000000..22d68f2 --- /dev/null +++ b/helm/airflow/templates/jobs/create-user-job.yaml @@ -0,0 +1,134 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +################################ +## Airflow Create User Job +################################# +{{- if .Values.webserver.defaultUser.enabled }} +{{- $nodeSelector := or .Values.createUserJob.nodeSelector .Values.nodeSelector }} +{{- $affinity := or .Values.createUserJob.affinity .Values.affinity }} +{{- $tolerations := or .Values.createUserJob.tolerations .Values.tolerations }} +{{- $topologySpreadConstraints := or .Values.createUserJob.topologySpreadConstraints .Values.topologySpreadConstraints }} +{{- $securityContext := include "airflowPodSecurityContext" (list . .Values.createUserJob) }} +{{- $containerSecurityContext := include "containerSecurityContext" (list . .Values.createUserJob) }} +{{- $containerLifecycleHooks := or .Values.createUserJob.containerLifecycleHooks .Values.containerLifecycleHooks }} +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ include "airflow.fullname" . }}-create-user + labels: + tier: airflow + component: create-user-job + release: {{ .Release.Name }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- $annotations := dict }} + {{- if .Values.createUserJob.useHelmHooks }} + {{- $_ := set $annotations "helm.sh/hook" "post-install,post-upgrade" }} + {{- $_ := set $annotations "helm.sh/hook-weight" "2" }} + {{- $_ := set $annotations "helm.sh/hook-delete-policy" "before-hook-creation,hook-succeeded" }} + {{- end }} + {{- with $annotations := merge $annotations .Values.createUserJob.jobAnnotations }} + annotations: {{- $annotations | toYaml | nindent 4 }} + {{- end }} +spec: + {{- if not (kindIs "invalid" .Values.createUserJob.ttlSecondsAfterFinished) }} + ttlSecondsAfterFinished: {{ .Values.createUserJob.ttlSecondsAfterFinished }} + {{- end }} + template: + metadata: + labels: + tier: airflow + component: create-user-job + release: {{ .Release.Name }} + {{- if or (.Values.labels) (.Values.createUserJob.labels) }} + {{- mustMerge .Values.createUserJob.labels .Values.labels | toYaml | nindent 8 }} + {{- end }} + {{- if or .Values.airflowPodAnnotations .Values.createUserJob.annotations }} + annotations: + {{- if .Values.airflowPodAnnotations }} + {{- toYaml .Values.airflowPodAnnotations | nindent 8 }} + {{- end }} + {{- if .Values.createUserJob.annotations }} + {{- toYaml .Values.createUserJob.annotations | nindent 8 }} + {{- end }} + {{- end }} + spec: + securityContext: {{ $securityContext | nindent 8 }} + restartPolicy: OnFailure + nodeSelector: {{- toYaml $nodeSelector | nindent 8 }} + affinity: {{- toYaml $affinity | nindent 8 }} + {{- if .Values.schedulerName }} + schedulerName: {{ .Values.schedulerName }} + {{- end }} + tolerations: {{- toYaml $tolerations | nindent 8 }} + topologySpreadConstraints: {{- toYaml $topologySpreadConstraints | nindent 8 }} + serviceAccountName: {{ include "createUserJob.serviceAccountName" . }} + {{- if or .Values.registry.secretName .Values.registry.connection }} + imagePullSecrets: + - name: {{ template "registry_secret" . }} + {{- end }} + containers: + - name: create-user + image: {{ template "airflow_image" . }} + imagePullPolicy: {{ .Values.images.airflow.pullPolicy }} + securityContext: {{ $containerSecurityContext | nindent 12 }} + {{- if $containerLifecycleHooks }} + lifecycle: {{- tpl (toYaml $containerLifecycleHooks) . | nindent 12 }} + {{- end }} + {{- if .Values.createUserJob.command }} + command: {{ tpl (toYaml .Values.createUserJob.command) . | nindent 12 }} + {{- end }} + {{- if .Values.createUserJob.args }} + args: {{ tpl (toYaml .Values.createUserJob.args) . | nindent 12 }} + {{- end }} + {{- if .Values.createUserJob.applyCustomEnv }} + envFrom: {{- include "custom_airflow_environment_from" . | default "\n []" | indent 10 }} + env: {{- include "custom_airflow_environment" . | indent 10 }} + {{- else }} + env: + {{- end }} + {{- include "standard_airflow_environment" . | indent 10 }} + {{- include "container_extra_envs" (list . .Values.createUserJob.env) | indent 10 }} + resources: {{- toYaml .Values.createUserJob.resources | nindent 12 }} + volumeMounts: + {{- include "airflow_config_mount" . | nindent 12 }} + {{- if .Values.volumeMounts }} + {{- toYaml .Values.volumeMounts | nindent 12 }} + {{- end }} + {{- if .Values.createUserJob.extraVolumeMounts }} + {{- tpl (toYaml .Values.createUserJob.extraVolumeMounts) . | nindent 12 }} + {{- end }} + {{- if .Values.createUserJob.extraContainers }} + {{- toYaml .Values.createUserJob.extraContainers | nindent 8 }} + {{- end }} + volumes: + - name: config + configMap: + name: {{ template "airflow_config" . }} + {{- if .Values.volumes }} + {{- toYaml .Values.volumes | nindent 8 }} + {{- end }} + {{- if .Values.createUserJob.extraVolumes }} + {{- tpl (toYaml .Values.createUserJob.extraVolumes) . | nindent 8 }} + {{- end }} +{{- end }} diff --git a/helm/airflow/templates/jobs/migrate-database-job-serviceaccount.yaml b/helm/airflow/templates/jobs/migrate-database-job-serviceaccount.yaml new file mode 100644 index 0000000..52a07e5 --- /dev/null +++ b/helm/airflow/templates/jobs/migrate-database-job-serviceaccount.yaml @@ -0,0 +1,41 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +############################################# +## Airflow Migrate Database Job ServiceAccount +############################################## +{{- if .Values.migrateDatabaseJob.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +automountServiceAccountToken: {{ .Values.migrateDatabaseJob.serviceAccount.automountServiceAccountToken }} +metadata: + name: {{ include "migrateDatabaseJob.serviceAccountName" . }} + labels: + tier: airflow + component: run-airflow-migrations + release: {{ .Release.Name }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.migrateDatabaseJob.serviceAccount.annotations }} + annotations: {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/helm/airflow/templates/jobs/migrate-database-job.yaml b/helm/airflow/templates/jobs/migrate-database-job.yaml new file mode 100644 index 0000000..7281377 --- /dev/null +++ b/helm/airflow/templates/jobs/migrate-database-job.yaml @@ -0,0 +1,135 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +################################ +## Airflow Run Migrations +################################# +{{- if .Values.migrateDatabaseJob.enabled }} +{{- $nodeSelector := or .Values.migrateDatabaseJob.nodeSelector .Values.nodeSelector }} +{{- $affinity := or .Values.migrateDatabaseJob.affinity .Values.affinity }} +{{- $tolerations := or .Values.migrateDatabaseJob.tolerations .Values.tolerations }} +{{- $topologySpreadConstraints := or .Values.migrateDatabaseJob.topologySpreadConstraints .Values.topologySpreadConstraints }} +{{- $securityContext := include "airflowPodSecurityContext" (list . .Values.migrateDatabaseJob) }} +{{- $containerSecurityContext := include "containerSecurityContext" (list . .Values.migrateDatabaseJob) }} +{{- $containerLifecycleHooks := or .Values.migrateDatabaseJob.containerLifecycleHooks .Values.containerLifecycleHooks }} +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ include "airflow.fullname" . }}-run-airflow-migrations + labels: + tier: airflow + component: run-airflow-migrations + release: {{ .Release.Name }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- $annotations := dict }} + {{- if .Values.migrateDatabaseJob.useHelmHooks }} + {{- $_ := set $annotations "helm.sh/hook" "post-install,post-upgrade" }} + {{- $_ := set $annotations "helm.sh/hook-weight" "1" }} + {{- $_ := set $annotations "helm.sh/hook-delete-policy" "before-hook-creation,hook-succeeded" }} + {{- end }} + {{- with $annotations := merge $annotations .Values.migrateDatabaseJob.jobAnnotations }} + annotations: {{- $annotations | toYaml | nindent 4 }} + {{- end }} +spec: + {{- if not (kindIs "invalid" .Values.migrateDatabaseJob.ttlSecondsAfterFinished) }} + ttlSecondsAfterFinished: {{ .Values.migrateDatabaseJob.ttlSecondsAfterFinished }} + {{- end }} + template: + metadata: + labels: + tier: airflow + component: run-airflow-migrations + release: {{ .Release.Name }} + {{- with .Values.labels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if or .Values.airflowPodAnnotations .Values.migrateDatabaseJob.annotations }} + annotations: + {{- if .Values.airflowPodAnnotations }} + {{- toYaml .Values.airflowPodAnnotations | nindent 8 }} + {{- end }} + {{- if .Values.migrateDatabaseJob.annotations }} + {{- toYaml .Values.migrateDatabaseJob.annotations | nindent 8 }} + {{- end }} + {{- end }} + spec: + securityContext: {{ $securityContext | nindent 8 }} + restartPolicy: OnFailure + nodeSelector: {{- toYaml $nodeSelector | nindent 8 }} + affinity: {{- toYaml $affinity | nindent 8 }} + {{- if .Values.schedulerName }} + schedulerName: {{ .Values.schedulerName }} + {{- end }} + tolerations: {{- toYaml $tolerations | nindent 8 }} + topologySpreadConstraints: {{- toYaml $topologySpreadConstraints | nindent 8 }} + serviceAccountName: {{ include "migrateDatabaseJob.serviceAccountName" . }} + {{- if or .Values.registry.secretName .Values.registry.connection }} + imagePullSecrets: + - name: {{ template "registry_secret" . }} + {{- end }} + containers: + - name: run-airflow-migrations + image: {{ template "airflow_image_for_migrations" . }} + imagePullPolicy: {{ .Values.images.airflow.pullPolicy }} + securityContext: {{ $containerSecurityContext | nindent 12 }} + {{- if $containerLifecycleHooks }} + lifecycle: {{- tpl (toYaml $containerLifecycleHooks) . | nindent 12 }} + {{- end }} + {{- if .Values.migrateDatabaseJob.command }} + command: {{- tpl (toYaml .Values.migrateDatabaseJob.command) . | nindent 12 }} + {{- end }} + {{- if .Values.migrateDatabaseJob.args }} + args: {{- tpl (toYaml .Values.migrateDatabaseJob.args) . | nindent 12 }} + {{- end }} + {{- if .Values.migrateDatabaseJob.applyCustomEnv }} + envFrom: {{- include "custom_airflow_environment_from" . | default "\n []" | indent 10 }} + env: {{- include "custom_airflow_environment" . | indent 10 }} + {{- else }} + env: + {{- end }} + - name: PYTHONUNBUFFERED + value: "1" + {{- include "standard_airflow_environment" . | indent 10 }} + resources: {{- toYaml .Values.migrateDatabaseJob.resources | nindent 12 }} + volumeMounts: + {{- include "airflow_config_mount" . | nindent 12 }} + {{- if .Values.volumeMounts }} + {{- toYaml .Values.volumeMounts | nindent 12 }} + {{- end }} + {{- if .Values.migrateDatabaseJob.extraVolumeMounts }} + {{- tpl (toYaml .Values.migrateDatabaseJob.extraVolumeMounts) . | nindent 12 }} + {{- end }} + {{- if .Values.migrateDatabaseJob.extraContainers }} + {{- toYaml .Values.migrateDatabaseJob.extraContainers | nindent 8 }} + {{- end }} + volumes: + - name: config + configMap: + name: {{ template "airflow_config" . }} + {{- if .Values.volumes }} + {{- toYaml .Values.volumes | nindent 8 }} + {{- end }} + {{- if .Values.migrateDatabaseJob.extraVolumes }} + {{- tpl (toYaml .Values.migrateDatabaseJob.extraVolumes) . | nindent 8 }} + {{- end }} +{{- end }} diff --git a/helm/airflow/templates/limitrange.yaml b/helm/airflow/templates/limitrange.yaml new file mode 100644 index 0000000..8b9f716 --- /dev/null +++ b/helm/airflow/templates/limitrange.yaml @@ -0,0 +1,39 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +################################ +## Airflow Namespace LimitRange +################################# +{{- if .Values.limits }} +apiVersion: v1 +kind: LimitRange +metadata: + name: {{ .Release.Name }}-limit-range + labels: + tier: resources + component: limitrange + release: {{ .Release.Name }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + limits: {{- toYaml .Values.limits | nindent 4 }} +{{- end }} diff --git a/helm/airflow/templates/logs-persistent-volume-claim.yaml b/helm/airflow/templates/logs-persistent-volume-claim.yaml new file mode 100644 index 0000000..a450888 --- /dev/null +++ b/helm/airflow/templates/logs-persistent-volume-claim.yaml @@ -0,0 +1,52 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +###################################### +## Airflow LOGs PersistentVolumeClaim +###################################### +{{- if and (not .Values.logs.persistence.existingClaim ) .Values.logs.persistence.enabled }} +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ template "airflow_logs_volume_claim" . }} + labels: + tier: airflow + component: logs-pvc + release: {{ .Release.Name }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.logs.persistence.annotations }} + annotations: {{- toYaml . | nindent 4 }} + {{- end }} +spec: + accessModes: ["ReadWriteMany"] + resources: + requests: + storage: {{ .Values.logs.persistence.size | quote }} + {{- if .Values.logs.persistence.storageClassName }} + {{- if (eq "-" .Values.logs.persistence.storageClassName) }} + storageClassName: "" + {{- else }} + storageClassName: "{{ .Values.logs.persistence.storageClassName }}" + {{- end }} + {{- end }} +{{- end }} diff --git a/helm/airflow/templates/pgbouncer/pgbouncer-deployment.yaml b/helm/airflow/templates/pgbouncer/pgbouncer-deployment.yaml new file mode 100644 index 0000000..ff4dc0d --- /dev/null +++ b/helm/airflow/templates/pgbouncer/pgbouncer-deployment.yaml @@ -0,0 +1,212 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +################################ +## Airflow Pgbouncer Deployment +################################# +{{- if .Values.pgbouncer.enabled }} +{{- $nodeSelector := or .Values.pgbouncer.nodeSelector .Values.nodeSelector }} +{{- $affinity := or .Values.pgbouncer.affinity .Values.affinity }} +{{- $tolerations := or .Values.pgbouncer.tolerations .Values.tolerations }} +{{- $topologySpreadConstraints := or .Values.pgbouncer.topologySpreadConstraints .Values.topologySpreadConstraints }} +{{- $revisionHistoryLimit := or .Values.pgbouncer.revisionHistoryLimit .Values.revisionHistoryLimit }} +{{- $securityContext := include "localPodSecurityContext" .Values.pgbouncer }} +{{- $containerSecurityContext := include "externalContainerSecurityContext" .Values.pgbouncer }} +{{- $containerSecurityContextMetricsExporter := include "externalContainerSecurityContext" .Values.pgbouncer.metricsExporterSidecar }} +{{- $containerLifecycleHooks := .Values.pgbouncer.containerLifecycleHooks }} +{{- $containerLifecycleHooksMetricsExporter := .Values.pgbouncer.metricsExporterSidecar.containerLifecycleHooks }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "airflow.fullname" . }}-pgbouncer + labels: + tier: airflow + component: pgbouncer + release: {{ .Release.Name }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if .Values.pgbouncer.annotations }} + annotations: {{- toYaml .Values.pgbouncer.annotations | nindent 4 }} + {{- end }} +spec: + replicas: {{ .Values.pgbouncer.replicas | default "1" }} + {{- if $revisionHistoryLimit }} + revisionHistoryLimit: {{ $revisionHistoryLimit }} + {{- end }} + strategy: + rollingUpdate: + maxSurge: 1 + maxUnavailable: 0 + selector: + matchLabels: + tier: airflow + component: pgbouncer + release: {{ .Release.Name }} + template: + metadata: + labels: + tier: airflow + component: pgbouncer + release: {{ .Release.Name }} + {{- with .Values.labels }} + {{- toYaml . | nindent 8 }} + {{- end }} + annotations: + checksum/pgbouncer-config-secret: {{ include (print $.Template.BasePath "/secrets/pgbouncer-config-secret.yaml") . | sha256sum }} + checksum/pgbouncer-certificates-secret: {{ include (print $.Template.BasePath "/secrets/pgbouncer-certificates-secret.yaml") . | sha256sum }} + {{- if .Values.pgbouncer.podAnnotations }} + {{- toYaml .Values.pgbouncer.podAnnotations | nindent 8 }} + {{- end }} + spec: + {{- if .Values.pgbouncer.priorityClassName }} + priorityClassName: {{ .Values.pgbouncer.priorityClassName }} + {{- end }} + nodeSelector: {{- toYaml $nodeSelector | nindent 8 }} + affinity: {{- toYaml $affinity | nindent 8 }} + {{- if .Values.schedulerName }} + schedulerName: {{ .Values.schedulerName }} + {{- end }} + tolerations: {{- toYaml $tolerations | nindent 8 }} + topologySpreadConstraints: {{- toYaml $topologySpreadConstraints | nindent 8 }} + serviceAccountName: {{ include "pgbouncer.serviceAccountName" . }} + securityContext: {{ $securityContext | nindent 8 }} + restartPolicy: Always + {{- if or .Values.registry.secretName .Values.registry.connection }} + imagePullSecrets: + - name: {{ template "registry_secret" . }} + {{- end }} + containers: + - name: pgbouncer + image: {{ template "pgbouncer_image" . }} + imagePullPolicy: {{ .Values.images.pgbouncer.pullPolicy }} + securityContext: {{ $containerSecurityContext | nindent 12 }} + {{- if .Values.pgbouncer.command }} + command: {{ tpl (toYaml .Values.pgbouncer.command) . | nindent 12 }} + {{- end }} + {{- if .Values.pgbouncer.args }} + args: {{ tpl (toYaml .Values.pgbouncer.args) . | nindent 12 }} + {{- end }} + resources: {{- toYaml .Values.pgbouncer.resources | nindent 12 }} + {{- with .Values.pgbouncer.env }} + env: {{- toYaml . | nindent 12 }} + {{- end }} + ports: + - name: pgbouncer + containerPort: {{ .Values.ports.pgbouncer }} + livenessProbe: + tcpSocket: + port: {{ .Values.ports.pgbouncer }} + readinessProbe: + tcpSocket: + port: {{ .Values.ports.pgbouncer }} + volumeMounts: + - name: pgbouncer-config + subPath: pgbouncer.ini + mountPath: /etc/pgbouncer/pgbouncer.ini + readOnly: true + - name: pgbouncer-config + subPath: users.txt + mountPath: /etc/pgbouncer/users.txt + readOnly: true + {{- if .Values.pgbouncer.ssl.ca }} + - name: pgbouncer-certificates + subPath: root.crt + mountPath: /etc/pgbouncer/root.crt + readOnly: true + {{- end }} + {{- if .Values.pgbouncer.ssl.cert }} + - name: pgbouncer-certificates + subPath: server.crt + mountPath: /etc/pgbouncer/server.crt + readOnly: true + {{- end }} + {{- if .Values.pgbouncer.ssl.key }} + - name: pgbouncer-certificates + subPath: server.key + mountPath: /etc/pgbouncer/server.key + readOnly: true + {{- end }} + {{- if .Values.volumeMounts }} + {{- toYaml .Values.volumeMounts | nindent 12 }} + {{- end }} + {{- if .Values.pgbouncer.extraVolumeMounts }} + {{- tpl (toYaml .Values.pgbouncer.extraVolumeMounts) . | nindent 12 }} + {{- end }} + {{- if $containerLifecycleHooks }} + lifecycle: {{- tpl (toYaml $containerLifecycleHooks) . | nindent 12 }} + {{- end }} + - name: metrics-exporter + resources: {{- toYaml .Values.pgbouncer.metricsExporterSidecar.resources | nindent 12 }} + image: {{ template "pgbouncer_exporter_image" . }} + imagePullPolicy: {{ .Values.images.pgbouncerExporter.pullPolicy }} + securityContext: {{ $containerSecurityContextMetricsExporter | nindent 12 }} + env: + - name: DATABASE_URL + valueFrom: + secretKeyRef: + name: {{ template "pgbouncer_stats_secret" . }} + {{- if (and .Values.pgbouncer.metricsExporterSidecar.statsSecretName .Values.pgbouncer.metricsExporterSidecar.statsSecretKey) }} + key: {{ .Values.pgbouncer.metricsExporterSidecar.statsSecretKey }} + {{- else }} + key: "connection" + {{- end }} + ports: + - name: metrics + containerPort: {{ .Values.ports.pgbouncerScrape }} + livenessProbe: + exec: + command: + - pgbouncer_exporter + - health + initialDelaySeconds: {{ .Values.pgbouncer.metricsExporterSidecar.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.pgbouncer.metricsExporterSidecar.livenessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.pgbouncer.metricsExporterSidecar.livenessProbe.timeoutSeconds }} + readinessProbe: + exec: + command: + - pgbouncer_exporter + - health + initialDelaySeconds: {{ .Values.pgbouncer.metricsExporterSidecar.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.pgbouncer.metricsExporterSidecar.readinessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.pgbouncer.metricsExporterSidecar.readinessProbe.timeoutSeconds }} + {{- if $containerLifecycleHooksMetricsExporter }} + lifecycle: {{- tpl (toYaml $containerLifecycleHooksMetricsExporter) . | nindent 12 }} + {{- end }} + {{- if .Values.pgbouncer.extraContainers }} + {{- toYaml .Values.pgbouncer.extraContainers | nindent 8 }} + {{- end }} + volumes: + - name: pgbouncer-config + secret: + secretName: {{ template "pgbouncer_config_secret" . }} + {{- if or .Values.pgbouncer.ssl.ca .Values.pgbouncer.ssl.cert .Values.pgbouncer.ssl.key }} + - name: pgbouncer-certificates + secret: + secretName: {{ template "pgbouncer_certificates_secret" . }} + {{- end }} + {{- if .Values.volumes }} + {{- toYaml .Values.volumes | nindent 8 }} + {{- end }} + {{- if .Values.pgbouncer.extraVolumes }} + {{- tpl (toYaml .Values.pgbouncer.extraVolumes) . | nindent 8 }} + {{- end }} +{{- end }} diff --git a/helm/airflow/templates/pgbouncer/pgbouncer-networkpolicy.yaml b/helm/airflow/templates/pgbouncer/pgbouncer-networkpolicy.yaml new file mode 100644 index 0000000..a621b68 --- /dev/null +++ b/helm/airflow/templates/pgbouncer/pgbouncer-networkpolicy.yaml @@ -0,0 +1,77 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +################################ +## Pgbouncer NetworkPolicy +################################# +{{- $workersKedaEnabled := and .Values.workers.keda.enabled (has .Values.executor (list "CeleryExecutor" "CeleryKubernetesExecutor")) }} +{{- $triggererEnabled := and (semverCompare ">=2.2.0" .Values.airflowVersion) .Values.triggerer.enabled }} +{{- $triggererKedaEnabled := and $triggererEnabled .Values.triggerer.keda.enabled }} +{{- if and .Values.pgbouncer.enabled .Values.networkPolicies.enabled }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "airflow.fullname" . }}-pgbouncer-policy + labels: + tier: airflow + component: airflow-pgbouncer-policy + release: {{ .Release.Name }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + podSelector: + matchLabels: + tier: airflow + component: pgbouncer + release: {{ .Release.Name }} + policyTypes: + - Ingress + ingress: + - from: + - podSelector: + matchLabels: + tier: airflow + release: {{ .Release.Name }} + {{- if or $workersKedaEnabled $triggererKedaEnabled }} + {{- if and $workersKedaEnabled .Values.workers.keda.namespaceLabels }} + - namespaceSelector: + matchLabels: {{- toYaml .Values.workers.keda.namespaceLabels | nindent 10 }} + podSelector: + {{- else if and $triggererEnabled .Values.triggerer.keda.namespaceLabels }} + - namespaceSelector: + matchLabels: {{- toYaml .Values.triggerer.keda.namespaceLabels | nindent 10 }} + podSelector: + {{- else }} + - podSelector: + {{- end }} + matchLabels: + app: keda-operator + {{- end }} + {{- if .Values.pgbouncer.extraNetworkPolicies}} + {{- toYaml .Values.pgbouncer.extraNetworkPolicies | nindent 4 }} + {{- end }} + ports: + - protocol: TCP + port: {{ .Values.ports.pgbouncer }} + - protocol: TCP + port: {{ .Values.ports.pgbouncerScrape }} +{{- end }} diff --git a/helm/airflow/templates/pgbouncer/pgbouncer-poddisruptionbudget.yaml b/helm/airflow/templates/pgbouncer/pgbouncer-poddisruptionbudget.yaml new file mode 100644 index 0000000..964438c --- /dev/null +++ b/helm/airflow/templates/pgbouncer/pgbouncer-poddisruptionbudget.yaml @@ -0,0 +1,44 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +################################ +## Pgbouncer PodDisruptionBudget +################################# +{{- if and .Values.pgbouncer.enabled .Values.pgbouncer.podDisruptionBudget.enabled }} +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: {{ include "airflow.fullname" . }}-pgbouncer-pdb + labels: + tier: airflow + component: pgbouncer + release: {{ .Release.Name }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + selector: + matchLabels: + tier: airflow + component: pgbouncer + release: {{ .Release.Name }} + {{- toYaml .Values.pgbouncer.podDisruptionBudget.config | nindent 2 }} +{{- end }} diff --git a/helm/airflow/templates/pgbouncer/pgbouncer-service.yaml b/helm/airflow/templates/pgbouncer/pgbouncer-service.yaml new file mode 100644 index 0000000..c93dce8 --- /dev/null +++ b/helm/airflow/templates/pgbouncer/pgbouncer-service.yaml @@ -0,0 +1,56 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +################################ +## Airflow Pgbouncer Service +################################# +{{- if .Values.pgbouncer.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "airflow.fullname" . }}-pgbouncer + labels: + tier: airflow + component: pgbouncer + release: {{ .Release.Name }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + prometheus.io/scrape: "true" + prometheus.io/port: {{ .Values.ports.pgbouncerScrape | quote }} + {{- if .Values.pgbouncer.service.extraAnnotations }} + {{- toYaml .Values.pgbouncer.service.extraAnnotations | nindent 4 }} + {{- end }} +spec: + type: ClusterIP + selector: + tier: airflow + component: pgbouncer + release: {{ .Release.Name }} + ports: + - name: pgbouncer + protocol: TCP + port: {{ .Values.ports.pgbouncer }} + - name: pgbouncer-metrics + protocol: TCP + port: {{ .Values.ports.pgbouncerScrape }} +{{- end }} diff --git a/helm/airflow/templates/pgbouncer/pgbouncer-serviceaccount.yaml b/helm/airflow/templates/pgbouncer/pgbouncer-serviceaccount.yaml new file mode 100644 index 0000000..c0994f7 --- /dev/null +++ b/helm/airflow/templates/pgbouncer/pgbouncer-serviceaccount.yaml @@ -0,0 +1,41 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +###################################### +## Airflow Pgbouncer ServiceAccount +###################################### +{{- if and .Values.pgbouncer.serviceAccount.create .Values.pgbouncer.enabled }} +apiVersion: v1 +kind: ServiceAccount +automountServiceAccountToken: {{ .Values.pgbouncer.serviceAccount.automountServiceAccountToken }} +metadata: + name: {{ include "pgbouncer.serviceAccountName" . }} + labels: + tier: airflow + component: pgbouncer + release: {{ .Release.Name }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.pgbouncer.serviceAccount.annotations }} + annotations: {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/helm/airflow/templates/priorityclasses/priority-classes.yaml b/helm/airflow/templates/priorityclasses/priority-classes.yaml new file mode 100644 index 0000000..cc11ea2 --- /dev/null +++ b/helm/airflow/templates/priorityclasses/priority-classes.yaml @@ -0,0 +1,34 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +################################################# +## Priority classes provisioned via the chart values +################################################# +{{- $Global := . }} +{{- range $e := .Values.priorityClasses }} +--- +apiVersion: scheduling.k8s.io/v1 +kind: PriorityClass +metadata: + name: {{ $Global.Release.Name }}-{{ $e.name }} + labels: + release: {{ $Global.Release.Name }} +preemptionPolicy: {{ default "PreemptLowerPriority" $e.preemptionPolicy }} +value: {{ $e.value | required "value is required" }} +{{- end }} diff --git a/helm/airflow/templates/rbac/pod-cleanup-role.yaml b/helm/airflow/templates/rbac/pod-cleanup-role.yaml new file mode 100644 index 0000000..af73df6 --- /dev/null +++ b/helm/airflow/templates/rbac/pod-cleanup-role.yaml @@ -0,0 +1,44 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +################################ +## Airflow Cleanup Role +################################# +{{- if and .Values.rbac.create .Values.cleanup.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ include "airflow.fullname" . }}-cleanup-role + labels: + tier: airflow + release: {{ .Release.Name }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +rules: + - apiGroups: + - "" + resources: + - "pods" + verbs: + - "list" + - "delete" +{{- end }} diff --git a/helm/airflow/templates/rbac/pod-cleanup-rolebinding.yaml b/helm/airflow/templates/rbac/pod-cleanup-rolebinding.yaml new file mode 100644 index 0000000..8d927fb --- /dev/null +++ b/helm/airflow/templates/rbac/pod-cleanup-rolebinding.yaml @@ -0,0 +1,44 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +################################ +## Airflow Cleanup Role Binding +################################# +{{- if and .Values.rbac.create .Values.cleanup.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ include "airflow.fullname" . }}-cleanup-rolebinding + labels: + tier: airflow + release: {{ .Release.Name }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ include "airflow.fullname" . }}-cleanup-role +subjects: + - kind: ServiceAccount + name: {{ include "cleanup.serviceAccountName" . }} + namespace: "{{ .Release.Namespace }}" +{{- end }} diff --git a/helm/airflow/templates/rbac/pod-launcher-role.yaml b/helm/airflow/templates/rbac/pod-launcher-role.yaml new file mode 100644 index 0000000..271394d --- /dev/null +++ b/helm/airflow/templates/rbac/pod-launcher-role.yaml @@ -0,0 +1,74 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +################################ +## Airflow Pod Launcher Role +################################# +{{- if and .Values.rbac.create .Values.allowPodLaunching }} +apiVersion: rbac.authorization.k8s.io/v1 +{{- if .Values.multiNamespaceMode }} +kind: ClusterRole +{{- else }} +kind: Role +{{- end }} +metadata: + name: {{ include "airflow.fullname" . }}-pod-launcher-role + {{- if not .Values.multiNamespaceMode }} + namespace: "{{ .Release.Namespace }}" + {{- end }} + labels: + tier: airflow + release: {{ .Release.Name }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +rules: + - apiGroups: + - "" + resources: + - "pods" + verbs: + - "create" + - "list" + - "get" + - "patch" + - "watch" + - "delete" + - apiGroups: + - "" + resources: + - "pods/log" + verbs: + - "get" + - apiGroups: + - "" + resources: + - "pods/exec" + verbs: + - "create" + - "get" + - apiGroups: + - "" + resources: + - "events" + verbs: + - "list" +{{- end }} diff --git a/helm/airflow/templates/rbac/pod-launcher-rolebinding.yaml b/helm/airflow/templates/rbac/pod-launcher-rolebinding.yaml new file mode 100644 index 0000000..60705c8 --- /dev/null +++ b/helm/airflow/templates/rbac/pod-launcher-rolebinding.yaml @@ -0,0 +1,64 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +################################ +## Airflow Pod Launcher Role Binding +################################# +{{- if and .Values.rbac.create .Values.allowPodLaunching }} +{{- $schedulerLaunchExecutors := list "LocalExecutor" "LocalKubernetesExecutor" "KubernetesExecutor" "CeleryKubernetesExecutor" }} +{{- $workerLaunchExecutors := list "CeleryExecutor" "LocalKubernetesExecutor" "KubernetesExecutor" "CeleryKubernetesExecutor" }} +apiVersion: rbac.authorization.k8s.io/v1 +{{- if .Values.multiNamespaceMode }} +kind: ClusterRoleBinding +{{- else }} +kind: RoleBinding +{{- end }} +metadata: + {{- if not .Values.multiNamespaceMode }} + namespace: "{{ .Release.Namespace }}" + {{- end }} + name: {{ include "airflow.fullname" . }}-pod-launcher-rolebinding + labels: + tier: airflow + release: {{ .Release.Name }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +roleRef: + apiGroup: rbac.authorization.k8s.io + {{- if .Values.multiNamespaceMode }} + kind: ClusterRole + {{- else }} + kind: Role + {{- end }} + name: {{ include "airflow.fullname" . }}-pod-launcher-role +subjects: + {{- if has .Values.executor $schedulerLaunchExecutors }} + - kind: ServiceAccount + name: {{ include "scheduler.serviceAccountName" . }} + namespace: "{{ .Release.Namespace }}" + {{- end }} + {{- if has .Values.executor $workerLaunchExecutors }} + - kind: ServiceAccount + name: {{ include "worker.serviceAccountName" . }} + namespace: "{{ .Release.Namespace }}" + {{- end }} +{{- end }} diff --git a/helm/airflow/templates/rbac/pod-log-reader-role.yaml b/helm/airflow/templates/rbac/pod-log-reader-role.yaml new file mode 100644 index 0000000..d048d36 --- /dev/null +++ b/helm/airflow/templates/rbac/pod-log-reader-role.yaml @@ -0,0 +1,59 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +################################ +## Airflow Pod Reader Role +################################# +{{- if and .Values.rbac.create (or .Values.webserver.allowPodLogReading .Values.triggerer.enabled) }} +apiVersion: rbac.authorization.k8s.io/v1 +{{- if .Values.multiNamespaceMode }} +kind: ClusterRole +{{- else }} +kind: Role +{{- end }} +metadata: + name: {{ include "airflow.fullname" . }}-pod-log-reader-role + {{- if not .Values.multiNamespaceMode }} + namespace: "{{ .Release.Namespace }}" + {{- end }} + labels: + tier: airflow + release: {{ .Release.Name }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +rules: + - apiGroups: + - "" + resources: + - "pods" + verbs: + - "list" + - "get" + - "watch" + - apiGroups: + - "" + resources: + - "pods/log" + verbs: + - "get" + - "list" +{{- end }} diff --git a/helm/airflow/templates/rbac/pod-log-reader-rolebinding.yaml b/helm/airflow/templates/rbac/pod-log-reader-rolebinding.yaml new file mode 100644 index 0000000..e441f9a --- /dev/null +++ b/helm/airflow/templates/rbac/pod-log-reader-rolebinding.yaml @@ -0,0 +1,62 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +################################ +## Airflow Pod Reader Role Binding +################################# +{{- if and .Values.rbac.create (or .Values.webserver.allowPodLogReading .Values.triggerer.enabled) }} +apiVersion: rbac.authorization.k8s.io/v1 +{{- if .Values.multiNamespaceMode }} +kind: ClusterRoleBinding +{{- else }} +kind: RoleBinding +{{- end }} +metadata: + {{- if not .Values.multiNamespaceMode }} + namespace: "{{ .Release.Namespace }}" + {{- end }} + name: {{ include "airflow.fullname" . }}-pod-log-reader-rolebinding + labels: + tier: airflow + release: {{ .Release.Name }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +roleRef: + apiGroup: rbac.authorization.k8s.io + {{- if .Values.multiNamespaceMode }} + kind: ClusterRole + {{- else }} + kind: Role + {{- end }} + name: {{ include "airflow.fullname" . }}-pod-log-reader-role +subjects: + {{- if .Values.webserver.allowPodLogReading }} + - kind: ServiceAccount + name: {{ include "webserver.serviceAccountName" . }} + namespace: "{{ .Release.Namespace }}" + {{- end }} + {{- if .Values.triggerer.enabled }} + - kind: ServiceAccount + name: {{ include "triggerer.serviceAccountName" . }} + namespace: "{{ .Release.Namespace }}" + {{- end }} +{{- end }} diff --git a/helm/airflow/templates/rbac/security-context-constraint-rolebinding.yaml b/helm/airflow/templates/rbac/security-context-constraint-rolebinding.yaml new file mode 100644 index 0000000..070a8e8 --- /dev/null +++ b/helm/airflow/templates/rbac/security-context-constraint-rolebinding.yaml @@ -0,0 +1,88 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +################################ +## Airflow SCC Role Binding +################################# +{{- if and .Values.rbac.create .Values.rbac.createSCCRoleBinding }} +{{- $hasWorkers := has .Values.executor (list "CeleryExecutor" "LocalKubernetesExecutor" "KubernetesExecutor" "CeleryKubernetesExecutor") }} +apiVersion: rbac.authorization.k8s.io/v1 +{{- if .Values.multiNamespaceMode }} +kind: ClusterRoleBinding +{{- else }} +kind: RoleBinding +{{- end }} +metadata: + {{- if not .Values.multiNamespaceMode }} + namespace: "{{ .Release.Namespace }}" + {{- end }} + name: {{ include "airflow.fullname" . }}-scc-rolebinding + labels: + tier: airflow + release: {{ .Release.Name }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: system:openshift:scc:anyuid +subjects: + - kind: ServiceAccount + name: {{ include "webserver.serviceAccountName" . }} + namespace: "{{ .Release.Namespace }}" + {{- if $hasWorkers }} + - kind: ServiceAccount + name: {{ include "worker.serviceAccountName" . }} + namespace: "{{ .Release.Namespace }}" + {{- end }} + - kind: ServiceAccount + name: {{ include "scheduler.serviceAccountName" . }} + namespace: "{{ .Release.Namespace }}" + {{- if and .Values.statsd.enabled }} + - kind: ServiceAccount + name: {{ include "statsd.serviceAccountName" . }} + namespace: "{{ .Release.Namespace }}" + {{- end }} + {{- if and .Values.flower.enabled (or (eq .Values.executor "CeleryExecutor") (eq .Values.executor "CeleryKubernetesExecutor")) }} + - kind: ServiceAccount + name: {{ include "flower.serviceAccountName" . }} + namespace: "{{ .Release.Namespace }}" + {{- end }} + {{- if and (semverCompare ">=2.2.0" .Values.airflowVersion) }} + - kind: ServiceAccount + name: {{ include "triggerer.serviceAccountName" . }} + namespace: "{{ .Release.Namespace }}" + {{- end }} + - kind: ServiceAccount + name: {{ include "migrateDatabaseJob.serviceAccountName" . }} + namespace: "{{ .Release.Namespace }}" + {{- if .Values.webserver.defaultUser.enabled }} + - kind: ServiceAccount + name: {{ include "createUserJob.serviceAccountName" . }} + namespace: "{{ .Release.Namespace }}" + {{- end }} + {{- if and .Values.cleanup.enabled }} + - kind: ServiceAccount + name: {{ include "cleanup.serviceAccountName" . }} + namespace: "{{ .Release.Namespace }}" + {{- end }} +{{- end }} diff --git a/helm/airflow/templates/redis/redis-networkpolicy.yaml b/helm/airflow/templates/redis/redis-networkpolicy.yaml new file mode 100644 index 0000000..457d183 --- /dev/null +++ b/helm/airflow/templates/redis/redis-networkpolicy.yaml @@ -0,0 +1,65 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +################################ +## Airflow Redis NetworkPolicy +################################# +{{- if and .Values.redis.enabled .Values.networkPolicies.enabled (or (eq .Values.executor "CeleryExecutor") (eq .Values.executor "CeleryKubernetesExecutor")) }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "airflow.fullname" . }}-redis-policy + labels: + tier: airflow + component: redis-policy + release: {{ .Release.Name }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + podSelector: + matchLabels: + tier: airflow + component: redis + release: {{ .Release.Name }} + policyTypes: + - Ingress + ingress: + - from: + - podSelector: + matchLabels: + tier: airflow + component: worker + release: {{ .Release.Name }} + - podSelector: + matchLabels: + tier: airflow + component: scheduler + release: {{ .Release.Name }} + - podSelector: + matchLabels: + tier: airflow + component: flower + release: {{ .Release.Name }} + ports: + - protocol: TCP + port: {{ .Values.ports.redisDB }} +{{- end }} diff --git a/helm/airflow/templates/redis/redis-service.yaml b/helm/airflow/templates/redis/redis-service.yaml new file mode 100644 index 0000000..17d4c8d --- /dev/null +++ b/helm/airflow/templates/redis/redis-service.yaml @@ -0,0 +1,48 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +################################ +## Airflow Redis Service +################################# +{{- if and .Values.redis.enabled (or (eq .Values.executor "CeleryExecutor") (eq .Values.executor "CeleryKubernetesExecutor")) }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "airflow.fullname" . }}-redis + labels: + tier: airflow + component: redis + release: {{ .Release.Name }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + type: ClusterIP + selector: + tier: airflow + component: redis + release: {{ .Release.Name }} + ports: + - name: redis-db + protocol: TCP + port: {{ .Values.ports.redisDB }} + targetPort: {{ .Values.ports.redisDB }} +{{- end }} diff --git a/helm/airflow/templates/redis/redis-serviceaccount.yaml b/helm/airflow/templates/redis/redis-serviceaccount.yaml new file mode 100644 index 0000000..42921f3 --- /dev/null +++ b/helm/airflow/templates/redis/redis-serviceaccount.yaml @@ -0,0 +1,41 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +###################################### +## Airflow Redis ServiceAccount +###################################### +{{- if and .Values.redis.enabled .Values.redis.serviceAccount.create (or (eq .Values.executor "CeleryExecutor") (eq .Values.executor "CeleryKubernetesExecutor")) }} +apiVersion: v1 +kind: ServiceAccount +automountServiceAccountToken: {{ .Values.redis.serviceAccount.automountServiceAccountToken }} +metadata: + name: {{ include "redis.serviceAccountName" . }} + labels: + tier: airflow + component: redis + release: {{ .Release.Name }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.redis.serviceAccount.annotations }} + annotations: {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/helm/airflow/templates/redis/redis-statefulset.yaml b/helm/airflow/templates/redis/redis-statefulset.yaml new file mode 100644 index 0000000..224f38f --- /dev/null +++ b/helm/airflow/templates/redis/redis-statefulset.yaml @@ -0,0 +1,126 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +################################ +## Airflow Redis StatefulSet +################################# +{{- if and .Values.redis.enabled (or (eq .Values.executor "CeleryExecutor") (eq .Values.executor "CeleryKubernetesExecutor")) }} +{{- $nodeSelector := or .Values.redis.nodeSelector .Values.nodeSelector }} +{{- $affinity := or .Values.redis.affinity .Values.affinity }} +{{- $tolerations := or .Values.redis.tolerations .Values.tolerations }} +{{- $topologySpreadConstraints := or .Values.redis.topologySpreadConstraints .Values.topologySpreadConstraints }} +{{- $securityContext := include "localPodSecurityContext" .Values.redis }} +{{- $containerSecurityContext := include "externalContainerSecurityContext" .Values.redis }} +{{- $containerLifecycleHooks := .Values.redis.containerLifecycleHooks }} +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ include "airflow.fullname" . }}-redis + labels: + tier: airflow + component: redis + release: {{ .Release.Name }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + serviceName: {{ include "airflow.fullname" . }}-redis + selector: + matchLabels: + tier: airflow + component: redis + release: {{ .Release.Name }} + template: + metadata: + labels: + tier: airflow + component: redis + release: {{ .Release.Name }} + {{- with .Values.labels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if or .Values.redis.safeToEvict .Values.redis.podAnnotations }} + annotations: + {{- if .Values.redis.podAnnotations }} + {{- toYaml .Values.redis.podAnnotations | nindent 8 }} + {{- end }} + {{- if .Values.redis.safeToEvict }} + cluster-autoscaler.kubernetes.io/safe-to-evict: "true" + {{- end }} + {{- end }} + spec: + nodeSelector: {{- toYaml $nodeSelector | nindent 8 }} + affinity: {{- toYaml $affinity | nindent 8 }} + tolerations: {{- toYaml $tolerations | nindent 8 }} + topologySpreadConstraints: {{- toYaml $topologySpreadConstraints | nindent 8 }} + serviceAccountName: {{ include "redis.serviceAccountName" . }} + {{- if .Values.schedulerName }} + schedulerName: {{ .Values.schedulerName }} + {{- end }} + {{- if or .Values.registry.secretName .Values.registry.connection }} + imagePullSecrets: + - name: {{ template "registry_secret" . }} + {{- end }} + securityContext: {{ $securityContext | nindent 8 }} + containers: + - name: redis + image: {{ template "redis_image" . }} + imagePullPolicy: {{ .Values.images.redis.pullPolicy }} + securityContext: {{ $containerSecurityContext | nindent 12 }} + {{- if $containerLifecycleHooks }} + lifecycle: {{- tpl (toYaml $containerLifecycleHooks) . | nindent 12 }} + {{- end }} + command: ["/bin/sh"] + resources: {{- toYaml .Values.redis.resources | nindent 12 }} + args: ["-c", "redis-server --requirepass ${REDIS_PASSWORD}"] + ports: + - name: redis-db + containerPort: {{ .Values.ports.redisDB }} + volumeMounts: + - name: redis-db + mountPath: /data + env: + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + name: {{ template "redis_password_secret" . }} + key: password + {{- if not .Values.redis.persistence.enabled }} + volumes: + - name: redis-db + emptyDir: {} + {{- else }} + volumeClaimTemplates: + - metadata: + name: redis-db + {{- if .Values.redis.persistence.annotations }} + annotations: {{- toYaml .Values.redis.persistence.annotations | nindent 10 }} + {{- end }} + spec: + {{- if .Values.redis.persistence.storageClassName }} + storageClassName: {{ .Values.redis.persistence.storageClassName }} + {{- end }} + accessModes: ["ReadWriteOnce"] + resources: + requests: + storage: {{ .Values.redis.persistence.size }} + {{- end }} +{{- end }} diff --git a/helm/airflow/templates/resourcequota.yaml b/helm/airflow/templates/resourcequota.yaml new file mode 100644 index 0000000..6a7071f --- /dev/null +++ b/helm/airflow/templates/resourcequota.yaml @@ -0,0 +1,39 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +################################ +## Airflow Namespace ResourceQuota +################################# +{{- if .Values.quotas }} +apiVersion: v1 +kind: ResourceQuota +metadata: + name: {{ .Release.Name }}-resource-quota + labels: + tier: resources + component: resourcequota + release: {{ .Release.Name }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + hard: {{- toYaml .Values.quotas | nindent 4 }} +{{- end }} diff --git a/helm/airflow/templates/scheduler/scheduler-deployment.yaml b/helm/airflow/templates/scheduler/scheduler-deployment.yaml new file mode 100644 index 0000000..04dc58b --- /dev/null +++ b/helm/airflow/templates/scheduler/scheduler-deployment.yaml @@ -0,0 +1,339 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +################################ +## Airflow Scheduler Deployment/StatefulSet +################################# + +# Are we using a local executor? +{{- $local := contains "Local" .Values.executor }} +# Is persistence enabled on the _workers_? +# This is important because in $local mode, the scheduler assumes the role of the worker +{{- $persistence := .Values.workers.persistence.enabled }} +# If we're using a StatefulSet +{{- $stateful := and $local $persistence }} +# We can skip DAGs mounts on scheduler if dagProcessor is enabled, except with $local mode +{{- $localOrDagProcessorDisabled := or (not .Values.dagProcessor.enabled) $local }} +# If we're using elasticsearch logging +{{- $elasticsearch := .Values.elasticsearch.enabled }} +{{- $nodeSelector := or .Values.scheduler.nodeSelector .Values.nodeSelector }} +{{- $affinity := or .Values.scheduler.affinity .Values.affinity }} +{{- $tolerations := or .Values.scheduler.tolerations .Values.tolerations }} +{{- $topologySpreadConstraints := or .Values.scheduler.topologySpreadConstraints .Values.topologySpreadConstraints }} +{{- $revisionHistoryLimit := or .Values.scheduler.revisionHistoryLimit .Values.revisionHistoryLimit }} +{{- $securityContext := include "airflowPodSecurityContext" (list . .Values.scheduler) }} +{{- $containerSecurityContext := include "containerSecurityContext" (list . .Values.scheduler) }} +{{- $containerSecurityContextWaitForMigrations := include "containerSecurityContext" (list . .Values.scheduler.waitForMigrations) }} +{{- $containerSecurityContextLogGroomerSidecar := include "containerSecurityContext" (list . .Values.scheduler.logGroomerSidecar) }} +{{- $containerLifecycleHooks := or .Values.scheduler.containerLifecycleHooks .Values.containerLifecycleHooks }} +{{- $containerLifecycleHooksWaitForMigrations := or .Values.scheduler.waitForMigrations.containerLifecycleHooks .Values.containerLifecycleHooks }} +{{- $containerLifecycleHooksLogGroomerSidecar := or .Values.scheduler.logGroomerSidecar.containerLifecycleHooks .Values.containerLifecycleHooks }} +apiVersion: apps/v1 +kind: {{ if $stateful }}StatefulSet{{ else }}Deployment{{ end }} +metadata: + name: {{ include "airflow.fullname" . }}-scheduler + labels: + tier: airflow + component: scheduler + release: {{ .Release.Name }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + executor: {{ .Values.executor }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if .Values.scheduler.annotations }} + annotations: {{- toYaml .Values.scheduler.annotations | nindent 4 }} + {{- end }} +spec: + {{- if $stateful }} + serviceName: {{ include "airflow.fullname" . }}-scheduler + {{- end }} + replicas: {{ .Values.scheduler.replicas }} + {{- if $revisionHistoryLimit }} + revisionHistoryLimit: {{ $revisionHistoryLimit }} + {{- end }} + {{- if and $stateful .Values.scheduler.updateStrategy }} + updateStrategy: {{- toYaml .Values.scheduler.updateStrategy | nindent 4 }} + {{- end }} + {{- if and (not $stateful) .Values.scheduler.strategy }} + strategy: {{- toYaml .Values.scheduler.strategy | nindent 4 }} + {{- end }} + selector: + matchLabels: + tier: airflow + component: scheduler + release: {{ .Release.Name }} + template: + metadata: + labels: + tier: airflow + component: scheduler + release: {{ .Release.Name }} + {{- if or (.Values.labels) (.Values.scheduler.labels) }} + {{- mustMerge .Values.scheduler.labels .Values.labels | toYaml | nindent 8 }} + {{- end }} + annotations: + checksum/metadata-secret: {{ include (print $.Template.BasePath "/secrets/metadata-connection-secret.yaml") . | sha256sum }} + checksum/result-backend-secret: {{ include (print $.Template.BasePath "/secrets/result-backend-connection-secret.yaml") . | sha256sum }} + checksum/pgbouncer-config-secret: {{ include (print $.Template.BasePath "/secrets/pgbouncer-config-secret.yaml") . | sha256sum }} + checksum/airflow-config: {{ include (print $.Template.BasePath "/configmaps/configmap.yaml") . | sha256sum }} + checksum/extra-configmaps: {{ include (print $.Template.BasePath "/configmaps/extra-configmaps.yaml") . | sha256sum }} + checksum/extra-secrets: {{ include (print $.Template.BasePath "/secrets/extra-secrets.yaml") . | sha256sum }} + {{- if .Values.scheduler.safeToEvict }} + cluster-autoscaler.kubernetes.io/safe-to-evict: "true" + {{- end }} + {{- if .Values.airflowPodAnnotations }} + {{- toYaml .Values.airflowPodAnnotations | nindent 8 }} + {{- end }} + {{- if .Values.scheduler.podAnnotations }} + {{- toYaml .Values.scheduler.podAnnotations | nindent 8 }} + {{- end }} + spec: + {{- if .Values.scheduler.priorityClassName }} + priorityClassName: {{ .Values.scheduler.priorityClassName }} + {{- end }} + {{- if .Values.schedulerName }} + schedulerName: {{ .Values.schedulerName }} + {{- end }} + nodeSelector: {{- toYaml $nodeSelector | nindent 8 }} + affinity: + {{- if $affinity }} + {{- toYaml $affinity | nindent 8 }} + {{- else }} + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchLabels: + component: scheduler + topologyKey: kubernetes.io/hostname + weight: 100 + {{- end }} + tolerations: {{- toYaml $tolerations | nindent 8 }} + topologySpreadConstraints: {{- toYaml $topologySpreadConstraints | nindent 8 }} + restartPolicy: Always + terminationGracePeriodSeconds: 10 + serviceAccountName: {{ include "scheduler.serviceAccountName" . }} + securityContext: {{ $securityContext | nindent 8 }} + {{- if or .Values.registry.secretName .Values.registry.connection }} + imagePullSecrets: + - name: {{ template "registry_secret" . }} + {{- end }} + {{- if .Values.scheduler.hostAliases }} + hostAliases: {{- toYaml .Values.scheduler.hostAliases | nindent 8 }} + {{- end }} + initContainers: + {{- if .Values.scheduler.waitForMigrations.enabled }} + - name: wait-for-airflow-migrations + resources: {{- toYaml .Values.scheduler.resources | nindent 12 }} + image: {{ template "airflow_image_for_migrations" . }} + imagePullPolicy: {{ .Values.images.airflow.pullPolicy }} + securityContext: {{ $containerSecurityContextWaitForMigrations | nindent 12 }} + {{- if $containerLifecycleHooksWaitForMigrations }} + lifecycle: {{- tpl (toYaml $containerLifecycleHooksWaitForMigrations) . | nindent 12 }} + {{- end }} + volumeMounts: + {{- include "airflow_config_mount" . | nindent 12 }} + {{- if .Values.volumeMounts }} + {{- toYaml .Values.volumeMounts | nindent 12 }} + {{- end }} + {{- if .Values.scheduler.extraVolumeMounts }} + {{- tpl (toYaml .Values.scheduler.extraVolumeMounts) . | nindent 12 }} + {{- end }} + {{- if or .Values.webserver.webserverConfig .Values.webserver.webserverConfigConfigMapName }} + {{- include "airflow_webserver_config_mount" . | nindent 12 }} + {{- end }} + args: {{- include "wait-for-migrations-command" . | indent 10 }} + envFrom: {{- include "custom_airflow_environment_from" . | default "\n []" | indent 10 }} + env: + {{- include "custom_airflow_environment" . | indent 10 }} + {{- include "standard_airflow_environment" . | indent 10 }} + {{- if .Values.scheduler.waitForMigrations.env }} + {{- tpl (toYaml .Values.scheduler.waitForMigrations.env) $ | nindent 12 }} + {{- end }} + {{- end }} + {{- if and $localOrDagProcessorDisabled .Values.dags.gitSync.enabled }} + {{- include "git_sync_container" (dict "Values" .Values "is_init" "true" "Template" .Template) | nindent 8 }} + {{- end }} + {{- if .Values.scheduler.extraInitContainers }} + {{- toYaml .Values.scheduler.extraInitContainers | nindent 8 }} + {{- end }} + containers: + # Always run the main scheduler container. + - name: scheduler + image: {{ template "airflow_image" . }} + imagePullPolicy: {{ .Values.images.airflow.pullPolicy }} + securityContext: {{ $containerSecurityContext | nindent 12 }} + {{- if $containerLifecycleHooks }} + lifecycle: {{- tpl (toYaml $containerLifecycleHooks) . | nindent 12 }} + {{- end }} + {{- if .Values.scheduler.command }} + command: {{ tpl (toYaml .Values.scheduler.command) . | nindent 12 }} + {{- end }} + {{- if .Values.scheduler.args }} + args: {{ tpl (toYaml .Values.scheduler.args) . | nindent 12 }} + {{- end }} + envFrom: {{- include "custom_airflow_environment_from" . | default "\n []" | indent 10 }} + env: + {{- include "custom_airflow_environment" . | indent 10 }} + {{- include "standard_airflow_environment" . | indent 10 }} + {{- include "container_extra_envs" (list . .Values.scheduler.env) | indent 10 }} + livenessProbe: + initialDelaySeconds: {{ .Values.scheduler.livenessProbe.initialDelaySeconds }} + timeoutSeconds: {{ .Values.scheduler.livenessProbe.timeoutSeconds }} + failureThreshold: {{ .Values.scheduler.livenessProbe.failureThreshold }} + periodSeconds: {{ .Values.scheduler.livenessProbe.periodSeconds }} + exec: + command: + {{- if .Values.scheduler.livenessProbe.command }} + {{- toYaml .Values.scheduler.livenessProbe.command | nindent 16 }} + {{- else }} + {{- include "scheduler_liveness_check_command" . | indent 14 }} + {{- end }} + startupProbe: + timeoutSeconds: {{ .Values.scheduler.startupProbe.timeoutSeconds }} + failureThreshold: {{ .Values.scheduler.startupProbe.failureThreshold }} + periodSeconds: {{ .Values.scheduler.startupProbe.periodSeconds }} + exec: + command: + {{- if .Values.scheduler.startupProbe.command }} + {{- toYaml .Values.scheduler.startupProbe.command | nindent 16 }} + {{- else }} + {{- include "scheduler_startup_check_command" . | indent 14 }} + {{- end }} + {{- if and $local (not $elasticsearch) }} + # Serve logs if we're in local mode and we don't have elasticsearch enabled. + ports: + - name: worker-logs + containerPort: {{ .Values.ports.workerLogs }} + {{- end }} + resources: {{- toYaml .Values.scheduler.resources | nindent 12 }} + volumeMounts: + {{- if semverCompare ">=1.10.12" .Values.airflowVersion }} + - name: config + mountPath: {{ include "airflow_pod_template_file" . }}/pod_template_file.yaml + subPath: pod_template_file.yaml + readOnly: true + {{- end }} + - name: logs + mountPath: {{ template "airflow_logs" . }} + {{- include "airflow_config_mount" . | nindent 12 }} + {{- if or .Values.webserver.webserverConfig .Values.webserver.webserverConfigConfigMapName }} + {{- include "airflow_webserver_config_mount" . | nindent 12 }} + {{- end }} + {{- if and $localOrDagProcessorDisabled (or .Values.dags.persistence.enabled .Values.dags.gitSync.enabled) }} + {{- include "airflow_dags_mount" . | nindent 12 }} + {{- end }} + {{- if .Values.volumeMounts }} + {{- toYaml .Values.volumeMounts | nindent 12 }} + {{- end }} + {{- if .Values.scheduler.extraVolumeMounts }} + {{- tpl (toYaml .Values.scheduler.extraVolumeMounts) . | nindent 12 }} + {{- end }} + {{- if and $localOrDagProcessorDisabled .Values.dags.gitSync.enabled }} + {{- include "git_sync_container" . | indent 8 }} + {{- end }} + {{- if .Values.scheduler.logGroomerSidecar.enabled }} + - name: scheduler-log-groomer + resources: {{- toYaml .Values.scheduler.logGroomerSidecar.resources | nindent 12 }} + image: {{ template "airflow_image" . }} + imagePullPolicy: {{ .Values.images.airflow.pullPolicy }} + securityContext: {{ $containerSecurityContextLogGroomerSidecar | nindent 12 }} + {{- if $containerLifecycleHooksLogGroomerSidecar }} + lifecycle: {{- tpl (toYaml $containerLifecycleHooksLogGroomerSidecar) . | nindent 12 }} + {{- end }} + {{- if .Values.scheduler.logGroomerSidecar.command }} + command: {{ tpl (toYaml .Values.scheduler.logGroomerSidecar.command) . | nindent 12 }} + {{- end }} + {{- if .Values.scheduler.logGroomerSidecar.args }} + args: {{- tpl (toYaml .Values.scheduler.logGroomerSidecar.args) . | nindent 12 }} + {{- end }} + {{- if .Values.scheduler.logGroomerSidecar.retentionDays }} + env: + - name: AIRFLOW__LOG_RETENTION_DAYS + value: "{{ .Values.scheduler.logGroomerSidecar.retentionDays }}" + {{- end }} + volumeMounts: + - name: logs + mountPath: {{ template "airflow_logs" . }} + {{- if .Values.volumeMounts }} + {{- toYaml .Values.volumeMounts | nindent 12 }} + {{- end }} + {{- if .Values.scheduler.extraVolumeMounts }} + {{- tpl (toYaml .Values.scheduler.extraVolumeMounts) . | nindent 12 }} + {{- end }} + {{- if or .Values.webserver.webserverConfig .Values.webserver.webserverConfigConfigMapName }} + {{- include "airflow_webserver_config_mount" . | nindent 12 }} + {{- end }} + {{- end }} + {{- if .Values.scheduler.extraContainers }} + {{- toYaml .Values.scheduler.extraContainers | nindent 8 }} + {{- end }} + volumes: + - name: config + configMap: + name: {{ template "airflow_config" . }} + {{- if or .Values.webserver.webserverConfig .Values.webserver.webserverConfigConfigMapName }} + - name: webserver-config + configMap: + name: {{ template "airflow_webserver_config_configmap_name" . }} + {{- end }} + {{- if $localOrDagProcessorDisabled }} + {{- if .Values.dags.persistence.enabled }} + - name: dags + persistentVolumeClaim: + claimName: {{ template "airflow_dags_volume_claim" . }} + {{- else if .Values.dags.gitSync.enabled }} + - name: dags + emptyDir: {} + {{- if .Values.dags.gitSync.sshKeySecret }} + {{- include "git_sync_ssh_key_volume" . | indent 8 }} + {{- end }} + {{- end }} + {{- end }} + {{- if .Values.volumes }} + {{- toYaml .Values.volumes | nindent 8 }} + {{- end }} + {{- if .Values.scheduler.extraVolumes }} + {{- tpl (toYaml .Values.scheduler.extraVolumes) . | nindent 8 }} + {{- end }} + {{- if .Values.logs.persistence.enabled }} + - name: logs + persistentVolumeClaim: + claimName: {{ template "airflow_logs_volume_claim" . }} + {{- else if not $stateful }} + - name: logs + emptyDir: {} + {{- else }} + volumeClaimTemplates: + - metadata: + name: logs + {{- if .Values.workers.persistence.annotations }} + annotations: {{- toYaml .Values.workers.persistence.annotations | nindent 10 }} + {{- end }} + spec: + {{- if .Values.workers.persistence.storageClassName }} + storageClassName: {{ .Values.workers.persistence.storageClassName }} + {{- end }} + accessModes: ["ReadWriteOnce"] + resources: + requests: + storage: {{ .Values.workers.persistence.size }} + {{- end }} diff --git a/helm/airflow/templates/scheduler/scheduler-networkpolicy.yaml b/helm/airflow/templates/scheduler/scheduler-networkpolicy.yaml new file mode 100644 index 0000000..bbd9853 --- /dev/null +++ b/helm/airflow/templates/scheduler/scheduler-networkpolicy.yaml @@ -0,0 +1,57 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +################################ +## Airflow Scheduler NetworkPolicy +################################# +{{- if .Values.networkPolicies.enabled }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "airflow.fullname" . }}-scheduler-policy + labels: + tier: airflow + component: airflow-scheduler-policy + release: {{ .Release.Name }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + {{- if or (.Values.labels) (.Values.scheduler.labels) }} + {{- mustMerge .Values.scheduler.labels .Values.labels | toYaml | nindent 4 }} + {{- end }} +spec: + podSelector: + matchLabels: + tier: airflow + component: scheduler + release: {{ .Release.Name }} + policyTypes: + - Ingress + {{- if eq .Values.executor "LocalExecutor" }} + ingress: + - from: + - podSelector: + matchLabels: + tier: airflow + component: webserver + release: {{ .Release.Name }} + ports: + - protocol: TCP + port: {{ .Values.ports.workerLogs }} + {{- end }} +{{- end }} diff --git a/helm/airflow/templates/scheduler/scheduler-poddisruptionbudget.yaml b/helm/airflow/templates/scheduler/scheduler-poddisruptionbudget.yaml new file mode 100644 index 0000000..3c6d798 --- /dev/null +++ b/helm/airflow/templates/scheduler/scheduler-poddisruptionbudget.yaml @@ -0,0 +1,44 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +################################ +## Airflow Scheduler PodDisruptionBudget +################################# +{{- if .Values.scheduler.podDisruptionBudget.enabled }} +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: {{ include "airflow.fullname" . }}-scheduler-pdb + labels: + tier: airflow + component: scheduler + release: {{ .Release.Name }} + chart: {{ .Chart.Name }} + heritage: {{ .Release.Service }} + {{- if or (.Values.labels) (.Values.scheduler.labels) }} + {{- mustMerge .Values.scheduler.labels .Values.labels | toYaml | nindent 4 }} + {{- end }} +spec: + selector: + matchLabels: + tier: airflow + component: scheduler + release: {{ .Release.Name }} + {{- toYaml .Values.scheduler.podDisruptionBudget.config | nindent 2 }} +{{- end }} diff --git a/helm/airflow/templates/scheduler/scheduler-service.yaml b/helm/airflow/templates/scheduler/scheduler-service.yaml new file mode 100644 index 0000000..b2bf2a8 --- /dev/null +++ b/helm/airflow/templates/scheduler/scheduler-service.yaml @@ -0,0 +1,48 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +################################ +## Airflow Scheduler Service +################################# +{{- if or (eq .Values.executor "LocalExecutor") (eq .Values.executor "LocalKubernetesExecutor") }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "airflow.fullname" . }}-scheduler + labels: + tier: airflow + component: scheduler + release: {{ .Release.Name }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + {{- if or (.Values.labels) (.Values.scheduler.labels) }} + {{- mustMerge .Values.scheduler.labels .Values.labels | toYaml | nindent 4 }} + {{- end }} +spec: + clusterIP: None + selector: + tier: airflow + component: scheduler + release: {{ .Release.Name }} + ports: + - name: task-logs + protocol: TCP + port: {{ .Values.ports.workerLogs }} + targetPort: {{ .Values.ports.workerLogs }} +{{- end }} diff --git a/helm/airflow/templates/scheduler/scheduler-serviceaccount.yaml b/helm/airflow/templates/scheduler/scheduler-serviceaccount.yaml new file mode 100644 index 0000000..1a359ab --- /dev/null +++ b/helm/airflow/templates/scheduler/scheduler-serviceaccount.yaml @@ -0,0 +1,44 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +################################ +## Airflow Scheduler ServiceAccount +################################# +{{- if .Values.scheduler.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +automountServiceAccountToken: {{ .Values.scheduler.serviceAccount.automountServiceAccountToken }} +metadata: + name: {{ include "scheduler.serviceAccountName" . }} + labels: + tier: airflow + component: scheduler + release: {{ .Release.Name }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + {{- if or (.Values.labels) (.Values.scheduler.labels) }} + {{- mustMerge .Values.scheduler.labels .Values.labels | toYaml | nindent 4 }} + {{- end }} + {{- with .Values.scheduler.serviceAccount.annotations }} + annotations: + {{- range $key, $value := . }} + {{- printf "%s: %s" $key (tpl $value $ | quote) | nindent 4 }} + {{- end }} + {{- end }} +{{- end }} diff --git a/helm/airflow/templates/secrets/elasticsearch-secret.yaml b/helm/airflow/templates/secrets/elasticsearch-secret.yaml new file mode 100644 index 0000000..aea70f7 --- /dev/null +++ b/helm/airflow/templates/secrets/elasticsearch-secret.yaml @@ -0,0 +1,44 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +################################ +## Elasticsearch Secret +################################# +{{- if (and .Values.elasticsearch.enabled (not .Values.elasticsearch.secretName)) }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "airflow.fullname" . }}-elasticsearch + labels: + release: {{ .Release.Name }} + chart: {{ .Chart.Name }} + heritage: {{ .Release.Service }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +type: Opaque +data: + {{- with .Values.elasticsearch.connection }} + {{- if and .user .pass }} + connection: {{ urlJoin (dict "scheme" (default "http" .scheme) "userinfo" (printf "%s:%s" (.user | urlquery) (.pass | urlquery)) "host" (printf "%s:%s" .host ((default 9200 .port) | toString) ) ) | b64enc | quote }} + {{- else }} + connection: {{ urlJoin (dict "scheme" (default "http" .scheme) "host" (printf "%s:%s" .host ((default 9200 .port) | toString))) | b64enc | quote }} + {{- end }} + {{- end }} +{{- end }} diff --git a/helm/airflow/templates/secrets/extra-secrets.yaml b/helm/airflow/templates/secrets/extra-secrets.yaml new file mode 100644 index 0000000..7d8bda5 --- /dev/null +++ b/helm/airflow/templates/secrets/extra-secrets.yaml @@ -0,0 +1,62 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +################################################# +## Extra Secrets provisioned via the chart values +################################################# +{{- $Global := . }} +{{- range $secretName, $secretContent := .Values.extraSecrets }} +--- +apiVersion: v1 +kind: Secret +metadata: + name: {{ tpl $secretName $Global | quote }} + labels: + release: {{ $Global.Release.Name }} + chart: "{{ $Global.Chart.Name }}-{{ $Global.Chart.Version }}" + heritage: {{ $Global.Release.Service }} + {{- with $Global.Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if $secretContent.labels }} + {{- toYaml $secretContent.labels | nindent 4 }} + {{- end }} + annotations: + "helm.sh/hook": "pre-install,pre-upgrade" + "helm.sh/hook-delete-policy": "before-hook-creation" + "helm.sh/hook-weight": "0" + {{- if $secretContent.annotations }} + {{- toYaml $secretContent.annotations | nindent 4 }} + {{- end }} +{{- if $secretContent.type }} +type: {{ $secretContent.type }} +{{- end }} +{{- if $secretContent.data }} +data: + {{- with $secretContent.data }} + {{- tpl . $Global | nindent 2 }} + {{- end }} +{{- end }} +{{- if $secretContent.stringData }} +stringData: + {{- with $secretContent.stringData }} + {{- tpl . $Global | nindent 2 }} + {{- end }} +{{- end }} +{{- end }} diff --git a/helm/airflow/templates/secrets/fernetkey-secret.yaml b/helm/airflow/templates/secrets/fernetkey-secret.yaml new file mode 100644 index 0000000..a917aab --- /dev/null +++ b/helm/airflow/templates/secrets/fernetkey-secret.yaml @@ -0,0 +1,44 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +################################ +## Airflow Fernet Key Secret +################################# +{{- if not .Values.fernetKeySecretName }} +{{- $generated_fernet_key := (randAlphaNum 32 | b64enc) }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ .Release.Name }}-fernet-key + labels: + tier: airflow + release: {{ .Release.Name }} + chart: {{ .Chart.Name }} + heritage: {{ .Release.Service }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + "helm.sh/hook": "pre-install" + "helm.sh/hook-delete-policy": "before-hook-creation" + "helm.sh/hook-weight": "0" +type: Opaque +data: + fernet-key: {{ (default $generated_fernet_key .Values.fernetKey) | b64enc | quote }} +{{- end }} diff --git a/helm/airflow/templates/secrets/flower-secret.yaml b/helm/airflow/templates/secrets/flower-secret.yaml new file mode 100644 index 0000000..c28fa17 --- /dev/null +++ b/helm/airflow/templates/secrets/flower-secret.yaml @@ -0,0 +1,38 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +################################ +## Flower Secret +################################# +{{- if (and (not .Values.flower.secretName) .Values.flower.username .Values.flower.password) }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "airflow.fullname" . }}-flower + labels: + release: {{ .Release.Name }} + chart: {{ .Chart.Name }} + heritage: {{ .Release.Service }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +type: Opaque +data: + basicAuth: {{ (printf "%s:%s" .Values.flower.username .Values.flower.password) | b64enc | quote }} +{{- end }} diff --git a/helm/airflow/templates/secrets/kerberos-keytab-secret.yaml b/helm/airflow/templates/secrets/kerberos-keytab-secret.yaml new file mode 100644 index 0000000..7095e50 --- /dev/null +++ b/helm/airflow/templates/secrets/kerberos-keytab-secret.yaml @@ -0,0 +1,40 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +################################ +## Kerberos Secret +################################# +{{- if .Values.kerberos.keytabBase64Content }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "kerberos_keytab_secret" . | quote }} + labels: + tier: airflow + component: webserver + release: {{ .Release.Name }} + chart: {{ .Chart.Name }} + heritage: {{ .Release.Service }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +type: Opaque +data: + kerberos.keytab: {{ .Values.kerberos.keytabBase64Content }} +{{- end }} diff --git a/helm/airflow/templates/secrets/metadata-connection-secret.yaml b/helm/airflow/templates/secrets/metadata-connection-secret.yaml new file mode 100644 index 0000000..7f9840f --- /dev/null +++ b/helm/airflow/templates/secrets/metadata-connection-secret.yaml @@ -0,0 +1,53 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +################################ +## Airflow Metadata Secret +################################# +{{- if not .Values.data.metadataSecretName }} +{{- $defaultMetadataHost := .Values.postgresql.nameOverride | default (printf "%s-%s.%s" .Release.Name "postgresql" .Release.Namespace) }} +{{- $metadataHost := .Values.data.metadataConnection.host | default $defaultMetadataHost }} +{{- $pgbouncerHost := (printf "%s-%s.%s" .Release.Name "pgbouncer" .Release.Namespace) }} +{{- $host := ternary $pgbouncerHost $metadataHost .Values.pgbouncer.enabled }} +{{- $port := ((ternary .Values.ports.pgbouncer .Values.data.metadataConnection.port .Values.pgbouncer.enabled) | toString) }} +{{- $database := (ternary (printf "%s-%s" .Release.Name "metadata") .Values.data.metadataConnection.db .Values.pgbouncer.enabled) }} +{{- $query := ternary (printf "sslmode=%s" .Values.data.metadataConnection.sslmode) "" (eq .Values.data.metadataConnection.protocol "postgresql") }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "airflow.fullname" . }}-metadata + labels: + tier: airflow + release: {{ .Release.Name }} + chart: {{ .Chart.Name }} + heritage: {{ .Release.Service }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +type: Opaque +data: + {{- with .Values.data.metadataConnection }} + connection: {{ urlJoin (dict "scheme" .protocol "userinfo" (printf "%s:%s" (.user | urlquery) (.pass | urlquery) ) "host" (printf "%s:%s" $host $port) "path" (printf "/%s" $database) "query" $query) | b64enc | quote }} + {{- end }} + {{- if and .Values.workers.keda.enabled .Values.pgbouncer.enabled (not .Values.workers.keda.usePgbouncer) }} + {{- with .Values.data.metadataConnection }} + kedaConnection: {{ urlJoin (dict "scheme" .protocol "userinfo" (printf "%s:%s" (.user | urlquery) (.pass | urlquery) ) "host" (printf "%s:%s" $metadataHost $port) "path" (printf "/%s" $database) "query" $query) | b64enc | quote }} + {{- end }} + {{- end }} +{{- end }} diff --git a/helm/airflow/templates/secrets/pgbouncer-certificates-secret.yaml b/helm/airflow/templates/secrets/pgbouncer-certificates-secret.yaml new file mode 100644 index 0000000..4514839 --- /dev/null +++ b/helm/airflow/templates/secrets/pgbouncer-certificates-secret.yaml @@ -0,0 +1,46 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +################################ +## Pgbouncer Certificate Secret +################################# +{{- if or .Values.pgbouncer.ssl.ca .Values.pgbouncer.ssl.cert .Values.pgbouncer.ssl.key }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "pgbouncer_certificates_secret" . }} + labels: + release: {{ .Release.Name }} + chart: {{ .Chart.Name }} + heritage: {{ .Release.Service }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +type: Opaque +data: + {{- if .Values.pgbouncer.ssl.ca }} + root.crt: {{ .Values.pgbouncer.ssl.ca | b64enc }} + {{- end }} + {{- if .Values.pgbouncer.ssl.cert }} + server.crt: {{ .Values.pgbouncer.ssl.cert | b64enc }} + {{- end }} + {{- if .Values.pgbouncer.ssl.key }} + server.key: {{ .Values.pgbouncer.ssl.key | b64enc }} + {{- end }} +{{- end }} diff --git a/helm/airflow/templates/secrets/pgbouncer-config-secret.yaml b/helm/airflow/templates/secrets/pgbouncer-config-secret.yaml new file mode 100644 index 0000000..7ffc97f --- /dev/null +++ b/helm/airflow/templates/secrets/pgbouncer-config-secret.yaml @@ -0,0 +1,41 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +################################ +## Pgbouncer Config Secret +################################# +{{- if (and .Values.pgbouncer.enabled (not .Values.pgbouncer.configSecretName)) }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "pgbouncer_config_secret" . }} + labels: + tier: airflow + component: pgbouncer + release: {{ .Release.Name }} + chart: {{ .Chart.Name }} + heritage: {{ .Release.Service }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +type: Opaque +data: + pgbouncer.ini: {{ include "pgbouncer_config" . | b64enc }} + users.txt: {{ include "pgbouncer_users" . | b64enc }} +{{- end }} diff --git a/helm/airflow/templates/secrets/pgbouncer-stats-secret.yaml b/helm/airflow/templates/secrets/pgbouncer-stats-secret.yaml new file mode 100644 index 0000000..298bc7b --- /dev/null +++ b/helm/airflow/templates/secrets/pgbouncer-stats-secret.yaml @@ -0,0 +1,40 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +################################ +## Pgbouncer Stats Secret +################################# +{{- if (and .Values.pgbouncer.enabled (not .Values.pgbouncer.metricsExporterSidecar.statsSecretName)) }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "pgbouncer_stats_secret" . }} + labels: + tier: airflow + component: pgbouncer + release: {{ .Release.Name }} + chart: {{ .Chart.Name }} + heritage: {{ .Release.Service }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +type: Opaque +data: + connection: {{ urlJoin (dict "scheme" "postgresql" "userinfo" (printf "%s:%s" (.Values.data.metadataConnection.user | urlquery) (.Values.data.metadataConnection.pass | urlquery) ) "host" (printf "127.0.0.1:%s" (.Values.ports.pgbouncer | toString)) "path" "/pgbouncer" "query" (printf "sslmode=%s" (.Values.pgbouncer.metricsExporterSidecar.sslmode | toString ))) | b64enc | quote }} +{{- end }} diff --git a/helm/airflow/templates/secrets/redis-secrets.yaml b/helm/airflow/templates/secrets/redis-secrets.yaml new file mode 100644 index 0000000..ec1ed48 --- /dev/null +++ b/helm/airflow/templates/secrets/redis-secrets.yaml @@ -0,0 +1,83 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +# We will create these secrets (if necessary) _even if_ we aren't +# currently using CeleryExecutor or CeleryKubernetesExecutor. As we are +# relying on the "pre-install" hack to prevent changing randomly generated passwords, +# updating the executor later doesn't give us the opportunity to deploy them +# when we need them. We will always deploy them defensively to make the executor +# update path actually work. + +################################ +## Airflow Redis Password Secret +################################# +{{- $random_redis_password := randAlphaNum 10 }} +{{- if and .Values.redis.enabled (not .Values.redis.passwordSecretName) }} +# If passwordSecretName is not set, we will either use the set password, or use the generated one +apiVersion: v1 +kind: Secret +metadata: + name: {{ .Release.Name }}-redis-password + labels: + tier: airflow + component: redis + release: {{ .Release.Name }} + chart: {{ .Chart.Name }} + heritage: {{ .Release.Service }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + "helm.sh/hook": "pre-install" + "helm.sh/hook-delete-policy": "before-hook-creation" + "helm.sh/hook-weight": "0" +type: Opaque +data: + password: {{ (default $random_redis_password .Values.redis.password) | b64enc | quote }} +--- +{{- end }} +{{- if not .Values.data.brokerUrlSecretName }} +################################## +## Airflow Redis Connection Secret +################################## +apiVersion: v1 +kind: Secret +metadata: + name: {{ .Release.Name }}-broker-url + labels: + tier: airflow + component: redis + release: {{ .Release.Name }} + chart: {{ .Chart.Name }} + heritage: {{ .Release.Service }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + "helm.sh/hook": "pre-install" + "helm.sh/hook-delete-policy": "before-hook-creation" + "helm.sh/hook-weight": "0" +type: Opaque +data: + {{- if .Values.redis.enabled }} + connection: {{ urlJoin (dict "scheme" "redis" "userinfo" (printf ":%s" ((default $random_redis_password .Values.redis.password) | urlquery)) "host" (printf "%s-redis:6379" .Release.Name ) "path" "/0") | b64enc | quote }} + {{- else }} + connection: {{ (printf "%s" .Values.data.brokerUrl) | b64enc | quote }} + {{- end }} +{{- end }} diff --git a/helm/airflow/templates/secrets/registry-secret.yaml b/helm/airflow/templates/secrets/registry-secret.yaml new file mode 100644 index 0000000..19add84 --- /dev/null +++ b/helm/airflow/templates/secrets/registry-secret.yaml @@ -0,0 +1,38 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +################################ +## Registry Secret +################################# +{{- if (and .Values.registry.connection (not .Values.registry.secretName)) }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "airflow.fullname" . }}-registry + labels: + release: {{ .Release.Name }} + chart: {{ .Chart.Name }} + heritage: {{ .Release.Service }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +type: kubernetes.io/dockerconfigjson +data: + .dockerconfigjson: {{ include "registry_docker_config" . | b64enc }} +{{- end }} diff --git a/helm/airflow/templates/secrets/result-backend-connection-secret.yaml b/helm/airflow/templates/secrets/result-backend-connection-secret.yaml new file mode 100644 index 0000000..e89046d --- /dev/null +++ b/helm/airflow/templates/secrets/result-backend-connection-secret.yaml @@ -0,0 +1,50 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +################################ +## Airflow Result Backend Secret +################################# +{{- if not .Values.data.resultBackendSecretName }} +{{- if or (eq .Values.executor "CeleryExecutor") (eq .Values.executor "CeleryKubernetesExecutor") }} +{{- if or (semverCompare "<2.4.0" .Values.airflowVersion) (and (semverCompare ">=2.4.0" .Values.airflowVersion) .Values.data.resultBackendConnection) }} +{{- $connection := .Values.data.resultBackendConnection | default .Values.data.metadataConnection }} +{{- $resultBackendHost := $connection.host | default (printf "%s-%s" .Release.Name "postgresql") }} +{{- $pgbouncerHost := printf "%s-%s" .Release.Name "pgbouncer" }} +{{- $host := ternary $pgbouncerHost $resultBackendHost .Values.pgbouncer.enabled }} +{{- $port := (ternary .Values.ports.pgbouncer $connection.port .Values.pgbouncer.enabled) | toString }} +{{- $database := ternary (printf "%s-%s" .Release.Name "result-backend") $connection.db .Values.pgbouncer.enabled }} +{{- $query := ternary (printf "sslmode=%s" $connection.sslmode) "" (eq $connection.protocol "postgresql") }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "airflow.fullname" . }}-result-backend + labels: + tier: airflow + release: {{ .Release.Name }} + chart: {{ .Chart.Name }} + heritage: {{ .Release.Service }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +type: Opaque +data: + connection: {{ urlJoin (dict "scheme" (printf "db+%s" $connection.protocol) "userinfo" (printf "%s:%s" ($connection.user|urlquery) ($connection.pass | urlquery)) "host" (printf "%s:%s" $host $port) "path" (printf "/%s" $database) "query" $query) | b64enc | quote }} +{{- end }} +{{- end }} +{{- end }} diff --git a/helm/airflow/templates/secrets/webserver-secret-key-secret.yaml b/helm/airflow/templates/secrets/webserver-secret-key-secret.yaml new file mode 100644 index 0000000..d7b1d52 --- /dev/null +++ b/helm/airflow/templates/secrets/webserver-secret-key-secret.yaml @@ -0,0 +1,41 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +############################################ +## Airflow Webserver Flask Secret Key Secret +############################################ +{{- if not .Values.webserverSecretKeySecretName }} +{{ $generated_secret_key := (randAlphaNum 32 | b64enc) }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "airflow.fullname" . }}-webserver-secret-key + labels: + tier: airflow + component: webserver + release: {{ .Release.Name }} + chart: {{ .Chart.Name }} + heritage: {{ .Release.Service }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +type: Opaque +data: + webserver-secret-key: {{ (default $generated_secret_key .Values.webserverSecretKey) | b64enc | quote }} +{{- end }} diff --git a/helm/airflow/templates/statsd/statsd-deployment.yaml b/helm/airflow/templates/statsd/statsd-deployment.yaml new file mode 100644 index 0000000..dd7723f --- /dev/null +++ b/helm/airflow/templates/statsd/statsd-deployment.yaml @@ -0,0 +1,138 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +################################ +## Airflow StatsD Deployment +################################# +{{- if .Values.statsd.enabled }} +{{- $nodeSelector := or .Values.statsd.nodeSelector .Values.nodeSelector }} +{{- $affinity := or .Values.statsd.affinity .Values.affinity }} +{{- $tolerations := or .Values.statsd.tolerations .Values.tolerations }} +{{- $topologySpreadConstraints := or .Values.statsd.topologySpreadConstraints .Values.topologySpreadConstraints }} +{{- $revisionHistoryLimit := or .Values.statsd.revisionHistoryLimit .Values.revisionHistoryLimit }} +{{- $securityContext := include "localPodSecurityContext" .Values.statsd }} +{{- $containerSecurityContext := include "externalContainerSecurityContext" .Values.statsd }} +{{- $containerLifecycleHooks := .Values.statsd.containerLifecycleHooks }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "airflow.fullname" . }}-statsd + labels: + tier: airflow + component: statsd + release: {{ .Release.Name }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.statsd.annotations }} + annotations: {{- toYaml . | nindent 4 }} + {{- end }} +spec: + replicas: 1 + {{- if $revisionHistoryLimit }} + revisionHistoryLimit: {{ $revisionHistoryLimit }} + {{- end }} + selector: + matchLabels: + tier: airflow + component: statsd + release: {{ .Release.Name }} + template: + metadata: + labels: + tier: airflow + component: statsd + release: {{ .Release.Name }} + {{- with .Values.labels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if or .Values.statsd.extraMappings .Values.statsd.podAnnotations }} + annotations: + checksum/statsd-config: {{ include (print $.Template.BasePath "/configmaps/statsd-configmap.yaml") . | sha256sum }} + {{- if .Values.statsd.podAnnotations }} + {{- toYaml .Values.statsd.podAnnotations | nindent 8 }} + {{- end }} + {{- end }} + spec: + {{- if .Values.statsd.priorityClassName }} + priorityClassName: {{ .Values.statsd.priorityClassName }} + {{- end }} + nodeSelector: {{- toYaml $nodeSelector | nindent 8 }} + affinity: {{- toYaml $affinity | nindent 8 }} + tolerations: {{- toYaml $tolerations | nindent 8 }} + {{- if .Values.schedulerName }} + schedulerName: {{ .Values.schedulerName }} + {{- end }} + topologySpreadConstraints: {{- toYaml $topologySpreadConstraints | nindent 8 }} + serviceAccountName: {{ include "statsd.serviceAccountName" . }} + securityContext: {{ $securityContext | nindent 8 }} + restartPolicy: Always + {{- if or .Values.registry.secretName .Values.registry.connection }} + imagePullSecrets: + - name: {{ template "registry_secret" . }} + {{- end }} + containers: + - name: statsd + image: {{ template "statsd_image" . }} + imagePullPolicy: {{ .Values.images.statsd.pullPolicy }} + securityContext: {{ $containerSecurityContext | nindent 12 }} + {{- if $containerLifecycleHooks }} + lifecycle: {{- tpl (toYaml $containerLifecycleHooks) . | nindent 12 }} + {{- end }} + {{- if .Values.statsd.args }} + args: {{ tpl (toYaml .Values.statsd.args) . | nindent 12 }} + {{- else}} + args: + - "--statsd.mapping-config=/etc/statsd-exporter/mappings.yml" + {{- end }} + resources: {{- toYaml .Values.statsd.resources | nindent 12 }} + {{- with .Values.statsd.env }} + env: {{- toYaml . | nindent 12 }} + {{- end }} + ports: + - name: statsd-ingest + protocol: UDP + containerPort: {{ .Values.ports.statsdIngest }} + - name: statsd-scrape + containerPort: {{ .Values.ports.statsdScrape }} + livenessProbe: + httpGet: + path: /metrics + port: {{ .Values.ports.statsdScrape }} + initialDelaySeconds: 10 + periodSeconds: 10 + timeoutSeconds: 5 + readinessProbe: + httpGet: + path: /metrics + port: {{ .Values.ports.statsdScrape }} + initialDelaySeconds: 10 + periodSeconds: 10 + timeoutSeconds: 5 + volumeMounts: + - name: config + mountPath: /etc/statsd-exporter/mappings.yml + subPath: mappings.yml + volumes: + - name: config + configMap: + name: {{ include "airflow.fullname" . }}-statsd +{{- end }} diff --git a/helm/airflow/templates/statsd/statsd-networkpolicy.yaml b/helm/airflow/templates/statsd/statsd-networkpolicy.yaml new file mode 100644 index 0000000..3690cda --- /dev/null +++ b/helm/airflow/templates/statsd/statsd-networkpolicy.yaml @@ -0,0 +1,59 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +################################ +## Airflow StatsD NetworkPolicy +################################# +{{- if and .Values.networkPolicies.enabled .Values.statsd.enabled }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "airflow.fullname" . }}-statsd-policy + labels: + tier: airflow + component: statsd-policy + release: {{ .Release.Name }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + podSelector: + matchLabels: + tier: airflow + component: statsd + release: {{ .Release.Name }} + policyTypes: + - Ingress + ingress: + - from: + - podSelector: + matchLabels: + tier: airflow + release: {{ .Release.Name }} + {{- if .Values.statsd.extraNetworkPolicies }} + {{- toYaml .Values.statsd.extraNetworkPolicies | nindent 4 }} + {{- end }} + ports: + - protocol: UDP + port: {{ .Values.ports.statsdIngest }} + - protocol: TCP + port: {{ .Values.ports.statsdScrape }} +{{- end }} diff --git a/helm/airflow/templates/statsd/statsd-service.yaml b/helm/airflow/templates/statsd/statsd-service.yaml new file mode 100644 index 0000000..2486264 --- /dev/null +++ b/helm/airflow/templates/statsd/statsd-service.yaml @@ -0,0 +1,58 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +################################ +## Airflow StatsD Service +################################# +{{- if .Values.statsd.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "airflow.fullname" . }}-statsd + labels: + tier: airflow + component: statsd + release: {{ .Release.Name }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + prometheus.io/scrape: "true" + prometheus.io/port: {{ .Values.ports.statsdScrape | quote }} + {{- if .Values.statsd.service.extraAnnotations }} + {{- toYaml .Values.statsd.service.extraAnnotations | nindent 4 }} + {{- end }} +spec: + type: ClusterIP + selector: + tier: airflow + component: statsd + release: {{ .Release.Name }} + ports: + - name: statsd-ingest + protocol: UDP + port: {{ .Values.ports.statsdIngest }} + targetPort: {{ .Values.ports.statsdIngest }} + - name: statsd-scrape + protocol: TCP + port: {{ .Values.ports.statsdScrape }} + targetPort: {{ .Values.ports.statsdScrape }} +{{- end }} diff --git a/helm/airflow/templates/statsd/statsd-serviceaccount.yaml b/helm/airflow/templates/statsd/statsd-serviceaccount.yaml new file mode 100644 index 0000000..838cbdd --- /dev/null +++ b/helm/airflow/templates/statsd/statsd-serviceaccount.yaml @@ -0,0 +1,41 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +###################################### +## Airflow StatsD ServiceAccount +###################################### +{{- if and .Values.statsd.enabled .Values.statsd.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +automountServiceAccountToken: {{ .Values.statsd.serviceAccount.automountServiceAccountToken }} +metadata: + name: {{ include "statsd.serviceAccountName" . }} + labels: + tier: airflow + component: statsd + release: {{ .Release.Name }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.statsd.serviceAccount.annotations }} + annotations: {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/helm/airflow/templates/triggerer/triggerer-deployment.yaml b/helm/airflow/templates/triggerer/triggerer-deployment.yaml new file mode 100644 index 0000000..ccaedb8 --- /dev/null +++ b/helm/airflow/templates/triggerer/triggerer-deployment.yaml @@ -0,0 +1,312 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +################################ +## Airflow Triggerer Deployment +################################# +{{- if semverCompare ">=2.2.0" .Values.airflowVersion }} +{{- if .Values.triggerer.enabled }} +{{- /* Airflow version 2.6.0 is when triggerer logs serve introduced */ -}} +{{- $persistence := and .Values.triggerer.persistence.enabled (semverCompare ">=2.6.0" .Values.airflowVersion) }} +{{- $keda := .Values.triggerer.keda.enabled }} +{{- $nodeSelector := or .Values.triggerer.nodeSelector .Values.nodeSelector }} +{{- $affinity := or .Values.triggerer.affinity .Values.affinity }} +{{- $tolerations := or .Values.triggerer.tolerations .Values.tolerations }} +{{- $topologySpreadConstraints := or .Values.triggerer.topologySpreadConstraints .Values.topologySpreadConstraints }} +{{- $revisionHistoryLimit := or .Values.triggerer.revisionHistoryLimit .Values.revisionHistoryLimit }} +{{- $securityContext := include "airflowPodSecurityContext" (list . .Values.triggerer) }} +{{- $containerSecurityContext := include "containerSecurityContext" (list . .Values.triggerer) }} +{{- $containerSecurityContextWaitForMigrations := include "containerSecurityContext" (list . .Values.triggerer.waitForMigrations) }} +{{- $containerSecurityContextLogGroomer := include "containerSecurityContext" (list . .Values.triggerer.logGroomerSidecar) }} +{{- $containerLifecycleHooks := or .Values.triggerer.containerLifecycleHooks .Values.containerLifecycleHooks }} +{{- $containerLifecycleHooksWaitForMigrations := or .Values.triggerer.waitForMigrations.containerLifecycleHooks .Values.containerLifecycleHooks }} +{{- $containerLifecycleHooksLogGroomerSidecar := or .Values.triggerer.logGroomerSidecar.containerLifecycleHooks .Values.containerLifecycleHooks }} +apiVersion: apps/v1 +kind: {{ if $persistence }}StatefulSet{{ else }}Deployment{{ end }} +metadata: + name: {{ include "airflow.fullname" . }}-triggerer + labels: + tier: airflow + component: triggerer + release: {{ .Release.Name }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if .Values.triggerer.annotations }} + annotations: {{- toYaml .Values.triggerer.annotations | nindent 4 }} + {{- end }} +spec: + {{- if $persistence }} + serviceName: {{ .Release.Name }}-triggerer + {{- end }} + {{- if not $keda }} + replicas: {{ .Values.triggerer.replicas }} + {{- end }} + {{- if $revisionHistoryLimit }} + revisionHistoryLimit: {{ $revisionHistoryLimit }} + {{- end }} + selector: + matchLabels: + tier: airflow + component: triggerer + release: {{ .Release.Name }} + {{- if and $persistence .Values.triggerer.updateStrategy }} + updateStrategy: {{- toYaml .Values.triggerer.updateStrategy | nindent 4 }} + {{- end }} + {{- if and (not $persistence) (.Values.triggerer.strategy) }} + strategy: {{- toYaml .Values.triggerer.strategy | nindent 4 }} + {{- end }} + template: + metadata: + labels: + tier: airflow + component: triggerer + release: {{ .Release.Name }} + {{- if or (.Values.labels) (.Values.triggerer.labels) }} + {{- mustMerge .Values.triggerer.labels .Values.labels | toYaml | nindent 8 }} + {{- end }} + annotations: + checksum/metadata-secret: {{ include (print $.Template.BasePath "/secrets/metadata-connection-secret.yaml") . | sha256sum }} + checksum/pgbouncer-config-secret: {{ include (print $.Template.BasePath "/secrets/pgbouncer-config-secret.yaml") . | sha256sum }} + checksum/airflow-config: {{ include (print $.Template.BasePath "/configmaps/configmap.yaml") . | sha256sum }} + checksum/extra-configmaps: {{ include (print $.Template.BasePath "/configmaps/extra-configmaps.yaml") . | sha256sum }} + checksum/extra-secrets: {{ include (print $.Template.BasePath "/secrets/extra-secrets.yaml") . | sha256sum }} + {{- if .Values.triggerer.safeToEvict }} + cluster-autoscaler.kubernetes.io/safe-to-evict: "true" + {{- end }} + {{- if .Values.airflowPodAnnotations }} + {{- toYaml .Values.airflowPodAnnotations | nindent 8 }} + {{- end }} + {{- if .Values.triggerer.podAnnotations }} + {{- toYaml .Values.triggerer.podAnnotations | nindent 8 }} + {{- end }} + spec: + {{- if .Values.triggerer.priorityClassName }} + priorityClassName: {{ .Values.triggerer.priorityClassName }} + {{- end }} + nodeSelector: {{- toYaml $nodeSelector | nindent 8 }} + {{- if .Values.schedulerName }} + schedulerName: {{ .Values.schedulerName }} + {{- end }} + affinity: + {{- if $affinity }} + {{- toYaml $affinity | nindent 8 }} + {{- else }} + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchLabels: + component: triggerer + topologyKey: kubernetes.io/hostname + weight: 100 + {{- end }} + tolerations: {{- toYaml $tolerations | nindent 8 }} + topologySpreadConstraints: {{- toYaml $topologySpreadConstraints | nindent 8 }} + terminationGracePeriodSeconds: {{ .Values.triggerer.terminationGracePeriodSeconds }} + restartPolicy: Always + serviceAccountName: {{ include "triggerer.serviceAccountName" . }} + securityContext: {{ $securityContext | nindent 8 }} + {{- if or .Values.registry.secretName .Values.registry.connection }} + imagePullSecrets: + - name: {{ template "registry_secret" . }} + {{- end }} + initContainers: + {{- if .Values.triggerer.waitForMigrations.enabled }} + - name: wait-for-airflow-migrations + resources: + {{- toYaml .Values.triggerer.resources | nindent 12 }} + image: {{ template "airflow_image_for_migrations" . }} + imagePullPolicy: {{ .Values.images.airflow.pullPolicy }} + securityContext: {{ $containerSecurityContextWaitForMigrations | nindent 12 }} + {{- if $containerLifecycleHooksWaitForMigrations }} + lifecycle: {{- tpl (toYaml $containerLifecycleHooksWaitForMigrations) . | nindent 12 }} + {{- end }} + volumeMounts: + {{- include "airflow_config_mount" . | nindent 12 }} + {{- if .Values.volumeMounts }} + {{- toYaml .Values.volumeMounts | nindent 12 }} + {{- end }} + {{- if .Values.triggerer.extraVolumeMounts }} + {{- tpl (toYaml .Values.triggerer.extraVolumeMounts) . | nindent 12 }} + {{- end }} + {{- if or .Values.webserver.webserverConfig .Values.webserver.webserverConfigConfigMapName }} + {{- include "airflow_webserver_config_mount" . | nindent 12 }} + {{- end }} + args: {{- include "wait-for-migrations-command" . | indent 10 }} + envFrom: {{- include "custom_airflow_environment_from" . | default "\n []" | indent 10 }} + env: + {{- include "custom_airflow_environment" . | indent 10 }} + {{- include "standard_airflow_environment" . | indent 10 }} + {{- if .Values.triggerer.waitForMigrations.env }} + {{- tpl (toYaml .Values.triggerer.waitForMigrations.env) $ | nindent 12 }} + {{- end }} + {{- end }} + {{- if and (.Values.dags.gitSync.enabled) (not .Values.dags.persistence.enabled) }} + {{- include "git_sync_container" (dict "Values" .Values "is_init" "true" "Template" .Template) | nindent 8 }} + {{- end }} + {{- if .Values.triggerer.extraInitContainers }} + {{- toYaml .Values.triggerer.extraInitContainers | nindent 8 }} + {{- end }} + containers: + - name: triggerer + image: {{ template "airflow_image" . }} + imagePullPolicy: {{ .Values.images.airflow.pullPolicy }} + securityContext: {{ $containerSecurityContext | nindent 12 }} + {{- if $containerLifecycleHooks }} + lifecycle: {{- tpl (toYaml $containerLifecycleHooks) . | nindent 12 }} + {{- end }} + {{- if .Values.triggerer.command }} + command: {{ tpl (toYaml .Values.triggerer.command) . | nindent 12 }} + {{- end }} + {{- if .Values.triggerer.args }} + args: {{ tpl (toYaml .Values.triggerer.args) . | nindent 12 }} + {{- end }} + resources: {{- toYaml .Values.triggerer.resources | nindent 12 }} + volumeMounts: + {{- if .Values.volumeMounts }} + {{- toYaml .Values.volumeMounts | nindent 12 }} + {{- end }} + {{- if .Values.triggerer.extraVolumeMounts }} + {{- tpl (toYaml .Values.triggerer.extraVolumeMounts) . | nindent 12 }} + {{- end }} + - name: logs + mountPath: {{ template "airflow_logs" . }} + {{- include "airflow_config_mount" . | nindent 12 }} + {{- if or .Values.webserver.webserverConfig .Values.webserver.webserverConfigConfigMapName }} + {{- include "airflow_webserver_config_mount" . | nindent 12 }} + {{- end }} + {{- if or .Values.dags.persistence.enabled .Values.dags.gitSync.enabled }} + {{- include "airflow_dags_mount" . | nindent 12 }} + {{- end }} + envFrom: {{- include "custom_airflow_environment_from" . | default "\n []" | indent 10 }} + env: + {{- include "custom_airflow_environment" . | indent 10 }} + {{- include "standard_airflow_environment" . | indent 10 }} + {{- include "container_extra_envs" (list . .Values.triggerer.env) | nindent 10 }} + livenessProbe: + initialDelaySeconds: {{ .Values.triggerer.livenessProbe.initialDelaySeconds }} + timeoutSeconds: {{ .Values.triggerer.livenessProbe.timeoutSeconds }} + failureThreshold: {{ .Values.triggerer.livenessProbe.failureThreshold }} + periodSeconds: {{ .Values.triggerer.livenessProbe.periodSeconds }} + exec: + command: + {{- if .Values.triggerer.livenessProbe.command }} + {{- toYaml .Values.triggerer.livenessProbe.command | nindent 16 }} + {{- else }} + {{- include "triggerer_liveness_check_command" . | indent 14 }} + {{- end }} + {{- /* Airflow version 2.6.0 is when triggerer logs serve introduced */ -}} + {{- if semverCompare ">=2.6.0" .Values.airflowVersion }} + ports: + - name: triggerer-logs + containerPort: {{ .Values.ports.triggererLogs }} + {{- end }} + {{- if and (.Values.dags.gitSync.enabled) (not .Values.dags.persistence.enabled) }} + {{- include "git_sync_container" . | nindent 8 }} + {{- end }} + {{- if .Values.triggerer.logGroomerSidecar.enabled }} + - name: triggerer-log-groomer + resources: {{- toYaml .Values.triggerer.logGroomerSidecar.resources | nindent 12 }} + image: {{ template "airflow_image" . }} + imagePullPolicy: {{ .Values.images.airflow.pullPolicy }} + securityContext: {{ $containerSecurityContextLogGroomer | nindent 12 }} + {{- if $containerLifecycleHooksLogGroomerSidecar }} + lifecycle: {{- tpl (toYaml $containerLifecycleHooksLogGroomerSidecar) . | nindent 12 }} + {{- end }} + {{- if .Values.triggerer.logGroomerSidecar.command }} + command: {{ tpl (toYaml .Values.triggerer.logGroomerSidecar.command) . | nindent 12 }} + {{- end }} + {{- if .Values.triggerer.logGroomerSidecar.args }} + args: {{- tpl (toYaml .Values.triggerer.logGroomerSidecar.args) . | nindent 12 }} + {{- end }} + {{- if .Values.triggerer.logGroomerSidecar.retentionDays }} + env: + - name: AIRFLOW__LOG_RETENTION_DAYS + value: "{{ .Values.triggerer.logGroomerSidecar.retentionDays }}" + {{- end }} + volumeMounts: + - name: logs + mountPath: {{ template "airflow_logs" . }} + {{- if .Values.volumeMounts }} + {{- toYaml .Values.volumeMounts | nindent 12 }} + {{- end }} + {{- if .Values.triggerer.extraVolumeMounts }} + {{- tpl (toYaml .Values.triggerer.extraVolumeMounts) . | nindent 12 }} + {{- end }} + {{- if or .Values.webserver.webserverConfig .Values.webserver.webserverConfigConfigMapName }} + {{- include "airflow_webserver_config_mount" . | nindent 12 }} + {{- end }} + {{- end }} + {{- if .Values.triggerer.extraContainers }} + {{- toYaml .Values.triggerer.extraContainers | nindent 8 }} + {{- end }} + volumes: + - name: config + configMap: + name: {{ template "airflow_config" . }} + {{- if or .Values.webserver.webserverConfig .Values.webserver.webserverConfigConfigMapName }} + - name: webserver-config + configMap: + name: {{ template "airflow_webserver_config_configmap_name" . }} + {{- end }} + {{- if .Values.dags.persistence.enabled }} + - name: dags + persistentVolumeClaim: + claimName: {{ template "airflow_dags_volume_claim" . }} + {{- else if .Values.dags.gitSync.enabled }} + - name: dags + emptyDir: {} + {{- if .Values.dags.gitSync.sshKeySecret }} + {{- include "git_sync_ssh_key_volume" . | nindent 8 }} + {{- end }} + {{- end }} + {{- if .Values.volumes }} + {{- toYaml .Values.volumes | nindent 8 }} + {{- end }} + {{- if .Values.triggerer.extraVolumes }} + {{- tpl (toYaml .Values.triggerer.extraVolumes) . | nindent 8 }} + {{- end }} + {{- if .Values.logs.persistence.enabled }} + - name: logs + persistentVolumeClaim: + claimName: {{ template "airflow_logs_volume_claim" . }} + {{- else if not $persistence }} + - name: logs + emptyDir: {} + {{- else }} + volumeClaimTemplates: + - metadata: + name: logs + {{- if .Values.triggerer.persistence.annotations }} + annotations: {{- toYaml .Values.triggerer.persistence.annotations | nindent 10 }} + {{- end }} + spec: + {{- if .Values.triggerer.persistence.storageClassName }} + storageClassName: {{ .Values.triggerer.persistence.storageClassName }} + {{- end }} + accessModes: ["ReadWriteOnce"] + resources: + requests: + storage: {{ .Values.triggerer.persistence.size }} + {{- end }} +{{- end }} +{{- end }} diff --git a/helm/airflow/templates/triggerer/triggerer-kedaautoscaler.yaml b/helm/airflow/templates/triggerer/triggerer-kedaautoscaler.yaml new file mode 100644 index 0000000..a83834a --- /dev/null +++ b/helm/airflow/templates/triggerer/triggerer-kedaautoscaler.yaml @@ -0,0 +1,57 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +################################ +## Airflow Triggerer KEDA Scaler +################################# +{{- if semverCompare ">=2.2.0" .Values.airflowVersion }} +{{- if and .Values.triggerer.enabled .Values.triggerer.keda.enabled }} +apiVersion: keda.sh/v1alpha1 +kind: ScaledObject +metadata: + name: {{ .Release.Name }}-triggerer + labels: + tier: airflow + component: triggerer-horizontalpodautoscaler + release: {{ .Release.Name }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + deploymentName: {{ .Release.Name }}-triggerer + {{- if or (.Values.labels) (.Values.triggerer.labels) }} + {{- mustMerge .Values.triggerer.labels .Values.labels | toYaml | nindent 4 }} + {{- end }} +spec: + scaleTargetRef: + kind: {{ ternary "StatefulSet" "Deployment" .Values.triggerer.persistence.enabled }} + name: {{ .Release.Name }}-triggerer + pollingInterval: {{ .Values.triggerer.keda.pollingInterval }} + cooldownPeriod: {{ .Values.triggerer.keda.cooldownPeriod }} + minReplicaCount: {{ .Values.triggerer.keda.minReplicaCount }} + maxReplicaCount: {{ .Values.triggerer.keda.maxReplicaCount }} + {{- if .Values.triggerer.keda.advanced }} + advanced: {{- toYaml .Values.triggerer.keda.advanced | nindent 4 }} + {{- end }} + triggers: + - type: postgresql + metadata: + targetQueryValue: "1" + connectionFromEnv: AIRFLOW_CONN_AIRFLOW_DB + query: {{ tpl .Values.triggerer.keda.query . | quote }} +{{- end }} +{{- end }} diff --git a/helm/airflow/templates/triggerer/triggerer-networkpolicy.yaml b/helm/airflow/templates/triggerer/triggerer-networkpolicy.yaml new file mode 100644 index 0000000..408fb98 --- /dev/null +++ b/helm/airflow/templates/triggerer/triggerer-networkpolicy.yaml @@ -0,0 +1,60 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +################################## +## Airflow triggerer NetworkPolicy +################################## +{{- /* Airflow version 2.6.0 is when triggerer logs serve introduced */ -}} +{{- if semverCompare ">=2.6.0" .Values.airflowVersion }} +{{- if .Values.networkPolicies.enabled }} +{{- if .Values.triggerer.enabled }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "airflow.fullname" . }}-triggerer-policy + labels: + tier: airflow + component: airflow-triggerer-policy + release: {{ .Release.Name }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + {{- if or (.Values.labels) (.Values.triggerer.labels) }} + {{- mustMerge .Values.triggerer.labels .Values.labels | toYaml | nindent 4 }} + {{- end }} +spec: + podSelector: + matchLabels: + tier: airflow + component: triggerer + release: {{ .Release.Name }} + policyTypes: + - Ingress + ingress: + - from: + - podSelector: + matchLabels: + tier: airflow + release: {{ .Release.Name }} + component: webserver + ports: + - protocol: TCP + port: {{ .Values.ports.triggererLogs }} +{{- end }} +{{- end }} +{{- end }} diff --git a/helm/airflow/templates/triggerer/triggerer-service.yaml b/helm/airflow/templates/triggerer/triggerer-service.yaml new file mode 100644 index 0000000..92aada7 --- /dev/null +++ b/helm/airflow/templates/triggerer/triggerer-service.yaml @@ -0,0 +1,51 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +################################ +## Airflow triggerer Service +################################# +{{- /* Airflow version 2.6.0 is when triggerer logs serve introduced */ -}} +{{- if semverCompare ">=2.6.0" .Values.airflowVersion }} +{{- if .Values.triggerer.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "airflow.fullname" . }}-triggerer + labels: + tier: airflow + component: triggerer + release: {{ .Release.Name }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + {{- if or (.Values.labels) (.Values.triggerer.labels) }} + {{- mustMerge .Values.triggerer.labels .Values.labels | toYaml | nindent 4 }} + {{- end }} +spec: + clusterIP: None + selector: + tier: airflow + component: triggerer + release: {{ .Release.Name }} + ports: + - name: triggerer-logs + protocol: TCP + port: {{ .Values.ports.triggererLogs }} + targetPort: {{ .Values.ports.triggererLogs }} +{{- end }} +{{- end }} diff --git a/helm/airflow/templates/triggerer/triggerer-serviceaccount.yaml b/helm/airflow/templates/triggerer/triggerer-serviceaccount.yaml new file mode 100644 index 0000000..566d2b3 --- /dev/null +++ b/helm/airflow/templates/triggerer/triggerer-serviceaccount.yaml @@ -0,0 +1,43 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +################################ +## Airflow Triggerer ServiceAccount +################################# +{{- if semverCompare ">=2.2.0" .Values.airflowVersion }} +{{- if and .Values.triggerer.serviceAccount.create .Values.triggerer.enabled }} +apiVersion: v1 +kind: ServiceAccount +automountServiceAccountToken: {{ .Values.triggerer.serviceAccount.automountServiceAccountToken }} +metadata: + name: {{ include "triggerer.serviceAccountName" . }} + labels: + tier: airflow + component: triggerer + release: {{ .Release.Name }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + {{- if or (.Values.labels) (.Values.triggerer.labels) }} + {{- mustMerge .Values.triggerer.labels .Values.labels | toYaml | nindent 4 }} + {{- end }} + {{- with .Values.triggerer.serviceAccount.annotations}} + annotations: {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} +{{- end }} diff --git a/helm/airflow/templates/webserver/webserver-deployment.yaml b/helm/airflow/templates/webserver/webserver-deployment.yaml new file mode 100644 index 0000000..dcbe67b --- /dev/null +++ b/helm/airflow/templates/webserver/webserver-deployment.yaml @@ -0,0 +1,297 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +################################ +## Airflow Webserver Deployment +################################# +{{- $nodeSelector := or .Values.webserver.nodeSelector .Values.nodeSelector }} +{{- $affinity := or .Values.webserver.affinity .Values.affinity }} +{{- $tolerations := or .Values.webserver.tolerations .Values.tolerations }} +{{- $topologySpreadConstraints := or .Values.webserver.topologySpreadConstraints .Values.topologySpreadConstraints }} +{{- $revisionHistoryLimit := or .Values.webserver.revisionHistoryLimit .Values.revisionHistoryLimit }} +{{- $securityContext := include "airflowPodSecurityContext" (list . .Values.webserver) }} +{{- $containerSecurityContext := include "containerSecurityContext" (list . .Values.webserver) }} +{{- $containerSecurityContextWaitForMigrations := include "containerSecurityContext" (list . .Values.webserver.waitForMigrations) }} +{{- $containerLifecycleHooks := or .Values.webserver.containerLifecycleHooks .Values.containerLifecycleHooks }} +{{- $containerLifecycleHooksWaitForMigrations := or .Values.webserver.waitForMigrations.containerLifecycleHooks .Values.containerLifecycleHooks }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "airflow.fullname" . }}-webserver + labels: + tier: airflow + component: webserver + release: {{ .Release.Name }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if .Values.webserver.annotations }} + annotations: {{- toYaml .Values.webserver.annotations | nindent 4 }} + {{- end }} +spec: + replicas: {{ .Values.webserver.replicas }} + {{- if $revisionHistoryLimit }} + revisionHistoryLimit: {{ $revisionHistoryLimit }} + {{- end }} + strategy: + {{- if .Values.webserver.strategy }} + {{- toYaml .Values.webserver.strategy | nindent 4 }} + {{- else }} + {{- if semverCompare ">=2.0.0" .Values.airflowVersion }} + # Here we define the rolling update strategy + # - maxSurge define how many pod we can add at a time + # - maxUnavailable define how many pod can be unavailable + # during the rolling update + # Setting maxUnavailable to 0 would make sure we have the appropriate + # capacity during the rolling update. + # You can also use percentage based value instead of integer. + type: RollingUpdate + rollingUpdate: + maxSurge: 1 + maxUnavailable: 0 + {{- else }} + type: Recreate + {{- end }} + {{- end }} + selector: + matchLabels: + tier: airflow + component: webserver + release: {{ .Release.Name }} + template: + metadata: + labels: + tier: airflow + component: webserver + release: {{ .Release.Name }} + {{- if or (.Values.labels) (.Values.webserver.labels) }} + {{- mustMerge .Values.webserver.labels .Values.labels | toYaml | nindent 8 }} + {{- end }} + annotations: + checksum/metadata-secret: {{ include (print $.Template.BasePath "/secrets/metadata-connection-secret.yaml") . | sha256sum }} + checksum/pgbouncer-config-secret: {{ include (print $.Template.BasePath "/secrets/pgbouncer-config-secret.yaml") . | sha256sum }} + checksum/webserver-secret-key: {{ include (print $.Template.BasePath "/secrets/webserver-secret-key-secret.yaml") . | sha256sum }} + checksum/airflow-config: {{ include (print $.Template.BasePath "/configmaps/configmap.yaml") . | sha256sum }} + checksum/webserver-config: {{ include (print $.Template.BasePath "/configmaps/webserver-configmap.yaml") . | sha256sum }} + checksum/extra-configmaps: {{ include (print $.Template.BasePath "/configmaps/extra-configmaps.yaml") . | sha256sum }} + checksum/extra-secrets: {{ include (print $.Template.BasePath "/secrets/extra-secrets.yaml") . | sha256sum }} + {{- if .Values.airflowPodAnnotations }} + {{- toYaml .Values.airflowPodAnnotations | nindent 8 }} + {{- end }} + {{- if .Values.webserver.podAnnotations }} + {{- toYaml .Values.webserver.podAnnotations | nindent 8 }} + {{- end }} + spec: + {{- if .Values.webserver.hostAliases }} + hostAliases: {{- toYaml .Values.webserver.hostAliases | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "webserver.serviceAccountName" . }} + {{- if .Values.webserver.priorityClassName }} + priorityClassName: {{ .Values.webserver.priorityClassName }} + {{- end }} + {{- if .Values.schedulerName }} + schedulerName: {{ .Values.schedulerName }} + {{- end }} + nodeSelector: {{- toYaml $nodeSelector | nindent 8 }} + affinity: + {{- if $affinity }} + {{- toYaml $affinity | nindent 8 }} + {{- else }} + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchLabels: + component: webserver + topologyKey: kubernetes.io/hostname + weight: 100 + {{- end }} + tolerations: {{- toYaml $tolerations | nindent 8 }} + topologySpreadConstraints: {{- toYaml $topologySpreadConstraints | nindent 8 }} + restartPolicy: Always + securityContext: {{ $securityContext | nindent 8 }} + {{- if or .Values.registry.secretName .Values.registry.connection }} + imagePullSecrets: + - name: {{ template "registry_secret" . }} + {{- end }} + initContainers: + {{- if .Values.webserver.waitForMigrations.enabled }} + - name: wait-for-airflow-migrations + resources: {{- toYaml .Values.webserver.resources | nindent 12 }} + image: {{ template "airflow_image_for_migrations" . }} + imagePullPolicy: {{ .Values.images.airflow.pullPolicy }} + securityContext: {{ $containerSecurityContextWaitForMigrations | nindent 12 }} + {{- if $containerLifecycleHooksWaitForMigrations }} + lifecycle: {{- tpl (toYaml $containerLifecycleHooksWaitForMigrations) . | nindent 12 }} + {{- end }} + volumeMounts: + {{- include "airflow_config_mount" . | nindent 12 }} + {{- if .Values.volumeMounts }} + {{- toYaml .Values.volumeMounts | nindent 12 }} + {{- end }} + {{- if .Values.webserver.extraVolumeMounts }} + {{- tpl (toYaml .Values.webserver.extraVolumeMounts) . | nindent 12 }} + {{- end }} + {{- if or .Values.webserver.webserverConfig .Values.webserver.webserverConfigConfigMapName }} + {{- include "airflow_webserver_config_mount" . | nindent 12 }} + {{- end }} + args: {{- include "wait-for-migrations-command" . | indent 10 }} + envFrom: {{- include "custom_airflow_environment_from" . | default "\n []" | indent 10 }} + env: + {{- include "custom_airflow_environment" . | indent 10 }} + {{- include "standard_airflow_environment" . | indent 10 }} + {{- if .Values.webserver.waitForMigrations.env }} + {{- tpl (toYaml .Values.webserver.waitForMigrations.env) $ | nindent 12 }} + {{- end }} + {{- end }} + {{- if and (.Values.dags.gitSync.enabled) (not .Values.dags.persistence.enabled) (semverCompare "<2.0.0" .Values.airflowVersion) }} + {{- include "git_sync_container" (dict "Values" .Values "is_init" "true" "Template" .Template) | nindent 8 }} + {{- end }} + {{- if .Values.webserver.extraInitContainers }} + {{- toYaml .Values.webserver.extraInitContainers | nindent 8 }} + {{- end }} + containers: + - name: webserver + image: {{ template "airflow_image" . }} + imagePullPolicy: {{ .Values.images.airflow.pullPolicy }} + securityContext: {{ or $containerSecurityContext .Values.webserver.securityContexts.container .Values.securityContexts.container | nindent 12 }} + {{- if $containerLifecycleHooks }} + lifecycle: {{- tpl (toYaml $containerLifecycleHooks) . | nindent 12 }} + {{- end }} + {{- if .Values.webserver.command }} + command: {{ tpl (toYaml .Values.webserver.command) . | nindent 12 }} + {{- end }} + {{- if .Values.webserver.args }} + args: {{- tpl (toYaml .Values.webserver.args) . | nindent 12 }} + {{- end }} + resources: {{- toYaml .Values.webserver.resources | nindent 12 }} + volumeMounts: + {{- if semverCompare ">=1.10.12" .Values.airflowVersion }} + - name: config + mountPath: {{ include "airflow_pod_template_file" . }}/pod_template_file.yaml + subPath: pod_template_file.yaml + readOnly: true + {{- end }} + {{- include "airflow_config_mount" . | nindent 12 }} + {{- if or .Values.webserver.webserverConfig .Values.webserver.webserverConfigConfigMapName }} + {{- include "airflow_webserver_config_mount" . | nindent 12 }} + {{- end }} + {{- if and (semverCompare "<2.0.0" .Values.airflowVersion) (or .Values.dags.gitSync.enabled .Values.dags.persistence.enabled) }} + {{- include "airflow_dags_mount" . | nindent 12 }} + {{- end }} + {{- if .Values.logs.persistence.enabled }} + - name: logs + mountPath: {{ template "airflow_logs" . }} + {{- end }} + {{- if .Values.volumeMounts }} + {{- toYaml .Values.volumeMounts | nindent 12 }} + {{- end }} + {{- if .Values.webserver.extraVolumeMounts }} + {{- tpl (toYaml .Values.webserver.extraVolumeMounts) . | nindent 12 }} + {{- end }} + ports: + - name: airflow-ui + containerPort: {{ .Values.ports.airflowUI }} + livenessProbe: + httpGet: + path: {{ if .Values.config.webserver.base_url }}{{- with urlParse (tpl .Values.config.webserver.base_url .) }}{{ .path }}{{ end }}{{ end }}/health + port: {{ .Values.ports.airflowUI }} + {{- if .Values.config.webserver.base_url}} + httpHeaders: + - name: Host + value: {{ regexReplaceAll ":\\d+$" (urlParse (tpl .Values.config.webserver.base_url .)).host "" }} + {{- end }} + scheme: {{ .Values.webserver.livenessProbe.scheme | default "http" }} + initialDelaySeconds: {{ .Values.webserver.livenessProbe.initialDelaySeconds }} + timeoutSeconds: {{ .Values.webserver.livenessProbe.timeoutSeconds }} + failureThreshold: {{ .Values.webserver.livenessProbe.failureThreshold }} + periodSeconds: {{ .Values.webserver.livenessProbe.periodSeconds }} + readinessProbe: + httpGet: + path: {{ if .Values.config.webserver.base_url }}{{- with urlParse (tpl .Values.config.webserver.base_url .) }}{{ .path }}{{ end }}{{ end }}/health + port: {{ .Values.ports.airflowUI }} + {{- if .Values.config.webserver.base_url }} + httpHeaders: + - name: Host + value: {{ regexReplaceAll ":\\d+$" (urlParse (tpl .Values.config.webserver.base_url .)).host "" }} + {{- end }} + scheme: {{ .Values.webserver.readinessProbe.scheme | default "http" }} + initialDelaySeconds: {{ .Values.webserver.readinessProbe.initialDelaySeconds }} + timeoutSeconds: {{ .Values.webserver.readinessProbe.timeoutSeconds }} + failureThreshold: {{ .Values.webserver.readinessProbe.failureThreshold }} + periodSeconds: {{ .Values.webserver.readinessProbe.periodSeconds }} + startupProbe: + httpGet: + path: {{ if .Values.config.webserver.base_url }}{{- with urlParse (tpl .Values.config.webserver.base_url .) }}{{ .path }}{{ end }}{{ end }}/health + port: {{ .Values.ports.airflowUI }} + {{- if .Values.config.webserver.base_url}} + httpHeaders: + - name: Host + value: {{ regexReplaceAll ":\\d+$" (urlParse (tpl .Values.config.webserver.base_url .)).host "" }} + {{- end }} + scheme: {{ .Values.webserver.startupProbe.scheme | default "http" }} + timeoutSeconds: {{ .Values.webserver.startupProbe.timeoutSeconds }} + failureThreshold: {{ .Values.webserver.startupProbe.failureThreshold }} + periodSeconds: {{ .Values.webserver.startupProbe.periodSeconds }} + envFrom: {{- include "custom_airflow_environment_from" . | default "\n []" | indent 10 }} + env: + {{- include "custom_airflow_environment" . | indent 10 }} + {{- include "standard_airflow_environment" . | indent 10 }} + {{- include "container_extra_envs" (list . .Values.webserver.env) | indent 10 }} + {{- if and (.Values.dags.gitSync.enabled) (not .Values.dags.persistence.enabled) (semverCompare "<2.0.0" .Values.airflowVersion) }} + {{- include "git_sync_container" . | nindent 8 }} + {{- end }} + {{- if .Values.webserver.extraContainers }} + {{- toYaml .Values.webserver.extraContainers | nindent 8 }} + {{- end }} + volumes: + - name: config + configMap: + name: {{ template "airflow_config" . }} + {{- if or .Values.webserver.webserverConfig .Values.webserver.webserverConfigConfigMapName }} + - name: webserver-config + configMap: + name: {{ template "airflow_webserver_config_configmap_name" . }} + {{- end }} + {{- if (semverCompare "<2.0.0" .Values.airflowVersion) }} + {{- if .Values.dags.persistence.enabled }} + - name: dags + persistentVolumeClaim: + claimName: {{ template "airflow_dags_volume_claim" . }} + {{- else if .Values.dags.gitSync.enabled }} + - name: dags + emptyDir: {} + {{- if .Values.dags.gitSync.sshKeySecret }} + {{- include "git_sync_ssh_key_volume" . | indent 8 }} + {{- end }} + {{- end }} + {{- end }} + {{- if .Values.logs.persistence.enabled }} + - name: logs + persistentVolumeClaim: + claimName: {{ template "airflow_logs_volume_claim" . }} + {{- end }} + {{- if .Values.volumes }} + {{- toYaml .Values.volumes | nindent 8 }} + {{- end }} + {{- if .Values.webserver.extraVolumes }} + {{- tpl (toYaml .Values.webserver.extraVolumes) . | nindent 8 }} + {{- end }} diff --git a/helm/airflow/templates/webserver/webserver-ingress.yaml b/helm/airflow/templates/webserver/webserver-ingress.yaml new file mode 100644 index 0000000..451a57c --- /dev/null +++ b/helm/airflow/templates/webserver/webserver-ingress.yaml @@ -0,0 +1,111 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +################################ +## Airflow Webserver Ingress +################################# +{{- if or .Values.ingress.web.enabled .Values.ingress.enabled }} +{{- $fullname := (include "airflow.fullname" .) }} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ $fullname }}-ingress + labels: + tier: airflow + component: airflow-ingress + release: {{ .Release.Name }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + {{- if or (.Values.labels) (.Values.webserver.labels) }} + {{- mustMerge .Values.webserver.labels .Values.labels | toYaml | nindent 4 }} + {{- end }} + {{- with .Values.ingress.web.annotations }} + annotations: {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if and .Values.ingress.web.hosts (.Values.ingress.web.hosts | first | kindIs "string" | not) }} + {{- $anyTlsHosts := false -}} + {{- range .Values.ingress.web.hosts }} + {{- if .tls }} + {{- if .tls.enabled }} + {{- $anyTlsHosts = true -}} + {{- end }} + {{- end }} + {{- end }} + {{- if $anyTlsHosts }} + tls: + {{- range .Values.ingress.web.hosts }} + {{- if .tls }} + {{- if .tls.enabled }} + - hosts: + - {{ .name | quote }} + secretName: {{ .tls.secretName }} + {{- end }} + {{- end }} + {{- end }} + {{- end }} + {{- else if .Values.ingress.web.tls.enabled }} + tls: + - hosts: + {{- .Values.ingress.web.hosts | default (list .Values.ingress.web.host) | toYaml | nindent 8 }} + secretName: {{ .Values.ingress.web.tls.secretName }} + {{- end }} + rules: + {{- range .Values.ingress.web.hosts | default (list .Values.ingress.web.host) }} + - http: + paths: + {{- range $.Values.ingress.web.precedingPaths }} + - path: {{ .path }} + pathType: {{ .pathType }} + backend: + service: + name: {{ .serviceName }} + port: + name: {{ .servicePort }} + {{- end }} + - backend: + service: + name: {{ $fullname }}-webserver + port: + name: airflow-ui + {{- if $.Values.ingress.web.path }} + path: {{ $.Values.ingress.web.path }} + pathType: {{ $.Values.ingress.web.pathType }} + {{- end }} + {{- range $.Values.ingress.web.succeedingPaths }} + - path: {{ .path }} + pathType: {{ .pathType }} + backend: + service: + name: {{ .serviceName }} + port: + name: {{ .servicePort }} + {{- end }} + {{- $hostname := . -}} + {{- if . | kindIs "string" | not }} + {{- $hostname = .name -}} + {{- end }} + {{- if $hostname }} + host: {{ tpl $hostname $ | quote }} + {{- end }} + {{- end }} + {{- if .Values.ingress.web.ingressClassName }} + ingressClassName: {{ .Values.ingress.web.ingressClassName }} + {{- end }} +{{- end }} diff --git a/helm/airflow/templates/webserver/webserver-networkpolicy.yaml b/helm/airflow/templates/webserver/webserver-networkpolicy.yaml new file mode 100644 index 0000000..d0be9e3 --- /dev/null +++ b/helm/airflow/templates/webserver/webserver-networkpolicy.yaml @@ -0,0 +1,57 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +################################ +## Airflow Webserver NetworkPolicy +################################# +{{- if .Values.networkPolicies.enabled }} +{{- $from := or .Values.webserver.networkPolicy.ingress.from .Values.webserver.extraNetworkPolicies }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "airflow.fullname" . }}-webserver-policy + labels: + tier: airflow + component: airflow-webserver-policy + release: {{ .Release.Name }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + {{- if or (.Values.labels) (.Values.webserver.labels) }} + {{- mustMerge .Values.webserver.labels .Values.labels | toYaml | nindent 4 }} + {{- end }} +spec: + podSelector: + matchLabels: + tier: airflow + component: webserver + release: {{ .Release.Name }} + policyTypes: + - Ingress + {{- if $from }} + ingress: + - from: {{- toYaml $from | nindent 6 }} + ports: + {{ range .Values.webserver.networkPolicy.ingress.ports }} + - + {{- range $key, $val := . }} + {{ $key }}: {{ tpl (toString $val) $ }} + {{- end }} + {{- end }} + {{- end }} +{{- end }} diff --git a/helm/airflow/templates/webserver/webserver-poddisruptionbudget.yaml b/helm/airflow/templates/webserver/webserver-poddisruptionbudget.yaml new file mode 100644 index 0000000..840219a --- /dev/null +++ b/helm/airflow/templates/webserver/webserver-poddisruptionbudget.yaml @@ -0,0 +1,44 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +################################ +## Airflow Webserver PodDisruptionBudget +################################# +{{- if .Values.webserver.podDisruptionBudget.enabled }} +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: {{ include "airflow.fullname" . }}-webserver-pdb + labels: + tier: airflow + component: webserver + release: {{ .Release.Name }} + chart: {{ .Chart.Name }} + heritage: {{ .Release.Service }} + {{- if or (.Values.labels) (.Values.webserver.labels) }} + {{- mustMerge .Values.webserver.labels .Values.labels | toYaml | nindent 4 }} + {{- end }} +spec: + selector: + matchLabels: + tier: airflow + component: webserver + release: {{ .Release.Name }} + {{- toYaml .Values.webserver.podDisruptionBudget.config | nindent 2 }} +{{- end }} diff --git a/helm/airflow/templates/webserver/webserver-service.yaml b/helm/airflow/templates/webserver/webserver-service.yaml new file mode 100644 index 0000000..a3c49d3 --- /dev/null +++ b/helm/airflow/templates/webserver/webserver-service.yaml @@ -0,0 +1,56 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +################################ +## Airflow Webserver Service +################################# +apiVersion: v1 +kind: Service +metadata: + name: {{ include "airflow.fullname" . }}-webserver + labels: + tier: airflow + component: webserver + release: {{ .Release.Name }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + {{- if or (.Values.labels) (.Values.webserver.labels) }} + {{- mustMerge .Values.webserver.labels .Values.labels | toYaml | nindent 4 }} + {{- end }} + {{- with .Values.webserver.service.annotations }} + annotations: {{- toYaml . | nindent 4 }} + {{- end }} +spec: + type: {{ .Values.webserver.service.type }} + selector: + tier: airflow + component: webserver + release: {{ .Release.Name }} + ports: + {{- range .Values.webserver.service.ports }} + - {{ range $key, $val := . }} + {{- $key }}: {{ tpl (toString $val) $ }} + {{ end }} + {{- end }} + {{- if .Values.webserver.service.loadBalancerIP }} + loadBalancerIP: {{ .Values.webserver.service.loadBalancerIP }} + {{- end }} + {{- if .Values.webserver.service.loadBalancerSourceRanges }} + loadBalancerSourceRanges: {{- toYaml .Values.webserver.service.loadBalancerSourceRanges | nindent 4 }} + {{- end }} diff --git a/helm/airflow/templates/webserver/webserver-serviceaccount.yaml b/helm/airflow/templates/webserver/webserver-serviceaccount.yaml new file mode 100644 index 0000000..853e376 --- /dev/null +++ b/helm/airflow/templates/webserver/webserver-serviceaccount.yaml @@ -0,0 +1,41 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +###################################### +## Airflow Webserver ServiceAccount +###################################### +{{- if .Values.webserver.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +automountServiceAccountToken: {{ .Values.webserver.serviceAccount.automountServiceAccountToken }} +metadata: + name: {{ include "webserver.serviceAccountName" . }} + labels: + tier: airflow + component: webserver + release: {{ .Release.Name }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + {{- if or (.Values.labels) (.Values.webserver.labels) }} + {{- mustMerge .Values.webserver.labels .Values.labels | toYaml | nindent 4 }} + {{- end }} + {{- with .Values.webserver.serviceAccount.annotations }} + annotations: {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/helm/airflow/templates/workers/worker-deployment.yaml b/helm/airflow/templates/workers/worker-deployment.yaml new file mode 100644 index 0000000..f98ca3f --- /dev/null +++ b/helm/airflow/templates/workers/worker-deployment.yaml @@ -0,0 +1,412 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +################################ +## Airflow Worker Deployment +################################# +{{- $persistence := .Values.workers.persistence.enabled }} +{{- $keda := .Values.workers.keda.enabled }} +{{- if or (eq .Values.executor "CeleryExecutor") (eq .Values.executor "CeleryKubernetesExecutor") }} +{{- $nodeSelector := or .Values.workers.nodeSelector .Values.nodeSelector }} +{{- $affinity := or .Values.workers.affinity .Values.affinity }} +{{- $tolerations := or .Values.workers.tolerations .Values.tolerations }} +{{- $topologySpreadConstraints := or .Values.workers.topologySpreadConstraints .Values.topologySpreadConstraints }} +{{- $revisionHistoryLimit := or .Values.workers.revisionHistoryLimit .Values.revisionHistoryLimit }} +{{- $securityContext := include "airflowPodSecurityContext" (list . .Values.workers) }} +{{- $containerSecurityContext := include "containerSecurityContext" (list . .Values.workers) }} +{{- $containerSecurityContextPersistence := include "containerSecurityContext" (list . .Values.workers.persistence) }} +{{- $containerSecurityContextWaitForMigrations := include "containerSecurityContext" (list . .Values.workers.waitForMigrations) }} +{{- $containerSecurityContextLogGroomerSidecar := include "containerSecurityContext" (list . .Values.workers.logGroomerSidecar) }} +{{- $containerSecurityContextKerberosSidecar := include "containerSecurityContext" (list . .Values.workers.kerberosSidecar) }} +{{- $containerLifecycleHooks := or .Values.workers.containerLifecycleHooks .Values.containerLifecycleHooks }} +{{- $containerLifecycleHooksPersistence := or .Values.workers.persistence.containerLifecycleHooks .Values.containerLifecycleHooks }} +{{- $containerLifecycleHooksWaitForMigrations := or .Values.workers.waitForMigrations.containerLifecycleHooks .Values.containerLifecycleHooks }} +{{- $containerLifecycleHooksLogGroomerSidecar := or .Values.workers.logGroomerSidecar.containerLifecycleHooks .Values.containerLifecycleHooks }} +{{- $containerLifecycleHooksKerberosSidecar := or .Values.workers.kerberosSidecar.containerLifecycleHooks .Values.containerLifecycleHooks }} +apiVersion: apps/v1 +kind: {{ if $persistence }}StatefulSet{{ else }}Deployment{{ end }} +metadata: + name: {{ include "airflow.fullname" . }}-worker + labels: + tier: airflow + component: worker + release: {{ .Release.Name }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if .Values.workers.annotations }} + annotations: {{- toYaml .Values.workers.annotations | nindent 4 }} + {{- end }} +spec: + {{- if $persistence }} + serviceName: {{ include "airflow.fullname" . }}-worker + {{- end }} + {{- if not $keda }} + replicas: {{ .Values.workers.replicas }} + {{- end }} + {{- if $revisionHistoryLimit }} + revisionHistoryLimit: {{ $revisionHistoryLimit }} + {{- end }} + selector: + matchLabels: + tier: airflow + component: worker + release: {{ .Release.Name }} + {{- if and $persistence .Values.workers.updateStrategy }} + updateStrategy: {{- toYaml .Values.workers.updateStrategy | nindent 4 }} + {{- end }} + {{- if and (not $persistence) (.Values.workers.strategy) }} + strategy: {{- toYaml .Values.workers.strategy | nindent 4 }} + {{- end }} + template: + metadata: + labels: + tier: airflow + component: worker + release: {{ .Release.Name }} + {{- if or (.Values.labels) (.Values.workers.labels) }} + {{- mustMerge .Values.workers.labels .Values.labels | toYaml | nindent 8 }} + {{- end }} + annotations: + checksum/metadata-secret: {{ include (print $.Template.BasePath "/secrets/metadata-connection-secret.yaml") . | sha256sum }} + checksum/result-backend-secret: {{ include (print $.Template.BasePath "/secrets/result-backend-connection-secret.yaml") . | sha256sum }} + checksum/pgbouncer-config-secret: {{ include (print $.Template.BasePath "/secrets/pgbouncer-config-secret.yaml") . | sha256sum }} + checksum/webserver-secret-key: {{ include (print $.Template.BasePath "/secrets/webserver-secret-key-secret.yaml") . | sha256sum }} + checksum/kerberos-keytab: {{ include (print $.Template.BasePath "/secrets/kerberos-keytab-secret.yaml") . | sha256sum }} + checksum/airflow-config: {{ include (print $.Template.BasePath "/configmaps/configmap.yaml") . | sha256sum }} + checksum/extra-configmaps: {{ include (print $.Template.BasePath "/configmaps/extra-configmaps.yaml") . | sha256sum }} + checksum/extra-secrets: {{ include (print $.Template.BasePath "/secrets/extra-secrets.yaml") . | sha256sum }} + {{- if .Values.workers.safeToEvict }} + cluster-autoscaler.kubernetes.io/safe-to-evict: "true" + {{- end }} + {{- if .Values.airflowPodAnnotations }} + {{- toYaml .Values.airflowPodAnnotations | nindent 8 }} + {{- end }} + {{- if .Values.workers.podAnnotations }} + {{- toYaml .Values.workers.podAnnotations | nindent 8 }} + {{- end }} + spec: + {{- if .Values.workers.runtimeClassName }} + runtimeClassName: {{ .Values.workers.runtimeClassName }} + {{- end }} + {{- if .Values.workers.priorityClassName }} + priorityClassName: {{ .Values.workers.priorityClassName }} + {{- end }} + {{- if .Values.schedulerName }} + schedulerName: {{ .Values.schedulerName }} + {{- end }} + nodeSelector: {{- toYaml $nodeSelector | nindent 8 }} + affinity: + {{- if $affinity }} + {{- toYaml $affinity | nindent 8 }} + {{- else }} + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchLabels: + component: worker + topologyKey: kubernetes.io/hostname + weight: 100 + {{- end }} + tolerations: {{- toYaml $tolerations | nindent 8 }} + topologySpreadConstraints: {{- toYaml $topologySpreadConstraints | nindent 8 }} + {{- if .Values.workers.hostAliases }} + hostAliases: {{- toYaml .Values.workers.hostAliases | nindent 8 }} + {{- end }} + terminationGracePeriodSeconds: {{ .Values.workers.terminationGracePeriodSeconds }} + restartPolicy: Always + serviceAccountName: {{ include "worker.serviceAccountName" . }} + securityContext: {{ $securityContext | nindent 8 }} + {{- if or .Values.registry.secretName .Values.registry.connection }} + imagePullSecrets: + - name: {{ template "registry_secret" . }} + {{- end }} + initContainers: + {{- if and $persistence .Values.workers.persistence.fixPermissions }} + - name: volume-permissions + resources: {{- toYaml .Values.workers.resources | nindent 12 }} + image: {{ template "airflow_image" . }} + imagePullPolicy: {{ .Values.images.airflow.pullPolicy }} + command: + - chown + - -R + - "{{ include "airflowPodSecurityContextsIds" (list . .Values.workers) }}" + - {{ template "airflow_logs" . }} + securityContext: {{ $containerSecurityContextPersistence | nindent 12 }} + {{- if $containerLifecycleHooksPersistence }} + lifecycle: {{- tpl (toYaml $containerLifecycleHooksPersistence) . | nindent 12 }} + {{- end }} + volumeMounts: + - name: logs + mountPath: {{ template "airflow_logs" . }} + {{- end }} + {{- if .Values.workers.waitForMigrations.enabled }} + - name: wait-for-airflow-migrations + resources: {{- toYaml .Values.workers.resources | nindent 12 }} + image: {{ template "airflow_image_for_migrations" . }} + imagePullPolicy: {{ .Values.images.airflow.pullPolicy }} + securityContext: {{ $containerSecurityContextWaitForMigrations | nindent 12 }} + {{- if $containerLifecycleHooksWaitForMigrations }} + lifecycle: {{- tpl (toYaml $containerLifecycleHooksWaitForMigrations) . | nindent 12 }} + {{- end }} + volumeMounts: + {{- include "airflow_config_mount" . | nindent 12 }} + {{- if .Values.volumeMounts }} + {{- toYaml .Values.volumeMounts | nindent 12 }} + {{- end }} + {{- if .Values.workers.extraVolumeMounts }} + {{- tpl (toYaml .Values.workers.extraVolumeMounts) . | nindent 12 }} + {{- end }} + {{- if or .Values.webserver.webserverConfig .Values.webserver.webserverConfigConfigMapName }} + {{- include "airflow_webserver_config_mount" . | nindent 12 }} + {{- end }} + args: {{- include "wait-for-migrations-command" . | indent 10 }} + envFrom: {{- include "custom_airflow_environment_from" . | default "\n []" | indent 10 }} + env: + {{- include "custom_airflow_environment" . | indent 10 }} + {{- include "standard_airflow_environment" . | indent 10 }} + {{- if .Values.workers.waitForMigrations.env }} + {{- tpl (toYaml .Values.workers.waitForMigrations.env) $ | nindent 12 }} + {{- end }} + {{- end }} + {{- if and (.Values.dags.gitSync.enabled) (not .Values.dags.persistence.enabled) }} + {{- include "git_sync_container" (dict "Values" .Values "is_init" "true" "Template" .Template) | nindent 8 }} + {{- end }} + {{- if .Values.workers.extraInitContainers }} + {{- toYaml .Values.workers.extraInitContainers | nindent 8 }} + {{- end }} + containers: + - name: worker + image: {{ template "airflow_image" . }} + imagePullPolicy: {{ .Values.images.airflow.pullPolicy }} + securityContext: {{ $containerSecurityContext | nindent 12 }} + {{- if $containerLifecycleHooks }} + lifecycle: {{- tpl (toYaml $containerLifecycleHooks) . | nindent 12 }} + {{- end }} + {{- if .Values.workers.command }} + command: {{ tpl (toYaml .Values.workers.command) . | nindent 12 }} + {{- end }} + {{- if .Values.workers.args }} + args: {{ tpl (toYaml .Values.workers.args) . | nindent 12 }} + {{- end }} + resources: {{- toYaml .Values.workers.resources | nindent 12 }} + {{- if .Values.workers.livenessProbe.enabled }} + livenessProbe: + initialDelaySeconds: {{ .Values.workers.livenessProbe.initialDelaySeconds }} + timeoutSeconds: {{ .Values.workers.livenessProbe.timeoutSeconds }} + failureThreshold: {{ .Values.workers.livenessProbe.failureThreshold }} + periodSeconds: {{ .Values.workers.livenessProbe.periodSeconds }} + exec: + command: + {{- if .Values.workers.livenessProbe.command }} + {{- toYaml .Values.workers.livenessProbe.command | nindent 16 }} + {{- else }} + - sh + - -c + - CONNECTION_CHECK_MAX_COUNT=0 exec /entrypoint python -m celery --app {{ include "celery_executor_namespace" . }} inspect ping -d celery@$(hostname) + {{- end }} + {{- end }} + ports: + - name: worker-logs + containerPort: {{ .Values.ports.workerLogs }} + volumeMounts: + {{- if .Values.volumeMounts }} + {{- toYaml .Values.volumeMounts | nindent 12 }} + {{- end }} + {{- if .Values.workers.extraVolumeMounts }} + {{- tpl (toYaml .Values.workers.extraVolumeMounts) . | nindent 12 }} + {{- end }} + - name: logs + mountPath: {{ template "airflow_logs" . }} + {{- include "airflow_config_mount" . | nindent 12 }} + {{- if .Values.kerberos.enabled }} + - name: kerberos-keytab + subPath: "kerberos.keytab" + mountPath: {{ .Values.kerberos.keytabPath | quote }} + readOnly: true + - name: config + mountPath: {{ .Values.kerberos.configPath | quote }} + subPath: krb5.conf + readOnly: true + - name: kerberos-ccache + mountPath: {{ .Values.kerberos.ccacheMountPath | quote }} + readOnly: true + {{- end }} + {{- if or .Values.dags.persistence.enabled .Values.dags.gitSync.enabled }} + {{- include "airflow_dags_mount" . | nindent 12 }} + {{- end }} + {{- if or .Values.webserver.webserverConfig .Values.webserver.webserverConfigConfigMapName }} + {{- include "airflow_webserver_config_mount" . | nindent 12 }} + {{- end }} + envFrom: {{- include "custom_airflow_environment_from" . | default "\n []" | indent 10 }} + env: + # Only signal the main process, not the process group, to make Warm Shutdown work properly + - name: DUMB_INIT_SETSID + value: "0" + {{- include "custom_airflow_environment" . | indent 10 }} + {{- include "standard_airflow_environment" . | indent 10 }} + {{- include "container_extra_envs" (list . .Values.workers.env) | indent 10 }} + {{- if .Values.workers.kerberosSidecar.enabled }} + - name: KRB5_CONFIG + value: {{ .Values.kerberos.configPath | quote }} + - name: KRB5CCNAME + value: {{ include "kerberos_ccache_path" . | quote }} + {{- end }} + {{- if and (.Values.dags.gitSync.enabled) (not .Values.dags.persistence.enabled) }} + {{- include "git_sync_container" . | nindent 8 }} + {{- end }} + {{- if and $persistence .Values.workers.logGroomerSidecar.enabled }} + - name: worker-log-groomer + image: {{ template "airflow_image" . }} + imagePullPolicy: {{ .Values.images.airflow.pullPolicy }} + securityContext: {{ $containerSecurityContextLogGroomerSidecar | nindent 12 }} + {{- if $containerLifecycleHooksLogGroomerSidecar }} + lifecycle: {{- tpl (toYaml $containerLifecycleHooksLogGroomerSidecar) . | nindent 12 }} + {{- end }} + {{- if .Values.workers.logGroomerSidecar.command }} + command: {{ tpl (toYaml .Values.workers.logGroomerSidecar.command) . | nindent 12 }} + {{- end }} + {{- if .Values.workers.logGroomerSidecar.args }} + args: {{ tpl (toYaml .Values.workers.logGroomerSidecar.args) . | nindent 12 }} + {{- end }} + {{- if .Values.workers.logGroomerSidecar.retentionDays }} + env: + - name: AIRFLOW__LOG_RETENTION_DAYS + value: "{{ .Values.workers.logGroomerSidecar.retentionDays }}" + {{- end }} + resources: {{- toYaml .Values.workers.logGroomerSidecar.resources | nindent 12 }} + volumeMounts: + - name: logs + mountPath: {{ template "airflow_logs" . }} + {{- if .Values.volumeMounts }} + {{- toYaml .Values.volumeMounts | nindent 12 }} + {{- end }} + {{- if .Values.workers.extraVolumeMounts }} + {{- tpl (toYaml .Values.workers.extraVolumeMounts) . | nindent 12 }} + {{- end }} + {{- if or .Values.webserver.webserverConfig .Values.webserver.webserverConfigConfigMapName }} + {{- include "airflow_webserver_config_mount" . | nindent 12 }} + {{- end }} + {{- end }} + {{- if .Values.workers.kerberosSidecar.enabled }} + - name: worker-kerberos + image: {{ template "airflow_image" . }} + imagePullPolicy: {{ .Values.images.airflow.pullPolicy }} + securityContext: {{ $containerSecurityContextKerberosSidecar | nindent 12 }} + {{- if $containerLifecycleHooksKerberosSidecar }} + lifecycle: {{- tpl (toYaml $containerLifecycleHooksKerberosSidecar) . | nindent 12 }} + {{- end }} + args: ["kerberos"] + resources: {{- toYaml .Values.workers.kerberosSidecar.resources | nindent 12 }} + volumeMounts: + - name: logs + mountPath: {{ template "airflow_logs" . }} + {{- include "airflow_config_mount" . | nindent 12 }} + - name: config + mountPath: {{ .Values.kerberos.configPath | quote }} + subPath: krb5.conf + readOnly: true + - name: kerberos-keytab + subPath: "kerberos.keytab" + mountPath: {{ .Values.kerberos.keytabPath | quote }} + readOnly: true + - name: kerberos-ccache + mountPath: {{ .Values.kerberos.ccacheMountPath | quote }} + readOnly: false + {{- if .Values.volumeMounts }} + {{- toYaml .Values.volumeMounts | nindent 12 }} + {{- end }} + {{- if .Values.workers.extraVolumeMounts }} + {{- tpl (toYaml .Values.workers.extraVolumeMounts) . | nindent 12 }} + {{- end }} + {{- if or .Values.webserver.webserverConfig .Values.webserver.webserverConfigConfigMapName }} + {{- include "airflow_webserver_config_mount" . | nindent 12 }} + {{- end }} + envFrom: {{- include "custom_airflow_environment_from" . | default "\n []" | indent 10 }} + env: + - name: KRB5_CONFIG + value: {{ .Values.kerberos.configPath | quote }} + - name: KRB5CCNAME + value: {{ include "kerberos_ccache_path" . | quote }} + {{- include "custom_airflow_environment" . | indent 10 }} + {{- include "standard_airflow_environment" . | indent 10 }} + {{- end }} + {{- if .Values.workers.extraContainers }} + {{- toYaml .Values.workers.extraContainers | nindent 8 }} + {{- end }} + volumes: + {{- if .Values.volumes }} + {{- toYaml .Values.volumes | nindent 8 }} + {{- end }} + {{- if .Values.workers.extraVolumes }} + {{- tpl (toYaml .Values.workers.extraVolumes) . | nindent 8 }} + {{- end }} + - name: config + configMap: + name: {{ template "airflow_config" . }} + {{- if or .Values.webserver.webserverConfig .Values.webserver.webserverConfigConfigMapName }} + - name: webserver-config + configMap: + name: {{ template "airflow_webserver_config_configmap_name" . }} + {{- end }} + {{- if .Values.kerberos.enabled }} + - name: kerberos-keytab + secret: + secretName: {{ include "kerberos_keytab_secret" . | quote }} + - name: kerberos-ccache + emptyDir: {} + {{- end }} + {{- if .Values.dags.persistence.enabled }} + - name: dags + persistentVolumeClaim: + claimName: {{ template "airflow_dags_volume_claim" . }} + {{- else if .Values.dags.gitSync.enabled }} + - name: dags + emptyDir: {} + {{- if .Values.dags.gitSync.sshKeySecret }} + {{- include "git_sync_ssh_key_volume" . | indent 8 }} + {{- end }} + {{- end }} + {{- if .Values.logs.persistence.enabled }} + - name: logs + persistentVolumeClaim: + claimName: {{ template "airflow_logs_volume_claim" . }} + {{- else if not $persistence }} + - name: logs + emptyDir: {} + {{- else }} + volumeClaimTemplates: + - metadata: + name: logs + {{- if .Values.workers.persistence.annotations }} + annotations: {{- toYaml .Values.workers.persistence.annotations | nindent 10 }} + {{- end }} + spec: + {{- if .Values.workers.persistence.storageClassName }} + storageClassName: {{ .Values.workers.persistence.storageClassName }} + {{- end }} + accessModes: ["ReadWriteOnce"] + resources: + requests: + storage: {{ .Values.workers.persistence.size }} + {{- end }} +{{- end }} diff --git a/helm/airflow/templates/workers/worker-kedaautoscaler.yaml b/helm/airflow/templates/workers/worker-kedaautoscaler.yaml new file mode 100644 index 0000000..f93484e --- /dev/null +++ b/helm/airflow/templates/workers/worker-kedaautoscaler.yaml @@ -0,0 +1,59 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +################################ +## Airflow Worker KEDA Scaler +################################# +{{- if and .Values.workers.keda.enabled (has .Values.executor (list "CeleryExecutor" "CeleryKubernetesExecutor")) }} +apiVersion: keda.sh/v1alpha1 +kind: ScaledObject +metadata: + name: {{ include "airflow.fullname" . }}-worker + labels: + tier: airflow + component: worker-horizontalpodautoscaler + release: {{ .Release.Name }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + deploymentName: {{ .Release.Name }}-worker + {{- if or (.Values.labels) (.Values.workers.labels) }} + {{- mustMerge .Values.workers.labels .Values.labels | toYaml | nindent 4 }} + {{- end }} +spec: + scaleTargetRef: + kind: {{ ternary "StatefulSet" "Deployment" .Values.workers.persistence.enabled }} + name: {{ include "airflow.fullname" . }}-worker + pollingInterval: {{ .Values.workers.keda.pollingInterval }} + cooldownPeriod: {{ .Values.workers.keda.cooldownPeriod }} + minReplicaCount: {{ .Values.workers.keda.minReplicaCount }} + maxReplicaCount: {{ .Values.workers.keda.maxReplicaCount }} + {{- if .Values.workers.keda.advanced }} + advanced: {{- toYaml .Values.workers.keda.advanced | nindent 4 }} + {{- end }} + triggers: + - type: postgresql + metadata: + targetQueryValue: "1" + {{- if and .Values.pgbouncer.enabled (not .Values.workers.keda.usePgbouncer) }} + connectionFromEnv: KEDA_DB_CONN + {{- else }} + connectionFromEnv: AIRFLOW_CONN_AIRFLOW_DB + {{- end }} + query: {{ tpl .Values.workers.keda.query . | quote }} +{{- end }} diff --git a/helm/airflow/templates/workers/worker-networkpolicy.yaml b/helm/airflow/templates/workers/worker-networkpolicy.yaml new file mode 100644 index 0000000..05de793 --- /dev/null +++ b/helm/airflow/templates/workers/worker-networkpolicy.yaml @@ -0,0 +1,55 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +################################ +## Airflow Worker NetworkPolicy +################################# +{{- if and .Values.networkPolicies.enabled (or (eq .Values.executor "CeleryExecutor") (eq .Values.executor "CeleryKubernetesExecutor")) }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "airflow.fullname" . }}-worker-policy + labels: + tier: airflow + component: airflow-worker-policy + release: {{ .Release.Name }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + {{- if or (.Values.labels) (.Values.workers.labels) }} + {{- mustMerge .Values.workers.labels .Values.labels | toYaml | nindent 4 }} + {{- end }} +spec: + podSelector: + matchLabels: + tier: airflow + component: worker + release: {{ .Release.Name }} + policyTypes: + - Ingress + ingress: + - from: + - podSelector: + matchLabels: + tier: airflow + release: {{ .Release.Name }} + component: webserver + ports: + - protocol: TCP + port: {{ .Values.ports.workerLogs }} +{{- end }} diff --git a/helm/airflow/templates/workers/worker-service.yaml b/helm/airflow/templates/workers/worker-service.yaml new file mode 100644 index 0000000..463f51c --- /dev/null +++ b/helm/airflow/templates/workers/worker-service.yaml @@ -0,0 +1,48 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +################################ +## Airflow Worker Service +################################# +{{- if or (eq .Values.executor "CeleryExecutor") (eq .Values.executor "CeleryKubernetesExecutor") }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "airflow.fullname" . }}-worker + labels: + tier: airflow + component: worker + release: {{ .Release.Name }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + {{- if or (.Values.labels) (.Values.workers.labels) }} + {{- mustMerge .Values.workers.labels .Values.labels | toYaml | nindent 4 }} + {{- end }} +spec: + clusterIP: None + selector: + tier: airflow + component: worker + release: {{ .Release.Name }} + ports: + - name: worker-logs + protocol: TCP + port: {{ .Values.ports.workerLogs }} + targetPort: {{ .Values.ports.workerLogs }} +{{- end }} diff --git a/helm/airflow/templates/workers/worker-serviceaccount.yaml b/helm/airflow/templates/workers/worker-serviceaccount.yaml new file mode 100644 index 0000000..87dbb97 --- /dev/null +++ b/helm/airflow/templates/workers/worker-serviceaccount.yaml @@ -0,0 +1,41 @@ +{{/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/}} + +################################ +## Airflow Worker ServiceAccount +################################# +{{- if and .Values.workers.serviceAccount.create (or (eq .Values.executor "CeleryExecutor") (eq .Values.executor "CeleryKubernetesExecutor") (eq .Values.executor "KubernetesExecutor") (eq .Values.executor "LocalKubernetesExecutor")) }} +apiVersion: v1 +kind: ServiceAccount +automountServiceAccountToken: {{ .Values.workers.serviceAccount.automountServiceAccountToken }} +metadata: + name: {{ include "worker.serviceAccountName" . }} + labels: + tier: airflow + component: worker + release: {{ .Release.Name }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service }} + {{- if or (.Values.labels) (.Values.workers.labels) }} + {{- mustMerge .Values.workers.labels .Values.labels | toYaml | nindent 4 }} + {{- end }} + {{- with .Values.workers.serviceAccount.annotations}} + annotations: {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/helm/airflow/values.schema.json b/helm/airflow/values.schema.json new file mode 100644 index 0000000..395bea9 --- /dev/null +++ b/helm/airflow/values.schema.json @@ -0,0 +1,10226 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema", + "description": "Default values for airflow. Declare variables to be passed into your templates.", + "type": "object", + "x-docsSectionOrder": [ + "Common", + "Airflow", + "Images", + "Ports", + "Database", + "PgBouncer", + "Scheduler", + "Webserver", + "Workers", + "Triggerer", + "DagProcessor", + "Flower", + "Redis", + "StatsD", + "Jobs", + "Kubernetes", + "Ingress", + "Kerberos" + ], + "properties": { + "fullnameOverride": { + "description": "Provide a name to substitute for the full names of resources", + "type": "string", + "default": "", + "x-docsSection": null + }, + "revisionHistoryLimit": { + "description": "Global number of old replicasets to retain. Can be overridden by each deployment's revisionHistoryLimit", + "type": [ + "integer", + "null" + ], + "default": null, + "x-docsSection": null + }, + "nameOverride": { + "description": "Override the name of the chart", + "type": "string", + "default": "", + "x-docsSection": null + }, + "useStandardNaming": { + "description": "Use standard naming for all resources using airflow.fullname template", + "type": "boolean", + "default": false, + "x-docsSection": null + }, + "uid": { + "description": "User of airflow user.", + "type": "integer", + "default": 50000, + "x-docsSection": "Airflow" + }, + "gid": { + "description": "Group of airflow user.", + "type": "integer", + "default": 0, + "x-docsSection": "Airflow" + }, + "airflowHome": { + "description": "Airflow home directory. Used for mount paths.", + "type": "string", + "default": "/opt/airflow", + "x-docsSection": "Airflow" + }, + "defaultAirflowRepository": { + "description": "Default airflow repository. Overrides all the specific images below.", + "type": "string", + "default": "apache/airflow", + "x-docsSection": "Common" + }, + "defaultAirflowTag": { + "description": "Default airflow tag to deploy.", + "type": "string", + "default": "2.7.1", + "x-docsSection": "Common" + }, + "defaultAirflowDigest": { + "description": "Default airflow digest to deploy. Overrides tag.", + "type": [ + "string", + "null" + ], + "default": null, + "x-docsSection": "Common" + }, + "airflowVersion": { + "description": "Airflow version (Used to make some decisions based on Airflow Version being deployed).", + "type": "string", + "default": "2.7.1", + "x-docsSection": "Common" + }, + "securityContext": { + "description": "Default pod security context definition (deprecated, use `securityContexts` instead). The values in this parameter will be used when `securityContext` is not defined for specific Pods", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.PodSecurityContext", + "default": {}, + "x-docsSection": "Kubernetes", + "examples": [ + { + "runAsUser": 50000, + "runAsGroup": 0, + "fsGroup": 0 + } + ] + }, + "securityContexts": { + "description": "Default security context definition. The values in this parameter will be used when `securityContexts` is not defined for specific Pods/Container.", + "type": "object", + "x-docsSection": "Kubernetes", + "properties": { + "pod": { + "description": "Default pod security context definition. The values in this parameter will be used when `securityContexts` is not defined for specific Pods.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.PodSecurityContext", + "default": {}, + "x-docsSection": "Kubernetes", + "examples": [ + { + "runAsUser": 50000, + "runAsGroup": 0, + "fsGroup": 0 + } + ] + }, + "container": { + "description": "Default container security context definition. The values in this parameter will be used when `securityContexts` is not defined for specific containers", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.SecurityContext", + "default": {}, + "x-docsSection": "Kubernetes", + "examples": [ + { + "allowPrivilegeEscalation": false + } + ] + } + } + }, + "containerLifecycleHooks": { + "description": "Default Container Lifecycle Hooks definition. The values in this parameter will be used when `containerLifecycleHooks` is not defined for specific containers.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.Lifecycle", + "default": {}, + "x-docsSection": "Kubernetes", + "examples": [ + { + "postStart": { + "exec": { + "command": [ + "/bin/sh", + "-c", + "echo postStart handler > /usr/share/message" + ] + } + }, + "preStop": { + "exec": { + "command": [ + "/bin/sh", + "-c", + "echo preStop handler > /usr/share/message" + ] + } + } + } + ] + }, + "nodeSelector": { + "description": "Select certain nodes for all pods.", + "type": "object", + "default": {}, + "x-docsSection": "Kubernetes", + "additionalProperties": { + "type": "string" + } + }, + "affinity": { + "description": "Specify scheduling constraints for all pods.", + "type": "object", + "default": {}, + "x-docsSection": "Kubernetes", + "$ref": "#/definitions/io.k8s.api.core.v1.Affinity" + }, + "tolerations": { + "description": "Specify Tolerations for all pods.", + "type": "array", + "default": [], + "x-docsSection": "Kubernetes", + "items": { + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.Toleration" + } + }, + "topologySpreadConstraints": { + "description": "Specify topology spread constraints for all pods.", + "type": "array", + "default": [], + "x-docsSection": "Kubernetes", + "items": { + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.TopologySpreadConstraint" + } + }, + "schedulerName": { + "description": "Specify kube scheduler name for Pods.", + "type": [ + "string", + "null" + ], + "default": null, + "x-docsSection": "Common" + }, + "labels": { + "description": "Add common labels to all objects and pods defined in this chart.", + "type": "object", + "default": {}, + "x-docsSection": "Kubernetes", + "additionalProperties": { + "type": "string" + } + }, + "ingress": { + "description": "Ingress configuration.", + "type": "object", + "x-docsSection": "Ingress", + "properties": { + "enabled": { + "description": "Enable all ingress resources (deprecated - use ingress.web.enabled and ingress.flower.enabled).", + "type": [ + "boolean", + "null" + ], + "default": null + }, + "web": { + "description": "Configuration for the Ingress of the web Service.", + "type": "object", + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Enable web ingress resource.", + "type": "boolean", + "default": false + }, + "annotations": { + "description": "Annotations for the web Ingress.", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + }, + "path": { + "description": "The path for the web Ingress.", + "type": "string", + "default": "/" + }, + "pathType": { + "description": "The pathType for the web Ingress (required for Kubernetes 1.19 and above).", + "type": "string", + "default": "ImplementationSpecific" + }, + "host": { + "description": "The hostname for the web Ingress. (Deprecated - renamed to `ingress.web.hosts`)", + "type": "string", + "default": "" + }, + "hosts": { + "description": "The hostnames or hosts configuration for the web Ingress.", + "type": "array", + "default": [], + "items": { + "oneOf": [ + { + "type": "object", + "additionalProperties": false, + "properties": { + "name": { + "description": "The hostname for the web Ingress.", + "type": "string", + "default": "" + }, + "tls": { + "description": "Configuration for web Ingress TLS.", + "type": "object", + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Enable TLS termination for the web Ingress.", + "type": "boolean", + "default": false + }, + "secretName": { + "description": "The name of a pre-created Secret containing a TLS private key and certificate.", + "type": "string", + "default": "" + } + } + } + }, + "required": [ + "name" + ] + }, + { + "type": "string", + "default": "", + "$comment": "Deprecated by object above" + } + ] + } + }, + "ingressClassName": { + "description": "The Ingress Class for the web Ingress.", + "type": "string", + "default": "" + }, + "tls": { + "description": "Configuration for web Ingress TLS. (Deprecated - renamed to `ingress.web.hosts[*].tls`)", + "type": "object", + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Enable TLS termination for the web Ingress.", + "type": "boolean", + "default": false + }, + "secretName": { + "description": "The name of a pre-created Secret containing a TLS private key and certificate.", + "type": "string", + "default": "" + } + } + }, + "precedingPaths": { + "description": "HTTP paths to add to the web Ingress before the default path.", + "type": "array", + "default": [] + }, + "succeedingPaths": { + "description": "HTTP paths to add to the web Ingress after the default path.", + "type": "array", + "default": [] + } + } + }, + "flower": { + "description": "Configuration for the Ingress of the flower Service.", + "type": "object", + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Enable flower ingress resource.", + "type": "boolean", + "default": false + }, + "annotations": { + "description": "Annotations for the flower Ingress.", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + }, + "path": { + "description": "The path for the flower Ingress.", + "type": "string", + "default": "/" + }, + "pathType": { + "description": "The pathType for the flower Ingress (required for Kubernetes 1.19 and above).", + "type": "string", + "default": "ImplementationSpecific" + }, + "host": { + "description": "The hostname for the flower Ingress. (Deprecated - renamed to `ingress.flower.hosts`)", + "type": "string", + "default": "" + }, + "hosts": { + "description": "The hostnames or hosts configuration for the flower Ingress.", + "type": "array", + "default": [], + "items": { + "oneOf": [ + { + "type": "object", + "additionalProperties": false, + "properties": { + "name": { + "description": "The hostname for the web Ingress.", + "type": "string", + "default": "" + }, + "tls": { + "description": "Configuration for web Ingress TLS.", + "type": "object", + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Enable TLS termination for the web Ingress.", + "type": "boolean", + "default": false + }, + "secretName": { + "description": "The name of a pre-created Secret containing a TLS private key and certificate.", + "type": "string", + "default": "" + } + } + } + }, + "required": [ + "name" + ] + }, + { + "type": "string", + "default": "", + "$comment": "Deprecated by object above" + } + ] + } + }, + "ingressClassName": { + "description": "The Ingress Class for the flower Ingress.", + "type": "string", + "default": "" + }, + "tls": { + "description": "Configuration for flower Ingress TLS. (Deprecated - renamed to `ingress.flower.hosts[*].tls`)", + "type": "object", + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Enable TLS termination for the flower Ingress.", + "type": "boolean", + "default": false + }, + "secretName": { + "description": "The name of a pre-created Secret containing a TLS private key and certificate.", + "type": "string", + "default": "" + } + } + } + } + } + } + }, + "networkPolicies": { + "description": "Network policy configuration.", + "type": "object", + "x-docsSection": "Kubernetes", + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Enabled network policies.", + "type": "boolean", + "default": false + } + } + }, + "airflowPodAnnotations": { + "description": "Extra annotations to apply to all Airflow pods.", + "type": "object", + "default": {}, + "x-docsSection": "Kubernetes", + "additionalProperties": { + "type": "string" + } + }, + "airflowConfigAnnotations": { + "description": "Extra annotations to apply to the main Airflow configmap.", + "type": "object", + "default": {}, + "x-docsSection": "Kubernetes", + "additionalProperties": { + "type": "string" + } + }, + "airflowLocalSettings": { + "description": "`airflow_local_settings` file as a string (can be templated).", + "type": [ + "string", + "null" + ], + "x-docsSection": "Common", + "default": "See values.yaml" + }, + "rbac": { + "description": "Enable RBAC (default on most clusters these days).", + "type": "object", + "x-docsSection": "Kubernetes", + "properties": { + "create": { + "description": "Specifies whether RBAC resources should be created.", + "type": "boolean", + "default": true + }, + "createSCCRoleBinding": { + "description": "Specifies whether SCC RoleBinding resource should be created (refer to :doc:`Production Guide `).", + "type": "boolean", + "default": false + } + } + }, + "executor": { + "description": "Airflow executor.", + "type": "string", + "x-docsSection": "Common", + "default": "CeleryExecutor", + "enum": [ + "LocalExecutor", + "LocalKubernetesExecutor", + "CeleryExecutor", + "KubernetesExecutor", + "CeleryKubernetesExecutor" + ] + }, + "allowPodLaunching": { + "description": "Whether various Airflow components launch pods.", + "type": "boolean", + "x-docsSection": "Airflow", + "default": true + }, + "images": { + "description": "Images.", + "type": "object", + "x-docsSection": "Images", + "additionalProperties": false, + "properties": { + "airflow": { + "description": "Configuration of the airflow image.", + "type": "object", + "additionalProperties": false, + "properties": { + "repository": { + "description": "The airflow image repository.", + "type": [ + "string", + "null" + ], + "default": null + }, + "tag": { + "description": "The airflow image tag.", + "type": [ + "string", + "null" + ], + "default": null + }, + "digest": { + "description": "The airflow image digest. If set, it will override the tag.", + "type": [ + "string", + "null" + ], + "default": null + }, + "pullPolicy": { + "description": "The airflow image pull policy.", + "type": "string", + "enum": [ + "Always", + "Never", + "IfNotPresent" + ], + "default": "IfNotPresent" + } + } + }, + "useDefaultImageForMigration": { + "description": "To avoid images with user code for running and waiting for DB migrations set this to ``true``. ", + "type": "boolean", + "x-docsSection": "Images", + "default": false + }, + "migrationsWaitTimeout": { + "description": "The time (in seconds) to wait for the DB migrations to complete.", + "type": "number", + "x-docsSection": "Images", + "default": 60 + }, + "pod_template": { + "description": "Configuration of the pod_template image.", + "type": "object", + "additionalProperties": false, + "properties": { + "repository": { + "description": "The pod_template image repository. If ``config.kubernetes.worker_container_repository`` is set, k8s executor will use config value instead.", + "type": [ + "string", + "null" + ], + "default": null + }, + "tag": { + "description": "The pod_template image tag. If ``config.kubernetes.worker_container_tag`` is set, k8s executor will use config value instead.", + "type": [ + "string", + "null" + ], + "default": null + }, + "pullPolicy": { + "description": "The pod_template image pull policy.", + "type": "string", + "enum": [ + "Always", + "Never", + "IfNotPresent" + ], + "default": "IfNotPresent" + } + } + }, + "flower": { + "description": "Configuration of the flower image.", + "type": "object", + "additionalProperties": false, + "properties": { + "repository": { + "description": "The flower image repository.", + "type": [ + "string", + "null" + ], + "default": null + }, + "tag": { + "description": "The flower image tag.", + "type": [ + "string", + "null" + ], + "default": null + }, + "pullPolicy": { + "description": "The flower image pull policy.", + "type": "string", + "enum": [ + "Always", + "Never", + "IfNotPresent" + ], + "default": "IfNotPresent" + } + } + }, + "statsd": { + "description": "Configuration of the StatsD image.", + "type": "object", + "additionalProperties": false, + "properties": { + "repository": { + "description": "The StatsD image repository.", + "type": "string", + "default": "quay.io/prometheus/statsd-exporter" + }, + "tag": { + "description": "The StatsD image tag.", + "type": "string", + "default": "v0.22.8" + }, + "pullPolicy": { + "description": "The StatsD image pull policy.", + "type": "string", + "enum": [ + "Always", + "Never", + "IfNotPresent" + ], + "default": "IfNotPresent" + } + } + }, + "redis": { + "description": "Configuration of the redis image.", + "type": "object", + "additionalProperties": false, + "properties": { + "repository": { + "description": "The redis image repository.", + "type": "string", + "default": "redis" + }, + "tag": { + "description": "The redis image tag.", + "type": "string", + "default": "7-bullseye" + }, + "pullPolicy": { + "description": "The redis image pull policy.", + "type": "string", + "enum": [ + "Always", + "Never", + "IfNotPresent" + ], + "default": "IfNotPresent" + } + } + }, + "pgbouncer": { + "description": "Configuration of the PgBouncer image.", + "type": "object", + "additionalProperties": false, + "properties": { + "repository": { + "description": "The PgBouncer image repository.", + "type": "string", + "default": "apache/airflow" + }, + "tag": { + "description": "The PgBouncer image tag.", + "type": "string", + "default": "airflow-pgbouncer-2023.02.24-1.16.1" + }, + "pullPolicy": { + "description": "The PgBouncer image pull policy.", + "type": "string", + "enum": [ + "Always", + "Never", + "IfNotPresent" + ], + "default": "IfNotPresent" + } + } + }, + "pgbouncerExporter": { + "description": "Configuration of the PgBouncer exporter image.", + "type": "object", + "additionalProperties": false, + "properties": { + "repository": { + "description": "The PgBouncer exporter image repository.", + "type": "string", + "default": "apache/airflow" + }, + "tag": { + "description": "The PgBouncer exporter image tag.", + "type": "string", + "default": "airflow-pgbouncer-exporter-2023.02.21-0.14.0" + }, + "pullPolicy": { + "description": "The PgBouncer exporter image pull policy.", + "type": "string", + "enum": [ + "Always", + "Never", + "IfNotPresent" + ], + "default": "IfNotPresent" + } + } + }, + "gitSync": { + "description": "Configuration of the gitSync image.", + "type": "object", + "additionalProperties": false, + "properties": { + "repository": { + "description": "The gitSync image repository.", + "type": "string", + "default": "registry.k8s.io/git-sync/git-sync" + }, + "tag": { + "description": "The gitSync image tag.", + "type": "string", + "default": "v3.6.9" + }, + "pullPolicy": { + "description": "The gitSync image pull policy.", + "type": "string", + "enum": [ + "Always", + "Never", + "IfNotPresent" + ], + "default": "IfNotPresent" + } + } + } + } + }, + "env": { + "description": "Environment variables for all Airflow containers.", + "type": "array", + "x-docsSection": "Airflow", + "default": [], + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": [ + "name", + "value" + ], + "additionalProperties": false + }, + "examples": [ + { + "name": "MYENVVAR", + "value": "something_fun" + } + ] + }, + "volumes": { + "description": "Volumes for all Airflow containers.", + "x-docsSection": "Airflow", + "type": "array", + "default": [], + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.Volume" + } + }, + "volumeMounts": { + "description": "VolumeMounts for all Airflow containers.", + "x-docsSection": "Airflow", + "type": "array", + "default": [], + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.VolumeMount" + } + }, + "secret": { + "description": "Secrets for all Airflow containers.", + "type": "array", + "x-docsSection": "Airflow", + "default": [], + "items": { + "type": "object", + "properties": { + "envName": { + "description": "The name of the environment variable under which the secret will be available", + "type": "string" + }, + "secretName": { + "description": "The name of the Kubernetes secret that will be read", + "type": "string" + }, + "secretKey": { + "description": "The key of the Kubernetes secret", + "type": "string" + } + }, + "additionalProperties": false, + "required": [ + "envName", + "secretName" + ] + }, + "examples": [ + { + "envName": "SecretEnvVar", + "secretName": "somesecret", + "secretKey": "somekey" + } + ] + }, + "enableBuiltInSecretEnvVars": { + "description": "Uses built-in secret values set as environment variables passed to Airflow. You should supply corresponding environment variables as ``extraEnv`` variables if you disable them here.", + "type": "object", + "additionalProperties": false, + "x-docsSection": "Airflow", + "properties": { + "AIRFLOW__CORE__FERNET_KEY": { + "description": "Enable ``AIRFLOW__CORE__FERNET_KEY`` variable to be read from the Fernet key Secret", + "type": "boolean", + "default": true + }, + "AIRFLOW__CORE__SQL_ALCHEMY_CONN": { + "description": "Enable ``AIRFLOW__CORE__SQL_ALCHEMY_CONN`` variable to be read from the Metadata Secret", + "type": "boolean", + "default": true + }, + "AIRFLOW__DATABASE__SQL_ALCHEMY_CONN": { + "description": "Enable ``AIRFLOW__DATABASE__SQL_ALCHEMY_CONN`` variable to be read from the Metadata Secret", + "type": "boolean", + "default": true + }, + "AIRFLOW_CONN_AIRFLOW_DB": { + "description": "Enable ``AIRFLOW_CONN_AIRFLOW_DB`` variable to be read from the Metadata Secret", + "type": "boolean", + "default": true + }, + "AIRFLOW__WEBSERVER__SECRET_KEY": { + "description": "Enable ``AIRFLOW__WEBSERVER__SECRET_KEY`` variable to be read from the Webserver Secret Key Secret", + "type": "boolean", + "default": true + }, + "AIRFLOW__CELERY__CELERY_RESULT_BACKEND": { + "description": "Enable ``AIRFLOW__CELERY__CELERY_RESULT_BACKEND`` variable to be read from the Celery Result Backend Secret - Airflow 1.10.* variant", + "type": "boolean", + "default": true + }, + "AIRFLOW__CELERY__RESULT_BACKEND": { + "description": "Enable ``AIRFLOW__CELERY__RESULT_BACKEND`` variable to be read from the Celery Result Backend Secret", + "type": "boolean", + "default": true + }, + "AIRFLOW__CELERY__BROKER_URL": { + "description": "Enable ``AIRFLOW__CELERY__BROKER_URL`` variable to be read from the Celery Broker URL Secret", + "type": "boolean", + "default": true + }, + "AIRFLOW__ELASTICSEARCH__HOST": { + "description": "Enable ``AIRFLOW__ELASTICSEARCH__HOST`` variable to be read from the Elasticsearch Host Secret", + "type": "boolean", + "default": true + }, + "AIRFLOW__ELASTICSEARCH__ELASTICSEARCH_HOST": { + "description": "Enable ``AIRFLOW__ELASTICSEARCH__ELASTICSEARCH_HOST`` variable to be read from the Elasticsearch Host Secret - Airflow <1.10.4 variant", + "type": "boolean", + "default": true + } + } + }, + "extraEnv": { + "description": "Extra env 'items' that will be added to the definition of Airflow containers; a string is expected (can be templated).", + "type": [ + "null", + "string" + ], + "x-docsSection": "Airflow", + "default": null, + "examples": [ + "- name: AIRFLOW__CORE__LOAD_EXAMPLES\n value: True" + ] + }, + "extraEnvFrom": { + "description": "Extra envFrom 'items' that will be added to the definition of Airflow containers; a string is expected (can be templated).", + "type": [ + "null", + "string" + ], + "x-docsSection": "Airflow", + "default": null, + "examples": [ + "- secretRef:\n name: '{{ .Release.Name }}-airflow-connections'", + "- configMapRef:\n name: '{{ .Release.Name }}-airflow-variables'" + ] + }, + "priorityClasses": { + "description": "Priority Classes created by helm charts", + "type": "array", + "x-docsSection": "Kubernetes", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "preemptionPolicy": { + "type": "string" + }, + "value": { + "type": "integer" + } + }, + "required": [ + "value" + ], + "additionalProperties": false + }, + "default": [], + "examples": [ + { + "name": "class1", + "preemptionPolicy": "PreemptLowerPriority", + "value": 10000 + }, + { + "name": "class2", + "preemptionPolicy": "Never", + "value": 100000 + } + ] + }, + "extraSecrets": { + "description": "Extra secrets that will be managed by the chart.", + "type": "object", + "x-docsSection": "Kubernetes", + "default": {}, + "additionalProperties": { + "description": "Name of the secret (can be templated).", + "type": "object", + "minProperties": 1, + "additionalProperties": false, + "properties": { + "type": { + "description": "Type **as string** of secret E.G. Opaque, kubernetes.io/dockerconfigjson, etc.", + "type": "string" + }, + "labels": { + "description": "Labels for the secret", + "type": "object", + "default": null, + "additionalProperties": { + "type": "string" + } + }, + "annotations": { + "description": "Annotations for the secret", + "type": "object", + "default": null, + "additionalProperties": { + "type": "string" + } + }, + "data": { + "description": "Content **as string** for the 'data' item of the secret (can be templated)", + "type": "string" + }, + "stringData": { + "description": "Content **as string** for the 'stringData' item of the secret (can be templated)", + "type": "string" + } + } + }, + "examples": [ + { + "{{ .Release.Name }}-airflow-connections": { + "data": "AIRFLOW_CONN_GCP: 'base64_encoded_gcp_conn_string'\nAIRFLOW_CONN_AWS: 'base64_encoded_aws_conn_string'", + "stringData": "AIRFLOW_CONN_OTHER: 'other_conn'" + } + } + ] + }, + "extraConfigMaps": { + "description": "Extra ConfigMaps that will be managed by the chart.", + "type": "object", + "x-docsSection": "Kubernetes", + "default": {}, + "additionalProperties": { + "description": "Name of the configMap (can be templated).", + "type": "object", + "minProperties": 1, + "additionalProperties": false, + "properties": { + "labels": { + "description": "Labels for the configmap", + "type": "object", + "default": null, + "additionalProperties": { + "type": "string" + } + }, + "annotations": { + "description": "Annotations for the configmap", + "type": "object", + "default": null, + "additionalProperties": { + "type": "string" + } + }, + "data": { + "description": "Content **as string** for the 'data' item of the configmap (can be templated)", + "type": "string" + } + } + }, + "examples": [ + { + "{{ .Release.Name }}-airflow-variables": { + "data": "AIRFLOW_VAR_HELLO_MESSAGE: 'Hi!'\nAIRFLOW_VAR_KUBERNETES_NAMESPACE: '{{ .Release.Namespace }}'" + } + } + ] + }, + "data": { + "description": "Airflow database & redis configuration.", + "type": "object", + "x-docsSection": "Database", + "additionalProperties": false, + "properties": { + "metadataSecretName": { + "description": "Metadata connection string secret.", + "type": [ + "string", + "null" + ], + "default": null + }, + "resultBackendSecretName": { + "description": "Result backend connection string secret.", + "type": [ + "string", + "null" + ], + "default": null + }, + "brokerUrlSecretName": { + "description": "Redis broker URL secret.", + "type": [ + "string", + "null" + ], + "x-docsSection": "Redis", + "default": null + }, + "metadataConnection": { + "description": "Metadata connection configuration.", + "type": "object", + "additionalProperties": false, + "properties": { + "user": { + "description": "The database user.", + "type": "string", + "default": "postgres" + }, + "pass": { + "description": "The user's password.", + "type": "string", + "default": "postgres" + }, + "protocol": { + "description": "The database protocol.", + "type": "string", + "default": "postgresql" + }, + "host": { + "description": "The database host.", + "type": [ + "string", + "null" + ], + "default": null + }, + "port": { + "description": "The database port.", + "type": "integer", + "default": 5432 + }, + "db": { + "description": "The name of the database.", + "type": "string", + "default": "postgres" + }, + "sslmode": { + "description": "The database SSL parameter.", + "type": "string", + "default": "disable" + } + } + }, + "resultBackendConnection": { + "description": "Result backend connection configuration.", + "type": [ + "object", + "null" + ], + "default": null, + "additionalProperties": false, + "properties": { + "user": { + "description": "The database user.", + "type": "string", + "default": null + }, + "pass": { + "description": "The database password.", + "type": "string", + "default": null + }, + "protocol": { + "description": "The database protocol.", + "type": "string", + "default": null + }, + "host": { + "description": "The database host.", + "type": [ + "string", + "null" + ], + "default": null + }, + "port": { + "description": "The database port.", + "type": "integer", + "default": null + }, + "db": { + "description": "The name of the database.", + "type": "string", + "default": null + }, + "sslmode": { + "description": "The database SSL parameter.", + "type": "string", + "default": null + } + }, + "required": [ + "user", + "pass", + "protocol", + "host", + "port", + "db", + "sslmode" + ] + }, + "brokerUrl": { + "description": "Direct url to the redis broker (when using an external redis instance) (can only be set during install, not upgrade).", + "type": [ + "string", + "null" + ], + "x-docsSection": "Redis", + "default": null + } + } + }, + "fernetKey": { + "description": "The Fernet key used to encrypt passwords (can only be set during install, not upgrade).", + "type": [ + "string", + "null" + ], + "x-docsSection": "Common", + "default": null + }, + "fernetKeySecretName": { + "description": "The Fernet key secret name.", + "type": [ + "string", + "null" + ], + "x-docsSection": "Airflow", + "default": null + }, + "webserverSecretKey": { + "description": "The Flask secret key for Airflow Webserver to encrypt browser session.", + "type": [ + "string", + "null" + ], + "x-docsSection": "Common", + "default": null + }, + "webserverSecretKeySecretName": { + "description": "The Secret name containing Flask secret_key for the Webserver.", + "type": [ + "string", + "null" + ], + "x-docsSection": "Airflow", + "default": null + }, + "kerberos": { + "description": "Kerberos configurations for airflow", + "type": "object", + "x-docsSection": "Kerberos", + "properties": { + "enabled": { + "description": "Enable kerberos.", + "type": "boolean", + "default": false + }, + "ccacheMountPath": { + "description": "Path to mount shared volume for kerberos credentials cache.", + "type": "string", + "default": "/var/kerberos-ccache" + }, + "ccacheFileName": { + "description": "Name for kerberos credentials cache file.", + "type": "string", + "default": "cache" + }, + "configPath": { + "description": "Path to mount krb5.conf kerberos configuration file.", + "type": "string", + "default": "/etc/krb5.conf" + }, + "keytabBase64Content": { + "description": "Kerberos keytab base64 encoded content.", + "type": [ + "string", + "null" + ], + "default": null + }, + "keytabPath": { + "description": "Path to mount the keytab for refreshing credentials in the kerberos sidecar.", + "type": "string", + "default": "/etc/airflow.keytab" + }, + "principal": { + "description": "Principal to use when refreshing kerberos credentials.", + "type": "string", + "default": "airflow@FOO.COM" + }, + "reinitFrequency": { + "description": "How often (in seconds) airflow kerberos will reinitialize the credentials cache.", + "type": "integer", + "default": 3600 + }, + "config": { + "description": "Contents of krb5.conf.", + "type": "string", + "default": "See values.yaml" + } + } + }, + "workers": { + "description": "Airflow Worker configuration.", + "type": "object", + "x-docsSection": "Workers", + "additionalProperties": false, + "properties": { + "replicas": { + "description": "Number of Airflow Celery workers in StatefulSet.", + "type": "integer", + "default": 1 + }, + "revisionHistoryLimit": { + "description": "Number of old replicasets to retain.", + "type": [ + "integer", + "null" + ], + "default": null, + "x-docsSection": null + }, + "command": { + "description": "Command to use when running Airflow workers (templated).", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + }, + "default": null + }, + "args": { + "description": "Args to use when running Airflow workers (templated).", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + }, + "default": [ + "bash", + "-c", + "exec \\\nairflow {{ semverCompare \">=2.0.0\" .Values.airflowVersion | ternary \"celery worker\" \"worker\" }}" + ] + }, + "livenessProbe": { + "description": "Liveness probe configuration for worker containers.", + "type": "object", + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Enable liveness probe for celery workers.", + "type": "boolean", + "default": true + }, + "initialDelaySeconds": { + "description": "Number of seconds after the container has started before liveness probes are initiated.", + "type": "integer", + "default": 10 + }, + "timeoutSeconds": { + "description": "Number of seconds after which the probe times out. Minimum value is 1 seconds.", + "type": "integer", + "default": 20 + }, + "failureThreshold": { + "description": "Minimum consecutive failures for the probe to be considered failed after having succeeded. Minimum value is 1.", + "type": "integer", + "default": 5 + }, + "periodSeconds": { + "description": "How often (in seconds) to perform the probe. Minimum value is 1.", + "type": "integer", + "default": 60 + }, + "command": { + "description": "Command for livenessProbe", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + } + } + }, + "updateStrategy": { + "description": "Specifies the strategy used to replace old Pods by new ones when deployed as a StatefulSet.", + "type": [ + "null", + "object" + ], + "default": null + }, + "strategy": { + "description": "Specifies the strategy used to replace old Pods by new ones when deployed as a Deployment.", + "type": [ + "null", + "object" + ], + "default": { + "rollingUpdate": { + "maxSurge": "100%", + "maxUnavailable": "50%" + } + } + }, + "serviceAccount": { + "description": "Create ServiceAccount.", + "type": "object", + "properties": { + "automountServiceAccountToken": { + "description": "Specifies if ServiceAccount's API credentials should be mounted onto Pods", + "type": "boolean", + "default": true + }, + "create": { + "description": "Specifies whether a ServiceAccount should be created.", + "type": "boolean", + "default": true + }, + "name": { + "description": "The name of the ServiceAccount to use. If not set and create is true, a name is generated using the release name.", + "type": [ + "string", + "null" + ], + "default": null + }, + "annotations": { + "description": "Annotations to add to the worker Kubernetes ServiceAccount.", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + } + } + }, + "keda": { + "description": "KEDA configuration.", + "type": "object", + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Allow KEDA autoscaling.", + "type": "boolean", + "default": false + }, + "namespaceLabels": { + "description": "Labels used in `matchLabels` for namespace in the PgBouncer NetworkPolicy.", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + }, + "pollingInterval": { + "description": "How often KEDA polls the airflow DB to report new scale requests to the HPA.", + "type": "integer", + "default": 5 + }, + "cooldownPeriod": { + "description": "How many seconds KEDA will wait before scaling to zero.", + "type": "integer", + "default": 30 + }, + "minReplicaCount": { + "description": "Minimum number of workers created by KEDA.", + "type": "integer", + "default": 0 + }, + "maxReplicaCount": { + "description": "Maximum number of workers created by KEDA.", + "type": "integer", + "default": 10 + }, + "advanced": { + "description": "Advanced KEDA configuration.", + "type": "object", + "default": {}, + "additionalProperties": false, + "properties": { + "horizontalPodAutoscalerConfig": { + "description": "HorizontalPodAutoscalerConfig specifies horizontal scale config.", + "type": "object", + "default": {}, + "properties": { + "behavior": { + "description": "HorizontalPodAutoscalerBehavior configures the scaling behavior of the target.", + "type": "object", + "default": {}, + "$ref": "#/definitions/io.k8s.api.autoscaling.v2beta2.HorizontalPodAutoscalerBehavior" + } + } + } + } + }, + "query": { + "description": "Query to use for KEDA autoscaling. Must return a single integer.", + "type": "string", + "default": "SELECT ceil(COUNT(*)::decimal / {{ .Values.config.celery.worker_concurrency }}) FROM task_instance WHERE (state='running' OR state='queued') {{- if eq .Values.executor \"CeleryKubernetesExecutor\" }} AND queue != '{{ .Values.config.celery_kubernetes_executor.kubernetes_queue }}' {{- end }}" + }, + "usePgbouncer": { + "description": "Weather to use PGBouncer to connect to the database or not when it is enabled. This configuration will be ignored if PGBouncer is not enabled.", + "type": "boolean", + "default": true + } + } + }, + "persistence": { + "description": "Persistence configuration.", + "type": "object", + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Enable persistent volumes.", + "type": "boolean", + "default": true + }, + "size": { + "description": "Volume size for worker StatefulSet.", + "type": "string", + "default": "100Gi" + }, + "storageClassName": { + "description": "If using a custom StorageClass, pass name ref to all StatefulSets here.", + "type": [ + "string", + "null" + ], + "default": null + }, + "fixPermissions": { + "description": "Execute init container to chown log directory. This is currently only needed in kind, due to usage of local-path provisioner.", + "type": "boolean", + "default": false + }, + "annotations": { + "description": "Annotations to add to worker volumes.", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + }, + "containerLifecycleHooks": { + "description": "Container Lifecycle Hooks definition for the persistence. If not set, the values from global `containerLifecycleHooks` will be used.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.Lifecycle", + "default": {}, + "x-docsSection": "Kubernetes", + "examples": [ + { + "postStart": { + "exec": { + "command": [ + "/bin/sh", + "-c", + "echo postStart handler > /usr/share/message" + ] + } + }, + "preStop": { + "exec": { + "command": [ + "/bin/sh", + "-c", + "echo preStop handler > /usr/share/message" + ] + } + } + } + ] + }, + "securityContexts": { + "description": "Security context definition for the persistence. If not set, the values from global `securityContexts` will be used.", + "type": "object", + "x-docsSection": "Kubernetes", + "properties": { + "container": { + "description": "Container security context definition for the persistence.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.SecurityContext", + "default": {}, + "x-docsSection": "Kubernetes", + "examples": [ + { + "allowPrivilegeEscalation": false, + "capabilities": { + "drop": [ + "ALL" + ] + } + } + ] + } + } + } + } + }, + "kerberosSidecar": { + "description": "Kerberos sidecar for Airflow workers.", + "type": "object", + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Enable Kerberos sidecar for the worker.", + "type": "boolean", + "default": false + }, + "resources": { + "description": "Resources on workers kerberos sidecar", + "type": "object", + "default": {}, + "examples": [ + { + "limits": { + "cpu": "100m", + "memory": "128Mi" + }, + "requests": { + "cpu": "100m", + "memory": "128Mi" + } + } + ], + "$ref": "#/definitions/io.k8s.api.core.v1.ResourceRequirements" + }, + "containerLifecycleHooks": { + "description": "Container Lifecycle Hooks definition for the kerberos sidecar. If not set, the values from global `containerLifecycleHooks` will be used.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.Lifecycle", + "default": {}, + "x-docsSection": "Kubernetes", + "examples": [ + { + "postStart": { + "exec": { + "command": [ + "/bin/sh", + "-c", + "echo postStart handler > /usr/share/message" + ] + } + }, + "preStop": { + "exec": { + "command": [ + "/bin/sh", + "-c", + "echo preStop handler > /usr/share/message" + ] + } + } + } + ] + }, + "securityContexts": { + "description": "Security context definition for the kerberos sidecar. If not set, the values from global `securityContexts` will be used.", + "type": "object", + "x-docsSection": "Kubernetes", + "properties": { + "container": { + "description": "Container security context definition for the kerberos sidecar.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.SecurityContext", + "default": {}, + "x-docsSection": "Kubernetes", + "examples": [ + { + "allowPrivilegeEscalation": false, + "capabilities": { + "drop": [ + "ALL" + ] + } + } + ] + } + } + } + } + }, + "resources": { + "description": "Resources on workers", + "type": "object", + "default": {}, + "examples": [ + { + "limits": { + "cpu": "100m", + "memory": "128Mi" + }, + "requests": { + "cpu": "100m", + "memory": "128Mi" + } + } + ], + "$ref": "#/definitions/io.k8s.api.core.v1.ResourceRequirements" + }, + "terminationGracePeriodSeconds": { + "description": "Grace period for tasks to finish after SIGTERM is sent from Kubernetes.", + "type": "integer", + "default": 600 + }, + "safeToEvict": { + "description": "This setting tells Kubernetes that it's ok to evict when it wants to scale a node down.", + "type": "boolean", + "default": true + }, + "extraContainers": { + "description": "Launch additional containers into workers. Note, if used with KubernetesExecutor, you are responsible for signaling sidecars to exit when the main container finishes so Airflow can continue the worker shutdown process!", + "type": "array", + "default": [], + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.Container" + } + }, + "extraInitContainers": { + "description": "Add additional init containers into workers.", + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.Container" + }, + "type": "array", + "default": [] + }, + "extraVolumes": { + "description": "Mount additional volumes into workers.", + "type": "array", + "default": [], + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.Volume" + } + }, + "extraVolumeMounts": { + "description": "Mount additional volumes into workers.", + "type": "array", + "default": [], + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.VolumeMount" + } + }, + "nodeSelector": { + "description": "Select certain nodes for worker pods.", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + }, + "runtimeClassName": { + "description": "Specify runtime for worker pods.", + "type": [ + "string", + "null" + ], + "default": null + }, + "priorityClassName": { + "description": "Specify priority for worker pods.", + "type": [ + "string", + "null" + ], + "default": null + }, + "affinity": { + "description": "Specify scheduling constraints for worker pods.", + "type": "object", + "default": "See values.yaml", + "$ref": "#/definitions/io.k8s.api.core.v1.Affinity" + }, + "tolerations": { + "description": "Specify Tolerations for worker pods.", + "type": "array", + "default": [], + "items": { + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.Toleration" + } + }, + "topologySpreadConstraints": { + "description": "Specify topology spread constraints for worker pods.", + "type": "array", + "default": [], + "items": { + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.TopologySpreadConstraint" + } + }, + "hostAliases": { + "description": "Specify HostAliases for workers.", + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.HostAlias" + }, + "type": "array", + "default": [], + "examples": [ + { + "ip": "127.0.0.2", + "hostnames": [ + "test.hostname.one" + ] + }, + { + "ip": "127.0.0.3", + "hostnames": [ + "test.hostname.two" + ] + } + ] + }, + "annotations": { + "description": "Annotations to add to the worker deployment", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + }, + "podAnnotations": { + "description": "Annotations to add to the worker pods.", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + }, + "labels": { + "description": "Labels to add to the worker objects and pods.", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + }, + "logGroomerSidecar": { + "$ref": "#/definitions/logGroomerConfigType", + "description": "Configuration for worker log groomer sidecar" + }, + "securityContext": { + "description": "Security context for the worker pod (deprecated, use `securityContexts` instead). If not set, the values from `securityContext` will be used.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.PodSecurityContext", + "default": {}, + "examples": [ + { + "runAsUser": 50000, + "runAsGroup": 0, + "fsGroup": 0 + } + ] + }, + "containerLifecycleHooks": { + "description": "Container Lifecycle Hooks definition for the worker. If not set, the values from global `containerLifecycleHooks` will be used.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.Lifecycle", + "default": {}, + "x-docsSection": "Kubernetes", + "examples": [ + { + "postStart": { + "exec": { + "command": [ + "/bin/sh", + "-c", + "echo postStart handler > /usr/share/message" + ] + } + }, + "preStop": { + "exec": { + "command": [ + "/bin/sh", + "-c", + "echo preStop handler > /usr/share/message" + ] + } + } + } + ] + }, + "securityContexts": { + "description": "Security context definition for the workers. If not set, the values from global `securityContexts` will be used.", + "type": "object", + "x-docsSection": "Kubernetes", + "properties": { + "pod": { + "description": "Pod security context definition for the workers.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.PodSecurityContext", + "default": {}, + "x-docsSection": "Kubernetes", + "examples": [ + { + "runAsUser": 50000, + "runAsGroup": 0, + "fsGroup": 0 + } + ] + }, + "container": { + "description": "Container security context definition for the workers.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.SecurityContext", + "default": {}, + "x-docsSection": "Kubernetes", + "examples": [ + { + "allowPrivilegeEscalation": false, + "capabilities": { + "drop": [ + "ALL" + ] + } + } + ] + } + } + }, + "waitForMigrations": { + "description": "wait-for-airflow-migrations init container.", + "type": "object", + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Enable wait-for-airflow-migrations init container.", + "type": "boolean", + "default": true + }, + "env": { + "description": "Add additional env vars to wait-for-airflow-migrations init container.", + "type": "array", + "default": [], + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": [ + "name", + "value" + ], + "additionalProperties": false + } + }, + "containerLifecycleHooks": { + "description": "Container Lifecycle Hooks definition for the worker. If not set, the values from global `containerLifecycleHooks` will be used.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.Lifecycle", + "default": {}, + "x-docsSection": "Kubernetes", + "examples": [ + { + "postStart": { + "exec": { + "command": [ + "/bin/sh", + "-c", + "echo postStart handler > /usr/share/message" + ] + } + }, + "preStop": { + "exec": { + "command": [ + "/bin/sh", + "-c", + "echo preStop handler > /usr/share/message" + ] + } + } + } + ] + }, + "securityContexts": { + "description": "Security context definition for the wait for migrations. If not set, the values from global `securityContexts` will be used.", + "type": "object", + "x-docsSection": "Kubernetes", + "properties": { + "container": { + "description": "Container security context definition for the wait for migrations.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.SecurityContext", + "default": {}, + "x-docsSection": "Kubernetes", + "examples": [ + { + "allowPrivilegeEscalation": false, + "capabilities": { + "drop": [ + "ALL" + ] + } + } + ] + } + } + } + } + }, + "env": { + "description": "Add additional env vars to worker.", + "type": "array", + "default": [], + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": [ + "name", + "value" + ], + "additionalProperties": false + } + } + } + }, + "scheduler": { + "description": "Airflow scheduler settings.", + "type": "object", + "x-docsSection": "Scheduler", + "additionalProperties": false, + "properties": { + "hostAliases": { + "description": "HostAliases for the scheduler pod.", + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.HostAlias" + }, + "type": "array", + "default": [], + "examples": [ + { + "ip": "127.0.0.1", + "hostnames": [ + "foo.local" + ] + }, + { + "ip": "10.1.2.3", + "hostnames": [ + "foo.remote" + ] + } + ] + }, + "livenessProbe": { + "description": "Liveness probe configuration for scheduler container.", + "type": "object", + "additionalProperties": false, + "properties": { + "initialDelaySeconds": { + "description": "Number of seconds after the container has started before liveness probes are initiated.", + "type": "integer", + "default": 10 + }, + "timeoutSeconds": { + "description": "Number of seconds after which the probe times out. Minimum value is 1 seconds.", + "type": "integer", + "default": 20 + }, + "failureThreshold": { + "description": "Minimum consecutive failures for the probe to be considered failed after having succeeded. Minimum value is 1.", + "type": "integer", + "default": 5 + }, + "periodSeconds": { + "description": "How often (in seconds) to perform the probe. Minimum value is 1.", + "type": "integer", + "default": 60 + }, + "command": { + "description": "Command for livenessProbe", + "type": [ + "array", + "null" + ], + "items": { + "type": [ + "string", + "null" + ] + } + } + } + }, + "startupProbe": { + "description": "Startup probe configuration for scheduler container.", + "type": "object", + "additionalProperties": false, + "properties": { + "timeoutSeconds": { + "description": "Number of seconds after which the probe times out. Minimum value is 1 seconds.", + "type": "integer", + "default": 20 + }, + "failureThreshold": { + "description": "Minimum consecutive failures for the probe to be considered failed after having succeeded. Minimum value is 1.", + "type": "integer", + "default": 6 + }, + "periodSeconds": { + "description": "How often (in seconds) to perform the probe. Minimum value is 1.", + "type": "integer", + "default": 10 + }, + "command": { + "description": "Command for livenessProbe", + "type": [ + "array", + "null" + ], + "items": { + "type": [ + "string", + "null" + ] + } + } + } + }, + "replicas": { + "description": "Airflow 2.0 allows users to run multiple schedulers. This feature is only recommended for MySQL 8+ and PostgreSQL", + "type": "integer", + "default": 1 + }, + "revisionHistoryLimit": { + "description": "Number of old replicasets to retain.", + "type": [ + "integer", + "null" + ], + "default": null, + "x-docsSection": null + }, + "command": { + "description": "Command to use when running the Airflow scheduler (templated).", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + }, + "default": null + }, + "args": { + "description": "Args to use when running the Airflow scheduler (templated).", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + }, + "default": [ + "bash", + "-c", + "exec airflow scheduler" + ] + }, + "updateStrategy": { + "description": "Specifies the strategy used to replace old Pods by new ones when deployed as a StatefulSet (when using LocalExecutor and workers.persistence).", + "type": [ + "null", + "object" + ], + "default": null + }, + "strategy": { + "description": "Specifies the strategy used to replace old Pods by new ones when deployed as a Deployment (when not using LocalExecutor and workers.persistence).", + "type": [ + "null", + "object" + ], + "default": null + }, + "serviceAccount": { + "description": "Create ServiceAccount.", + "type": "object", + "properties": { + "automountServiceAccountToken": { + "description": "Specifies if ServiceAccount's API credentials should be mounted onto Pods", + "type": "boolean", + "default": true + }, + "create": { + "description": "Specifies whether a ServiceAccount should be created.", + "type": "boolean", + "default": true + }, + "name": { + "description": "The name of the ServiceAccount to use. If not set and create is true, a name is generated using the release name.", + "type": [ + "string", + "null" + ], + "default": null + }, + "annotations": { + "description": "Annotations to add to the scheduler Kubernetes ServiceAccount.", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + } + } + }, + "podDisruptionBudget": { + "description": "Scheduler pod disruption budget.", + "type": "object", + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Enable pod disruption budget.", + "type": "boolean", + "default": false + }, + "config": { + "description": "Disruption budget configuration.", + "type": "object", + "additionalProperties": false, + "properties": { + "maxUnavailable": { + "description": "Max unavailable pods for scheduler.", + "type": [ + "integer", + "string" + ], + "default": 1 + }, + "minAvailable": { + "description": "Min available pods for scheduler.", + "type": [ + "integer", + "string" + ], + "default": 1 + } + } + } + } + }, + "resources": { + "description": "Resources for scheduler pods.", + "type": "object", + "default": {}, + "examples": [ + { + "limits": { + "cpu": "100m", + "memory": "128Mi" + }, + "requests": { + "cpu": "100m", + "memory": "128Mi" + } + } + ], + "$ref": "#/definitions/io.k8s.api.core.v1.ResourceRequirements" + }, + "safeToEvict": { + "description": "This setting tells Kubernetes that its ok to evict when it wants to scale a node down.", + "type": "boolean", + "default": true + }, + "extraContainers": { + "description": "Launch additional containers into scheduler.", + "type": "array", + "default": [], + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.Container" + } + }, + "extraInitContainers": { + "description": "Add additional init containers into scheduler.", + "type": "array", + "default": [], + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.Container" + } + }, + "extraVolumes": { + "description": "Mount additional volumes into scheduler.", + "type": "array", + "default": [], + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.Volume" + } + }, + "extraVolumeMounts": { + "description": "Mount additional volumes into scheduler.", + "type": "array", + "default": [], + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.VolumeMount" + } + }, + "nodeSelector": { + "description": "Select certain nodes for scheduler pods.", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + }, + "priorityClassName": { + "description": "Specify priority for scheduler pods.", + "type": [ + "string", + "null" + ], + "default": null + }, + "affinity": { + "description": "Specify scheduling constraints for scheduler pods.", + "type": "object", + "default": "See values.yaml", + "$ref": "#/definitions/io.k8s.api.core.v1.Affinity" + }, + "tolerations": { + "description": "Specify Tolerations for scheduler pods.", + "type": "array", + "default": [], + "items": { + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.Toleration" + } + }, + "topologySpreadConstraints": { + "description": "Specify topology spread constraints for scheduler pods.", + "type": "array", + "default": [], + "items": { + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.TopologySpreadConstraint" + } + }, + "annotations": { + "description": "Annotations to add to the scheduler deployment", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + }, + "podAnnotations": { + "description": "Annotations to add to the scheduler pods.", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + }, + "labels": { + "description": "Labels to add to the scheduler objects and pods.", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + }, + "logGroomerSidecar": { + "$ref": "#/definitions/logGroomerConfigType", + "description": "Configuration for the schedulers log groomer sidecar." + }, + "securityContext": { + "description": "Security context for the scheduler pod (deprecated, use `securityContexts` instead). If not set, the values from `securityContext` will be used.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.PodSecurityContext", + "default": {}, + "examples": [ + { + "runAsUser": 50000, + "runAsGroup": 0, + "fsGroup": 0 + } + ] + }, + "containerLifecycleHooks": { + "description": "Container Lifecycle Hooks definition for the scheduler. If not set, the values from global `containerLifecycleHooks` will be used.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.Lifecycle", + "default": {}, + "x-docsSection": "Kubernetes", + "examples": [ + { + "postStart": { + "exec": { + "command": [ + "/bin/sh", + "-c", + "echo postStart handler > /usr/share/message" + ] + } + }, + "preStop": { + "exec": { + "command": [ + "/bin/sh", + "-c", + "echo preStop handler > /usr/share/message" + ] + } + } + } + ] + }, + "securityContexts": { + "description": "Security context definition for the scheduler. If not set, the values from global `securityContexts` will be used.", + "type": "object", + "x-docsSection": "Kubernetes", + "properties": { + "pod": { + "description": "Pod security context definition for the scheduler.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.PodSecurityContext", + "default": {}, + "x-docsSection": "Kubernetes", + "examples": [ + { + "runAsUser": 50000, + "runAsGroup": 0, + "fsGroup": 0 + } + ] + }, + "container": { + "description": "Container security context definition for the scheduler.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.SecurityContext", + "default": {}, + "x-docsSection": "Kubernetes", + "examples": [ + { + "allowPrivilegeEscalation": false, + "capabilities": { + "drop": [ + "ALL" + ] + } + } + ] + } + } + }, + "waitForMigrations": { + "description": "wait-for-airflow-migrations init container.", + "type": "object", + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Enable wait-for-airflow-migrations init container.", + "type": "boolean", + "default": true + }, + "env": { + "description": "Add additional env vars to wait-for-airflow-migrations init container.", + "type": "array", + "default": [], + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": [ + "name", + "value" + ], + "additionalProperties": false + } + }, + "containerLifecycleHooks": { + "description": "Container Lifecycle Hooks definition for the wait for migrations. If not set, the values from global `containerLifecycleHooks` will be used.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.Lifecycle", + "default": {}, + "x-docsSection": "Kubernetes", + "examples": [ + { + "postStart": { + "exec": { + "command": [ + "/bin/sh", + "-c", + "echo postStart handler > /usr/share/message" + ] + } + }, + "preStop": { + "exec": { + "command": [ + "/bin/sh", + "-c", + "echo preStop handler > /usr/share/message" + ] + } + } + } + ] + }, + "securityContexts": { + "description": "Security context definition for the wait for migrations. If not set, the values from global `securityContexts` will be used.", + "type": "object", + "x-docsSection": "Kubernetes", + "properties": { + "container": { + "description": "Container security context definition for the wait for migrations.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.SecurityContext", + "default": {}, + "x-docsSection": "Kubernetes", + "examples": [ + { + "allowPrivilegeEscalation": false, + "capabilities": { + "drop": [ + "ALL" + ] + } + } + ] + } + } + } + } + }, + "env": { + "description": "Add additional env vars to scheduler.", + "type": "array", + "default": [], + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": [ + "name", + "value" + ], + "additionalProperties": false + } + } + } + }, + "triggerer": { + "description": "Airflow triggerer settings.", + "type": "object", + "x-docsSection": "Triggerer", + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Enable triggerer", + "type": "boolean", + "default": true + }, + "livenessProbe": { + "description": "Liveness probe configuration for triggerer.", + "type": "object", + "additionalProperties": false, + "properties": { + "initialDelaySeconds": { + "description": "Number of seconds after the container has started before liveness probes are initiated.", + "type": "integer", + "default": 10 + }, + "timeoutSeconds": { + "description": "Number of seconds after which the probe times out. Minimum value is 1 seconds.", + "type": "integer", + "default": 20 + }, + "failureThreshold": { + "description": "Minimum consecutive failures for the probe to be considered failed after having succeeded. Minimum value is 1.", + "type": "integer", + "default": 5 + }, + "periodSeconds": { + "description": "How often (in seconds) to perform the probe. Minimum value is 1.", + "type": "integer", + "default": 60 + }, + "command": { + "description": "Command for livenessProbe", + "type": [ + "array", + "null" + ], + "items": { + "type": [ + "string", + "null" + ] + } + } + } + }, + "replicas": { + "description": "Number of triggerers to run.", + "type": "integer", + "default": 1 + }, + "revisionHistoryLimit": { + "description": "Number of old replicasets to retain.", + "type": [ + "integer", + "null" + ], + "default": null, + "x-docsSection": null + }, + "command": { + "description": "Command to use when running the Airflow triggerer (templated).", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + }, + "default": null + }, + "args": { + "description": "Args to use when running the Airflow triggerer (templated).", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + }, + "default": [ + "bash", + "-c", + "exec airflow triggerer" + ] + }, + "updateStrategy": { + "description": "Specifies the strategy used to replace old Pods by new ones when deployed as a StatefulSet.", + "type": [ + "null", + "object" + ], + "default": null + }, + "strategy": { + "description": "Specifies the strategy used to replace old Pods by new ones when deployed as a Deployment.", + "type": [ + "null", + "object" + ], + "$ref": "#/definitions/io.k8s.api.apps.v1.DeploymentStrategy", + "default": { + "rollingUpdate": { + "maxSurge": "100%", + "maxUnavailable": "50%" + } + } + }, + "serviceAccount": { + "description": "Create ServiceAccount.", + "type": "object", + "properties": { + "automountServiceAccountToken": { + "description": "Specifies if ServiceAccount's API credentials should be mounted onto Pods", + "type": "boolean", + "default": true + }, + "create": { + "description": "Specifies whether a ServiceAccount should be created.", + "type": "boolean", + "default": true + }, + "name": { + "description": "The name of the ServiceAccount to use. If not set and create is true, a name is generated using the release name.", + "type": [ + "string", + "null" + ], + "default": null + }, + "annotations": { + "description": "Annotations to add to the triggerer Kubernetes ServiceAccount.", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + } + } + }, + "persistence": { + "description": "Persistence configuration.", + "type": "object", + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Enable persistent volumes.", + "type": "boolean", + "default": true + }, + "size": { + "description": "Volume size for triggerer StatefulSet.", + "type": "string", + "default": "100Gi" + }, + "storageClassName": { + "description": "If using a custom StorageClass, pass name ref to all StatefulSets here.", + "type": [ + "string", + "null" + ], + "default": null + }, + "fixPermissions": { + "description": "Execute init container to chown log directory. This is currently only needed in kind, due to usage of local-path provisioner.", + "type": "boolean", + "default": false + }, + "annotations": { + "description": "Annotations to add to triggerer volumes.", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + } + } + }, + "resources": { + "description": "Resources for triggerer pods.", + "type": "object", + "default": {}, + "examples": [ + { + "limits": { + "cpu": "100m", + "memory": "128Mi" + }, + "requests": { + "cpu": "100m", + "memory": "128Mi" + } + } + ], + "$ref": "#/definitions/io.k8s.api.core.v1.ResourceRequirements" + }, + "safeToEvict": { + "description": "This setting tells Kubernetes that its ok to evict when it wants to scale a node down.", + "type": "boolean", + "default": true + }, + "extraContainers": { + "description": "Launch additional containers into triggerer.", + "type": "array", + "default": [], + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.Container" + } + }, + "extraInitContainers": { + "description": "Add additional init containers into triggerer.", + "type": "array", + "default": [], + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.Container" + } + }, + "extraVolumes": { + "description": "Mount additional volumes into triggerer.", + "type": "array", + "default": [], + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.Volume" + } + }, + "extraVolumeMounts": { + "description": "Mount additional volumes into triggerer.", + "type": "array", + "default": [], + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.VolumeMount" + } + }, + "nodeSelector": { + "description": "Select certain nodes for triggerer pods.", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + }, + "priorityClassName": { + "description": "Specify priority for triggerer pods.", + "type": [ + "string", + "null" + ], + "default": null + }, + "affinity": { + "description": "Specify scheduling constraints for triggerer pods.", + "type": "object", + "default": "See values.yaml", + "$ref": "#/definitions/io.k8s.api.core.v1.Affinity" + }, + "tolerations": { + "description": "Specify Tolerations for triggerer pods.", + "type": "array", + "default": [], + "items": { + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.Toleration" + } + }, + "topologySpreadConstraints": { + "description": "Specify topology spread constraints for triggerer pods.", + "type": "array", + "default": [], + "items": { + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.TopologySpreadConstraint" + } + }, + "terminationGracePeriodSeconds": { + "description": "Grace period for tasks to finish after SIGTERM is sent from Kubernetes.", + "type": "integer", + "default": 60 + }, + "annotations": { + "description": "Annotations to add to the triggerer deployment", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + }, + "podAnnotations": { + "description": "Annotations to add to the triggerer pods.", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + }, + "labels": { + "description": "Labels to add to the triggerer objects and pods.", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + }, + "securityContext": { + "description": "Security context for the triggerer pod (deprecated, use `securityContexts` instead). If not set, the values from `securityContext` will be used.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.PodSecurityContext", + "default": {}, + "examples": [ + { + "runAsUser": 50000, + "runAsGroup": 0, + "fsGroup": 0 + } + ] + }, + "containerLifecycleHooks": { + "description": "Container Lifecycle Hooks definition for the triggerer. If not set, the values from global `containerLifecycleHooks` will be used.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.Lifecycle", + "default": {}, + "x-docsSection": "Kubernetes", + "examples": [ + { + "postStart": { + "exec": { + "command": [ + "/bin/sh", + "-c", + "echo postStart handler > /usr/share/message" + ] + } + }, + "preStop": { + "exec": { + "command": [ + "/bin/sh", + "-c", + "echo preStop handler > /usr/share/message" + ] + } + } + } + ] + }, + "securityContexts": { + "description": "Security context definition for the triggerer. If not set, the values from global `securityContexts` will be used.", + "type": "object", + "x-docsSection": "Kubernetes", + "properties": { + "pod": { + "description": "Pod security context definition for the triggerer.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.PodSecurityContext", + "default": {}, + "x-docsSection": "Kubernetes", + "examples": [ + { + "runAsUser": 50000, + "runAsGroup": 0, + "fsGroup": 0 + } + ] + }, + "container": { + "description": "Container security context definition for the triggerer.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.SecurityContext", + "default": {}, + "x-docsSection": "Kubernetes", + "examples": [ + { + "allowPrivilegeEscalation": false, + "capabilities": { + "drop": [ + "ALL" + ] + } + } + ] + } + } + }, + "logGroomerSidecar": { + "$ref": "#/definitions/logGroomerConfigType", + "description": "Configuration for log groomer sidecar" + }, + "waitForMigrations": { + "description": "wait-for-airflow-migrations init container.", + "type": "object", + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Enable wait-for-airflow-migrations init container.", + "type": "boolean", + "default": true + }, + "env": { + "description": "Add additional env vars to wait-for-airflow-migrations init container.", + "type": "array", + "default": [], + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": [ + "name", + "value" + ], + "additionalProperties": false + } + }, + "containerLifecycleHooks": { + "description": "Container Lifecycle Hooks definition for the wait for migrations. If not set, the values from global `containerLifecycleHooks` will be used.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.Lifecycle", + "default": {}, + "x-docsSection": "Kubernetes", + "examples": [ + { + "postStart": { + "exec": { + "command": [ + "/bin/sh", + "-c", + "echo postStart handler > /usr/share/message" + ] + } + }, + "preStop": { + "exec": { + "command": [ + "/bin/sh", + "-c", + "echo preStop handler > /usr/share/message" + ] + } + } + } + ] + }, + "securityContexts": { + "description": "Security context definition for the wait for migrations. If not set, the values from global `securityContexts` will be used.", + "type": "object", + "x-docsSection": "Kubernetes", + "properties": { + "container": { + "description": "Container security context definition for the wait for migrations.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.SecurityContext", + "default": {}, + "x-docsSection": "Kubernetes", + "examples": [ + { + "allowPrivilegeEscalation": false, + "capabilities": { + "drop": [ + "ALL" + ] + } + } + ] + } + } + } + } + }, + "env": { + "description": "Add additional env vars to triggerer.", + "type": "array", + "default": [], + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": [ + "name", + "value" + ], + "additionalProperties": false + } + }, + "keda": { + "description": "KEDA configuration.", + "type": "object", + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Allow KEDA autoscaling.", + "type": "boolean", + "default": false + }, + "namespaceLabels": { + "description": "Labels used in `matchLabels` for namespace in the PgBouncer NetworkPolicy.", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + }, + "pollingInterval": { + "description": "How often KEDA polls the airflow DB to report new scale requests to the HPA.", + "type": "integer", + "default": 5 + }, + "cooldownPeriod": { + "description": "How many seconds KEDA will wait before scaling to zero.", + "type": "integer", + "default": 30 + }, + "minReplicaCount": { + "description": "Minimum number of triggerers created by KEDA.", + "type": "integer", + "default": 0 + }, + "maxReplicaCount": { + "description": "Maximum number of triggerers created by KEDA.", + "type": "integer", + "default": 10 + }, + "advanced": { + "description": "Advanced KEDA configuration.", + "type": "object", + "default": {}, + "additionalProperties": false, + "properties": { + "horizontalPodAutoscalerConfig": { + "description": "HorizontalPodAutoscalerConfig specifies horizontal scale config.", + "type": "object", + "default": {}, + "properties": { + "behavior": { + "description": "HorizontalPodAutoscalerBehavior configures the scaling behavior of the target.", + "type": "object", + "default": {}, + "$ref": "#/definitions/io.k8s.api.autoscaling.v2beta2.HorizontalPodAutoscalerBehavior" + } + } + } + } + }, + "query": { + "description": "Query to use for KEDA autoscaling. Must return a single integer.", + "type": "string", + "default": "SELECT ceil(COUNT(*)::decimal / {{ .Values.config.triggerer.default_capacity }}) FROM trigger" + } + } + } + } + }, + "dagProcessor": { + "description": "Airflow dag processor settings.", + "type": "object", + "x-docsSection": "DagProcessor", + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Enable standalone dag processor (requires Airflow 2.3.0+).", + "type": "boolean", + "default": false + }, + "livenessProbe": { + "description": "Liveness probe configuration for dag processor.", + "type": "object", + "additionalProperties": false, + "properties": { + "initialDelaySeconds": { + "description": "Number of seconds after the container has started before liveness probes are initiated.", + "type": "integer", + "default": 10 + }, + "timeoutSeconds": { + "description": "Number of seconds after which the probe times out. Minimum value is 1 seconds.", + "type": "integer", + "default": 20 + }, + "failureThreshold": { + "description": "Minimum consecutive failures for the probe to be considered failed after having succeeded. Minimum value is 1.", + "type": "integer", + "default": 5 + }, + "periodSeconds": { + "description": "How often (in seconds) to perform the probe. Minimum value is 1.", + "type": "integer", + "default": 60 + }, + "command": { + "description": "Command for livenessProbe", + "type": [ + "array", + "null" + ], + "items": { + "type": [ + "string", + "null" + ] + } + } + } + }, + "replicas": { + "description": "Number of dag processors to run.", + "type": "integer", + "default": 1 + }, + "revisionHistoryLimit": { + "description": "Number of old replicasets to retain.", + "type": [ + "integer", + "null" + ], + "default": null, + "x-docsSection": null + }, + "command": { + "description": "Command to use when running the Airflow dag processor (templated).", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + }, + "default": null + }, + "args": { + "description": "Args to use when running the Airflow dag processor (templated).", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + }, + "default": [ + "bash", + "-c", + "exec airflow dag-processor" + ] + }, + "strategy": { + "description": "Specifies the strategy used to replace old Pods by new ones when deployed as a Deployment.", + "type": [ + "null", + "object" + ], + "$ref": "#/definitions/io.k8s.api.apps.v1.DeploymentStrategy", + "default": { + "rollingUpdate": { + "maxSurge": "100%", + "maxUnavailable": "50%" + } + } + }, + "serviceAccount": { + "description": "Create ServiceAccount.", + "type": "object", + "properties": { + "automountServiceAccountToken": { + "description": "Specifies if ServiceAccount's API credentials should be mounted onto Pods", + "type": "boolean", + "default": true + }, + "create": { + "description": "Specifies whether a ServiceAccount should be created.", + "type": "boolean", + "default": true + }, + "name": { + "description": "The name of the ServiceAccount to use. If not set and create is true, a name is generated using the release name.", + "type": [ + "string", + "null" + ], + "default": null + }, + "annotations": { + "description": "Annotations to add to the dag processor Kubernetes ServiceAccount.", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + } + } + }, + "resources": { + "description": "Resources for dag processor pods.", + "type": "object", + "default": {}, + "examples": [ + { + "limits": { + "cpu": "100m", + "memory": "128Mi" + }, + "requests": { + "cpu": "100m", + "memory": "128Mi" + } + } + ], + "$ref": "#/definitions/io.k8s.api.core.v1.ResourceRequirements" + }, + "safeToEvict": { + "description": "This setting tells Kubernetes that its ok to evict when it wants to scale a node down.", + "type": "boolean", + "default": true + }, + "extraContainers": { + "description": "Launch additional containers into dag processor.", + "type": "array", + "default": [], + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.Container" + } + }, + "extraInitContainers": { + "description": "Add additional init containers into dag processor.", + "type": "array", + "default": [], + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.Container" + } + }, + "extraVolumes": { + "description": "Mount additional volumes into dag processor.", + "type": "array", + "default": [], + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.Volume" + } + }, + "extraVolumeMounts": { + "description": "Mount additional volumes into dag processor.", + "type": "array", + "default": [], + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.VolumeMount" + } + }, + "nodeSelector": { + "description": "Select certain nodes for dag processor pods.", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + }, + "priorityClassName": { + "description": "Specify priority for dag processor pods.", + "type": [ + "string", + "null" + ], + "default": null + }, + "affinity": { + "description": "Specify scheduling constraints for dag processor pods.", + "type": "object", + "default": "See values.yaml", + "$ref": "#/definitions/io.k8s.api.core.v1.Affinity" + }, + "tolerations": { + "description": "Specify Tolerations for dag processor pods.", + "type": "array", + "default": [], + "items": { + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.Toleration" + } + }, + "topologySpreadConstraints": { + "description": "Specify topology spread constraints for dag processor pods.", + "type": "array", + "default": [], + "items": { + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.TopologySpreadConstraint" + } + }, + "terminationGracePeriodSeconds": { + "description": "Grace period for tasks to finish after SIGTERM is sent from Kubernetes.", + "type": "integer", + "default": 60 + }, + "annotations": { + "description": "Annotations to add to the dag processor deployment", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + }, + "podAnnotations": { + "description": "Annotations to add to the dag processor pods.", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + }, + "securityContext": { + "description": "Security context for the dag processor pod (deprecated, use `securityContexts` instead). If not set, the values from `securityContext` will be used.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.PodSecurityContext", + "default": {}, + "examples": [ + { + "runAsUser": 50000, + "runAsGroup": 0, + "fsGroup": 0 + } + ] + }, + "containerLifecycleHooks": { + "description": "Container Lifecycle Hooks definition for the dag processor. If not set, the values from global `containerLifecycleHooks` will be used.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.Lifecycle", + "default": {}, + "x-docsSection": "Kubernetes", + "examples": [ + { + "postStart": { + "exec": { + "command": [ + "/bin/sh", + "-c", + "echo postStart handler > /usr/share/message" + ] + } + }, + "preStop": { + "exec": { + "command": [ + "/bin/sh", + "-c", + "echo preStop handler > /usr/share/message" + ] + } + } + } + ] + }, + "securityContexts": { + "description": "Security context definition for the dag processor. If not set, the values from global `securityContexts` will be used.", + "type": "object", + "x-docsSection": "Kubernetes", + "properties": { + "pod": { + "description": "Pod security context definition for the dag processor.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.PodSecurityContext", + "default": {}, + "x-docsSection": "Kubernetes", + "examples": [ + { + "runAsUser": 50000, + "runAsGroup": 0, + "fsGroup": 0 + } + ] + }, + "container": { + "description": "Container security context definition for the dag processor.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.SecurityContext", + "default": {}, + "x-docsSection": "Kubernetes", + "examples": [ + { + "allowPrivilegeEscalation": false, + "capabilities": { + "drop": [ + "ALL" + ] + } + } + ] + } + } + }, + "logGroomerSidecar": { + "$ref": "#/definitions/logGroomerConfigType", + "description": "Configuration for log groomer sidecar" + }, + "waitForMigrations": { + "description": "wait-for-airflow-migrations init container.", + "type": "object", + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Enable wait-for-airflow-migrations init container.", + "type": "boolean", + "default": true + }, + "env": { + "description": "Add additional env vars to wait-for-airflow-migrations init container.", + "type": "array", + "default": [], + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": [ + "name", + "value" + ], + "additionalProperties": false + } + }, + "containerLifecycleHooks": { + "description": "Container Lifecycle Hooks definition for the wait for migrations. If not set, the values from global `containerLifecycleHooks` will be used.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.Lifecycle", + "default": {}, + "x-docsSection": "Kubernetes", + "examples": [ + { + "postStart": { + "exec": { + "command": [ + "/bin/sh", + "-c", + "echo postStart handler > /usr/share/message" + ] + } + }, + "preStop": { + "exec": { + "command": [ + "/bin/sh", + "-c", + "echo preStop handler > /usr/share/message" + ] + } + } + } + ] + }, + "securityContexts": { + "description": "Security context definition for the wait for migrations. If not set, the values from global `securityContexts` will be used.", + "type": "object", + "x-docsSection": "Kubernetes", + "properties": { + "container": { + "description": "Container security context definition for the wait for migrations.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.SecurityContext", + "default": {}, + "x-docsSection": "Kubernetes", + "examples": [ + { + "allowPrivilegeEscalation": false, + "capabilities": { + "drop": [ + "ALL" + ] + } + } + ] + } + } + } + } + }, + "env": { + "description": "Add additional env vars to dag processor.", + "type": "array", + "default": [], + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": [ + "name", + "value" + ], + "additionalProperties": false + } + } + } + }, + "createUserJob": { + "description": "Airflow job to create a user settings.", + "type": "object", + "x-docsSection": "Jobs", + "additionalProperties": false, + "properties": { + "command": { + "description": "Command to use when running create user job (templated).", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + }, + "default": null + }, + "args": { + "description": "Args to use when running create user job (templated).", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + }, + "default": [ + "bash", + "-c", + "exec \\\nairflow {{ semverCompare \">=2.0.0\" .Values.airflowVersion | ternary \"users create\" \"create_user\" }} \"$@\"", + "--", + "-r", + "{{ .Values.webserver.defaultUser.role }}", + "-u", + "{{ .Values.webserver.defaultUser.username }}", + "-e", + "{{ .Values.webserver.defaultUser.email }}", + "-f", + "{{ .Values.webserver.defaultUser.firstName }}", + "-l", + "{{ .Values.webserver.defaultUser.lastName }}", + "-p", + "{{ .Values.webserver.defaultUser.password }}" + ] + }, + "annotations": { + "description": "Annotations to add to the create user job pod.", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + }, + "jobAnnotations": { + "description": "Annotations to add to the create user job job.", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + }, + "labels": { + "description": "Labels to add to the create user job objects and pods.", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + }, + "serviceAccount": { + "description": "Create ServiceAccount.", + "type": "object", + "additionalProperties": false, + "properties": { + "automountServiceAccountToken": { + "description": "Specifies if ServiceAccount's API credentials should be mounted onto Pods", + "type": "boolean", + "default": true + }, + "create": { + "description": "Specifies whether a ServiceAccount should be created.", + "type": "boolean", + "default": true + }, + "name": { + "description": "The name of the ServiceAccount to use. If not set and create is true, a name is generated using the release name.", + "type": [ + "string", + "null" + ], + "default": null + }, + "annotations": { + "description": "Annotations to add to the create user job Kubernetes ServiceAccount.", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + } + } + }, + "extraContainers": { + "description": "Launch additional containers for the create user job pod", + "type": "array", + "default": [], + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.Container" + } + }, + "extraVolumes": { + "description": "Mount additional volumes into create user job", + "type": "array", + "default": [], + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.Volume" + } + }, + "extraVolumeMounts": { + "description": "Mount additional volumes into create user job", + "type": "array", + "default": [], + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.VolumeMount" + } + }, + "nodeSelector": { + "description": "Select certain nodes for the create user job pod.", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + }, + "affinity": { + "description": "Specify scheduling constraints for the create user job pod.", + "type": "object", + "default": {}, + "$ref": "#/definitions/io.k8s.api.core.v1.Affinity" + }, + "tolerations": { + "description": "Specify Tolerations for the create user job pod.", + "type": "array", + "default": [], + "items": { + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.Toleration" + } + }, + "topologySpreadConstraints": { + "description": "Specify topology spread constraints for the create user job pod.", + "type": "array", + "default": [], + "items": { + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.TopologySpreadConstraint" + } + }, + "securityContext": { + "description": "Security context for the create user job pod (deprecated, use `securityContexts` instead). If not set, the values from `securityContext` will be used.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.PodSecurityContext", + "default": {}, + "examples": [ + { + "runAsUser": 50000, + "runAsGroup": 0, + "fsGroup": 0 + } + ] + }, + "containerLifecycleHooks": { + "description": "Container Lifecycle Hooks definition for the create user job. If not set, the values from global `containerLifecycleHooks` will be used.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.Lifecycle", + "default": {}, + "x-docsSection": "Kubernetes", + "examples": [ + { + "postStart": { + "exec": { + "command": [ + "/bin/sh", + "-c", + "echo postStart handler > /usr/share/message" + ] + } + }, + "preStop": { + "exec": { + "command": [ + "/bin/sh", + "-c", + "echo preStop handler > /usr/share/message" + ] + } + } + } + ] + }, + "securityContexts": { + "description": "Security context definition for the create user job. If not set, the values from global `securityContexts` will be used.", + "type": "object", + "x-docsSection": "Kubernetes", + "properties": { + "pod": { + "description": "Pod security context definition for the create user job.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.PodSecurityContext", + "default": {}, + "x-docsSection": "Kubernetes", + "examples": [ + { + "runAsUser": 50000, + "runAsGroup": 0, + "fsGroup": 0 + } + ] + }, + "container": { + "description": "Container security context definition for the create user job.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.SecurityContext", + "default": {}, + "x-docsSection": "Kubernetes", + "examples": [ + { + "allowPrivilegeEscalation": false, + "capabilities": { + "drop": [ + "ALL" + ] + } + } + ] + } + } + }, + "resources": { + "description": "Resources for the create user job pod", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.ResourceRequirements", + "default": {}, + "examples": [ + { + "limits": { + "cpu": "100m", + "memory": "128Mi" + }, + "requests": { + "cpu": "100m", + "memory": "128Mi" + } + } + ] + }, + "useHelmHooks": { + "description": "Specify if you want to use the default Helm Hook annotations", + "type": "boolean", + "default": true + }, + "applyCustomEnv": { + "description": "Specify if you want additional configured env vars applied to this job", + "type": "boolean", + "default": true + }, + "ttlSecondsAfterFinished": { + "description": "Limit the lifetime of the job object after it finished execution", + "type": [ + "integer", + "null" + ], + "default": 300 + }, + "env": { + "description": "Add additional env vars to the create user job pod.", + "type": "array", + "default": [], + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": [ + "name", + "value" + ], + "additionalProperties": false + } + } + } + }, + "migrateDatabaseJob": { + "description": "Airflow job to migrate databases settings.", + "type": "object", + "x-docsSection": "Jobs", + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Enable migrate database job.", + "type": "boolean", + "default": true + }, + "command": { + "description": "Command to use when running migrate database job (templated).", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + }, + "default": null + }, + "args": { + "description": "Args to use when running migrate database job (templated).", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + }, + "default": [ + "bash", + "-c", + "exec \\\nairflow {{ semverCompare \">=2.7.0\" .Values.airflowVersion | ternary \"db migrate\" (semverCompare \">=2.0.0\" .Values.airflowVersion | ternary \"db upgrade\" \"upgradedb\") }}" + ] + }, + "annotations": { + "description": "Annotations to add to the migrate database job pod.", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + }, + "jobAnnotations": { + "description": "Annotations to add to the migrate database job.", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + }, + "serviceAccount": { + "description": "Create ServiceAccount.", + "type": "object", + "properties": { + "automountServiceAccountToken": { + "description": "Specifies if ServiceAccount's API credentials should be mounted onto Pods", + "type": "boolean", + "default": true + }, + "create": { + "description": "Specifies whether a ServiceAccount should be created.", + "type": "boolean", + "default": true + }, + "name": { + "description": "The name of the ServiceAccount to use. If not set and create is true, a name is generated using the release name.", + "type": [ + "string", + "null" + ], + "default": null + }, + "annotations": { + "description": "Annotations to add to the migrate database job Kubernetes ServiceAccount.", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + } + } + }, + "resources": { + "description": "Resources for the migrate database job pod", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.ResourceRequirements", + "default": {}, + "examples": [ + { + "limits": { + "cpu": "100m", + "memory": "128Mi" + }, + "requests": { + "cpu": "100m", + "memory": "128Mi" + } + } + ] + }, + "extraContainers": { + "description": "Launch additional containers for the migrate database job pod", + "type": "array", + "default": [], + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.Container" + } + }, + "extraVolumes": { + "description": "Mount additional volumes into migrate database job", + "type": "array", + "default": [], + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.Volume" + } + }, + "extraVolumeMounts": { + "description": "Mount additional volumes into migrate database job", + "type": "array", + "default": [], + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.VolumeMount" + } + }, + "nodeSelector": { + "description": "Select certain nodes for the migrate database job pod.", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + }, + "affinity": { + "description": "Specify scheduling constraints for the migrate database job pod.", + "type": "object", + "default": {}, + "$ref": "#/definitions/io.k8s.api.core.v1.Affinity" + }, + "tolerations": { + "description": "Specify Tolerations for the migrate database job pod.", + "type": "array", + "default": [], + "items": { + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.Toleration" + } + }, + "topologySpreadConstraints": { + "description": "Specify topology spread constraints for migrate database job pod.", + "type": "array", + "default": [], + "items": { + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.TopologySpreadConstraint" + } + }, + "securityContext": { + "description": "Security context for the migrate database job pod (deprecated, use `securityContexts` instead). If not set, the values from `securityContext` will be used.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.PodSecurityContext", + "default": {}, + "examples": [ + { + "runAsUser": 50000, + "runAsGroup": 0, + "fsGroup": 0 + } + ] + }, + "containerLifecycleHooks": { + "description": "Container Lifecycle Hooks definition for the migrate database job. If not set, the values from global `containerLifecycleHooks` will be used.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.Lifecycle", + "default": {}, + "x-docsSection": "Kubernetes", + "examples": [ + { + "postStart": { + "exec": { + "command": [ + "/bin/sh", + "-c", + "echo postStart handler > /usr/share/message" + ] + } + }, + "preStop": { + "exec": { + "command": [ + "/bin/sh", + "-c", + "echo preStop handler > /usr/share/message" + ] + } + } + } + ] + }, + "securityContexts": { + "description": "Security context definition for the migrate database job. If not set, the values from global `securityContexts` will be used.", + "type": "object", + "x-docsSection": "Kubernetes", + "properties": { + "pod": { + "description": "Pod security context definition for the migrate database job.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.PodSecurityContext", + "default": {}, + "x-docsSection": "Kubernetes", + "examples": [ + { + "runAsUser": 50000, + "runAsGroup": 0, + "fsGroup": 0 + } + ] + }, + "container": { + "description": "Container security context definition for the migrate database job.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.SecurityContext", + "default": {}, + "x-docsSection": "Kubernetes", + "examples": [ + { + "allowPrivilegeEscalation": false, + "capabilities": { + "drop": [ + "ALL" + ] + } + } + ] + } + } + }, + "useHelmHooks": { + "description": "Specify if you want to use the default Helm Hook annotations", + "type": "boolean", + "default": true + }, + "applyCustomEnv": { + "description": "Specify if you want additional configured env vars applied to this job", + "type": "boolean", + "default": true + }, + "ttlSecondsAfterFinished": { + "description": "Limit the lifetime of the job object after it finished execution", + "type": [ + "integer", + "null" + ], + "default": 300 + } + } + }, + "webserver": { + "description": "Airflow webserver settings.", + "type": "object", + "x-docsSection": "Webserver", + "additionalProperties": false, + "properties": { + "configMapAnnotations": { + "description": "Extra annotations to apply to the webserver configmap.", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + }, + "hostAliases": { + "description": "HostAliases for the webserver pod.", + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.HostAlias" + }, + "type": "array", + "default": [], + "examples": [ + { + "ip": "127.0.0.1", + "hostnames": [ + "foo.local" + ] + }, + { + "ip": "10.1.2.3", + "hostnames": [ + "foo.remote" + ] + } + ] + }, + "allowPodLogReading": { + "description": "Allow webserver to read k8s pod logs. Useful when you don't have an external log store.", + "type": "boolean", + "default": true + }, + "livenessProbe": { + "description": "Liveness probe configuration.", + "type": "object", + "additionalProperties": false, + "properties": { + "initialDelaySeconds": { + "description": "Webserver Liveness probe initial delay.", + "type": "integer", + "default": 15 + }, + "timeoutSeconds": { + "description": "Webserver Liveness probe timeout seconds.", + "type": "integer", + "default": 5 + }, + "failureThreshold": { + "description": "Webserver Liveness probe failure threshold.", + "type": "integer", + "default": 5 + }, + "periodSeconds": { + "description": "Webserver Liveness probe period seconds.", + "type": "integer", + "default": 10 + }, + "scheme": { + "description": "Webserver Liveness probe scheme.", + "type": "string", + "default": "HTTP" + } + } + }, + "readinessProbe": { + "description": "Readiness probe configuration.", + "type": "object", + "additionalProperties": false, + "properties": { + "initialDelaySeconds": { + "description": "Webserver Readiness probe initial delay.", + "type": "integer", + "default": 15 + }, + "timeoutSeconds": { + "description": "Webserver Readiness probe timeout seconds.", + "type": "integer", + "default": 5 + }, + "failureThreshold": { + "description": "Webserver Readiness probe failure threshold.", + "type": "integer", + "default": 5 + }, + "periodSeconds": { + "description": "Webserver Readiness probe period seconds.", + "type": "integer", + "default": 10 + }, + "scheme": { + "description": "Webserver Readiness probe scheme.", + "type": "string", + "default": "HTTP" + } + } + }, + "startupProbe": { + "description": "Startup probe configuration.", + "type": "object", + "additionalProperties": false, + "properties": { + "timeoutSeconds": { + "description": "Webserver Startup probe timeout seconds.", + "type": "integer", + "default": 20 + }, + "failureThreshold": { + "description": "Webserver Startup probe failure threshold.", + "type": "integer", + "default": 6 + }, + "periodSeconds": { + "description": "Webserver Startup probe period seconds.", + "type": "integer", + "default": 10 + }, + "scheme": { + "description": "Webserver Startup probe scheme.", + "type": "string", + "default": "HTTP" + } + } + }, + "replicas": { + "description": "How many Airflow webserver replicas should run.", + "type": "integer", + "default": 1 + }, + "revisionHistoryLimit": { + "description": "Number of old replicasets to retain.", + "type": [ + "integer", + "null" + ], + "default": null, + "x-docsSection": null + }, + "command": { + "description": "Command to use when running the Airflow webserver (templated).", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + }, + "default": null + }, + "args": { + "description": "Args to use when running the Airflow webserver (templated).", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + }, + "default": [ + "bash", + "-c", + "exec airflow webserver" + ] + }, + "strategy": { + "description": "Specifies the strategy used to replace old Pods by new ones.", + "type": [ + "null", + "object" + ], + "default": null + }, + "serviceAccount": { + "description": "Create ServiceAccount.", + "type": "object", + "properties": { + "automountServiceAccountToken": { + "description": "Specifies if ServiceAccount's API credentials should be mounted onto Pods", + "type": "boolean", + "default": true + }, + "create": { + "description": "Specifies whether a ServiceAccount should be created.", + "type": "boolean", + "default": true + }, + "name": { + "description": "The name of the ServiceAccount to use. If not set and create is true, a name is generated using the release name.", + "type": [ + "string", + "null" + ], + "default": null + }, + "annotations": { + "description": "Annotations to add to the webserver Kubernetes ServiceAccount.", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + } + } + }, + "podDisruptionBudget": { + "description": "Webserver pod disruption budget.", + "type": "object", + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Enable pod disruption budget.", + "type": "boolean", + "default": false + }, + "config": { + "description": "Disruption budget configuration.", + "type": "object", + "additionalProperties": false, + "properties": { + "maxUnavailable": { + "description": "Max unavailable pods for webserver.", + "type": [ + "integer", + "string" + ], + "default": 1 + }, + "minAvailable": { + "description": "Min available pods for webserver.", + "type": [ + "integer", + "string" + ], + "default": 1 + } + } + } + } + }, + "extraNetworkPolicies": { + "description": "Additional NetworkPolicies as needed (Deprecated - renamed to `webserver.networkPolicy.ingress.from`).", + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/io.k8s.api.networking.v1.NetworkPolicyPeer" + }, + "default": [] + }, + "networkPolicy": { + "description": "Webserver NetworkPolicy configuration", + "type": "object", + "additionalProperties": false, + "properties": { + "ingress": { + "description": "Webserver NetworkPolicyingress configuration", + "type": "object", + "additionalProperties": false, + "properties": { + "from": { + "description": "Peers for webserver NetworkPolicyingress.", + "type": "array", + "default": [], + "items": { + "$ref": "#/definitions/io.k8s.api.networking.v1.NetworkPolicyPeer" + } + }, + "ports": { + "description": "Ports for webserver NetworkPolicyingress (if `from` is set).", + "type": "array", + "items": { + "$ref": "#/definitions/io.k8s.api.networking.v1.NetworkPolicyPort" + }, + "default": [ + { + "port": "{{ .Values.ports.airflowUI }}" + } + ], + "examples": [ + { + "port": 8070 + } + ] + } + } + } + } + }, + "securityContext": { + "description": "Security context for the webserver job pod (deprecated, use `securityContexts` instead). If not set, the values from `securityContext` will be used.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.PodSecurityContext", + "default": {}, + "examples": [ + { + "runAsUser": 50000, + "runAsGroup": 0, + "fsGroup": 0 + } + ] + }, + "containerLifecycleHooks": { + "description": "Container Lifecycle Hooks definition for the webserver. If not set, the values from global `containerLifecycleHooks` will be used.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.Lifecycle", + "default": {}, + "x-docsSection": "Kubernetes", + "examples": [ + { + "postStart": { + "exec": { + "command": [ + "/bin/sh", + "-c", + "echo postStart handler > /usr/share/message" + ] + } + }, + "preStop": { + "exec": { + "command": [ + "/bin/sh", + "-c", + "echo preStop handler > /usr/share/message" + ] + } + } + } + ] + }, + "securityContexts": { + "description": "Security context definition for the webserver. If not set, the values from global `securityContexts` will be used.", + "type": "object", + "x-docsSection": "Kubernetes", + "properties": { + "pod": { + "description": "Pod security context definition for the webserver.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.PodSecurityContext", + "default": {}, + "x-docsSection": "Kubernetes", + "examples": [ + { + "runAsUser": 50000, + "runAsGroup": 0, + "fsGroup": 0 + } + ] + }, + "container": { + "description": "Container security context definition for the webserver.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.SecurityContext", + "default": {}, + "x-docsSection": "Kubernetes", + "examples": [ + { + "allowPrivilegeEscalation": false, + "capabilities": { + "drop": [ + "ALL" + ] + } + } + ] + } + } + }, + "resources": { + "description": "Resources for webserver pods.", + "type": "object", + "default": {}, + "examples": [ + { + "limits": { + "cpu": "100m", + "memory": "128Mi" + }, + "requests": { + "cpu": "100m", + "memory": "128Mi" + } + } + ], + "$ref": "#/definitions/io.k8s.api.core.v1.ResourceRequirements" + }, + "defaultUser": { + "description": "Optional default Airflow user information", + "type": "object", + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Enable default user creation.", + "type": "boolean", + "x-docsSection": "Common", + "default": true + }, + "role": { + "description": "Default user role.", + "type": "string", + "default": "Admin" + }, + "username": { + "description": "Default user username.", + "type": "string", + "default": "admin" + }, + "email": { + "description": "Default user email address.", + "type": "string", + "default": "admin@example.com" + }, + "firstName": { + "description": "Default user firstname.", + "type": "string", + "default": "admin" + }, + "lastName": { + "description": "Default user lastname.", + "type": "string", + "default": "user" + }, + "password": { + "description": "Default user password.", + "type": "string", + "default": "admin" + } + } + }, + "extraContainers": { + "description": "Launch additional containers into webserver.", + "type": "array", + "default": [], + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.Container" + } + }, + "extraInitContainers": { + "description": "Add additional init containers into webserver.", + "type": "array", + "default": [], + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.Container" + } + }, + "extraVolumes": { + "description": "Mount additional volumes into webserver.", + "type": "array", + "default": [], + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.Volume" + } + }, + "extraVolumeMounts": { + "description": "Mount additional volumes into webserver.", + "type": "array", + "default": [], + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.VolumeMount" + } + }, + "webserverConfig": { + "description": "This string (can be templated) will be mounted into the Airflow webserver as a custom `webserver_config.py`. You can bake a `webserver_config.py` in to your image instead or specify a configmap containing the webserver_config.py.", + "type": [ + "string", + "null" + ], + "x-docsSection": "Common", + "default": null, + "examples": [ + "from airflow import configuration as conf\n\n# The SQLAlchemy connection string.\nSQLALCHEMY_DATABASE_URI = conf.get('database', 'SQL_ALCHEMY_CONN')\n\n# Flask-WTF flag for CSRF\nCSRF_ENABLED = True" + ] + }, + "webserverConfigConfigMapName": { + "description": "The configmap name containing the webserver_config.py.", + "type": [ + "string", + "null" + ], + "x-docsSection": "Common", + "default": null, + "examples": [ + "my-webserver-configmap" + ] + }, + "service": { + "description": "Webserver Service configuration.", + "type": "object", + "additionalProperties": false, + "properties": { + "type": { + "description": "Webserver Service type.", + "type": "string", + "default": "ClusterIP" + }, + "annotations": { + "description": "Annotations for the webserver Service.", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + }, + "ports": { + "description": "Ports for the webserver Service.", + "type": "array", + "items": { + "type": "object", + "additionalProperties": false, + "properties": { + "name": { + "type": "string" + }, + "port": { + "type": [ + "string", + "integer" + ] + }, + "targetPort": { + "type": [ + "string", + "integer" + ] + }, + "nodePort": { + "type": [ + "string", + "integer" + ] + }, + "protocol": { + "type": "string" + } + } + }, + "default": [ + { + "name": "airflow-ui", + "port": "{{ .Values.ports.airflowUI }}" + } + ], + "examples": [ + { + "name": "airflow-ui", + "port": 80, + "targetPort": "airflow-ui" + }, + { + "name": "only_sidecar", + "port": 80, + "targetPort": 8888 + } + ] + }, + "loadBalancerIP": { + "description": "Webserver Service loadBalancerIP.", + "type": [ + "string", + "null" + ], + "default": null + }, + "loadBalancerSourceRanges": { + "description": "Webserver Service ``loadBalancerSourceRanges``.", + "type": "array", + "items": { + "type": "string" + }, + "default": [], + "examples": [ + "10.123.0.0/16" + ] + } + } + }, + "nodeSelector": { + "description": "Select certain nodes for webserver pods.", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + }, + "priorityClassName": { + "description": "Specify priority for webserver pods.", + "type": [ + "string", + "null" + ], + "default": null + }, + "affinity": { + "description": "Specify scheduling constraints for webserver pods.", + "type": "object", + "default": "See values.yaml", + "$ref": "#/definitions/io.k8s.api.core.v1.Affinity" + }, + "tolerations": { + "description": "Specify Tolerations for webserver pods.", + "type": "array", + "default": [], + "items": { + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.Toleration" + } + }, + "topologySpreadConstraints": { + "description": "Specify topology spread constraints for webserver pods.", + "type": "array", + "default": [], + "x-docsSection": "Kubernetes", + "items": { + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.TopologySpreadConstraint" + } + }, + "annotations": { + "description": "Annotations to add to the webserver deployment", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + }, + "podAnnotations": { + "description": "Annotations to add to the webserver pods.", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + }, + "labels": { + "description": "Labels to add to the webserver objects and pods.", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + }, + "waitForMigrations": { + "description": "wait-for-airflow-migrations init container.", + "type": "object", + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Enable wait-for-airflow-migrations init container.", + "type": "boolean", + "default": true + }, + "env": { + "description": "Add additional env vars to wait-for-airflow-migrations init container.", + "type": "array", + "default": [], + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": [ + "name", + "value" + ], + "additionalProperties": false + } + }, + "containerLifecycleHooks": { + "description": "Container Lifecycle Hooks definition for the wait for migrations. If not set, the values from global `containerLifecycleHooks` will be used.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.Lifecycle", + "default": {}, + "x-docsSection": "Kubernetes", + "examples": [ + { + "postStart": { + "exec": { + "command": [ + "/bin/sh", + "-c", + "echo postStart handler > /usr/share/message" + ] + } + }, + "preStop": { + "exec": { + "command": [ + "/bin/sh", + "-c", + "echo preStop handler > /usr/share/message" + ] + } + } + } + ] + }, + "securityContexts": { + "description": "Security context definition for the wait for migrations. If not set, the values from global `securityContexts` will be used.", + "type": "object", + "x-docsSection": "Kubernetes", + "properties": { + "container": { + "description": "Container security context definition for the wait for migrations.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.SecurityContext", + "default": {}, + "x-docsSection": "Kubernetes", + "examples": [ + { + "allowPrivilegeEscalation": false, + "capabilities": { + "drop": [ + "ALL" + ] + } + } + ] + } + } + } + } + }, + "env": { + "description": "Add additional env vars to webserver.", + "type": "array", + "default": [], + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": [ + "name", + "value" + ], + "additionalProperties": false + } + } + } + }, + "flower": { + "description": "Flower settings.", + "type": "object", + "x-docsSection": "Flower", + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Enable Flower.", + "type": "boolean", + "default": false + }, + "revisionHistoryLimit": { + "description": "Number of old replicasets to retain.", + "type": [ + "integer", + "null" + ], + "default": null, + "x-docsSection": null + }, + "command": { + "description": "Command to use when running flower (templated).", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + }, + "default": null + }, + "args": { + "description": "Args to use when running flower (templated).", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + }, + "default": [ + "bash", + "-c", + "exec \\\nairflow {{ semverCompare \">=2.0.0\" .Values.airflowVersion | ternary \"celery flower\" \"flower\" }}" + ] + }, + "extraNetworkPolicies": { + "description": "Additional NetworkPolicies as needed (Deprecated - renamed to `flower.networkPolicy.ingress.from`).", + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/io.k8s.api.networking.v1.NetworkPolicyPeer" + }, + "default": [] + }, + "networkPolicy": { + "description": "Flower NetworkPolicyconfiguration", + "type": "object", + "additionalProperties": false, + "properties": { + "ingress": { + "description": "Flower NetworkPolicyingress configuration", + "type": "object", + "additionalProperties": false, + "properties": { + "from": { + "description": "Peers for flower NetworkPolicyingress.", + "type": "array", + "default": [], + "items": { + "$ref": "#/definitions/io.k8s.api.networking.v1.NetworkPolicyPeer" + } + }, + "ports": { + "description": "Ports for flower NetworkPolicyingress (if `from` is set).", + "type": "array", + "items": { + "$ref": "#/definitions/io.k8s.api.networking.v1.NetworkPolicyPort" + }, + "default": [ + { + "port": "{{ .Values.ports.flowerUI }}" + } + ], + "examples": [ + { + "port": 5565 + } + ] + } + } + } + } + }, + "resources": { + "description": "Resources for Flower pods.", + "type": "object", + "default": {}, + "examples": [ + { + "limits": { + "cpu": "100m", + "memory": "128Mi" + }, + "requests": { + "cpu": "100m", + "memory": "128Mi" + } + } + ], + "$ref": "#/definitions/io.k8s.api.core.v1.ResourceRequirements" + }, + "secretName": { + "description": "A secret containing the user and password pair.", + "type": [ + "string", + "null" + ], + "default": null + }, + "username": { + "description": "Username use to access Flower.", + "type": [ + "string", + "null" + ], + "default": null + }, + "password": { + "description": "Password use to access Flower.", + "type": [ + "string", + "null" + ], + "default": null + }, + "service": { + "description": "Flower Service configuration.", + "type": "object", + "additionalProperties": false, + "properties": { + "type": { + "description": "Flower Service type.", + "type": "string", + "default": "ClusterIP" + }, + "annotations": { + "description": "Annotations for the flower Service.", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + }, + "ports": { + "description": "Ports for the flower Service.", + "type": "array", + "items": { + "type": "object", + "additionalProperties": false, + "properties": { + "name": { + "type": "string" + }, + "port": { + "type": [ + "string", + "integer" + ] + }, + "targetPort": { + "type": [ + "string", + "integer" + ] + }, + "protocol": { + "type": "string" + } + } + }, + "default": [ + { + "name": "flower-ui", + "port": "{{ .Values.ports.flowerUI }}" + } + ], + "examples": [ + { + "name": "flower-ui", + "port": 8080, + "targetPort": "flower-ui" + } + ] + }, + "loadBalancerIP": { + "description": "Flower Service loadBalancerIP.", + "type": [ + "string", + "null" + ], + "default": null + }, + "loadBalancerSourceRanges": { + "description": "Flower Service ``loadBalancerSourceRanges``.", + "type": "array", + "items": { + "type": "string" + }, + "default": [], + "examples": [ + "10.123.0.0/16" + ] + } + } + }, + "serviceAccount": { + "description": "Create ServiceAccount.", + "type": "object", + "properties": { + "automountServiceAccountToken": { + "description": "Specifies if ServiceAccount's API credentials should be mounted onto Pods", + "type": "boolean", + "default": true + }, + "create": { + "description": "Specifies whether a ServiceAccount should be created.", + "type": "boolean", + "default": true + }, + "name": { + "description": "The name of the ServiceAccount to use. If not set and create is true, a name is generated using the release name.", + "type": [ + "string", + "null" + ], + "default": null + }, + "annotations": { + "description": "Annotations to add to the worker Kubernetes ServiceAccount.", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + } + } + }, + "extraContainers": { + "description": "Launch additional containers into the flower pods.", + "type": "array", + "default": [], + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.Container" + } + }, + "extraVolumes": { + "description": "Mount additional volumes into the flower pods.", + "type": "array", + "default": [], + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.Volume" + } + }, + "extraVolumeMounts": { + "description": "Mount additional volumes into the flower pods.", + "type": "array", + "default": [], + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.VolumeMount" + } + }, + "nodeSelector": { + "description": "Select certain nodes for Flower pods.", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + }, + "priorityClassName": { + "description": "Specify priority for Flower pods.", + "type": [ + "string", + "null" + ], + "default": null + }, + "affinity": { + "description": "Specify scheduling constraints for Flower pods.", + "type": "object", + "default": {}, + "$ref": "#/definitions/io.k8s.api.core.v1.Affinity" + }, + "tolerations": { + "description": "Specify Tolerations for Flower pods.", + "type": "array", + "default": [], + "items": { + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.Toleration" + } + }, + "topologySpreadConstraints": { + "description": "Specify topology spread constraints for Flower pods.", + "type": "array", + "default": [], + "items": { + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.TopologySpreadConstraint" + } + }, + "annotations": { + "description": "Annotations to add to the flower deployment", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + }, + "podAnnotations": { + "description": "Annotations to add to the Flower pods.", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + }, + "labels": { + "description": "Labels to add to the flower objects and pods.", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + }, + "securityContext": { + "description": "Security context for the flower pod (deprecated, use `securityContexts` instead). If not set, the values from `securityContext` will be used.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.PodSecurityContext", + "default": {}, + "examples": [ + { + "runAsUser": 50000, + "runAsGroup": 0, + "fsGroup": 0 + } + ] + }, + "containerLifecycleHooks": { + "description": "Container Lifecycle Hooks definition for the network policy. If not set, the values from global `containerLifecycleHooks` will be used.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.Lifecycle", + "default": {}, + "x-docsSection": "Kubernetes", + "examples": [ + { + "postStart": { + "exec": { + "command": [ + "/bin/sh", + "-c", + "echo postStart handler > /usr/share/message" + ] + } + }, + "preStop": { + "exec": { + "command": [ + "/bin/sh", + "-c", + "echo preStop handler > /usr/share/message" + ] + } + } + } + ] + }, + "securityContexts": { + "description": "Security context definition for the network policy. If not set, the values from global `securityContexts` will be used.", + "type": "object", + "x-docsSection": "Kubernetes", + "properties": { + "pod": { + "description": "Pod security context definition for the network policy.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.PodSecurityContext", + "default": {}, + "x-docsSection": "Kubernetes", + "examples": [ + { + "runAsUser": 50000, + "runAsGroup": 0, + "fsGroup": 0 + } + ] + }, + "container": { + "description": "Container security context definition for the network policy.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.SecurityContext", + "default": {}, + "x-docsSection": "Kubernetes", + "examples": [ + { + "allowPrivilegeEscalation": false, + "capabilities": { + "drop": [ + "ALL" + ] + } + } + ] + } + } + }, + "env": { + "description": "Add additional env vars to flower.", + "type": "array", + "default": [], + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": [ + "name", + "value" + ], + "additionalProperties": false + } + } + } + }, + "statsd": { + "description": "StatsD settings.", + "type": "object", + "x-docsSection": "StatsD", + "additionalProperties": false, + "properties": { + "configMapAnnotations": { + "description": "Extra annotations to apply to the statsd configmap.", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + }, + "enabled": { + "description": "Enable StatsD.", + "type": "boolean", + "default": true + }, + "revisionHistoryLimit": { + "description": "Number of old replicasets to retain.", + "type": [ + "integer", + "null" + ], + "default": null, + "x-docsSection": null + }, + "extraNetworkPolicies": { + "description": "Additional NetworkPolicies as needed.", + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/io.k8s.api.networking.v1.NetworkPolicyPeer" + }, + "default": [] + }, + "resources": { + "description": "Resources for StatsD pods.", + "type": "object", + "default": {}, + "examples": [ + { + "limits": { + "cpu": "100m", + "memory": "128Mi" + }, + "requests": { + "cpu": "100m", + "memory": "128Mi" + } + } + ], + "$ref": "#/definitions/io.k8s.api.core.v1.ResourceRequirements" + }, + "service": { + "description": "StatsD Service configuration.", + "type": "object", + "additionalProperties": false, + "properties": { + "extraAnnotations": { + "description": "Extra annotations for the StatsD Service.", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + } + } + }, + "serviceAccount": { + "description": "Create ServiceAccount.", + "type": "object", + "properties": { + "automountServiceAccountToken": { + "description": "Specifies if ServiceAccount's API credentials should be mounted onto Pods", + "type": "boolean", + "default": true + }, + "create": { + "description": "Specifies whether a ServiceAccount should be created.", + "type": "boolean", + "default": true + }, + "name": { + "description": "The name of the ServiceAccount to use. If not set and create is true, a name is generated using the release name.", + "type": [ + "string", + "null" + ], + "default": null + }, + "annotations": { + "description": "Annotations to add to the StatsD Kubernetes ServiceAccount.", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + } + } + }, + "uid": { + "description": "StatsD run as user parameter.", + "type": "integer", + "default": 65534 + }, + "nodeSelector": { + "description": "Select certain nodes for StatsD pods.", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + }, + "priorityClassName": { + "description": "Specify priority for StatsD pods.", + "type": [ + "string", + "null" + ], + "default": null + }, + "affinity": { + "description": "Specify scheduling constraints for StatsD pods.", + "type": "object", + "default": {}, + "$ref": "#/definitions/io.k8s.api.core.v1.Affinity" + }, + "tolerations": { + "description": "Specify Tolerations for StatsD pods.", + "type": "array", + "default": [], + "items": { + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.Toleration" + } + }, + "topologySpreadConstraints": { + "description": "Specify topology spread constraints for StatsD pods.", + "type": "array", + "default": [], + "items": { + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.TopologySpreadConstraint" + } + }, + "extraMappings": { + "description": "Additional mappings for StatsD exporter.If set, will merge default mapping and extra mappings, default mapping has higher priority. So, if you want to change some default mapping, please use `overrideMappings`", + "type": "array", + "default": [] + }, + "overrideMappings": { + "description": "Override mappings for StatsD exporter.If set, will ignore setting item in default and `extraMappings`. So, If you use it, ensure all mapping item contains in it.", + "type": "array", + "default": [] + }, + "securityContext": { + "description": "Security context for the StatsD pod (deprecated, use `securityContexts` instead).", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.PodSecurityContext", + "default": {}, + "examples": [ + { + "runAsUser": 50000, + "runAsGroup": 0, + "fsGroup": 0 + } + ] + }, + "containerLifecycleHooks": { + "description": "Container Lifecycle Hooks definition for the statsd. If not set, the values from global `containerLifecycleHooks` will be used.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.Lifecycle", + "default": {}, + "x-docsSection": "Kubernetes", + "examples": [ + { + "postStart": { + "exec": { + "command": [ + "/bin/sh", + "-c", + "echo postStart handler > /usr/share/message" + ] + } + }, + "preStop": { + "exec": { + "command": [ + "/bin/sh", + "-c", + "echo preStop handler > /usr/share/message" + ] + } + } + } + ] + }, + "securityContexts": { + "description": "Security context definition for the statsd.", + "type": "object", + "x-docsSection": "Kubernetes", + "properties": { + "pod": { + "description": "Pod security context definition for the statsd.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.PodSecurityContext", + "default": {}, + "x-docsSection": "Kubernetes", + "examples": [ + { + "runAsUser": 50000, + "runAsGroup": 0, + "fsGroup": 0 + } + ] + }, + "container": { + "description": "Container security context definition for the statsd.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.SecurityContext", + "default": {}, + "x-docsSection": "Kubernetes", + "examples": [ + { + "allowPrivilegeEscalation": false, + "capabilities": { + "drop": [ + "ALL" + ] + } + } + ] + } + } + }, + "podAnnotations": { + "description": "Annotations to add to the StatsD pods.", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + }, + "annotations": { + "description": "Annotations to add to the StatsD deployment.", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + }, + "args": { + "description": "Args to use when running statsd-exporter (templated).", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + }, + "default": [ + "--statsd.mapping-config=/etc/statsd-exporter/mappings.yml" + ] + }, + "env": { + "description": "Add additional env vars to statsd container.", + "type": "array", + "default": [], + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": [ + "name", + "value" + ], + "additionalProperties": false + } + } + } + }, + "pgbouncer": { + "description": "PgBouncer settings.", + "type": "object", + "x-docsSection": "PgBouncer", + "additionalProperties": false, + "properties": { + "env": { + "description": "Add additional env vars to `pgbouncer` container.", + "type": "array", + "default": [], + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": [ + "name", + "value" + ], + "additionalProperties": false + } + }, + "enabled": { + "description": "Enable PgBouncer.", + "type": "boolean", + "x-docsSection": "Common", + "default": false + }, + "annotations": { + "description": "Annotations to add to the PgBouncer deployment", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + }, + "replicas": { + "description": "Number of PgBouncer replicas to run in Deployment.", + "type": "integer", + "default": 1 + }, + "revisionHistoryLimit": { + "description": "Number of old replicasets to retain.", + "type": [ + "integer", + "null" + ], + "default": null, + "x-docsSection": null + }, + "command": { + "description": "Command to use for PgBouncer (templated).", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + }, + "default": [ + "pgbouncer", + "-u", + "nobody", + "/etc/pgbouncer/pgbouncer.ini" + ] + }, + "args": { + "description": "Args to use for PgBouncer (templated).", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + }, + "default": null + }, + "extraNetworkPolicies": { + "description": "Additional NetworkPolicies as needed.", + "type": "array", + "items": { + "type": "object", + "$ref": "#/definitions/io.k8s.api.networking.v1.NetworkPolicyPeer" + }, + "default": [] + }, + "metadataPoolSize": { + "description": "Metadata pool size.", + "type": "integer", + "default": 10 + }, + "resultBackendPoolSize": { + "description": "Result backend pool size.", + "type": "integer", + "default": 5 + }, + "maxClientConn": { + "description": "Maximum clients that can connect to PgBouncer (higher = more file descriptors).", + "type": "integer", + "default": 100 + }, + "configSecretName": { + "description": "The PgBouncer config Secret name.", + "type": [ + "string", + "null" + ], + "default": null + }, + "podAnnotations": { + "description": "Add annotations for the PgBouncer Pod.", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + }, + "podDisruptionBudget": { + "description": "PgBouncer PodDisruptionBudget.", + "type": "object", + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Enabled PodDistributionBudget.", + "type": "boolean", + "default": false + }, + "config": { + "description": "Pod distribution configuration.", + "type": "object", + "additionalProperties": false, + "properties": { + "maxUnavailable": { + "description": "Max unavailable pods for PgBouncer.", + "type": [ + "integer", + "string" + ], + "default": 1 + }, + "minAvailable": { + "description": "Min available pods for PgBouncer.", + "type": [ + "integer", + "string" + ], + "default": 1 + } + } + } + } + }, + "resources": { + "description": "Resources for the PgBouncer pods.", + "type": "object", + "default": {}, + "examples": [ + { + "limits": { + "cpu": "100m", + "memory": "128Mi" + }, + "requests": { + "cpu": "100m", + "memory": "128Mi" + } + } + ], + "$ref": "#/definitions/io.k8s.api.core.v1.ResourceRequirements" + }, + "containerLifecycleHooks": { + "description": "Container Lifecycle Hooks definition for the PgBouncer. If not set, the values from global `containerLifecycleHooks` will be used.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.Lifecycle", + "default": { + "preStop": { + "exec": { + "command": [ + "/bin/sh", + "-c", + "killall -INT pgbouncer && sleep 120" + ] + } + } + }, + "x-docsSection": "Kubernetes", + "examples": [ + { + "postStart": { + "exec": { + "command": [ + "/bin/sh", + "-c", + "echo postStart handler > /usr/share/message" + ] + } + }, + "preStop": { + "exec": { + "command": [ + "/bin/sh", + "-c", + "echo preStop handler > /usr/share/message" + ] + } + } + } + ] + }, + "securityContexts": { + "description": "Security context definition for the PgBouncer.", + "type": "object", + "x-docsSection": "Kubernetes", + "properties": { + "pod": { + "description": "Pod security context definition for the PgBouncer.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.PodSecurityContext", + "default": {}, + "x-docsSection": "Kubernetes", + "examples": [ + { + "runAsUser": 65534, + "runAsGroup": 0, + "fsGroup": 0 + } + ] + }, + "container": { + "description": "Container security context definition for the PgBouncer.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.SecurityContext", + "default": {}, + "x-docsSection": "Kubernetes", + "examples": [ + { + "allowPrivilegeEscalation": false, + "capabilities": { + "drop": [ + "ALL" + ] + } + } + ] + } + } + }, + "service": { + "description": "PgBouncer Service configuration.", + "type": "object", + "additionalProperties": false, + "properties": { + "extraAnnotations": { + "description": "Extra annotations for the PgBouncer Service.", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + } + } + }, + "verbose": { + "description": "Increase PgBouncer verbosity.", + "type": "integer", + "default": 0 + }, + "auth_type": { + "description": "Method of authenticating users", + "type": "string", + "default": "md5" + }, + "auth_file": { + "description": "The name of the file to load user names and passwords from", + "type": "string", + "default": "/etc/pgbouncer/users.txt" + }, + "logDisconnections": { + "description": "Log disconnections with reasons.", + "type": "integer", + "default": 0 + }, + "logConnections": { + "description": "Log successful logins.", + "type": "integer", + "default": 0 + }, + "sslmode": { + "description": "SSL mode for PgBouncer.", + "type": "string", + "enum": [ + "disable", + "allow", + "prefer", + "require", + "verify-ca", + "verify-full" + ], + "default": "prefer" + }, + "ciphers": { + "description": "The allowed ciphers, might be 'fast', 'normal' or list ciphers separated with ':'.", + "type": "string", + "default": "normal" + }, + "ssl": { + "description": "SSL certificates for PgBouncer connection.", + "type": "object", + "properties": { + "ca": { + "description": "Certificate Authority for server side", + "type": [ + "string", + "null" + ], + "default": null + }, + "cert": { + "description": "Server Certificate for server side", + "type": [ + "string", + "null" + ], + "default": null + }, + "key": { + "description": "Private key used to authenticate with the server", + "type": [ + "string", + "null" + ], + "default": null + } + } + }, + "extraIniMetadata": { + "description": "Add extra metadata database specific PgBouncer ini configuration: https://www.pgbouncer.org/config.html#section-databases", + "type": [ + "string", + "null" + ], + "default": null + }, + "extraIniResultBackend": { + "description": "Add extra result backend database specific PgBouncer ini configuration: https://www.pgbouncer.org/config.html#section-databases", + "type": [ + "string", + "null" + ], + "default": null + }, + "extraIni": { + "description": "Add extra general PgBouncer ini configuration: https://www.pgbouncer.org/config.html", + "type": [ + "string", + "null" + ], + "default": null + }, + "extraVolumes": { + "description": "Mount additional volumes into PgBouncer.", + "type": "array", + "default": [], + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.Volume" + } + }, + "extraVolumeMounts": { + "description": "Mount additional volumes into PgBouncer.", + "type": "array", + "default": [], + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.VolumeMount" + } + }, + "extraContainers": { + "description": "Launch additional containers into `pgbouncer`.", + "type": "array", + "default": [], + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.Container" + } + }, + "serviceAccount": { + "description": "Create ServiceAccount.", + "type": "object", + "properties": { + "automountServiceAccountToken": { + "description": "Specifies if ServiceAccount's API credentials should be mounted onto Pods", + "type": "boolean", + "default": true + }, + "create": { + "description": "Specifies whether a ServiceAccount should be created.", + "type": "boolean", + "default": true + }, + "name": { + "description": "The name of the ServiceAccount to use. If not set and create is true, a name is generated using the release name.", + "type": [ + "string", + "null" + ], + "default": null + }, + "annotations": { + "description": "Annotations to add to the worker Kubernetes ServiceAccount.", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + } + } + }, + "nodeSelector": { + "description": "Select certain nodes for PgBouncer pods.", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + }, + "priorityClassName": { + "description": "Specify priority for PgBouncer pods.", + "type": [ + "string", + "null" + ], + "default": null + }, + "affinity": { + "description": "Specify scheduling constraints for PgBouncer pods.", + "type": "object", + "default": {}, + "$ref": "#/definitions/io.k8s.api.core.v1.Affinity" + }, + "tolerations": { + "description": "Specify Tolerations for PgBouncer pods.", + "type": "array", + "default": [], + "items": { + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.Toleration" + } + }, + "topologySpreadConstraints": { + "description": "Specify topology spread constraints for PgBouncer pods.", + "type": "array", + "default": [], + "items": { + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.TopologySpreadConstraint" + } + }, + "uid": { + "description": "PgBouncer run as user parameter.", + "type": "integer", + "default": 65534 + }, + "metricsExporterSidecar": { + "description": "PgBouncer - metrics exporter settings.", + "type": "object", + "x-docsSection": "PgBouncer", + "additionalProperties": false, + "properties": { + "resources": { + "description": "Resources for the PgBouncer metric exporter.", + "type": "object", + "default": {}, + "examples": [ + { + "limits": { + "cpu": "100m", + "memory": "128Mi" + }, + "requests": { + "cpu": "100m", + "memory": "128Mi" + } + } + ], + "$ref": "#/definitions/io.k8s.api.core.v1.ResourceRequirements" + }, + "statsSecretName": { + "description": "Name of an existing Secrets object containing PgBouncer Metrics secrets.", + "type": [ + "string", + "null" + ], + "default": null + }, + "statsSecretKey": { + "description": "Key referencing the PGBouncer Metrics connection URI within an existing Secrets object. Defaults to `connection` if left null.", + "type": [ + "string", + "null" + ], + "default": null + }, + "sslmode": { + "description": "SSL mode for ``metricsExporterSidecar``", + "type": "string", + "enum": [ + "disable", + "require", + "verify-ca", + "verify-full" + ], + "default": "disable" + }, + "containerLifecycleHooks": { + "description": "Container Lifecycle Hooks definition for the metrics exporter sidecar. If not set, the values from global `containerLifecycleHooks` will be used.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.Lifecycle", + "default": {}, + "x-docsSection": "Kubernetes", + "examples": [ + { + "postStart": { + "exec": { + "command": [ + "/bin/sh", + "-c", + "echo postStart handler > /usr/share/message" + ] + } + }, + "preStop": { + "exec": { + "command": [ + "/bin/sh", + "-c", + "echo preStop handler > /usr/share/message" + ] + } + } + } + ] + }, + "securityContexts": { + "description": "Security context definition for the metrics exporter sidecar. If not set, the values from global `securityContexts` will be used.", + "type": "object", + "x-docsSection": "Kubernetes", + "properties": { + "container": { + "description": "Container security context definition for the metrics exporter sidecar.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.SecurityContext", + "default": {}, + "x-docsSection": "Kubernetes", + "examples": [ + { + "allowPrivilegeEscalation": false, + "capabilities": { + "drop": [ + "ALL" + ] + } + } + ] + } + } + }, + "livenessProbe": { + "description": "LivenessProbe configurations for ``metricsExporterSidecar``", + "type": "object", + "additionalProperties": false, + "properties": { + "initialDelaySeconds": { + "description": "Metrics Exporter liveness probe initial delay", + "type": "integer", + "default": 10 + }, + "periodSeconds": { + "description": "Metrics Exporter liveness probe frequency", + "type": "integer", + "default": 10 + }, + "timeoutSeconds": { + "description": "Metrics Exporter liveness probe command timeout", + "type": "integer", + "default": 1 + } + } + }, + "readinessProbe": { + "description": "ReadinessProbe configurations for ``metricsExporterSidecar``", + "type": "object", + "additionalProperties": false, + "properties": { + "initialDelaySeconds": { + "description": "Metrics Exporter readiness probe initial delay", + "type": "integer", + "default": 10 + }, + "periodSeconds": { + "description": "Metrics Exporter readiness probe frequency", + "type": "integer", + "default": 10 + }, + "timeoutSeconds": { + "description": "Metrics Exporter readiness probe command timeout", + "type": "integer", + "default": 1 + } + } + } + } + } + } + }, + "redis": { + "description": "Configuration for the Redis provisioned by the chart.", + "type": "object", + "x-docsSection": "Redis", + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Enable the Redis provisioned by the chart (you can also use an external Redis instance with `data.brokerUrl` or `data.brokerUrlSecretName`).", + "type": "boolean", + "default": true + }, + "terminationGracePeriodSeconds": { + "description": "Grace period for Redis to exit after SIGTERM is sent from Kubernetes.", + "type": "integer", + "default": 600 + }, + "persistence": { + "description": "Persistence configuration.", + "type": "object", + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Enable persistent volumes.", + "type": "boolean", + "default": true + }, + "size": { + "description": "Volume size for Redis StatefulSet.", + "type": "string", + "default": "1Gi" + }, + "storageClassName": { + "description": "If using a custom StorageClass, pass name ref to all StatefulSets here.", + "type": [ + "string", + "null" + ], + "default": null + }, + "annotations": { + "description": "Annotations to add to redis volumes.", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + } + } + }, + "resources": { + "description": "Resources for the Redis pods", + "type": "object", + "default": {}, + "examples": [ + { + "limits": { + "cpu": "100m", + "memory": "128Mi" + }, + "requests": { + "cpu": "100m", + "memory": "128Mi" + } + } + ], + "$ref": "#/definitions/io.k8s.api.core.v1.ResourceRequirements" + }, + "passwordSecretName": { + "description": "Redis password secret.", + "type": [ + "string", + "null" + ], + "default": null + }, + "password": { + "description": "If password is set, create secret with it, else generate a new one on install (can only be set during install, not upgrade).", + "type": [ + "string", + "null" + ], + "default": null + }, + "safeToEvict": { + "description": "This setting tells Kubernetes that its ok to evict when it wants to scale a node down.", + "type": "boolean", + "default": true + }, + "nodeSelector": { + "description": "Select certain nodes for Redis pods.", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + }, + "affinity": { + "description": "Specify scheduling constraints for Redis pods.", + "type": "object", + "default": {}, + "$ref": "#/definitions/io.k8s.api.core.v1.Affinity" + }, + "tolerations": { + "description": "Specify Tolerations for Redis pods.", + "type": "array", + "default": [], + "items": { + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.Toleration" + } + }, + "topologySpreadConstraints": { + "description": "Specify topology spread constraints for Redis pods.", + "type": "array", + "default": [], + "items": { + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.TopologySpreadConstraint" + } + }, + "serviceAccount": { + "description": "Create ServiceAccount.", + "type": "object", + "properties": { + "automountServiceAccountToken": { + "description": "Specifies if ServiceAccount's API credentials should be mounted onto Pods", + "type": "boolean", + "default": true + }, + "create": { + "description": "Specifies whether a ServiceAccount should be created.", + "type": "boolean", + "default": true + }, + "name": { + "description": "The name of the ServiceAccount to use. If not set and create is true, a name is generated using the release name.", + "type": [ + "string", + "null" + ], + "default": null + }, + "annotations": { + "description": "Annotations to add to the worker Kubernetes ServiceAccount.", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + } + } + }, + "securityContext": { + "description": "Security context for the cleanup job pod (deprecated, use `securityContexts` instead). If not set, the values from `securityContext` will be used.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.PodSecurityContext", + "default": {}, + "examples": [ + { + "runAsUser": 50000, + "runAsGroup": 0, + "fsGroup": 0 + } + ] + }, + "containerLifecycleHooks": { + "description": "Container Lifecycle Hooks definition for the redis. If not set, the values from global `containerLifecycleHooks` will be used.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.Lifecycle", + "default": {}, + "x-docsSection": "Kubernetes", + "examples": [ + { + "postStart": { + "exec": { + "command": [ + "/bin/sh", + "-c", + "echo postStart handler > /usr/share/message" + ] + } + }, + "preStop": { + "exec": { + "command": [ + "/bin/sh", + "-c", + "echo preStop handler > /usr/share/message" + ] + } + } + } + ] + }, + "securityContexts": { + "description": "Security context definition for the redis.", + "type": "object", + "x-docsSection": "Kubernetes", + "properties": { + "pod": { + "description": "Pod security context definition for the redis.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.PodSecurityContext", + "default": {}, + "x-docsSection": "Kubernetes", + "examples": [ + { + "runAsUser": 999, + "runAsGroup": 0, + "fsGroup": 0 + } + ] + }, + "container": { + "description": "Container security context definition for the redis.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.SecurityContext", + "default": {}, + "x-docsSection": "Kubernetes", + "examples": [ + { + "allowPrivilegeEscalation": false, + "capabilities": { + "drop": [ + "ALL" + ] + } + } + ] + } + } + }, + "uid": { + "description": "Redis run as user parameter.", + "type": "integer", + "default": 0 + }, + "podAnnotations": { + "description": "Annotations to add to the redis pods.", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + } + } + }, + "registry": { + "description": "Auth secret for a private registry. This is used if pulling Airflow images from a private registry.", + "type": "object", + "x-docsSection": "Kubernetes", + "additionalProperties": false, + "properties": { + "secretName": { + "description": "Registry connection string secret.", + "type": [ + "string", + "null" + ], + "default": null + }, + "connection": { + "description": "Registry connection configuration.", + "type": "object", + "default": {}, + "additionalProperties": false, + "properties": { + "user": { + "description": "Username", + "type": "string", + "default": "" + }, + "pass": { + "description": "Password", + "type": "string", + "default": "" + }, + "host": { + "description": "Host", + "type": "string", + "default": "" + }, + "email": { + "description": "Email", + "type": "string", + "default": "" + } + }, + "examples": [ + { + "user": "...", + "pass": "...", + "host": "...", + "email": "..." + } + ] + } + } + }, + "elasticsearch": { + "description": "Elasticsearch logging configuration.", + "type": "object", + "x-docsSection": "Airflow", + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Enable Elasticsearch task logging.", + "type": "boolean", + "default": false + }, + "secretName": { + "description": "A secret containing the connection string.", + "type": [ + "string", + "null" + ], + "default": null + }, + "connection": { + "description": "Elasticsearch connection configuration.", + "type": "object", + "default": {}, + "additionalProperties": false, + "properties": { + "scheme": { + "description": "Scheme", + "type": "string", + "default": "http" + }, + "user": { + "description": "Username", + "type": "string", + "default": "" + }, + "pass": { + "description": "Password", + "type": "string", + "default": "" + }, + "host": { + "description": "Host", + "type": "string", + "default": "" + }, + "port": { + "description": "Port", + "type": "number", + "default": 80 + } + }, + "examples": [ + { + "scheme": "https", + "user": "...", + "pass": "...", + "host": "...", + "port": "..." + } + ] + } + } + }, + "ports": { + "description": "All ports used by chart.", + "type": "object", + "x-docsSection": "Ports", + "additionalProperties": false, + "properties": { + "flowerUI": { + "description": "Flower UI port.", + "type": "integer", + "default": 5555 + }, + "airflowUI": { + "description": "Airflow UI port.", + "type": "integer", + "default": 8080 + }, + "workerLogs": { + "description": "Worker logs port.", + "type": "integer", + "default": 8793 + }, + "triggererLogs": { + "description": "Triggerer logs port.", + "type": "integer", + "default": 8794 + }, + "redisDB": { + "description": "Redis port.", + "type": "integer", + "default": 6379 + }, + "statsdIngest": { + "description": "StatsD ingest port.", + "type": "integer", + "default": 9125 + }, + "statsdScrape": { + "description": "StatsD scrape port.", + "type": "integer", + "default": 9102 + }, + "pgbouncer": { + "description": "PgBouncer port.", + "type": "integer", + "default": 6543 + }, + "pgbouncerScrape": { + "description": "PgBouncer scrape port.", + "type": "integer", + "default": 9127 + } + } + }, + "quotas": { + "description": "Define any ResourceQuotas for namespace.", + "x-docsSection": "Kubernetes", + "default": {}, + "additionalProperties": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + } + }, + "limits": { + "description": "Define default/max/min values for pods and containers in namespace.", + "type": "array", + "x-docsSection": "Kubernetes", + "default": [], + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.LimitRangeItem" + } + }, + "cleanup": { + "description": "This runs as a CronJob to cleanup old pods.", + "type": "object", + "x-docsSection": "Jobs", + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Enable cleanup.", + "type": "boolean", + "default": false + }, + "schedule": { + "description": "Cleanup schedule (templated).", + "type": "string", + "default": "*/15 * * * *" + }, + "command": { + "description": "Command to use when running the cleanup cronjob (templated).", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + }, + "default": null + }, + "args": { + "description": "Args to use when running the cleanup cronjob (templated).", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + }, + "default": [ + "bash", + "-c", + "exec airflow kubernetes cleanup-pods --namespace={{ .Release.Namespace }}" + ] + }, + "jobAnnotations": { + "description": "Annotations to add to the cleanup cronjob.", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + }, + "nodeSelector": { + "description": "Select certain nodes for cleanup pods.", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + }, + "affinity": { + "description": "Specify scheduling constraints for cleanup pods.", + "type": "object", + "default": {}, + "$ref": "#/definitions/io.k8s.api.core.v1.Affinity" + }, + "tolerations": { + "description": "Specify Tolerations for cleanup pods.", + "type": "array", + "default": [], + "items": { + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.Toleration" + } + }, + "topologySpreadConstraints": { + "description": "Specify topology spread constraints for cleanup pods.", + "type": "array", + "default": [], + "items": { + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.TopologySpreadConstraint" + } + }, + "podAnnotations": { + "description": "Annotations to add to cleanup pods.", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + }, + "labels": { + "description": "labels to add to cleanup pods.", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + }, + "resources": { + "description": "Resources for or cleanup pods", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.ResourceRequirements", + "default": {}, + "examples": [ + { + "limits": { + "cpu": "100m", + "memory": "128Mi" + }, + "requests": { + "cpu": "100m", + "memory": "128Mi" + } + } + ] + }, + "serviceAccount": { + "description": "Create ServiceAccount.", + "type": "object", + "additionalProperties": false, + "properties": { + "automountServiceAccountToken": { + "description": "Specifies if ServiceAccount's API credentials should be mounted onto Pods", + "type": "boolean", + "default": true + }, + "create": { + "description": "Specifies whether a ServiceAccount should be created.", + "type": "boolean", + "default": true + }, + "name": { + "description": "The name of the ServiceAccount to use. If not set and create is true, a name is generated using the release name.", + "type": [ + "string", + "null" + ], + "default": null + }, + "annotations": { + "description": "Annotations to add to the cleanup CronJob Kubernetes ServiceAccount.", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + } + } + }, + "securityContext": { + "description": "Security context for the cleanup job pod (deprecated, use `securityContexts` instead). If not set, the values from `securityContext` will be used.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.PodSecurityContext", + "default": {}, + "examples": [ + { + "runAsUser": 50000, + "runAsGroup": 0, + "fsGroup": 0 + } + ] + }, + "containerLifecycleHooks": { + "description": "Container Lifecycle Hooks definition for the cleanup. If not set, the values from global `containerLifecycleHooks` will be used.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.Lifecycle", + "default": {}, + "x-docsSection": "Kubernetes", + "examples": [ + { + "postStart": { + "exec": { + "command": [ + "/bin/sh", + "-c", + "echo postStart handler > /usr/share/message" + ] + } + }, + "preStop": { + "exec": { + "command": [ + "/bin/sh", + "-c", + "echo preStop handler > /usr/share/message" + ] + } + } + } + ] + }, + "securityContexts": { + "description": "Security context definition for the cleanup. If not set, the values from global `securityContexts` will be used.", + "type": "object", + "x-docsSection": "Kubernetes", + "properties": { + "pod": { + "description": "Pod security context definition for the cleanup.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.PodSecurityContext", + "default": {}, + "x-docsSection": "Kubernetes", + "examples": [ + { + "runAsUser": 50000, + "runAsGroup": 0, + "fsGroup": 0 + } + ] + }, + "container": { + "description": "Container security context definition for the cleanup.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.SecurityContext", + "default": {}, + "x-docsSection": "Kubernetes", + "examples": [ + { + "allowPrivilegeEscalation": false, + "capabilities": { + "drop": [ + "ALL" + ] + } + } + ] + } + } + }, + "env": { + "description": "Add additional env vars to cleanup.", + "type": "array", + "default": [], + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": [ + "name", + "value" + ], + "additionalProperties": false + } + }, + "failedJobsHistoryLimit": { + "description": "The failed jobs history limit specifies the number of failed jobs to retain.", + "type": [ + "integer", + "null" + ], + "default": null, + "x-docsSection": null + }, + "successfulJobsHistoryLimit": { + "description": "The successful jobs history limit specifies the number of finished jobs to retain.", + "type": [ + "integer", + "null" + ], + "default": null, + "x-docsSection": null + } + } + }, + "postgresql": { + "description": "Configuration for PostgreSQL subchart.", + "type": "object", + "x-docsSection": "Database", + "properties": { + "enabled": { + "description": "Enable PostgreSQL subchart.", + "type": "boolean", + "default": true + }, + "images": { + "description": "PostgreSQL image values.", + "type": "object", + "additionalProperties": true, + "properties": { + "tag": { + "description": "The PostgreSQL image tag.", + "type": "string", + "default": "11" + } + } + }, + "auth": { + "description": "PostgreSQL authentication values.", + "type": "object", + "additionalProperties": true, + "properties": { + "enablePostgresUser": { + "description": "Assign a password to the 'postgres' admin user. Otherwise, remote access will be blocked for this user", + "type": "boolean", + "default": true + }, + "postgresPassword": { + "description": "Password for the 'postgres' admin user.", + "type": [ + "string", + "null" + ], + "default": "postgres" + }, + "username": { + "description": "Name for a custom user to create", + "type": [ + "string", + "null" + ], + "default": "" + }, + "password": { + "description": "Password for the custom user to create.", + "type": [ + "string", + "null" + ], + "default": "" + } + } + } + } + }, + "config": { + "description": "Settings to go into the mounted airflow.cfg", + "type": "object", + "x-docsSection": "Common", + "default": "See values.yaml", + "additionalProperties": { + "type": "object", + "additionalProperties": { + "type": [ + "boolean", + "integer", + "number", + "string" + ] + } + } + }, + "multiNamespaceMode": { + "description": "Whether Airflow can launch workers and/or pods in multiple namespaces. If true, it creates ``ClusterRole``/``ClusterRolebinding`` (with access to entire cluster)", + "x-docsSection": "Airflow", + "type": "boolean", + "default": false + }, + "podTemplate": { + "description": "The contents of ``pod_template_file.yaml`` used for KubernetesExecutor workers (templated). The default (see ``files/pod-template-file.kubernetes-helm-yaml``) already takes into account normal ``workers`` configuration parameters (e.g. ``workers.resources``), so you normally won't need to override this directly.", + "type": [ + "string", + "null" + ], + "x-docsSection": "Airflow", + "default": null, + "examples": [ + "apiVersion: v1\nkind: Pod\nmetadata:\n name: placeholder-name\n labels:\n tier: airflow\n component: worker\n release: {{ .Release.Name }}\nspec:\n priorityClassName: high-priority\n containers:\n - name: base\n ..." + ] + }, + "dags": { + "description": "DAGs settings.", + "type": "object", + "x-docsSection": "Airflow", + "additionalProperties": false, + "properties": { + "persistence": { + "description": "Persistence configuration.", + "type": "object", + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Enable persistent volume for storing dags.", + "type": "boolean", + "default": false + }, + "size": { + "description": "Volume size for dags.", + "type": "string", + "default": "1Gi" + }, + "storageClassName": { + "description": "If using a custom StorageClass, pass name here.", + "type": [ + "string", + "null" + ], + "default": null + }, + "accessMode": { + "description": "Access mode of the persistent volume.", + "type": "string", + "enum": [ + "ReadWriteOnce", + "ReadOnlyMany", + "ReadWriteMany" + ], + "default": "ReadWriteOnce" + }, + "existingClaim": { + "description": "The name of an existing PVC to use.", + "type": [ + "string", + "null" + ], + "default": null + }, + "annotations": { + "description": "Annotations for the dag PVC", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + }, + "subPath": { + "description": "Subpath within the PVC where dags are located.", + "type": [ + "string", + "null" + ], + "default": null + } + } + }, + "gitSync": { + "description": "Git sync settings.", + "type": "object", + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Enable Git sync.", + "type": "boolean", + "default": false + }, + "repo": { + "description": "Git repository.", + "type": "string", + "default": "https://github.com/apache/airflow.git" + }, + "branch": { + "description": "Git branch", + "type": "string", + "default": "v2-2-stable" + }, + "rev": { + "description": "Git revision.", + "type": "string", + "default": "HEAD" + }, + "depth": { + "description": "Repository depth.", + "type": "integer", + "default": 1 + }, + "maxFailures": { + "description": "The number of consecutive failures allowed before aborting.", + "type": "integer", + "default": 0 + }, + "subPath": { + "description": "Subpath within the repo where dags are located.", + "type": "string", + "default": "tests/dags" + }, + "wait": { + "description": "Interval between git sync attempts in seconds. High values are more likely to cause DAGs to become out of sync between different components. Low values cause more traffic to the remote git repository.", + "type": "integer", + "default": 5 + }, + "containerName": { + "description": "Git sync container name.", + "type": "string", + "default": "git-sync" + }, + "securityContext": { + "description": "Security context for the `gitSync` container (deprecated, use `securityContexts` instead). If not set, the values from `securityContext` will be used.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.SecurityContext", + "default": {}, + "examples": [ + { + "runAsUser": 50000, + "runAsGroup": 0 + } + ] + }, + "containerLifecycleHooks": { + "description": "Container Lifecycle Hooks definition for the git sync sidecar. If not set, the values from global `containerLifecycleHooks` will be used.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.Lifecycle", + "default": {}, + "x-docsSection": "Kubernetes", + "examples": [ + { + "postStart": { + "exec": { + "command": [ + "/bin/sh", + "-c", + "echo postStart handler > /usr/share/message" + ] + } + }, + "preStop": { + "exec": { + "command": [ + "/bin/sh", + "-c", + "echo preStop handler > /usr/share/message" + ] + } + } + } + ] + }, + "securityContexts": { + "description": "Security context definition for the git sync sidecar. If not set, the values from global `securityContexts` will be used.", + "type": "object", + "x-docsSection": "Kubernetes", + "properties": { + "container": { + "description": "Container security context definition for the git sync sidecar.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.SecurityContext", + "default": {}, + "x-docsSection": "Kubernetes", + "examples": [ + { + "allowPrivilegeEscalation": false, + "capabilities": { + "drop": [ + "ALL" + ] + } + } + ] + } + } + }, + "uid": { + "description": "Git sync container run as user parameter.", + "type": "integer", + "default": 65533 + }, + "extraVolumeMounts": { + "description": "Mount additional volumes into git sync container.", + "type": "array", + "default": [], + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.VolumeMount" + } + }, + "credentialsSecret": { + "description": "Name of a Secret containing the repo `GIT_SYNC_USERNAME` and `GIT_SYNC_PASSWORD`.", + "type": [ + "string", + "null" + ], + "default": null + }, + "sshKeySecret": { + "description": "Name of a Secret containing the repo `sshKeySecret`.", + "type": [ + "string", + "null" + ], + "default": null + }, + "knownHosts": { + "description": "When using a ssh private key, the contents of your `known_hosts` file.", + "type": [ + "string", + "null" + ], + "default": null, + "examples": [ + ", \n, ", + ", " + ] + }, + "env": { + "description": "Environment variables for git sync container.", + "type": "array", + "default": [], + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": [ + "name", + "value" + ], + "additionalProperties": false + }, + "examples": [ + { + "name": "GIT_SYNC_TIMEOUT", + "value": "60" + } + ] + }, + "resources": { + "description": "Resources on workers git-sync sidecar", + "type": "object", + "default": {}, + "examples": [ + { + "limits": { + "cpu": "100m", + "memory": "128Mi" + }, + "requests": { + "cpu": "100m", + "memory": "128Mi" + } + } + ], + "$ref": "#/definitions/io.k8s.api.core.v1.ResourceRequirements" + } + } + } + } + }, + "logs": { + "description": "Logs settings.", + "type": "object", + "x-docsSection": "Airflow", + "additionalProperties": false, + "properties": { + "persistence": { + "description": "Persistence configuration.", + "type": "object", + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Enable persistent volume for storing logs.", + "type": "boolean", + "default": false + }, + "size": { + "description": "Volume size for logs.", + "type": "string", + "default": "100Gi" + }, + "storageClassName": { + "description": "If using a custom StorageClass, pass name here.", + "type": [ + "string", + "null" + ], + "default": null + }, + "annotations": { + "description": "Annotations to add to logs PVC", + "type": "object", + "default": {}, + "additionalProperties": { + "type": "string" + } + }, + "existingClaim": { + "description": "The name of an existing PVC to use.", + "type": [ + "string", + "null" + ], + "default": null + } + } + } + } + } + }, + "definitions": { + "io.k8s.api.apps.v1.DeploymentStrategy": { + "description": "DeploymentStrategy describes how to replace existing pods with new ones.", + "properties": { + "rollingUpdate": { + "$ref": "#/definitions/io.k8s.api.apps.v1.RollingUpdateDeployment", + "description": "Rolling update config params. Present only if DeploymentStrategyType = RollingUpdate." + }, + "type": { + "description": "Type of deployment. Can be \"Recreate\" or \"RollingUpdate\". Default is RollingUpdate.", + "type": "string" + } + }, + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.apps.v1.RollingUpdateDeployment": { + "description": "Spec to control the desired behavior of rolling update.", + "properties": { + "maxSurge": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.util.intstr.IntOrString", + "description": "The maximum number of pods that can be scheduled above the desired number of pods. Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). This can not be 0 if MaxUnavailable is 0. Absolute number is calculated from percentage by rounding up. Defaults to 25%. Example: when this is set to 30%, the new ReplicaSet can be scaled up immediately when the rolling update starts, such that the total number of old and new pods do not exceed 130% of desired pods. Once old pods have been killed, new ReplicaSet can be scaled up further, ensuring that total number of pods running at any time during the update is at most 130% of desired pods." + }, + "maxUnavailable": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.util.intstr.IntOrString", + "description": "The maximum number of pods that can be unavailable during the update. Value can be an absolute number (ex: 5) or a percentage of desired pods (ex: 10%). Absolute number is calculated from percentage by rounding down. This can not be 0 if MaxSurge is 0. Defaults to 25%. Example: when this is set to 30%, the old ReplicaSet can be scaled down to 70% of desired pods immediately when the rolling update starts. Once new pods are ready, old ReplicaSet can be scaled down further, followed by scaling up the new ReplicaSet, ensuring that the total number of pods available at all times during the update is at least 70% of desired pods." + } + }, + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.autoscaling.v2beta2.HPAScalingPolicy": { + "description": "HPAScalingPolicy is a single policy which must hold true for a specified past interval.", + "properties": { + "periodSeconds": { + "description": "PeriodSeconds specifies the window of time for which the policy should hold true. PeriodSeconds must be greater than zero and less than or equal to 1800 (30 min).", + "format": "int32", + "type": "integer" + }, + "type": { + "description": "Type is used to specify the scaling policy.", + "type": "string" + }, + "value": { + "description": "Value contains the amount of change which is permitted by the policy. It must be greater than zero", + "format": "int32", + "type": "integer" + } + }, + "required": [ + "type", + "value", + "periodSeconds" + ], + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.autoscaling.v2beta2.HPAScalingRules": { + "description": "HPAScalingRules configures the scaling behavior for one direction. These Rules are applied after calculating DesiredReplicas from metrics for the HPA. They can limit the scaling velocity by specifying scaling policies. They can prevent flapping by specifying the stabilization window, so that the number of replicas is not set instantly, instead, the safest value from the stabilization window is chosen.", + "properties": { + "policies": { + "description": "policies is a list of potential scaling polices which can be used during scaling. At least one policy must be specified, otherwise the HPAScalingRules will be discarded as invalid", + "items": { + "$ref": "#/definitions/io.k8s.api.autoscaling.v2beta2.HPAScalingPolicy" + }, + "type": "array" + }, + "selectPolicy": { + "description": "selectPolicy is used to specify which policy should be used. If not set, the default value MaxPolicySelect is used.", + "type": "string" + }, + "stabilizationWindowSeconds": { + "description": "StabilizationWindowSeconds is the number of seconds for which past recommendations should be considered while scaling up or scaling down. StabilizationWindowSeconds must be greater than or equal to zero and less than or equal to 3600 (one hour). If not set, use the default values: - For scale up: 0 (i.e. no stabilization is done). - For scale down: 300 (i.e. the stabilization window is 300 seconds long).", + "format": "int32", + "type": "integer" + } + }, + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.autoscaling.v2beta2.HorizontalPodAutoscalerBehavior": { + "description": "HorizontalPodAutoscalerBehavior configures the scaling behavior of the target in both Up and Down directions (scaleUp and scaleDown fields respectively).", + "properties": { + "scaleDown": { + "$ref": "#/definitions/io.k8s.api.autoscaling.v2beta2.HPAScalingRules", + "description": "scaleDown is scaling policy for scaling Down. If not set, the default value is to allow to scale down to minReplicas pods, with a 300 second stabilization window (i.e., the highest recommendation for the last 300sec is used)." + }, + "scaleUp": { + "$ref": "#/definitions/io.k8s.api.autoscaling.v2beta2.HPAScalingRules", + "description": "scaleUp is scaling policy for scaling Up. If not set, the default value is the higher of:\n * increase no more than 4 pods per 60 seconds\n * double the number of pods per 60 seconds\nNo stabilization is used." + } + }, + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.AWSElasticBlockStoreVolumeSource": { + "description": "Represents a Persistent Disk resource in AWS.\n\nAn AWS EBS disk must exist before mounting to a container. The disk must also be in the same AWS zone as the kubelet. An AWS EBS disk can only be mounted as read/write once. AWS EBS volumes support ownership management and SELinux relabeling.", + "properties": { + "fsType": { + "description": "Filesystem type of the volume that you want to mount. Tip: Ensure that the filesystem type is supported by the host operating system. Examples: \"ext4\", \"xfs\", \"ntfs\". Implicitly inferred to be \"ext4\" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore", + "type": "string" + }, + "partition": { + "description": "The partition in the volume that you want to mount. If omitted, the default is to mount by volume name. Examples: For volume /dev/sda1, you specify the partition as \"1\". Similarly, the volume partition for /dev/sda is \"0\" (or you can leave the property empty).", + "format": "int32", + "type": "integer" + }, + "readOnly": { + "description": "Specify \"true\" to force and set the ReadOnly property in VolumeMounts to \"true\". If omitted, the default is \"false\". More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore", + "type": "boolean" + }, + "volumeID": { + "description": "Unique ID of the persistent disk resource in AWS (Amazon EBS volume). More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore", + "type": "string" + } + }, + "required": [ + "volumeID" + ], + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.Affinity": { + "description": "Affinity is a group of affinity scheduling rules.", + "properties": { + "nodeAffinity": { + "$ref": "#/definitions/io.k8s.api.core.v1.NodeAffinity", + "description": "Describes node affinity scheduling rules for the pod." + }, + "podAffinity": { + "$ref": "#/definitions/io.k8s.api.core.v1.PodAffinity", + "description": "Describes pod affinity scheduling rules (e.g. co-locate this pod in the same node, zone, etc. as some other pod(s))." + }, + "podAntiAffinity": { + "$ref": "#/definitions/io.k8s.api.core.v1.PodAntiAffinity", + "description": "Describes pod anti-affinity scheduling rules (e.g. avoid putting this pod in the same node, zone, etc. as some other pod(s))." + } + }, + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.AzureDiskVolumeSource": { + "description": "AzureDisk represents an Azure Data Disk mount on the host and bind mount to the pod.", + "properties": { + "cachingMode": { + "description": "Host Caching mode: None, Read Only, Read Write.", + "type": "string" + }, + "diskName": { + "description": "The Name of the data disk in the blob storage", + "type": "string" + }, + "diskURI": { + "description": "The URI the data disk in the blob storage", + "type": "string" + }, + "fsType": { + "description": "Filesystem type to mount. Must be a filesystem type supported by the host operating system. Ex. \"ext4\", \"xfs\", \"ntfs\". Implicitly inferred to be \"ext4\" if unspecified.", + "type": "string" + }, + "kind": { + "description": "Expected values Shared: multiple blob disks per storage account Dedicated: single blob disk per storage account Managed: azure managed data disk (only in managed availability set). defaults to shared", + "type": "string" + }, + "readOnly": { + "description": "Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts.", + "type": "boolean" + } + }, + "required": [ + "diskName", + "diskURI" + ], + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.AzureFileVolumeSource": { + "description": "AzureFile represents an Azure File Service mount on the host and bind mount to the pod.", + "properties": { + "readOnly": { + "description": "Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts.", + "type": "boolean" + }, + "secretName": { + "description": "the name of secret that contains Azure Storage Account Name and Key", + "type": "string" + }, + "shareName": { + "description": "Share Name", + "type": "string" + } + }, + "required": [ + "secretName", + "shareName" + ], + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.CSIVolumeSource": { + "description": "Represents a source location of a volume to mount, managed by an external CSI driver", + "properties": { + "driver": { + "description": "Driver is the name of the CSI driver that handles this volume. Consult with your admin for the correct name as registered in the cluster.", + "type": "string" + }, + "fsType": { + "description": "Filesystem type to mount. Ex. \"ext4\", \"xfs\", \"ntfs\". If not provided, the empty value is passed to the associated CSI driver which will determine the default filesystem to apply.", + "type": "string" + }, + "nodePublishSecretRef": { + "$ref": "#/definitions/io.k8s.api.core.v1.LocalObjectReference", + "description": "NodePublishSecretRef is a reference to the secret object containing sensitive information to pass to the CSI driver to complete the CSI NodePublishVolume and NodeUnpublishVolume calls. This field is optional, and may be empty if no secret is required. If the secret object contains more than one secret, all secret references are passed." + }, + "readOnly": { + "description": "Specifies a read-only configuration for the volume. Defaults to false (read/write).", + "type": "boolean" + }, + "volumeAttributes": { + "additionalProperties": { + "type": "string" + }, + "description": "VolumeAttributes stores driver-specific properties that are passed to the CSI driver. Consult your driver's documentation for supported values.", + "type": "object" + } + }, + "required": [ + "driver" + ], + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.Capabilities": { + "description": "Adds and removes POSIX capabilities from running containers.", + "properties": { + "add": { + "description": "Added capabilities", + "items": { + "type": "string" + }, + "type": "array" + }, + "drop": { + "description": "Removed capabilities", + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.CephFSVolumeSource": { + "description": "Represents a Ceph Filesystem mount that lasts the lifetime of a pod Cephfs volumes do not support ownership management or SELinux relabeling.", + "properties": { + "monitors": { + "description": "Required: Monitors is a collection of Ceph monitors More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it", + "items": { + "type": "string" + }, + "type": "array" + }, + "path": { + "description": "Optional: Used as the mounted root, rather than the full Ceph tree, default is /", + "type": "string" + }, + "readOnly": { + "description": "Optional: Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it", + "type": "boolean" + }, + "secretFile": { + "description": "Optional: SecretFile is the path to key ring for User, default is /etc/ceph/user.secret More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it", + "type": "string" + }, + "secretRef": { + "$ref": "#/definitions/io.k8s.api.core.v1.LocalObjectReference", + "description": "Optional: SecretRef is reference to the authentication secret for User, default is empty. More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it" + }, + "user": { + "description": "Optional: User is the rados user name, default is admin More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it", + "type": "string" + } + }, + "required": [ + "monitors" + ], + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.CinderVolumeSource": { + "description": "Represents a cinder volume resource in Openstack. A Cinder volume must exist before mounting to a container. The volume must also be in the same region as the kubelet. Cinder volumes support ownership management and SELinux relabeling.", + "properties": { + "fsType": { + "description": "Filesystem type to mount. Must be a filesystem type supported by the host operating system. Examples: \"ext4\", \"xfs\", \"ntfs\". Implicitly inferred to be \"ext4\" if unspecified. More info: https://examples.k8s.io/mysql-cinder-pd/README.md", + "type": "string" + }, + "readOnly": { + "description": "Optional: Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts. More info: https://examples.k8s.io/mysql-cinder-pd/README.md", + "type": "boolean" + }, + "secretRef": { + "$ref": "#/definitions/io.k8s.api.core.v1.LocalObjectReference", + "description": "Optional: points to a secret object containing parameters used to connect to OpenStack." + }, + "volumeID": { + "description": "volume id used to identify the volume in cinder. More info: https://examples.k8s.io/mysql-cinder-pd/README.md", + "type": "string" + } + }, + "required": [ + "volumeID" + ], + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.ConfigMapEnvSource": { + "description": "ConfigMapEnvSource selects a ConfigMap to populate the environment variables with.\n\nThe contents of the target ConfigMap's Data field will represent the key-value pairs as environment variables.", + "properties": { + "name": { + "description": "Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names", + "type": "string" + }, + "optional": { + "description": "Specify whether the ConfigMap must be defined", + "type": "boolean" + } + }, + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.ConfigMapKeySelector": { + "description": "Selects a key from a ConfigMap.", + "properties": { + "key": { + "description": "The key to select.", + "type": "string" + }, + "name": { + "description": "Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names", + "type": "string" + }, + "optional": { + "description": "Specify whether the ConfigMap or its key must be defined", + "type": "boolean" + } + }, + "required": [ + "key" + ], + "type": "object", + "x-kubernetes-map-type": "atomic", + "additionalProperties": false + }, + "io.k8s.api.core.v1.ConfigMapProjection": { + "description": "Adapts a ConfigMap into a projected volume.\n\nThe contents of the target ConfigMap's Data field will be presented in a projected volume as files using the keys in the Data field as the file names, unless the items element is populated with specific mappings of keys to paths. Note that this is identical to a configmap volume source without the default mode.", + "properties": { + "items": { + "description": "If unspecified, each key-value pair in the Data field of the referenced ConfigMap will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the ConfigMap, the volume setup will error unless it is marked optional. Paths must be relative and may not contain the '..' path or start with '..'.", + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.KeyToPath" + }, + "type": "array" + }, + "name": { + "description": "Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names", + "type": "string" + }, + "optional": { + "description": "Specify whether the ConfigMap or its keys must be defined", + "type": "boolean" + } + }, + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.ConfigMapVolumeSource": { + "description": "Adapts a ConfigMap into a volume.\n\nThe contents of the target ConfigMap's Data field will be presented in a volume as files using the keys in the Data field as the file names, unless the items element is populated with specific mappings of keys to paths. ConfigMap volumes support ownership management and SELinux relabeling.", + "properties": { + "defaultMode": { + "description": "Optional: mode bits used to set permissions on created files by default. Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. Defaults to 0644. Directories within the path are not affected by this setting. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.", + "format": "int32", + "type": "integer" + }, + "items": { + "description": "If unspecified, each key-value pair in the Data field of the referenced ConfigMap will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the ConfigMap, the volume setup will error unless it is marked optional. Paths must be relative and may not contain the '..' path or start with '..'.", + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.KeyToPath" + }, + "type": "array" + }, + "name": { + "description": "Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names", + "type": "string" + }, + "optional": { + "description": "Specify whether the ConfigMap or its keys must be defined", + "type": "boolean" + } + }, + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.Container": { + "description": "A single application container that you want to run within a pod.", + "properties": { + "args": { + "description": "Arguments to the entrypoint. The docker image's CMD is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. \"$$(VAR_NAME)\" will produce the string literal \"$(VAR_NAME)\". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell", + "items": { + "type": "string" + }, + "type": "array" + }, + "command": { + "description": "Entrypoint array. Not executed within a shell. The docker image's ENTRYPOINT is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. \"$$(VAR_NAME)\" will produce the string literal \"$(VAR_NAME)\". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell", + "items": { + "type": "string" + }, + "type": "array" + }, + "env": { + "description": "List of environment variables to set in the container. Cannot be updated.", + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.EnvVar" + }, + "type": "array", + "x-kubernetes-patch-merge-key": "name", + "x-kubernetes-patch-strategy": "merge" + }, + "envFrom": { + "description": "List of sources to populate environment variables in the container. The keys defined within a source must be a C_IDENTIFIER. All invalid keys will be reported as an event when the container is starting. When a key exists in multiple sources, the value associated with the last source will take precedence. Values defined by an Env with a duplicate key will take precedence. Cannot be updated.", + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.EnvFromSource" + }, + "type": "array" + }, + "image": { + "description": "Docker image name. More info: https://kubernetes.io/docs/concepts/containers/images This field is optional to allow higher level config management to default or override container images in workload controllers like Deployments and StatefulSets.", + "type": "string" + }, + "imagePullPolicy": { + "description": "Image pull policy. One of Always, Never, IfNotPresent. Defaults to Always if :latest tag is specified, or IfNotPresent otherwise. Cannot be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images", + "type": "string" + }, + "lifecycle": { + "$ref": "#/definitions/io.k8s.api.core.v1.Lifecycle", + "description": "Actions that the management system should take in response to container lifecycle events. Cannot be updated." + }, + "livenessProbe": { + "$ref": "#/definitions/io.k8s.api.core.v1.Probe", + "description": "Periodic probe of container liveness. Container will be restarted if the probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes" + }, + "name": { + "description": "Name of the container specified as a DNS_LABEL. Each container in a pod must have a unique name (DNS_LABEL). Cannot be updated.", + "type": "string" + }, + "ports": { + "description": "List of ports to expose from the container. Exposing a port here gives the system additional information about the network connections a container uses, but is primarily informational. Not specifying a port here DOES NOT prevent that port from being exposed. Any port which is listening on the default \"0.0.0.0\" address inside a container will be accessible from the network. Cannot be updated.", + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.ContainerPort" + }, + "type": "array", + "x-kubernetes-list-map-keys": [ + "containerPort", + "protocol" + ], + "x-kubernetes-list-type": "map", + "x-kubernetes-patch-merge-key": "containerPort", + "x-kubernetes-patch-strategy": "merge" + }, + "readinessProbe": { + "$ref": "#/definitions/io.k8s.api.core.v1.Probe", + "description": "Periodic probe of container service readiness. Container will be removed from service endpoints if the probe fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes" + }, + "resources": { + "$ref": "#/definitions/io.k8s.api.core.v1.ResourceRequirements", + "description": "Compute Resources required by this container. Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/" + }, + "securityContext": { + "$ref": "#/definitions/io.k8s.api.core.v1.SecurityContext", + "description": "SecurityContext defines the security options the container should be run with. If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/" + }, + "startupProbe": { + "$ref": "#/definitions/io.k8s.api.core.v1.Probe", + "description": "StartupProbe indicates that the Pod has successfully initialized. If specified, no other probes are executed until this completes successfully. If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. This can be used to provide different probe parameters at the beginning of a Pod's lifecycle, when it might take a long time to load data or warm a cache, than during steady-state operation. This cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes" + }, + "stdin": { + "description": "Whether this container should allocate a buffer for stdin in the container runtime. If this is not set, reads from stdin in the container will always result in EOF. Default is false.", + "type": "boolean" + }, + "stdinOnce": { + "description": "Whether the container runtime should close the stdin channel after it has been opened by a single attach. When stdin is true the stdin stream will remain open across multiple attach sessions. If stdinOnce is set to true, stdin is opened on container start, is empty until the first client attaches to stdin, and then remains open and accepts data until the client disconnects, at which time stdin is closed and remains closed until the container is restarted. If this flag is false, a container processes that reads from stdin will never receive an EOF. Default is false", + "type": "boolean" + }, + "terminationMessagePath": { + "description": "Optional: Path at which the file to which the container's termination message will be written is mounted into the container's filesystem. Message written is intended to be brief final status, such as an assertion failure message. Will be truncated by the node if greater than 4096 bytes. The total message length across all containers will be limited to 12kb. Defaults to /dev/termination-log. Cannot be updated.", + "type": "string" + }, + "terminationMessagePolicy": { + "description": "Indicate how the termination message should be populated. File will use the contents of terminationMessagePath to populate the container status message on both success and failure. FallbackToLogsOnError will use the last chunk of container log output if the termination message file is empty and the container exited with an error. The log output is limited to 2048 bytes or 80 lines, whichever is smaller. Defaults to File. Cannot be updated.", + "type": "string" + }, + "tty": { + "description": "Whether this container should allocate a TTY for itself, also requires 'stdin' to be true. Default is false.", + "type": "boolean" + }, + "volumeDevices": { + "description": "volumeDevices is the list of block devices to be used by the container.", + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.VolumeDevice" + }, + "type": "array", + "x-kubernetes-patch-merge-key": "devicePath", + "x-kubernetes-patch-strategy": "merge" + }, + "volumeMounts": { + "description": "Pod volumes to mount into the container's filesystem. Cannot be updated.", + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.VolumeMount" + }, + "type": "array", + "x-kubernetes-patch-merge-key": "mountPath", + "x-kubernetes-patch-strategy": "merge" + }, + "workingDir": { + "description": "Container's working directory. If not specified, the container runtime's default will be used, which might be configured in the container image. Cannot be updated.", + "type": "string" + } + }, + "required": [ + "name" + ], + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.ContainerPort": { + "description": "ContainerPort represents a network port in a single container.", + "properties": { + "containerPort": { + "description": "Number of port to expose on the pod's IP address. This must be a valid port number, 0 < x < 65536.", + "format": "int32", + "type": "integer" + }, + "hostIP": { + "description": "What host IP to bind the external port to.", + "type": "string" + }, + "hostPort": { + "description": "Number of port to expose on the host. If specified, this must be a valid port number, 0 < x < 65536. If HostNetwork is specified, this must match ContainerPort. Most containers do not need this.", + "format": "int32", + "type": "integer" + }, + "name": { + "description": "If specified, this must be an IANA_SVC_NAME and unique within the pod. Each named port in a pod must have a unique name. Name for the port that can be referred to by services.", + "type": "string" + }, + "protocol": { + "description": "Protocol for port. Must be UDP, TCP, or SCTP. Defaults to \"TCP\".", + "type": "string" + } + }, + "required": [ + "containerPort" + ], + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.DownwardAPIProjection": { + "description": "Represents downward API info for projecting into a projected volume. Note that this is identical to a downwardAPI volume source without the default mode.", + "properties": { + "items": { + "description": "Items is a list of DownwardAPIVolume file", + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.DownwardAPIVolumeFile" + }, + "type": "array" + } + }, + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.DownwardAPIVolumeFile": { + "description": "DownwardAPIVolumeFile represents information to create the file containing the pod field", + "properties": { + "fieldRef": { + "$ref": "#/definitions/io.k8s.api.core.v1.ObjectFieldSelector", + "description": "Required: Selects a field of the pod: only annotations, labels, name and namespace are supported." + }, + "mode": { + "description": "Optional: mode bits used to set permissions on this file, must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. If not specified, the volume defaultMode will be used. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.", + "format": "int32", + "type": "integer" + }, + "path": { + "description": "Required: Path is the relative path name of the file to be created. Must not be absolute or contain the '..' path. Must be utf-8 encoded. The first item of the relative path must not start with '..'", + "type": "string" + }, + "resourceFieldRef": { + "$ref": "#/definitions/io.k8s.api.core.v1.ResourceFieldSelector", + "description": "Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported." + } + }, + "required": [ + "path" + ], + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.DownwardAPIVolumeSource": { + "description": "DownwardAPIVolumeSource represents a volume containing downward API info. Downward API volumes support ownership management and SELinux relabeling.", + "properties": { + "defaultMode": { + "description": "Optional: mode bits to use on created files by default. Must be a Optional: mode bits used to set permissions on created files by default. Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. Defaults to 0644. Directories within the path are not affected by this setting. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.", + "format": "int32", + "type": "integer" + }, + "items": { + "description": "Items is a list of downward API volume file", + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.DownwardAPIVolumeFile" + }, + "type": "array" + } + }, + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.EmptyDirVolumeSource": { + "description": "Represents an empty directory for a pod. Empty directory volumes support ownership management and SELinux relabeling.", + "properties": { + "medium": { + "description": "What type of storage medium should back this directory. The default is \"\" which means to use the node's default medium. Must be an empty string (default) or Memory. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir", + "type": "string" + }, + "sizeLimit": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.api.resource.Quantity", + "description": "Total amount of local storage required for this EmptyDir volume. The size limit is also applicable for memory medium. The maximum usage on memory medium EmptyDir would be the minimum value between the SizeLimit specified here and the sum of memory limits of all containers in a pod. The default is nil which means that the limit is undefined. More info: http://kubernetes.io/docs/user-guide/volumes#emptydir" + } + }, + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.EnvFromSource": { + "description": "EnvFromSource represents the source of a set of ConfigMaps", + "properties": { + "configMapRef": { + "$ref": "#/definitions/io.k8s.api.core.v1.ConfigMapEnvSource", + "description": "The ConfigMap to select from" + }, + "prefix": { + "description": "An optional identifier to prepend to each key in the ConfigMap. Must be a C_IDENTIFIER.", + "type": "string" + }, + "secretRef": { + "$ref": "#/definitions/io.k8s.api.core.v1.SecretEnvSource", + "description": "The Secret to select from" + } + }, + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.EnvVar": { + "description": "EnvVar represents an environment variable present in a Container.", + "properties": { + "name": { + "description": "Name of the environment variable. Must be a C_IDENTIFIER.", + "type": "string" + }, + "value": { + "description": "Variable references $(VAR_NAME) are expanded using the previously defined environment variables in the container and any service environment variables. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. \"$$(VAR_NAME)\" will produce the string literal \"$(VAR_NAME)\". Escaped references will never be expanded, regardless of whether the variable exists or not. Defaults to \"\".", + "type": "string" + }, + "valueFrom": { + "$ref": "#/definitions/io.k8s.api.core.v1.EnvVarSource", + "description": "Source for the environment variable's value. Cannot be used if value is not empty." + } + }, + "required": [ + "name" + ], + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.EnvVarSource": { + "description": "EnvVarSource represents a source for the value of an EnvVar.", + "properties": { + "configMapKeyRef": { + "$ref": "#/definitions/io.k8s.api.core.v1.ConfigMapKeySelector", + "description": "Selects a key of a ConfigMap." + }, + "fieldRef": { + "$ref": "#/definitions/io.k8s.api.core.v1.ObjectFieldSelector", + "description": "Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['']`, `metadata.annotations['']`, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs." + }, + "resourceFieldRef": { + "$ref": "#/definitions/io.k8s.api.core.v1.ResourceFieldSelector", + "description": "Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported." + }, + "secretKeyRef": { + "$ref": "#/definitions/io.k8s.api.core.v1.SecretKeySelector", + "description": "Selects a key of a secret in the pod's namespace" + } + }, + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.EphemeralVolumeSource": { + "description": "Represents an ephemeral volume that is handled by a normal storage driver.", + "properties": { + "volumeClaimTemplate": { + "$ref": "#/definitions/io.k8s.api.core.v1.PersistentVolumeClaimTemplate", + "description": "Will be used to create a stand-alone PVC to provision the volume. The pod in which this EphemeralVolumeSource is embedded will be the owner of the PVC, i.e. the PVC will be deleted together with the pod. The name of the PVC will be `-` where `` is the name from the `PodSpec.Volumes` array entry. Pod validation will reject the pod if the concatenated name is not valid for a PVC (for example, too long).\n\nAn existing PVC with that name that is not owned by the pod will *not* be used for the pod to avoid using an unrelated volume by mistake. Starting the pod is then blocked until the unrelated PVC is removed. If such a pre-created PVC is meant to be used by the pod, the PVC has to updated with an owner reference to the pod once the pod exists. Normally this should not be necessary, but it may be useful when manually reconstructing a broken cluster.\n\nThis field is read-only and no changes will be made by Kubernetes to the PVC after it has been created.\n\nRequired, must not be nil." + } + }, + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.ExecAction": { + "description": "ExecAction describes a \"run in container\" action.", + "properties": { + "command": { + "description": "Command is the command line to execute inside the container, the working directory for the command is root ('/') in the container's filesystem. The command is simply exec'd, it is not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use a shell, you need to explicitly call out to that shell. Exit status of 0 is treated as live/healthy and non-zero is unhealthy.", + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.FCVolumeSource": { + "description": "Represents a Fibre Channel volume. Fibre Channel volumes can only be mounted as read/write once. Fibre Channel volumes support ownership management and SELinux relabeling.", + "properties": { + "fsType": { + "description": "Filesystem type to mount. Must be a filesystem type supported by the host operating system. Ex. \"ext4\", \"xfs\", \"ntfs\". Implicitly inferred to be \"ext4\" if unspecified.", + "type": "string" + }, + "lun": { + "description": "Optional: FC target lun number", + "format": "int32", + "type": "integer" + }, + "readOnly": { + "description": "Optional: Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts.", + "type": "boolean" + }, + "targetWWNs": { + "description": "Optional: FC target worldwide names (WWNs)", + "items": { + "type": "string" + }, + "type": "array" + }, + "wwids": { + "description": "Optional: FC volume world wide identifiers (wwids) Either wwids or combination of targetWWNs and lun must be set, but not both simultaneously.", + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.FlexVolumeSource": { + "description": "FlexVolume represents a generic volume resource that is provisioned/attached using an exec based plugin.", + "properties": { + "driver": { + "description": "Driver is the name of the driver to use for this volume.", + "type": "string" + }, + "fsType": { + "description": "Filesystem type to mount. Must be a filesystem type supported by the host operating system. Ex. \"ext4\", \"xfs\", \"ntfs\". The default filesystem depends on FlexVolume script.", + "type": "string" + }, + "options": { + "additionalProperties": { + "type": "string" + }, + "description": "Optional: Extra command options if any.", + "type": "object" + }, + "readOnly": { + "description": "Optional: Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts.", + "type": "boolean" + }, + "secretRef": { + "$ref": "#/definitions/io.k8s.api.core.v1.LocalObjectReference", + "description": "Optional: SecretRef is reference to the secret object containing sensitive information to pass to the plugin scripts. This may be empty if no secret object is specified. If the secret object contains more than one secret, all secrets are passed to the plugin scripts." + } + }, + "required": [ + "driver" + ], + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.FlockerVolumeSource": { + "description": "Represents a Flocker volume mounted by the Flocker agent. One and only one of datasetName and datasetUUID should be set. Flocker volumes do not support ownership management or SELinux relabeling.", + "properties": { + "datasetName": { + "description": "Name of the dataset stored as metadata -> name on the dataset for Flocker should be considered as deprecated", + "type": "string" + }, + "datasetUUID": { + "description": "UUID of the dataset. This is unique identifier of a Flocker dataset", + "type": "string" + } + }, + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.GCEPersistentDiskVolumeSource": { + "description": "Represents a Persistent Disk resource in Google Compute Engine.\n\nA GCE PD must exist before mounting to a container. The disk must also be in the same GCE project and zone as the kubelet. A GCE PD can only be mounted as read/write once or read-only many times. GCE PDs support ownership management and SELinux relabeling.", + "properties": { + "fsType": { + "description": "Filesystem type of the volume that you want to mount. Tip: Ensure that the filesystem type is supported by the host operating system. Examples: \"ext4\", \"xfs\", \"ntfs\". Implicitly inferred to be \"ext4\" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk", + "type": "string" + }, + "partition": { + "description": "The partition in the volume that you want to mount. If omitted, the default is to mount by volume name. Examples: For volume /dev/sda1, you specify the partition as \"1\". Similarly, the volume partition for /dev/sda is \"0\" (or you can leave the property empty). More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk", + "format": "int32", + "type": "integer" + }, + "pdName": { + "description": "Unique name of the PD resource in GCE. Used to identify the disk in GCE. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk", + "type": "string" + }, + "readOnly": { + "description": "ReadOnly here will force the ReadOnly setting in VolumeMounts. Defaults to false. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk", + "type": "boolean" + } + }, + "required": [ + "pdName" + ], + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.GitRepoVolumeSource": { + "description": "Represents a volume that is populated with the contents of a git repository. Git repo volumes do not support ownership management. Git repo volumes support SELinux relabeling.\n\nDEPRECATED: GitRepo is deprecated. To provision a container with a git repo, mount an EmptyDir into an InitContainer that clones the repo using git, then mount the EmptyDir into the Pod's container.", + "properties": { + "directory": { + "description": "Target directory name. Must not contain or start with '..'. If '.' is supplied, the volume directory will be the git repository. Otherwise, if specified, the volume will contain the git repository in the subdirectory with the given name.", + "type": "string" + }, + "repository": { + "description": "Repository URL", + "type": "string" + }, + "revision": { + "description": "Commit hash for the specified revision.", + "type": "string" + } + }, + "required": [ + "repository" + ], + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.GlusterfsVolumeSource": { + "description": "Represents a Glusterfs mount that lasts the lifetime of a pod. Glusterfs volumes do not support ownership management or SELinux relabeling.", + "properties": { + "endpoints": { + "description": "EndpointsName is the endpoint name that details Glusterfs topology. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod", + "type": "string" + }, + "path": { + "description": "Path is the Glusterfs volume path. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod", + "type": "string" + }, + "readOnly": { + "description": "ReadOnly here will force the Glusterfs volume to be mounted with read-only permissions. Defaults to false. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod", + "type": "boolean" + } + }, + "required": [ + "endpoints", + "path" + ], + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.HTTPGetAction": { + "description": "HTTPGetAction describes an action based on HTTP Get requests.", + "properties": { + "host": { + "description": "Host name to connect to, defaults to the pod IP. You probably want to set \"Host\" in httpHeaders instead.", + "type": "string" + }, + "httpHeaders": { + "description": "Custom headers to set in the request. HTTP allows repeated headers.", + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.HTTPHeader" + }, + "type": "array" + }, + "path": { + "description": "Path to access on the HTTP server.", + "type": "string" + }, + "port": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.util.intstr.IntOrString", + "description": "Name or number of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME." + }, + "scheme": { + "description": "Scheme to use for connecting to the host. Defaults to HTTP.", + "type": "string" + } + }, + "required": [ + "port" + ], + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.HTTPHeader": { + "description": "HTTPHeader describes a custom header to be used in HTTP probes", + "properties": { + "name": { + "description": "The header field name", + "type": "string" + }, + "value": { + "description": "The header field value", + "type": "string" + } + }, + "required": [ + "name", + "value" + ], + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.Handler": { + "description": "Handler defines a specific action that should be taken", + "properties": { + "exec": { + "$ref": "#/definitions/io.k8s.api.core.v1.ExecAction", + "description": "One and only one of the following should be specified. Exec specifies the action to take." + }, + "httpGet": { + "$ref": "#/definitions/io.k8s.api.core.v1.HTTPGetAction", + "description": "HTTPGet specifies the http request to perform." + }, + "tcpSocket": { + "$ref": "#/definitions/io.k8s.api.core.v1.TCPSocketAction", + "description": "TCPSocket specifies an action involving a TCP port. TCP hooks not yet supported" + } + }, + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.HostAlias": { + "description": "HostAlias holds the mapping between IP and hostnames that will be injected as an entry in the pod's hosts file.", + "properties": { + "hostnames": { + "description": "Hostnames for the above IP address.", + "items": { + "type": "string" + }, + "type": "array" + }, + "ip": { + "description": "IP address of the host file entry.", + "type": "string" + } + }, + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.HostPathVolumeSource": { + "description": "Represents a host path mapped into a pod. Host path volumes do not support ownership management or SELinux relabeling.", + "properties": { + "path": { + "description": "Path of the directory on the host. If the path is a symlink, it will follow the link to the real path. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath", + "type": "string" + }, + "type": { + "description": "Type for HostPath Volume Defaults to \"\" More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.ISCSIVolumeSource": { + "description": "Represents an ISCSI disk. ISCSI volumes can only be mounted as read/write once. ISCSI volumes support ownership management and SELinux relabeling.", + "properties": { + "chapAuthDiscovery": { + "description": "whether support iSCSI Discovery CHAP authentication", + "type": "boolean" + }, + "chapAuthSession": { + "description": "whether support iSCSI Session CHAP authentication", + "type": "boolean" + }, + "fsType": { + "description": "Filesystem type of the volume that you want to mount. Tip: Ensure that the filesystem type is supported by the host operating system. Examples: \"ext4\", \"xfs\", \"ntfs\". Implicitly inferred to be \"ext4\" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi", + "type": "string" + }, + "initiatorName": { + "description": "Custom iSCSI Initiator Name. If initiatorName is specified with iscsiInterface simultaneously, new iSCSI interface : will be created for the connection.", + "type": "string" + }, + "iqn": { + "description": "Target iSCSI Qualified Name.", + "type": "string" + }, + "iscsiInterface": { + "description": "iSCSI Interface Name that uses an iSCSI transport. Defaults to 'default' (tcp).", + "type": "string" + }, + "lun": { + "description": "iSCSI Target Lun number.", + "format": "int32", + "type": "integer" + }, + "portals": { + "description": "iSCSI Target Portal List. The portal is either an IP or ip_addr:port if the port is other than default (typically TCP ports 860 and 3260).", + "items": { + "type": "string" + }, + "type": "array" + }, + "readOnly": { + "description": "ReadOnly here will force the ReadOnly setting in VolumeMounts. Defaults to false.", + "type": "boolean" + }, + "secretRef": { + "$ref": "#/definitions/io.k8s.api.core.v1.LocalObjectReference", + "description": "CHAP Secret for iSCSI target and initiator authentication" + }, + "targetPortal": { + "description": "iSCSI Target Portal. The Portal is either an IP or ip_addr:port if the port is other than default (typically TCP ports 860 and 3260).", + "type": "string" + } + }, + "required": [ + "targetPortal", + "iqn", + "lun" + ], + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.KeyToPath": { + "description": "Maps a string key to a path within a volume.", + "properties": { + "key": { + "description": "The key to project.", + "type": "string" + }, + "mode": { + "description": "Optional: mode bits used to set permissions on this file. Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. If not specified, the volume defaultMode will be used. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.", + "format": "int32", + "type": "integer" + }, + "path": { + "description": "The relative path of the file to map the key to. May not be an absolute path. May not contain the path element '..'. May not start with the string '..'.", + "type": "string" + } + }, + "required": [ + "key", + "path" + ], + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.Lifecycle": { + "description": "Lifecycle describes actions that the management system should take in response to container lifecycle events. For the PostStart and PreStop lifecycle handlers, management of the container blocks until the action is complete, unless the container process fails, in which case the handler is aborted.", + "properties": { + "postStart": { + "$ref": "#/definitions/io.k8s.api.core.v1.Handler", + "description": "PostStart is called immediately after a container is created. If the handler fails, the container is terminated and restarted according to its restart policy. Other management of the container blocks until the hook completes. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks" + }, + "preStop": { + "$ref": "#/definitions/io.k8s.api.core.v1.Handler", + "description": "PreStop is called immediately before a container is terminated due to an API request or management event such as liveness/startup probe failure, preemption, resource contention, etc. The handler is not called if the container crashes or exits. The reason for termination is passed to the handler. The Pod's termination grace period countdown begins before the PreStop hooked is executed. Regardless of the outcome of the handler, the container will eventually terminate within the Pod's termination grace period. Other management of the container blocks until the hook completes or until the termination grace period is reached. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks" + } + }, + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.LimitRangeItem": { + "description": "LimitRangeItem defines a min/max usage limit for any resource that matches on kind.", + "properties": { + "default": { + "additionalProperties": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.api.resource.Quantity" + }, + "description": "Default resource requirement limit value by resource name if resource limit is omitted.", + "type": "object" + }, + "defaultRequest": { + "additionalProperties": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.api.resource.Quantity" + }, + "description": "DefaultRequest is the default resource requirement request value by resource name if resource request is omitted.", + "type": "object" + }, + "max": { + "additionalProperties": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.api.resource.Quantity" + }, + "description": "Max usage constraints on this kind by resource name.", + "type": "object" + }, + "maxLimitRequestRatio": { + "additionalProperties": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.api.resource.Quantity" + }, + "description": "MaxLimitRequestRatio if specified, the named resource must have a request and limit that are both non-zero where limit divided by request is less than or equal to the enumerated value; this represents the max burst for the named resource.", + "type": "object" + }, + "min": { + "additionalProperties": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.api.resource.Quantity" + }, + "description": "Min usage constraints on this kind by resource name.", + "type": "object" + }, + "type": { + "description": "Type of resource that this limit applies to.", + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.LocalObjectReference": { + "description": "LocalObjectReference contains enough information to let you locate the referenced object inside the same namespace.", + "properties": { + "name": { + "description": "Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names", + "type": "string" + } + }, + "type": "object", + "x-kubernetes-map-type": "atomic", + "additionalProperties": false + }, + "io.k8s.api.core.v1.NFSVolumeSource": { + "description": "Represents an NFS mount that lasts the lifetime of a pod. NFS volumes do not support ownership management or SELinux relabeling.", + "properties": { + "path": { + "description": "Path that is exported by the NFS server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs", + "type": "string" + }, + "readOnly": { + "description": "ReadOnly here will force the NFS export to be mounted with read-only permissions. Defaults to false. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs", + "type": "boolean" + }, + "server": { + "description": "Server is the hostname or IP address of the NFS server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs", + "type": "string" + } + }, + "required": [ + "server", + "path" + ], + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.NodeAffinity": { + "description": "Node affinity is a group of node affinity scheduling rules.", + "properties": { + "preferredDuringSchedulingIgnoredDuringExecution": { + "description": "The scheduler will prefer to schedule pods to nodes that satisfy the affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding \"weight\" to the sum if the node matches the corresponding matchExpressions; the node(s) with the highest sum are the most preferred.", + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.PreferredSchedulingTerm" + }, + "type": "array" + }, + "requiredDuringSchedulingIgnoredDuringExecution": { + "$ref": "#/definitions/io.k8s.api.core.v1.NodeSelector", + "description": "If the affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to an update), the system may or may not try to eventually evict the pod from its node." + } + }, + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.NodeSelector": { + "description": "A node selector represents the union of the results of one or more label queries over a set of nodes; that is, it represents the OR of the selectors represented by the node selector terms.", + "properties": { + "nodeSelectorTerms": { + "description": "Required. A list of node selector terms. The terms are ORed.", + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.NodeSelectorTerm" + }, + "type": "array" + } + }, + "required": [ + "nodeSelectorTerms" + ], + "type": "object", + "x-kubernetes-map-type": "atomic", + "additionalProperties": false + }, + "io.k8s.api.core.v1.NodeSelectorRequirement": { + "description": "A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values.", + "properties": { + "key": { + "description": "The label key that the selector applies to.", + "type": "string" + }, + "operator": { + "description": "Represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt.", + "type": "string" + }, + "values": { + "description": "An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch.", + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "key", + "operator" + ], + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.NodeSelectorTerm": { + "description": "A null or empty node selector term matches no objects. The requirements of them are ANDed. The TopologySelectorTerm type implements a subset of the NodeSelectorTerm.", + "properties": { + "matchExpressions": { + "description": "A list of node selector requirements by node's labels.", + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.NodeSelectorRequirement" + }, + "type": "array" + }, + "matchFields": { + "description": "A list of node selector requirements by node's fields.", + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.NodeSelectorRequirement" + }, + "type": "array" + } + }, + "type": "object", + "x-kubernetes-map-type": "atomic", + "additionalProperties": false + }, + "io.k8s.api.core.v1.ObjectFieldSelector": { + "description": "ObjectFieldSelector selects an APIVersioned field of an object.", + "properties": { + "apiVersion": { + "description": "Version of the schema the FieldPath is written in terms of, defaults to \"v1\".", + "type": "string" + }, + "fieldPath": { + "description": "Path of the field to select in the specified API version.", + "type": "string" + } + }, + "required": [ + "fieldPath" + ], + "type": "object", + "x-kubernetes-map-type": "atomic", + "additionalProperties": false + }, + "io.k8s.api.core.v1.PersistentVolumeClaimSpec": { + "description": "PersistentVolumeClaimSpec describes the common attributes of storage devices and allows a Source for provider-specific attributes", + "properties": { + "accessModes": { + "description": "AccessModes contains the desired access modes the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1", + "items": { + "type": "string" + }, + "type": "array" + }, + "dataSource": { + "$ref": "#/definitions/io.k8s.api.core.v1.TypedLocalObjectReference", + "description": "This field can be used to specify either: * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) * An existing PVC (PersistentVolumeClaim) If the provisioner or an external controller can support the specified data source, it will create a new volume based on the contents of the specified data source. If the AnyVolumeDataSource feature gate is enabled, this field will always have the same contents as the DataSourceRef field." + }, + "dataSourceRef": { + "$ref": "#/definitions/io.k8s.api.core.v1.TypedLocalObjectReference", + "description": "Specifies the object from which to populate the volume with data, if a non-empty volume is desired. This may be any local object from a non-empty API group (non core object) or a PersistentVolumeClaim object. When this field is specified, volume binding will only succeed if the type of the specified object matches some installed volume populator or dynamic provisioner. This field will replace the functionality of the DataSource field and as such if both fields are non-empty, they must have the same value. For backwards compatibility, both fields (DataSource and DataSourceRef) will be set to the same value automatically if one of them is empty and the other is non-empty. There are two important differences between DataSource and DataSourceRef: * While DataSource only allows two specific types of objects, DataSourceRef\n allows any non-core object, as well as PersistentVolumeClaim objects.\n* While DataSource ignores disallowed values (dropping them), DataSourceRef\n preserves all values, and generates an error if a disallowed value is\n specified.\n(Alpha) Using this field requires the AnyVolumeDataSource feature gate to be enabled." + }, + "resources": { + "$ref": "#/definitions/io.k8s.api.core.v1.ResourceRequirements", + "description": "Resources represents the minimum resources the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources" + }, + "selector": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.LabelSelector", + "description": "A label query over volumes to consider for binding." + }, + "storageClassName": { + "description": "Name of the StorageClass required by the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1", + "type": "string" + }, + "volumeMode": { + "description": "volumeMode defines what type of volume is required by the claim. Value of Filesystem is implied when not included in claim spec.", + "type": "string" + }, + "volumeName": { + "description": "VolumeName is the binding reference to the PersistentVolume backing this claim.", + "type": "string" + } + }, + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.PersistentVolumeClaimTemplate": { + "description": "PersistentVolumeClaimTemplate is used to produce PersistentVolumeClaim objects as part of an EphemeralVolumeSource.", + "properties": { + "metadata": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta", + "description": "May contain labels and annotations that will be copied into the PVC when creating it. No other fields are allowed and will be rejected during validation." + }, + "spec": { + "$ref": "#/definitions/io.k8s.api.core.v1.PersistentVolumeClaimSpec", + "description": "The specification for the PersistentVolumeClaim. The entire content is copied unchanged into the PVC that gets created from this template. The same fields as in a PersistentVolumeClaim are also valid here." + } + }, + "required": [ + "spec" + ], + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.PersistentVolumeClaimVolumeSource": { + "description": "PersistentVolumeClaimVolumeSource references the user's PVC in the same namespace. This volume finds the bound PV and mounts that volume for the pod. A PersistentVolumeClaimVolumeSource is, essentially, a wrapper around another type of volume that is owned by someone else (the system).", + "properties": { + "claimName": { + "description": "ClaimName is the name of a PersistentVolumeClaim in the same namespace as the pod using this volume. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims", + "type": "string" + }, + "readOnly": { + "description": "Will force the ReadOnly setting in VolumeMounts. Default false.", + "type": "boolean" + } + }, + "required": [ + "claimName" + ], + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.PhotonPersistentDiskVolumeSource": { + "description": "Represents a Photon Controller persistent disk resource.", + "properties": { + "fsType": { + "description": "Filesystem type to mount. Must be a filesystem type supported by the host operating system. Ex. \"ext4\", \"xfs\", \"ntfs\". Implicitly inferred to be \"ext4\" if unspecified.", + "type": "string" + }, + "pdID": { + "description": "ID that identifies Photon Controller persistent disk", + "type": "string" + } + }, + "required": [ + "pdID" + ], + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.PodAffinity": { + "description": "Pod affinity is a group of inter pod affinity scheduling rules.", + "properties": { + "preferredDuringSchedulingIgnoredDuringExecution": { + "description": "The scheduler will prefer to schedule pods to nodes that satisfy the affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding \"weight\" to the sum if the node has pods which matches the corresponding podAffinityTerm; the node(s) with the highest sum are the most preferred.", + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.WeightedPodAffinityTerm" + }, + "type": "array" + }, + "requiredDuringSchedulingIgnoredDuringExecution": { + "description": "If the affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system may or may not try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied.", + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.PodAffinityTerm" + }, + "type": "array" + } + }, + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.PodAffinityTerm": { + "description": "Defines a set of pods (namely those matching the labelSelector relative to the given namespace(s)) that this pod should be co-located (affinity) or not co-located (anti-affinity) with, where co-located is defined as running on a node whose value of the label with key matches that of any node on which a pod of the set of pods is running", + "properties": { + "labelSelector": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.LabelSelector", + "description": "A label query over a set of resources, in this case pods." + }, + "namespaceSelector": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.LabelSelector", + "description": "A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means \"this pod's namespace\". An empty selector ({}) matches all namespaces. This field is beta-level and is only honored when PodAffinityNamespaceSelector feature is enabled." + }, + "namespaces": { + "description": "namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means \"this pod's namespace\"", + "items": { + "type": "string" + }, + "type": "array" + }, + "topologyKey": { + "description": "This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed.", + "type": "string" + } + }, + "required": [ + "topologyKey" + ], + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.PodAntiAffinity": { + "description": "Pod anti affinity is a group of inter pod anti affinity scheduling rules.", + "properties": { + "preferredDuringSchedulingIgnoredDuringExecution": { + "description": "The scheduler will prefer to schedule pods to nodes that satisfy the anti-affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling anti-affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding \"weight\" to the sum if the node has pods which matches the corresponding podAffinityTerm; the node(s) with the highest sum are the most preferred.", + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.WeightedPodAffinityTerm" + }, + "type": "array" + }, + "requiredDuringSchedulingIgnoredDuringExecution": { + "description": "If the anti-affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the anti-affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system may or may not try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied.", + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.PodAffinityTerm" + }, + "type": "array" + } + }, + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.PodSecurityContext": { + "description": "PodSecurityContext holds pod-level security attributes and common container settings. Some fields are also present in container.securityContext. Field values of container.securityContext take precedence over field values of PodSecurityContext.", + "properties": { + "fsGroup": { + "description": "A special supplemental group that applies to all containers in a pod. Some volume types allow the Kubelet to change the ownership of that volume to be owned by the pod:\n\n1. The owning GID will be the FSGroup 2. The setgid bit is set (new files created in the volume will be owned by FSGroup) 3. The permission bits are OR'd with rw-rw----\n\nIf unset, the Kubelet will not modify the ownership and permissions of any volume.", + "format": "int64", + "type": "integer" + }, + "fsGroupChangePolicy": { + "description": "fsGroupChangePolicy defines behavior of changing ownership and permission of the volume before being exposed inside Pod. This field will only apply to volume types which support fsGroup based ownership(and permissions). It will have no effect on ephemeral volume types such as: secret, configmaps and emptydir. Valid values are \"OnRootMismatch\" and \"Always\". If not specified, \"Always\" is used.", + "type": "string" + }, + "runAsGroup": { + "description": "The GID to run the entrypoint of the container process. Uses runtime default if unset. May also be set in SecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence for that container.", + "format": "int64", + "type": "integer" + }, + "runAsNonRoot": { + "description": "Indicates that the container must run as a non-root user. If true, the Kubelet will validate the image at runtime to ensure that it does not run as UID 0 (root) and fail to start the container if it does. If unset or false, no such validation will be performed. May also be set in SecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence.", + "type": "boolean" + }, + "runAsUser": { + "description": "The UID to run the entrypoint of the container process. Defaults to user specified in image metadata if unspecified. May also be set in SecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence for that container.", + "format": "int64", + "type": "integer" + }, + "seLinuxOptions": { + "$ref": "#/definitions/io.k8s.api.core.v1.SELinuxOptions", + "description": "The SELinux context to be applied to all containers. If unspecified, the container runtime will allocate a random SELinux context for each container. May also be set in SecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence for that container." + }, + "seccompProfile": { + "$ref": "#/definitions/io.k8s.api.core.v1.SeccompProfile", + "description": "The seccomp options to use by the containers in this pod." + }, + "supplementalGroups": { + "description": "A list of groups applied to the first process run in each container, in addition to the container's primary GID. If unspecified, no groups will be added to any container.", + "items": { + "format": "int64", + "type": "integer" + }, + "type": "array" + }, + "sysctls": { + "description": "Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported sysctls (by the container runtime) might fail to launch.", + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.Sysctl" + }, + "type": "array" + }, + "windowsOptions": { + "$ref": "#/definitions/io.k8s.api.core.v1.WindowsSecurityContextOptions", + "description": "The Windows specific settings applied to all containers. If unspecified, the options within a container's SecurityContext will be used. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence." + } + }, + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.PortworxVolumeSource": { + "description": "PortworxVolumeSource represents a Portworx volume resource.", + "properties": { + "fsType": { + "description": "FSType represents the filesystem type to mount Must be a filesystem type supported by the host operating system. Ex. \"ext4\", \"xfs\". Implicitly inferred to be \"ext4\" if unspecified.", + "type": "string" + }, + "readOnly": { + "description": "Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts.", + "type": "boolean" + }, + "volumeID": { + "description": "VolumeID uniquely identifies a Portworx volume", + "type": "string" + } + }, + "required": [ + "volumeID" + ], + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.PreferredSchedulingTerm": { + "description": "An empty preferred scheduling term matches all objects with implicit weight 0 (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op).", + "properties": { + "preference": { + "$ref": "#/definitions/io.k8s.api.core.v1.NodeSelectorTerm", + "description": "A node selector term, associated with the corresponding weight." + }, + "weight": { + "description": "Weight associated with matching the corresponding nodeSelectorTerm, in the range 1-100.", + "format": "int32", + "type": "integer" + } + }, + "required": [ + "weight", + "preference" + ], + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.Probe": { + "description": "Probe describes a health check to be performed against a container to determine whether it is alive or ready to receive traffic.", + "properties": { + "exec": { + "$ref": "#/definitions/io.k8s.api.core.v1.ExecAction", + "description": "One and only one of the following should be specified. Exec specifies the action to take." + }, + "failureThreshold": { + "description": "Minimum consecutive failures for the probe to be considered failed after having succeeded. Defaults to 3. Minimum value is 1.", + "format": "int32", + "type": "integer" + }, + "httpGet": { + "$ref": "#/definitions/io.k8s.api.core.v1.HTTPGetAction", + "description": "HTTPGet specifies the http request to perform." + }, + "initialDelaySeconds": { + "description": "Number of seconds after the container has started before liveness probes are initiated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes", + "format": "int32", + "type": "integer" + }, + "periodSeconds": { + "description": "How often (in seconds) to perform the probe. Default to 10 seconds. Minimum value is 1.", + "format": "int32", + "type": "integer" + }, + "successThreshold": { + "description": "Minimum consecutive successes for the probe to be considered successful after having failed. Defaults to 1. Must be 1 for liveness and startup. Minimum value is 1.", + "format": "int32", + "type": "integer" + }, + "tcpSocket": { + "$ref": "#/definitions/io.k8s.api.core.v1.TCPSocketAction", + "description": "TCPSocket specifies an action involving a TCP port. TCP hooks not yet supported" + }, + "terminationGracePeriodSeconds": { + "description": "Optional duration in seconds the pod needs to terminate gracefully upon probe failure. The grace period is the duration in seconds after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal. Set this value longer than the expected cleanup time for your process. If this value is nil, the pod's terminationGracePeriodSeconds will be used. Otherwise, this value overrides the value provided by the pod spec. Value must be non-negative integer. The value zero indicates stop immediately via the kill signal (no opportunity to shut down). This is a beta field and requires enabling ProbeTerminationGracePeriod feature gate. Minimum value is 1. spec.terminationGracePeriodSeconds is used if unset.", + "format": "int64", + "type": "integer" + }, + "timeoutSeconds": { + "description": "Number of seconds after which the probe times out. Defaults to 1 second. Minimum value is 1. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes", + "format": "int32", + "type": "integer" + } + }, + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.ProjectedVolumeSource": { + "description": "Represents a projected volume source", + "properties": { + "defaultMode": { + "description": "Mode bits used to set permissions on created files by default. Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. Directories within the path are not affected by this setting. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.", + "format": "int32", + "type": "integer" + }, + "sources": { + "description": "list of volume projections", + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.VolumeProjection" + }, + "type": "array" + } + }, + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.QuobyteVolumeSource": { + "description": "Represents a Quobyte mount that lasts the lifetime of a pod. Quobyte volumes do not support ownership management or SELinux relabeling.", + "properties": { + "group": { + "description": "Group to map volume access to Default is no group", + "type": "string" + }, + "readOnly": { + "description": "ReadOnly here will force the Quobyte volume to be mounted with read-only permissions. Defaults to false.", + "type": "boolean" + }, + "registry": { + "description": "Registry represents a single or multiple Quobyte Registry services specified as a string as host:port pair (multiple entries are separated with commas) which acts as the central registry for volumes", + "type": "string" + }, + "tenant": { + "description": "Tenant owning the given Quobyte volume in the Backend Used with dynamically provisioned Quobyte volumes, value is set by the plugin", + "type": "string" + }, + "user": { + "description": "User to map volume access to Defaults to serivceaccount user", + "type": "string" + }, + "volume": { + "description": "Volume is a string that references an already created Quobyte volume by name.", + "type": "string" + } + }, + "required": [ + "registry", + "volume" + ], + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.RBDVolumeSource": { + "description": "Represents a Rados Block Device mount that lasts the lifetime of a pod. RBD volumes support ownership management and SELinux relabeling.", + "properties": { + "fsType": { + "description": "Filesystem type of the volume that you want to mount. Tip: Ensure that the filesystem type is supported by the host operating system. Examples: \"ext4\", \"xfs\", \"ntfs\". Implicitly inferred to be \"ext4\" if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd", + "type": "string" + }, + "image": { + "description": "The rados image name. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it", + "type": "string" + }, + "keyring": { + "description": "Keyring is the path to key ring for RBDUser. Default is /etc/ceph/keyring. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it", + "type": "string" + }, + "monitors": { + "description": "A collection of Ceph monitors. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it", + "items": { + "type": "string" + }, + "type": "array" + }, + "pool": { + "description": "The rados pool name. Default is rbd. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it", + "type": "string" + }, + "readOnly": { + "description": "ReadOnly here will force the ReadOnly setting in VolumeMounts. Defaults to false. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it", + "type": "boolean" + }, + "secretRef": { + "$ref": "#/definitions/io.k8s.api.core.v1.LocalObjectReference", + "description": "SecretRef is name of the authentication secret for RBDUser. If provided overrides keyring. Default is nil. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it" + }, + "user": { + "description": "The rados user name. Default is admin. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it", + "type": "string" + } + }, + "required": [ + "monitors", + "image" + ], + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.ResourceFieldSelector": { + "description": "ResourceFieldSelector represents container resources (cpu, memory) and their output format", + "properties": { + "containerName": { + "description": "Container name: required for volumes, optional for env vars", + "type": "string" + }, + "divisor": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.api.resource.Quantity", + "description": "Specifies the output format of the exposed resources, defaults to \"1\"" + }, + "resource": { + "description": "Required: resource to select", + "type": "string" + } + }, + "required": [ + "resource" + ], + "type": "object", + "x-kubernetes-map-type": "atomic", + "additionalProperties": false + }, + "io.k8s.api.core.v1.ResourceRequirements": { + "description": "ResourceRequirements describes the compute resource requirements.", + "properties": { + "limits": { + "additionalProperties": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.api.resource.Quantity" + }, + "description": "Limits describes the maximum amount of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/", + "type": "object" + }, + "requests": { + "additionalProperties": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.api.resource.Quantity" + }, + "description": "Requests describes the minimum amount of compute resources required. If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, otherwise to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/", + "type": "object" + } + }, + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.SELinuxOptions": { + "description": "SELinuxOptions are the labels to be applied to the container", + "properties": { + "level": { + "description": "Level is SELinux level label that applies to the container.", + "type": "string" + }, + "role": { + "description": "Role is a SELinux role label that applies to the container.", + "type": "string" + }, + "type": { + "description": "Type is a SELinux type label that applies to the container.", + "type": "string" + }, + "user": { + "description": "User is a SELinux user label that applies to the container.", + "type": "string" + } + }, + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.ScaleIOVolumeSource": { + "description": "ScaleIOVolumeSource represents a persistent ScaleIO volume", + "properties": { + "fsType": { + "description": "Filesystem type to mount. Must be a filesystem type supported by the host operating system. Ex. \"ext4\", \"xfs\", \"ntfs\". Default is \"xfs\".", + "type": "string" + }, + "gateway": { + "description": "The host address of the ScaleIO API Gateway.", + "type": "string" + }, + "protectionDomain": { + "description": "The name of the ScaleIO Protection Domain for the configured storage.", + "type": "string" + }, + "readOnly": { + "description": "Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts.", + "type": "boolean" + }, + "secretRef": { + "$ref": "#/definitions/io.k8s.api.core.v1.LocalObjectReference", + "description": "SecretRef references to the secret for ScaleIO user and other sensitive information. If this is not provided, Login operation will fail." + }, + "sslEnabled": { + "description": "Flag to enable/disable SSL communication with Gateway, default false", + "type": "boolean" + }, + "storageMode": { + "description": "Indicates whether the storage for a volume should be ThickProvisioned or ThinProvisioned. Default is ThinProvisioned.", + "type": "string" + }, + "storagePool": { + "description": "The ScaleIO Storage Pool associated with the protection domain.", + "type": "string" + }, + "system": { + "description": "The name of the storage system as configured in ScaleIO.", + "type": "string" + }, + "volumeName": { + "description": "The name of a volume already created in the ScaleIO system that is associated with this volume source.", + "type": "string" + } + }, + "required": [ + "gateway", + "system", + "secretRef" + ], + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.SeccompProfile": { + "description": "SeccompProfile defines a pod/container's seccomp profile settings. Only one profile source may be set.", + "properties": { + "localhostProfile": { + "description": "localhostProfile indicates a profile defined in a file on the node should be used. The profile must be preconfigured on the node to work. Must be a descending path, relative to the kubelet's configured seccomp profile location. Must only be set if type is \"Localhost\".", + "type": "string" + }, + "type": { + "description": "type indicates which kind of seccomp profile will be applied. Valid options are:\n\nLocalhost - a profile defined in a file on the node should be used. RuntimeDefault - the container runtime default profile should be used. Unconfined - no profile should be applied.", + "type": "string" + } + }, + "required": [ + "type" + ], + "type": "object", + "x-kubernetes-unions": [ + { + "discriminator": "type", + "fields-to-discriminateBy": { + "localhostProfile": "LocalhostProfile" + } + } + ], + "additionalProperties": false + }, + "io.k8s.api.core.v1.SecretEnvSource": { + "description": "SecretEnvSource selects a Secret to populate the environment variables with.\n\nThe contents of the target Secret's Data field will represent the key-value pairs as environment variables.", + "properties": { + "name": { + "description": "Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names", + "type": "string" + }, + "optional": { + "description": "Specify whether the Secret must be defined", + "type": "boolean" + } + }, + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.SecretKeySelector": { + "description": "SecretKeySelector selects a key of a Secret.", + "properties": { + "key": { + "description": "The key of the secret to select from. Must be a valid secret key.", + "type": "string" + }, + "name": { + "description": "Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names", + "type": "string" + }, + "optional": { + "description": "Specify whether the Secret or its key must be defined", + "type": "boolean" + } + }, + "required": [ + "key" + ], + "type": "object", + "x-kubernetes-map-type": "atomic", + "additionalProperties": false + }, + "io.k8s.api.core.v1.SecretProjection": { + "description": "Adapts a secret into a projected volume.\n\nThe contents of the target Secret's Data field will be presented in a projected volume as files using the keys in the Data field as the file names. Note that this is identical to a secret volume source without the default mode.", + "properties": { + "items": { + "description": "If unspecified, each key-value pair in the Data field of the referenced Secret will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the Secret, the volume setup will error unless it is marked optional. Paths must be relative and may not contain the '..' path or start with '..'.", + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.KeyToPath" + }, + "type": "array" + }, + "name": { + "description": "Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names", + "type": "string" + }, + "optional": { + "description": "Specify whether the Secret or its key must be defined", + "type": "boolean" + } + }, + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.SecretVolumeSource": { + "description": "Adapts a Secret into a volume.\n\nThe contents of the target Secret's Data field will be presented in a volume as files using the keys in the Data field as the file names. Secret volumes support ownership management and SELinux relabeling.", + "properties": { + "defaultMode": { + "description": "Optional: mode bits used to set permissions on created files by default. Must be an octal value between 0000 and 0777 or a decimal value between 0 and 511. YAML accepts both octal and decimal values, JSON requires decimal values for mode bits. Defaults to 0644. Directories within the path are not affected by this setting. This might be in conflict with other options that affect the file mode, like fsGroup, and the result can be other mode bits set.", + "format": "int32", + "type": "integer" + }, + "items": { + "description": "If unspecified, each key-value pair in the Data field of the referenced Secret will be projected into the volume as a file whose name is the key and content is the value. If specified, the listed keys will be projected into the specified paths, and unlisted keys will not be present. If a key is specified which is not present in the Secret, the volume setup will error unless it is marked optional. Paths must be relative and may not contain the '..' path or start with '..'.", + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.KeyToPath" + }, + "type": "array" + }, + "optional": { + "description": "Specify whether the Secret or its keys must be defined", + "type": "boolean" + }, + "secretName": { + "description": "Name of the secret in the pod's namespace to use. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret", + "type": "string" + } + }, + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.SecurityContext": { + "description": "SecurityContext holds security configuration that will be applied to a container. Some fields are present in both SecurityContext and PodSecurityContext. When both are set, the values in SecurityContext take precedence.", + "properties": { + "allowPrivilegeEscalation": { + "description": "AllowPrivilegeEscalation controls whether a process can gain more privileges than its parent process. This bool directly controls if the no_new_privs flag will be set on the container process. AllowPrivilegeEscalation is true always when the container is: 1) run as Privileged 2) has CAP_SYS_ADMIN", + "type": "boolean" + }, + "capabilities": { + "$ref": "#/definitions/io.k8s.api.core.v1.Capabilities", + "description": "The capabilities to add/drop when running containers. Defaults to the default set of capabilities granted by the container runtime." + }, + "privileged": { + "description": "Run container in privileged mode. Processes in privileged containers are essentially equivalent to root on the host. Defaults to false.", + "type": "boolean" + }, + "procMount": { + "description": "procMount denotes the type of proc mount to use for the containers. The default is DefaultProcMount which uses the container runtime defaults for readonly paths and masked paths. This requires the ProcMountType feature flag to be enabled.", + "type": "string" + }, + "readOnlyRootFilesystem": { + "description": "Whether this container has a read-only root filesystem. Default is false.", + "type": "boolean" + }, + "runAsGroup": { + "description": "The GID to run the entrypoint of the container process. Uses runtime default if unset. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence.", + "format": "int64", + "type": "integer" + }, + "runAsNonRoot": { + "description": "Indicates that the container must run as a non-root user. If true, the Kubelet will validate the image at runtime to ensure that it does not run as UID 0 (root) and fail to start the container if it does. If unset or false, no such validation will be performed. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence.", + "type": "boolean" + }, + "runAsUser": { + "description": "The UID to run the entrypoint of the container process. Defaults to user specified in image metadata if unspecified. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence.", + "format": "int64", + "type": "integer" + }, + "seLinuxOptions": { + "$ref": "#/definitions/io.k8s.api.core.v1.SELinuxOptions", + "description": "The SELinux context to be applied to the container. If unspecified, the container runtime will allocate a random SELinux context for each container. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence." + }, + "seccompProfile": { + "$ref": "#/definitions/io.k8s.api.core.v1.SeccompProfile", + "description": "The seccomp options to use by this container. If seccomp options are provided at both the pod & container level, the container options override the pod options." + }, + "windowsOptions": { + "$ref": "#/definitions/io.k8s.api.core.v1.WindowsSecurityContextOptions", + "description": "The Windows specific settings applied to all containers. If unspecified, the options from the PodSecurityContext will be used. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence." + } + }, + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.ServiceAccountTokenProjection": { + "description": "ServiceAccountTokenProjection represents a projected service account token volume. This projection can be used to insert a service account token into the pods runtime filesystem for use against APIs (Kubernetes API Server or otherwise).", + "properties": { + "audience": { + "description": "Audience is the intended audience of the token. A recipient of a token must identify itself with an identifier specified in the audience of the token, and otherwise should reject the token. The audience defaults to the identifier of the apiserver.", + "type": "string" + }, + "expirationSeconds": { + "description": "ExpirationSeconds is the requested duration of validity of the service account token. As the token approaches expiration, the kubelet volume plugin will proactively rotate the service account token. The kubelet will start trying to rotate the token if the token is older than 80 percent of its time to live or if the token is older than 24 hours.Defaults to 1 hour and must be at least 10 minutes.", + "format": "int64", + "type": "integer" + }, + "path": { + "description": "Path is the path relative to the mount point of the file to project the token into.", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.StorageOSVolumeSource": { + "description": "Represents a StorageOS persistent volume resource.", + "properties": { + "fsType": { + "description": "Filesystem type to mount. Must be a filesystem type supported by the host operating system. Ex. \"ext4\", \"xfs\", \"ntfs\". Implicitly inferred to be \"ext4\" if unspecified.", + "type": "string" + }, + "readOnly": { + "description": "Defaults to false (read/write). ReadOnly here will force the ReadOnly setting in VolumeMounts.", + "type": "boolean" + }, + "secretRef": { + "$ref": "#/definitions/io.k8s.api.core.v1.LocalObjectReference", + "description": "SecretRef specifies the secret to use for obtaining the StorageOS API credentials. If not specified, default values will be attempted." + }, + "volumeName": { + "description": "VolumeName is the human-readable name of the StorageOS volume. Volume names are only unique within a namespace.", + "type": "string" + }, + "volumeNamespace": { + "description": "VolumeNamespace specifies the scope of the volume within StorageOS. If no namespace is specified then the Pod's namespace will be used. This allows the Kubernetes name scoping to be mirrored within StorageOS for tighter integration. Set VolumeName to any name to override the default behaviour. Set to \"default\" if you are not using namespaces within StorageOS. Namespaces that do not pre-exist within StorageOS will be created.", + "type": "string" + } + }, + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.Sysctl": { + "description": "Sysctl defines a kernel parameter to be set", + "properties": { + "name": { + "description": "Name of a property to set", + "type": "string" + }, + "value": { + "description": "Value of a property to set", + "type": "string" + } + }, + "required": [ + "name", + "value" + ], + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.TCPSocketAction": { + "description": "TCPSocketAction describes an action based on opening a socket", + "properties": { + "host": { + "description": "Optional: Host name to connect to, defaults to the pod IP.", + "type": "string" + }, + "port": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.util.intstr.IntOrString", + "description": "Number or name of the port to access on the container. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME." + } + }, + "required": [ + "port" + ], + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.Toleration": { + "description": "The pod this Toleration is attached to tolerates any taint that matches the triple using the matching operator .", + "properties": { + "effect": { + "description": "Effect indicates the taint effect to match. Empty means match all taint effects. When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute.", + "type": "string" + }, + "key": { + "description": "Key is the taint key that the toleration applies to. Empty means match all taint keys. If the key is empty, operator must be Exists; this combination means to match all values and all keys.", + "type": "string" + }, + "operator": { + "description": "Operator represents a key's relationship to the value. Valid operators are Exists and Equal. Defaults to Equal. Exists is equivalent to wildcard for value, so that a pod can tolerate all taints of a particular category.", + "type": "string" + }, + "tolerationSeconds": { + "description": "TolerationSeconds represents the period of time the toleration (which must be of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, it is not set, which means tolerate the taint forever (do not evict). Zero and negative values will be treated as 0 (evict immediately) by the system.", + "format": "int64", + "type": "integer" + }, + "value": { + "description": "Value is the taint value the toleration matches to. If the operator is Exists, the value should be empty, otherwise just a regular string.", + "type": "string" + } + }, + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.TopologySpreadConstraint": { + "description": "TopologySpreadConstraint specifies how to spread matching pods among the given topology.", + "properties": { + "labelSelector": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.LabelSelector", + "description": "LabelSelector is used to find matching pods. Pods that match this label selector are counted to determine the number of pods in their corresponding topology domain." + }, + "maxSkew": { + "description": "MaxSkew describes the degree to which pods may be unevenly distributed. When `whenUnsatisfiable=DoNotSchedule`, it is the maximum permitted difference between the number of matching pods in the target topology and the global minimum. For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same labelSelector spread as 1/1/0: | zone1 | zone2 | zone3 | | P | P | | - if MaxSkew is 1, incoming pod can only be scheduled to zone3 to become 1/1/1; scheduling it onto zone1(zone2) would make the ActualSkew(2-0) on zone1(zone2) violate MaxSkew(1). - if MaxSkew is 2, incoming pod can be scheduled onto any zone. When `whenUnsatisfiable=ScheduleAnyway`, it is used to give higher precedence to topologies that satisfy it. It's a required field. Default value is 1 and 0 is not allowed.", + "format": "int32", + "type": "integer" + }, + "topologyKey": { + "description": "TopologyKey is the key of node labels. Nodes that have a label with this key and identical values are considered to be in the same topology. We consider each as a \"bucket\", and try to put balanced number of pods into each bucket. It's a required field.", + "type": "string" + }, + "whenUnsatisfiable": { + "description": "WhenUnsatisfiable indicates how to deal with a pod if it doesn't satisfy the spread constraint. - DoNotSchedule (default) tells the scheduler not to schedule it. - ScheduleAnyway tells the scheduler to schedule the pod in any location,\n but giving higher precedence to topologies that would help reduce the\n skew.\nA constraint is considered \"Unsatisfiable\" for an incoming pod if and only if every possible node assigment for that pod would violate \"MaxSkew\" on some topology. For example, in a 3-zone cluster, MaxSkew is set to 1, and pods with the same labelSelector spread as 3/1/1: | zone1 | zone2 | zone3 | | P P P | P | P | If WhenUnsatisfiable is set to DoNotSchedule, incoming pod can only be scheduled to zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on zone2(zone3) satisfies MaxSkew(1). In other words, the cluster can still be imbalanced, but scheduler won't make it *more* imbalanced. It's a required field.", + "type": "string" + } + }, + "required": [ + "maxSkew", + "topologyKey", + "whenUnsatisfiable" + ], + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.TypedLocalObjectReference": { + "description": "TypedLocalObjectReference contains enough information to let you locate the typed referenced object inside the same namespace.", + "properties": { + "apiGroup": { + "description": "APIGroup is the group for the resource being referenced. If APIGroup is not specified, the specified Kind must be in the core API group. For any other third-party types, APIGroup is required.", + "type": "string" + }, + "kind": { + "description": "Kind is the type of resource being referenced", + "type": "string" + }, + "name": { + "description": "Name is the name of resource being referenced", + "type": "string" + } + }, + "required": [ + "kind", + "name" + ], + "type": "object", + "x-kubernetes-map-type": "atomic", + "additionalProperties": false + }, + "io.k8s.api.core.v1.Volume": { + "description": "Volume represents a named volume in a pod that may be accessed by any container in the pod.", + "properties": { + "awsElasticBlockStore": { + "$ref": "#/definitions/io.k8s.api.core.v1.AWSElasticBlockStoreVolumeSource", + "description": "AWSElasticBlockStore represents an AWS Disk resource that is attached to a kubelet's host machine and then exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore" + }, + "azureDisk": { + "$ref": "#/definitions/io.k8s.api.core.v1.AzureDiskVolumeSource", + "description": "AzureDisk represents an Azure Data Disk mount on the host and bind mount to the pod." + }, + "azureFile": { + "$ref": "#/definitions/io.k8s.api.core.v1.AzureFileVolumeSource", + "description": "AzureFile represents an Azure File Service mount on the host and bind mount to the pod." + }, + "cephfs": { + "$ref": "#/definitions/io.k8s.api.core.v1.CephFSVolumeSource", + "description": "CephFS represents a Ceph FS mount on the host that shares a pod's lifetime" + }, + "cinder": { + "$ref": "#/definitions/io.k8s.api.core.v1.CinderVolumeSource", + "description": "Cinder represents a cinder volume attached and mounted on kubelets host machine. More info: https://examples.k8s.io/mysql-cinder-pd/README.md" + }, + "configMap": { + "$ref": "#/definitions/io.k8s.api.core.v1.ConfigMapVolumeSource", + "description": "ConfigMap represents a configMap that should populate this volume" + }, + "csi": { + "$ref": "#/definitions/io.k8s.api.core.v1.CSIVolumeSource", + "description": "CSI (Container Storage Interface) represents ephemeral storage that is handled by certain external CSI drivers (Beta feature)." + }, + "downwardAPI": { + "$ref": "#/definitions/io.k8s.api.core.v1.DownwardAPIVolumeSource", + "description": "DownwardAPI represents downward API about the pod that should populate this volume" + }, + "emptyDir": { + "$ref": "#/definitions/io.k8s.api.core.v1.EmptyDirVolumeSource", + "description": "EmptyDir represents a temporary directory that shares a pod's lifetime. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir" + }, + "ephemeral": { + "$ref": "#/definitions/io.k8s.api.core.v1.EphemeralVolumeSource", + "description": "Ephemeral represents a volume that is handled by a cluster storage driver. The volume's lifecycle is tied to the pod that defines it - it will be created before the pod starts, and deleted when the pod is removed.\n\nUse this if: a) the volume is only needed while the pod runs, b) features of normal volumes like restoring from snapshot or capacity\n tracking are needed,\nc) the storage driver is specified through a storage class, and d) the storage driver supports dynamic volume provisioning through\n a PersistentVolumeClaim (see EphemeralVolumeSource for more\n information on the connection between this volume type\n and PersistentVolumeClaim).\n\nUse PersistentVolumeClaim or one of the vendor-specific APIs for volumes that persist for longer than the lifecycle of an individual pod.\n\nUse CSI for light-weight local ephemeral volumes if the CSI driver is meant to be used that way - see the documentation of the driver for more information.\n\nA pod can use both types of ephemeral volumes and persistent volumes at the same time.\n\nThis is a beta feature and only available when the GenericEphemeralVolume feature gate is enabled." + }, + "fc": { + "$ref": "#/definitions/io.k8s.api.core.v1.FCVolumeSource", + "description": "FC represents a Fibre Channel resource that is attached to a kubelet's host machine and then exposed to the pod." + }, + "flexVolume": { + "$ref": "#/definitions/io.k8s.api.core.v1.FlexVolumeSource", + "description": "FlexVolume represents a generic volume resource that is provisioned/attached using an exec based plugin." + }, + "flocker": { + "$ref": "#/definitions/io.k8s.api.core.v1.FlockerVolumeSource", + "description": "Flocker represents a Flocker volume attached to a kubelet's host machine. This depends on the Flocker control service being running" + }, + "gcePersistentDisk": { + "$ref": "#/definitions/io.k8s.api.core.v1.GCEPersistentDiskVolumeSource", + "description": "GCEPersistentDisk represents a GCE Disk resource that is attached to a kubelet's host machine and then exposed to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk" + }, + "gitRepo": { + "$ref": "#/definitions/io.k8s.api.core.v1.GitRepoVolumeSource", + "description": "GitRepo represents a git repository at a particular revision. DEPRECATED: GitRepo is deprecated. To provision a container with a git repo, mount an EmptyDir into an InitContainer that clones the repo using git, then mount the EmptyDir into the Pod's container." + }, + "glusterfs": { + "$ref": "#/definitions/io.k8s.api.core.v1.GlusterfsVolumeSource", + "description": "Glusterfs represents a Glusterfs mount on the host that shares a pod's lifetime. More info: https://examples.k8s.io/volumes/glusterfs/README.md" + }, + "hostPath": { + "$ref": "#/definitions/io.k8s.api.core.v1.HostPathVolumeSource", + "description": "HostPath represents a pre-existing file or directory on the host machine that is directly exposed to the container. This is generally used for system agents or other privileged things that are allowed to see the host machine. Most containers will NOT need this. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath" + }, + "iscsi": { + "$ref": "#/definitions/io.k8s.api.core.v1.ISCSIVolumeSource", + "description": "ISCSI represents an ISCSI Disk resource that is attached to a kubelet's host machine and then exposed to the pod. More info: https://examples.k8s.io/volumes/iscsi/README.md" + }, + "name": { + "description": "Volume's name. Must be a DNS_LABEL and unique within the pod. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names", + "type": "string" + }, + "nfs": { + "$ref": "#/definitions/io.k8s.api.core.v1.NFSVolumeSource", + "description": "NFS represents an NFS mount on the host that shares a pod's lifetime More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs" + }, + "persistentVolumeClaim": { + "$ref": "#/definitions/io.k8s.api.core.v1.PersistentVolumeClaimVolumeSource", + "description": "PersistentVolumeClaimVolumeSource represents a reference to a PersistentVolumeClaim in the same namespace. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims" + }, + "photonPersistentDisk": { + "$ref": "#/definitions/io.k8s.api.core.v1.PhotonPersistentDiskVolumeSource", + "description": "PhotonPersistentDisk represents a PhotonController persistent disk attached and mounted on kubelets host machine" + }, + "portworxVolume": { + "$ref": "#/definitions/io.k8s.api.core.v1.PortworxVolumeSource", + "description": "PortworxVolume represents a portworx volume attached and mounted on kubelets host machine" + }, + "projected": { + "$ref": "#/definitions/io.k8s.api.core.v1.ProjectedVolumeSource", + "description": "Items for all in one resources secrets, configmaps, and downward API" + }, + "quobyte": { + "$ref": "#/definitions/io.k8s.api.core.v1.QuobyteVolumeSource", + "description": "Quobyte represents a Quobyte mount on the host that shares a pod's lifetime" + }, + "rbd": { + "$ref": "#/definitions/io.k8s.api.core.v1.RBDVolumeSource", + "description": "RBD represents a Rados Block Device mount on the host that shares a pod's lifetime. More info: https://examples.k8s.io/volumes/rbd/README.md" + }, + "scaleIO": { + "$ref": "#/definitions/io.k8s.api.core.v1.ScaleIOVolumeSource", + "description": "ScaleIO represents a ScaleIO persistent volume attached and mounted on Kubernetes nodes." + }, + "secret": { + "$ref": "#/definitions/io.k8s.api.core.v1.SecretVolumeSource", + "description": "Secret represents a secret that should populate this volume. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret" + }, + "storageos": { + "$ref": "#/definitions/io.k8s.api.core.v1.StorageOSVolumeSource", + "description": "StorageOS represents a StorageOS volume attached and mounted on Kubernetes nodes." + }, + "vsphereVolume": { + "$ref": "#/definitions/io.k8s.api.core.v1.VsphereVirtualDiskVolumeSource", + "description": "VsphereVolume represents a vSphere volume attached and mounted on kubelets host machine" + } + }, + "required": [ + "name" + ], + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.VolumeDevice": { + "description": "volumeDevice describes a mapping of a raw block device within a container.", + "properties": { + "devicePath": { + "description": "devicePath is the path inside of the container that the device will be mapped to.", + "type": "string" + }, + "name": { + "description": "name must match the name of a persistentVolumeClaim in the pod", + "type": "string" + } + }, + "required": [ + "name", + "devicePath" + ], + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.VolumeMount": { + "description": "VolumeMount describes a mounting of a Volume within a container.", + "properties": { + "mountPath": { + "description": "Path within the container at which the volume should be mounted. Must not contain ':'.", + "type": "string" + }, + "mountPropagation": { + "description": "mountPropagation determines how mounts are propagated from the host to container and the other way around. When not set, MountPropagationNone is used. This field is beta in 1.10.", + "type": "string" + }, + "name": { + "description": "This must match the Name of a Volume.", + "type": "string" + }, + "readOnly": { + "description": "Mounted read-only if true, read-write otherwise (false or unspecified). Defaults to false.", + "type": "boolean" + }, + "subPath": { + "description": "Path within the volume from which the container's volume should be mounted. Defaults to \"\" (volume's root).", + "type": "string" + }, + "subPathExpr": { + "description": "Expanded path within the volume from which the container's volume should be mounted. Behaves similarly to SubPath but environment variable references $(VAR_NAME) are expanded using the container's environment. Defaults to \"\" (volume's root). SubPathExpr and SubPath are mutually exclusive.", + "type": "string" + } + }, + "required": [ + "name", + "mountPath" + ], + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.VolumeProjection": { + "description": "Projection that may be projected along with other supported volume types", + "properties": { + "configMap": { + "$ref": "#/definitions/io.k8s.api.core.v1.ConfigMapProjection", + "description": "information about the configMap data to project" + }, + "downwardAPI": { + "$ref": "#/definitions/io.k8s.api.core.v1.DownwardAPIProjection", + "description": "information about the downwardAPI data to project" + }, + "secret": { + "$ref": "#/definitions/io.k8s.api.core.v1.SecretProjection", + "description": "information about the secret data to project" + }, + "serviceAccountToken": { + "$ref": "#/definitions/io.k8s.api.core.v1.ServiceAccountTokenProjection", + "description": "information about the serviceAccountToken data to project" + } + }, + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.VsphereVirtualDiskVolumeSource": { + "description": "Represents a vSphere volume resource.", + "properties": { + "fsType": { + "description": "Filesystem type to mount. Must be a filesystem type supported by the host operating system. Ex. \"ext4\", \"xfs\", \"ntfs\". Implicitly inferred to be \"ext4\" if unspecified.", + "type": "string" + }, + "storagePolicyID": { + "description": "Storage Policy Based Management (SPBM) profile ID associated with the StoragePolicyName.", + "type": "string" + }, + "storagePolicyName": { + "description": "Storage Policy Based Management (SPBM) profile name.", + "type": "string" + }, + "volumePath": { + "description": "Path that identifies vSphere volume vmdk", + "type": "string" + } + }, + "required": [ + "volumePath" + ], + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.WeightedPodAffinityTerm": { + "description": "The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred node(s)", + "properties": { + "podAffinityTerm": { + "$ref": "#/definitions/io.k8s.api.core.v1.PodAffinityTerm", + "description": "Required. A pod affinity term, associated with the corresponding weight." + }, + "weight": { + "description": "weight associated with matching the corresponding podAffinityTerm, in the range 1-100.", + "format": "int32", + "type": "integer" + } + }, + "required": [ + "weight", + "podAffinityTerm" + ], + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.core.v1.WindowsSecurityContextOptions": { + "description": "WindowsSecurityContextOptions contain Windows-specific options and credentials.", + "properties": { + "gmsaCredentialSpec": { + "description": "GMSACredentialSpec is where the GMSA admission webhook (https://github.com/kubernetes-sigs/windows-gmsa) inlines the contents of the GMSA credential spec named by the GMSACredentialSpecName field.", + "type": "string" + }, + "gmsaCredentialSpecName": { + "description": "GMSACredentialSpecName is the name of the GMSA credential spec to use.", + "type": "string" + }, + "hostProcess": { + "description": "HostProcess determines if a container should be run as a 'Host Process' container. This field is alpha-level and will only be honored by components that enable the WindowsHostProcessContainers feature flag. Setting this field without the feature flag will result in errors when validating the Pod. All of a Pod's containers must have the same effective HostProcess value (it is not allowed to have a mix of HostProcess containers and non-HostProcess containers). In addition, if HostProcess is true then HostNetwork must also be set to true.", + "type": "boolean" + }, + "runAsUserName": { + "description": "The UserName in Windows to run the entrypoint of the container process. Defaults to the user specified in image metadata if unspecified. May also be set in PodSecurityContext. If set in both SecurityContext and PodSecurityContext, the value specified in SecurityContext takes precedence.", + "type": "string" + } + }, + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.networking.v1.IPBlock": { + "description": "IPBlock describes a particular CIDR (Ex. \"192.168.1.1/24\",\"2001:db9::/64\") that is allowed to the pods matched by a NetworkPolicySpec's podSelector. The except entry describes CIDRs that should not be included within this rule.", + "properties": { + "cidr": { + "description": "CIDR is a string representing the IP Block Valid examples are \"192.168.1.1/24\" or \"2001:db9::/64\"", + "type": "string" + }, + "except": { + "description": "Except is a slice of CIDRs that should not be included within an IP Block Valid examples are \"192.168.1.1/24\" or \"2001:db9::/64\" Except values will be rejected if they are outside the CIDR range", + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "cidr" + ], + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.networking.v1.NetworkPolicyPeer": { + "description": "NetworkPolicyPeer describes a peer to allow traffic to/from. Only certain combinations of fields are allowed", + "properties": { + "ipBlock": { + "$ref": "#/definitions/io.k8s.api.networking.v1.IPBlock", + "description": "IPBlock defines policy on a particular IPBlock. If this field is set then neither of the other fields can be." + }, + "namespaceSelector": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.LabelSelector", + "description": "Selects Namespaces using cluster-scoped labels. This field follows standard label selector semantics; if present but empty, it selects all namespaces.\n\nIf PodSelector is also set, then the NetworkPolicyPeer as a whole selects the Pods matching PodSelector in the Namespaces selected by NamespaceSelector. Otherwise it selects all Pods in the Namespaces selected by NamespaceSelector." + }, + "podSelector": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.LabelSelector", + "description": "This is a label selector which selects Pods. This field follows standard label selector semantics; if present but empty, it selects all pods.\n\nIf NamespaceSelector is also set, then the NetworkPolicyPeer as a whole selects the Pods matching PodSelector in the Namespaces selected by NamespaceSelector. Otherwise it selects the Pods matching PodSelector in the policy's own Namespace." + } + }, + "type": "object", + "additionalProperties": false + }, + "io.k8s.api.networking.v1.NetworkPolicyPort": { + "description": "NetworkPolicyPort describes a port to allow traffic on", + "properties": { + "endPort": { + "description": "If set, indicates that the range of ports from port to endPort, inclusive, should be allowed by the policy. This field cannot be defined if the port field is not defined or if the port field is defined as a named (string) port. The endPort must be equal or greater than port. This feature is in Beta state and is enabled by default. It can be disabled using the Feature Gate \"NetworkPolicyEndPort\".", + "format": "int32", + "type": "integer" + }, + "port": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.util.intstr.IntOrString", + "description": "The port on the given protocol. This can either be a numerical or named port on a pod. If this field is not provided, this matches all port names and numbers. If present, only traffic on the specified protocol AND port will be matched." + }, + "protocol": { + "description": "The protocol (TCP, UDP, or SCTP) which traffic must match. If not specified, this field defaults to TCP.", + "type": "string" + } + }, + "type": "object", + "additionalProperties": false + }, + "io.k8s.apimachinery.pkg.api.resource.Quantity": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "number" + } + ] + }, + "io.k8s.apimachinery.pkg.apis.meta.v1.FieldsV1": { + "description": "FieldsV1 stores a set of fields in a data structure like a Trie, in JSON format.\n\nEach key is either a '.' representing the field itself, and will always map to an empty set, or a string representing a sub-field or item. The string will follow one of these four formats: 'f:', where is the name of a field in a struct, or key in a map 'v:', where is the exact json formatted value of a list item 'i:', where is position of a item in a list 'k:', where is a map of a list item's key fields to their unique values If a key maps to an empty Fields value, the field that key represents is part of the set.\n\nThe exact format is defined in sigs.k8s.io/structured-merge-diff", + "type": "object" + }, + "io.k8s.apimachinery.pkg.apis.meta.v1.LabelSelector": { + "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": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.LabelSelectorRequirement" + }, + "type": "array" + }, + "matchLabels": { + "additionalProperties": { + "type": "string" + }, + "description": "matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is \"key\", the operator is \"In\", and the values array contains only \"value\". The requirements are ANDed.", + "type": "object" + } + }, + "type": "object", + "x-kubernetes-map-type": "atomic", + "additionalProperties": false + }, + "io.k8s.apimachinery.pkg.apis.meta.v1.LabelSelectorRequirement": { + "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", + "x-kubernetes-patch-merge-key": "key", + "x-kubernetes-patch-strategy": "merge" + }, + "operator": { + "description": "operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist.", + "type": "string" + }, + "values": { + "description": "values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.", + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "key", + "operator" + ], + "type": "object", + "additionalProperties": false + }, + "io.k8s.apimachinery.pkg.apis.meta.v1.ManagedFieldsEntry": { + "description": "ManagedFieldsEntry is a workflow-id, a FieldSet and the group version of the resource that the fieldset applies to.", + "properties": { + "apiVersion": { + "description": "APIVersion defines the version of this resource that this field set applies to. The format is \"group/version\" just like the top-level APIVersion field. It is necessary to track the version of a field set because it cannot be automatically converted.", + "type": "string" + }, + "fieldsType": { + "description": "FieldsType is the discriminator for the different fields format and version. There is currently only one possible value: \"FieldsV1\"", + "type": "string" + }, + "fieldsV1": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.FieldsV1", + "description": "FieldsV1 holds the first JSON version format as described in the \"FieldsV1\" type." + }, + "manager": { + "description": "Manager is an identifier of the workflow managing these fields.", + "type": "string" + }, + "operation": { + "description": "Operation is the type of operation which lead to this ManagedFieldsEntry being created. The only valid values for this field are 'Apply' and 'Update'.", + "type": "string" + }, + "subresource": { + "description": "Subresource is the name of the subresource used to update that object, or empty string if the object was updated through the main resource. The value of this field is used to distinguish between managers, even if they share the same name. For example, a status update will be distinct from a regular update using the same manager name. Note that the APIVersion field is not related to the Subresource field and it always corresponds to the version of the main resource.", + "type": "string" + }, + "time": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.Time", + "description": "Time is timestamp of when these fields were set. It should always be empty if Operation is 'Apply'" + } + }, + "type": "object", + "additionalProperties": false + }, + "io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta": { + "description": "ObjectMeta is metadata that all persisted resources must have, which includes all objects users must create.", + "properties": { + "annotations": { + "additionalProperties": { + "type": "string" + }, + "description": "Annotations is an unstructured key value map stored with a resource that may be set by external tools to store and retrieve arbitrary metadata. They are not queryable and should be preserved when modifying objects. More info: http://kubernetes.io/docs/user-guide/annotations", + "type": "object" + }, + "clusterName": { + "description": "The name of the cluster which the object belongs to. This is used to distinguish resources with same name and namespace in different clusters. This field is not set anywhere right now and apiserver is going to ignore it if set in create or update request.", + "type": "string" + }, + "creationTimestamp": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.Time", + "description": "CreationTimestamp is a timestamp representing the server time when this object was created. It is not guaranteed to be set in happens-before order across separate operations. Clients may not set this value. It is represented in RFC3339 form and is in UTC.\n\nPopulated by the system. Read-only. Null for lists. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata" + }, + "deletionGracePeriodSeconds": { + "description": "Number of seconds allowed for this object to gracefully terminate before it will be removed from the system. Only set when deletionTimestamp is also set. May only be shortened. Read-only.", + "format": "int64", + "type": "integer" + }, + "deletionTimestamp": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.Time", + "description": "DeletionTimestamp is RFC 3339 date and time at which this resource will be deleted. This field is set by the server when a graceful deletion is requested by the user, and is not directly settable by a client. The resource is expected to be deleted (no longer visible from resource lists, and not reachable by name) after the time in this field, once the finalizers list is empty. As long as the finalizers list contains items, deletion is blocked. Once the deletionTimestamp is set, this value may not be unset or be set further into the future, although it may be shortened or the resource may be deleted prior to this time. For example, a user may request that a pod is deleted in 30 seconds. The Kubelet will react by sending a graceful termination signal to the containers in the pod. After that 30 seconds, the Kubelet will send a hard termination signal (SIGKILL) to the container and after cleanup, remove the pod from the API. In the presence of network partitions, this object may still exist after this timestamp, until an administrator or automated process can determine the resource is fully terminated. If not set, graceful deletion of the object has not been requested.\n\nPopulated by the system when a graceful deletion is requested. Read-only. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata" + }, + "finalizers": { + "description": "Must be empty before the object is deleted from the registry. Each entry is an identifier for the responsible component that will remove the entry from the list. If the deletionTimestamp of the object is non-nil, entries in this list can only be removed. Finalizers may be processed and removed in any order. Order is NOT enforced because it introduces significant risk of stuck finalizers. finalizers is a shared field, any actor with permission can reorder it. If the finalizer list is processed in order, then this can lead to a situation in which the component responsible for the first finalizer in the list is waiting for a signal (field value, external system, or other) produced by a component responsible for a finalizer later in the list, resulting in a deadlock. Without enforced ordering finalizers are free to order amongst themselves and are not vulnerable to ordering changes in the list.", + "items": { + "type": "string" + }, + "type": "array", + "x-kubernetes-patch-strategy": "merge" + }, + "generateName": { + "description": "GenerateName is an optional prefix, used by the server, to generate a unique name ONLY IF the Name field has not been provided. If this field is used, the name returned to the client will be different than the name passed. This value will also be combined with a unique suffix. The provided value has the same validation rules as the Name field, and may be truncated by the length of the suffix required to make the value unique on the server.\n\nIf this field is specified and the generated name exists, the server will NOT return a 409 - instead, it will either return 201 Created or 500 with Reason ServerTimeout indicating a unique name could not be found in the time allotted, and the client should retry (optionally after the time indicated in the Retry-After header).\n\nApplied only if Name is not specified. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#idempotency", + "type": "string" + }, + "generation": { + "description": "A sequence number representing a specific generation of the desired state. Populated by the system. Read-only.", + "format": "int64", + "type": "integer" + }, + "labels": { + "additionalProperties": { + "type": "string" + }, + "description": "Map of string keys and values that can be used to organize and categorize (scope and select) objects. May match selectors of replication controllers and services. More info: http://kubernetes.io/docs/user-guide/labels", + "type": "object" + }, + "managedFields": { + "description": "ManagedFields maps workflow-id and version to the set of fields that are managed by that workflow. This is mostly for internal housekeeping, and users typically shouldn't need to set or understand this field. A workflow can be the user's name, a controller's name, or the name of a specific apply path like \"ci-cd\". The set of fields is always in the version that the workflow used when modifying the object.", + "items": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.ManagedFieldsEntry" + }, + "type": "array" + }, + "name": { + "description": "Name must be unique within a namespace. Is required when creating resources, although some resources may allow a client to request the generation of an appropriate name automatically. Name is primarily intended for creation idempotence and configuration definition. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/identifiers#names", + "type": "string" + }, + "namespace": { + "description": "Namespace defines the space within which each name must be unique. An empty namespace is equivalent to the \"default\" namespace, but \"default\" is the canonical representation. Not all objects are required to be scoped to a namespace - the value of this field for those objects will be empty.\n\nMust be a DNS_LABEL. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/namespaces", + "type": "string" + }, + "ownerReferences": { + "description": "List of objects depended by this object. If ALL objects in the list have been deleted, this object will be garbage collected. If this object is managed by a controller, then an entry in this list will point to this controller, with the controller field set to true. There cannot be more than one managing controller.", + "items": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.OwnerReference" + }, + "type": "array", + "x-kubernetes-patch-merge-key": "uid", + "x-kubernetes-patch-strategy": "merge" + }, + "resourceVersion": { + "description": "An opaque value that represents the internal version of this object that can be used by clients to determine when objects have changed. May be used for optimistic concurrency, change detection, and the watch operation on a resource or set of resources. Clients must treat these values as opaque and passed unmodified back to the server. They may only be valid for a particular resource or set of resources.\n\nPopulated by the system. Read-only. Value must be treated as opaque by clients and . More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency", + "type": "string" + }, + "selfLink": { + "description": "SelfLink is a URL representing this object. Populated by the system. Read-only.\n\nDEPRECATED Kubernetes will stop propagating this field in 1.20 release and the field is planned to be removed in 1.21 release.", + "type": "string" + }, + "uid": { + "description": "UID is the unique in time and space value for this object. It is typically generated by the server on successful creation of a resource and is not allowed to change on PUT operations.\n\nPopulated by the system. Read-only. More info: http://kubernetes.io/docs/user-guide/identifiers#uids", + "type": "string" + } + }, + "type": "object", + "additionalProperties": false + }, + "io.k8s.apimachinery.pkg.apis.meta.v1.OwnerReference": { + "description": "OwnerReference contains enough information to let you identify an owning object. An owning object must be in the same namespace as the dependent, or be cluster-scoped, so there is no namespace field.", + "properties": { + "apiVersion": { + "description": "API version of the referent.", + "type": "string" + }, + "blockOwnerDeletion": { + "description": "If true, AND if the owner has the \"foregroundDeletion\" finalizer, then the owner cannot be deleted from the key-value store until this reference is removed. Defaults to false. To set this field, a user needs \"delete\" permission of the owner, otherwise 422 (Unprocessable Entity) will be returned.", + "type": "boolean" + }, + "controller": { + "description": "If true, this reference points to the managing controller.", + "type": "boolean" + }, + "kind": { + "description": "Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "name": { + "description": "Name of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#names", + "type": "string" + }, + "uid": { + "description": "UID of the referent. More info: http://kubernetes.io/docs/user-guide/identifiers#uids", + "type": "string" + } + }, + "required": [ + "apiVersion", + "kind", + "name", + "uid" + ], + "type": "object", + "x-kubernetes-map-type": "atomic", + "additionalProperties": false + }, + "io.k8s.apimachinery.pkg.apis.meta.v1.Time": { + "description": "Time is a wrapper around time.Time which supports correct marshaling to YAML and JSON. Wrappers are provided for many of the factory methods that the time package offers.", + "format": "date-time", + "type": "string" + }, + "io.k8s.apimachinery.pkg.util.intstr.IntOrString": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "integer" + } + ] + }, + "logGroomerConfigType": { + "description": "Configuration for log groomer sidecar", + "type": "object", + "additionalProperties": false, + "properties": { + "enabled": { + "description": "Whether to deploy the Airflow log groomer sidecar.", + "type": "boolean", + "default": true + }, + "command": { + "description": "Command to use when running the Airflow log groomer sidecar (templated).", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + }, + "default": null + }, + "args": { + "description": "Args to use when running the Airflow log groomer sidecar (templated).", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + }, + "default": [ + "bash", + "/clean-logs" + ] + }, + "retentionDays": { + "description": "Number of days to retain the logs when running the Airflow log groomer sidecar.", + "type": "integer", + "default": 15 + }, + "resources": { + "description": "Resources for Airflow log groomer sidecar.", + "type": "object", + "default": {}, + "examples": [ + { + "limits": { + "cpu": "100m", + "memory": "128Mi" + }, + "requests": { + "cpu": "100m", + "memory": "128Mi" + } + } + ], + "$ref": "#/definitions/io.k8s.api.core.v1.ResourceRequirements" + }, + "containerLifecycleHooks": { + "description": "Container Lifecycle Hooks definition for the log groomer sidecar. If not set, the values from global `containerLifecycleHooks` will be used.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.Lifecycle", + "default": {}, + "x-docsSection": "Kubernetes", + "examples": [ + { + "postStart": { + "exec": { + "command": [ + "/bin/sh", + "-c", + "echo postStart handler > /usr/share/message" + ] + } + }, + "preStop": { + "exec": { + "command": [ + "/bin/sh", + "-c", + "echo preStop handler > /usr/share/message" + ] + } + } + } + ] + }, + "securityContexts": { + "description": "Security context definition for the log groomer sidecar. If not set, the values from global `securityContexts` will be used.", + "type": "object", + "x-docsSection": "Kubernetes", + "properties": { + "container": { + "description": "Container security context definition for the log groomer sidecar.", + "type": "object", + "$ref": "#/definitions/io.k8s.api.core.v1.SecurityContext", + "default": {}, + "x-docsSection": "Kubernetes", + "examples": [ + { + "allowPrivilegeEscalation": false, + "capabilities": { + "drop": [ + "ALL" + ] + } + } + ] + } + } + } + } + } + } +} diff --git a/helm/airflow/values.yaml b/helm/airflow/values.yaml new file mode 100644 index 0000000..5f0732a --- /dev/null +++ b/helm/airflow/values.yaml @@ -0,0 +1,2471 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +--- +# Default values for airflow. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +# Provide a name to substitute for the full names of resources +fullnameOverride: "" + +# Provide a name to substitute for the name of the chart +nameOverride: "" + +# Use standard naming for all resources using airflow.fullname template +# Consider removing this later and default it to true +# to make this chart follow standard naming conventions using the fullname template. +# For now this is an opt-in switch for backwards compatibility to leverage the standard naming convention +# and being able to use fully fullnameOverride and nameOverride in all resources +# For new installations - it is recommended to set it to True to follow standard naming conventions +# For existing installations, this will rename and redeploy your resources with the new names. Be aware that +# this will recreate your deployment/statefulsets along with their persistent volume claims and data storage +# migration may be needed to keep your old data +# +# Note:fernet-key,redis-password and broker-url secrets don't use this logic yet, +# as this may break existing installations due to how they get installed via pre-install hook. +useStandardNaming: false + +# Max number of old replicasets to retain. Can be overridden by each deployment's revisionHistoryLimit +revisionHistoryLimit: ~ + +# User and group of airflow user +uid: 50000 +gid: 0 + +# Default security context for airflow (deprecated, use `securityContexts` instead) +securityContext: {} +# runAsUser: 50000 +# fsGroup: 0 +# runAsGroup: 0 + +# Detailed default security context for airflow deployments +securityContexts: + pod: {} + containers: {} + +# Default container lifecycle hooks for every service except for redis, statsd and pgbouncer. +containerLifecycleHooks: {} + +# Airflow home directory +# Used for mount paths +airflowHome: /opt/airflow + +# Default airflow repository -- overridden by all the specific images below +defaultAirflowRepository: apache/airflow + +# Default airflow tag to deploy +defaultAirflowTag: "2.7.1" + +# Default airflow digest. If specified, it takes precedence over tag +defaultAirflowDigest: ~ + +# Airflow version (Used to make some decisions based on Airflow Version being deployed) +airflowVersion: "2.7.1" + +# Images +images: + airflow: + repository: ~ + tag: ~ + # Specifying digest takes precedence over tag. + digest: ~ + pullPolicy: IfNotPresent + # To avoid images with user code, you can turn this to 'true' and + # all the 'run-airflow-migrations' and 'wait-for-airflow-migrations' containers/jobs + # will use the images from 'defaultAirflowRepository:defaultAirflowTag' values + # to run and wait for DB migrations . + useDefaultImageForMigration: false + # timeout (in seconds) for airflow-migrations to complete + migrationsWaitTimeout: 60 + pod_template: + # Note that `images.pod_template.repository` and `images.pod_template.tag` parameters + # can be overridden in `config.kubernetes` section. So for these parameters to have effect + # `config.kubernetes.worker_container_repository` and `config.kubernetes.worker_container_tag` + # must be not set . + repository: ~ + tag: ~ + pullPolicy: IfNotPresent + flower: + repository: ~ + tag: ~ + pullPolicy: IfNotPresent + statsd: + repository: quay.io/prometheus/statsd-exporter + tag: v0.22.8 + pullPolicy: IfNotPresent + redis: + repository: redis + tag: 7-bullseye + pullPolicy: IfNotPresent + pgbouncer: + repository: apache/airflow + tag: airflow-pgbouncer-2023.02.24-1.16.1 + pullPolicy: IfNotPresent + pgbouncerExporter: + repository: apache/airflow + tag: airflow-pgbouncer-exporter-2023.02.21-0.14.0 + pullPolicy: IfNotPresent + gitSync: + repository: registry.k8s.io/git-sync/git-sync + tag: v3.6.9 + pullPolicy: IfNotPresent + +# Select certain nodes for airflow pods. +nodeSelector: {} +affinity: {} +tolerations: [] +topologySpreadConstraints: [] +schedulerName: ~ + +# Add common labels to all objects and pods defined in this chart. +labels: {} + +# Ingress configuration +ingress: + # Enable all ingress resources (deprecated - use ingress.web.enabled and ingress.flower.enabled) + enabled: ~ + + # Configs for the Ingress of the web Service + web: + # Enable web ingress resource + enabled: false + + # Annotations for the web Ingress + annotations: {} + + # The path for the web Ingress + path: "/" + + # The pathType for the above path (used only with Kubernetes v1.19 and above) + pathType: "ImplementationSpecific" + + # The hostname for the web Ingress (Deprecated - renamed to `ingress.web.hosts`) + host: "" + + # The hostnames or hosts configuration for the web Ingress + hosts: [] + # # The hostname for the web Ingress (can be templated) + # - name: "" + # # configs for web Ingress TLS + # tls: + # # Enable TLS termination for the web Ingress + # enabled: false + # # the name of a pre-created Secret containing a TLS private key and certificate + # secretName: "" + + # The Ingress Class for the web Ingress (used only with Kubernetes v1.19 and above) + ingressClassName: "" + + # configs for web Ingress TLS (Deprecated - renamed to `ingress.web.hosts[*].tls`) + tls: + # Enable TLS termination for the web Ingress + enabled: false + # the name of a pre-created Secret containing a TLS private key and certificate + secretName: "" + + # HTTP paths to add to the web Ingress before the default path + precedingPaths: [] + + # Http paths to add to the web Ingress after the default path + succeedingPaths: [] + + # Configs for the Ingress of the flower Service + flower: + # Enable web ingress resource + enabled: false + + # Annotations for the flower Ingress + annotations: {} + + # The path for the flower Ingress + path: "/" + + # The pathType for the above path (used only with Kubernetes v1.19 and above) + pathType: "ImplementationSpecific" + + # The hostname for the flower Ingress (Deprecated - renamed to `ingress.flower.hosts`) + host: "" + + # The hostnames or hosts configuration for the flower Ingress + hosts: [] + # # The hostname for the flower Ingress (can be templated) + # - name: "" + # tls: + # # Enable TLS termination for the flower Ingress + # enabled: false + # # the name of a pre-created Secret containing a TLS private key and certificate + # secretName: "" + + # The Ingress Class for the flower Ingress (used only with Kubernetes v1.19 and above) + ingressClassName: "" + + # configs for flower Ingress TLS (Deprecated - renamed to `ingress.flower.hosts[*].tls`) + tls: + # Enable TLS termination for the flower Ingress + enabled: false + # the name of a pre-created Secret containing a TLS private key and certificate + secretName: "" + +# Network policy configuration +networkPolicies: + # Enabled network policies + enabled: false + +# Extra annotations to apply to all +# Airflow pods +airflowPodAnnotations: {} + +# Extra annotations to apply to +# main Airflow configmap +airflowConfigAnnotations: {} + +# `airflow_local_settings` file as a string (can be templated). +airflowLocalSettings: |- + {{- if semverCompare ">=2.2.0" .Values.airflowVersion }} + {{- if not (or .Values.webserverSecretKey .Values.webserverSecretKeySecretName) }} + from airflow.www.utils import UIAlert + + DASHBOARD_UIALERTS = [ + UIAlert( + 'Usage of a dynamic webserver secret key detected. We recommend a static webserver secret key instead.' + ' See the ' + 'Helm Chart Production Guide for more details.', + category="warning", + roles=["Admin"], + html=True, + ) + ] + {{- end }} + {{- end }} + +# Enable RBAC (default on most clusters these days) +rbac: + # Specifies whether RBAC resources should be created + create: true + createSCCRoleBinding: false + +# Airflow executor +# One of: LocalExecutor, LocalKubernetesExecutor, CeleryExecutor, KubernetesExecutor, CeleryKubernetesExecutor +executor: "CeleryExecutor" + +# If this is true and using LocalExecutor/KubernetesExecutor/CeleryKubernetesExecutor, the scheduler's +# service account will have access to communicate with the api-server and launch pods. +# If this is true and using CeleryExecutor/KubernetesExecutor/CeleryKubernetesExecutor, the workers +# will be able to launch pods. +allowPodLaunching: true + +# Environment variables for all airflow containers +env: [] +# - name: "" +# value: "" + +# Volumes for all airflow containers +volumes: [] + +# VolumeMounts for all airflow containers +volumeMounts: [] + +# Secrets for all airflow containers +secret: [] +# - envName: "" +# secretName: "" +# secretKey: "" + +# Enables selected built-in secrets that are set via environment variables by default. +# Those secrets are provided by the Helm Chart secrets by default but in some cases you +# might want to provide some of those variables with _CMD or _SECRET variable, and you should +# in this case disable setting of those variables by setting the relevant configuration to false. +enableBuiltInSecretEnvVars: + AIRFLOW__CORE__FERNET_KEY: true + # For Airflow <2.3, backward compatibility; moved to [database] in 2.3 + AIRFLOW__CORE__SQL_ALCHEMY_CONN: true + AIRFLOW__DATABASE__SQL_ALCHEMY_CONN: true + AIRFLOW_CONN_AIRFLOW_DB: true + AIRFLOW__WEBSERVER__SECRET_KEY: true + AIRFLOW__CELERY__CELERY_RESULT_BACKEND: true + AIRFLOW__CELERY__RESULT_BACKEND: true + AIRFLOW__CELERY__BROKER_URL: true + AIRFLOW__ELASTICSEARCH__HOST: true + AIRFLOW__ELASTICSEARCH__ELASTICSEARCH_HOST: true + +# Priority Classes that will be installed by charts. +# Ideally, there should be an entry for dagProcessor, flower, +# pgbouncer, scheduler, statsd, triggerer, webserver, worker. +# The format for priorityClasses is an array with each element having: +# * name is the name of the priorityClass. Ensure the same name is given to the respective section as well +# * preemptionPolicy for the priorityClass +# * value is the preemption value for the priorityClass +priorityClasses: [] +# - name: class1 (if this is for dagProcessor, ensure overriding .Values.dagProcessor.priorityClass too) +# preemptionPolicy: PreemptLowerPriority +# value: 10000 +# - name: class2 +# preemptionPolicy: Never +# value: 100000 + +# Extra secrets that will be managed by the chart +# (You can use them with extraEnv or extraEnvFrom or some of the extraVolumes values). +# The format for secret data is "key/value" where +# * key (can be templated) is the name of the secret that will be created +# * value: an object with the standard 'data' or 'stringData' key (or both). +# The value associated with those keys must be a string (can be templated) +extraSecrets: {} +# eg: +# extraSecrets: +# '{{ .Release.Name }}-airflow-connections': +# type: 'Opaque' +# labels: +# my.custom.label/v1: my_custom_label_value_1 +# data: | +# AIRFLOW_CONN_GCP: 'base64_encoded_gcp_conn_string' +# AIRFLOW_CONN_AWS: 'base64_encoded_aws_conn_string' +# stringData: | +# AIRFLOW_CONN_OTHER: 'other_conn' +# '{{ .Release.Name }}-other-secret-name-suffix': +# data: | +# ... + +# Extra ConfigMaps that will be managed by the chart +# (You can use them with extraEnv or extraEnvFrom or some of the extraVolumes values). +# The format for configmap data is "key/value" where +# * key (can be templated) is the name of the configmap that will be created +# * value: an object with the standard 'data' key. +# The value associated with this keys must be a string (can be templated) +extraConfigMaps: {} +# eg: +# extraConfigMaps: +# '{{ .Release.Name }}-airflow-variables': +# labels: +# my.custom.label/v2: my_custom_label_value_2 +# data: | +# AIRFLOW_VAR_HELLO_MESSAGE: "Hi!" +# AIRFLOW_VAR_KUBERNETES_NAMESPACE: "{{ .Release.Namespace }}" + +# Extra env 'items' that will be added to the definition of airflow containers +# a string is expected (can be templated). +# TODO: difference from `env`? This is a templated string. Probably should template `env` and remove this. +extraEnv: ~ +# eg: +# extraEnv: | +# - name: AIRFLOW__CORE__LOAD_EXAMPLES +# value: 'True' + +# Extra envFrom 'items' that will be added to the definition of airflow containers +# A string is expected (can be templated). +extraEnvFrom: ~ +# eg: +# extraEnvFrom: | +# - secretRef: +# name: '{{ .Release.Name }}-airflow-connections' +# - configMapRef: +# name: '{{ .Release.Name }}-airflow-variables' + +# Airflow database & redis config +data: + # If secret names are provided, use those secrets + # These secrets must be created manually, eg: + # + # kind: Secret + # apiVersion: v1 + # metadata: + # name: custom-airflow-metadata-secret + # type: Opaque + # data: + # connection: base64_encoded_connection_string + + metadataSecretName: ~ + # When providing secret names and using the same database for metadata and + # result backend, for Airflow < 2.4.0 it is necessary to create a separate + # secret for result backend but with a db+ scheme prefix. + # For Airflow >= 2.4.0 it is possible to not specify the secret again, + # as Airflow will use sql_alchemy_conn with a db+ scheme prefix by default. + resultBackendSecretName: ~ + brokerUrlSecretName: ~ + + # Otherwise pass connection values in + metadataConnection: + user: postgres + pass: postgres + protocol: postgresql + host: ~ + port: 5432 + db: postgres + sslmode: disable + # resultBackendConnection defaults to the same database as metadataConnection + resultBackendConnection: ~ + # or, you can use a different database + # resultBackendConnection: + # user: postgres + # pass: postgres + # protocol: postgresql + # host: ~ + # port: 5432 + # db: postgres + # sslmode: disable + # Note: brokerUrl can only be set during install, not upgrade + brokerUrl: ~ + +# Fernet key settings +# Note: fernetKey can only be set during install, not upgrade +fernetKey: ~ +fernetKeySecretName: ~ + +# Flask secret key for Airflow Webserver: `[webserver] secret_key` in airflow.cfg +webserverSecretKey: ~ +webserverSecretKeySecretName: ~ + +# In order to use kerberos you need to create secret containing the keytab file +# The secret name should follow naming convention of the application where resources are +# name {{ .Release-name }}-. In case of the keytab file, the postfix is "kerberos-keytab" +# So if your release is named "my-release" the name of the secret should be "my-release-kerberos-keytab" +# +# The Keytab content should be available in the "kerberos.keytab" key of the secret. +# +# apiVersion: v1 +# kind: Secret +# data: +# kerberos.keytab: +# type: Opaque +# +# +# If you have such keytab file you can do it with similar +# +# kubectl create secret generic {{ .Release.name }}-kerberos-keytab --from-file=kerberos.keytab +# +# +# Alternatively, instead of manually creating the secret, it is possible to specify +# kerberos.keytabBase64Content parameter. This parameter should contain base64 encoded keytab. +# + +kerberos: + enabled: false + ccacheMountPath: /var/kerberos-ccache + ccacheFileName: cache + configPath: /etc/krb5.conf + keytabBase64Content: ~ + keytabPath: /etc/airflow.keytab + principal: airflow@FOO.COM + reinitFrequency: 3600 + config: | + # This is an example config showing how you can use templating and how "example" config + # might look like. It works with the test kerberos server that we are using during integration + # testing at Apache Airflow (see `scripts/ci/docker-compose/integration-kerberos.yml` but in + # order to make it production-ready you must replace it with your own configuration that + # Matches your kerberos deployment. Administrators of your Kerberos instance should + # provide the right configuration. + + [logging] + default = "FILE:{{ template "airflow_logs_no_quote" . }}/kerberos_libs.log" + kdc = "FILE:{{ template "airflow_logs_no_quote" . }}/kerberos_kdc.log" + admin_server = "FILE:{{ template "airflow_logs_no_quote" . }}/kadmind.log" + + [libdefaults] + default_realm = FOO.COM + ticket_lifetime = 10h + renew_lifetime = 7d + forwardable = true + + [realms] + FOO.COM = { + kdc = kdc-server.foo.com + admin_server = admin_server.foo.com + } + +# Airflow Worker Config +workers: + # Number of airflow celery workers in StatefulSet + replicas: 1 + # Max number of old replicasets to retain + revisionHistoryLimit: ~ + + # Command to use when running Airflow workers (templated). + command: ~ + # Args to use when running Airflow workers (templated). + args: + - "bash" + - "-c" + # The format below is necessary to get `helm lint` happy + - |- + exec \ + airflow {{ semverCompare ">=2.0.0" .Values.airflowVersion | ternary "celery worker" "worker" }} + + # If the worker stops responding for 5 minutes (5*60s) kill the + # worker and let Kubernetes restart it + livenessProbe: + enabled: true + initialDelaySeconds: 10 + timeoutSeconds: 20 + failureThreshold: 5 + periodSeconds: 60 + command: ~ + + # Update Strategy when worker is deployed as a StatefulSet + updateStrategy: ~ + # Update Strategy when worker is deployed as a Deployment + strategy: + rollingUpdate: + maxSurge: "100%" + maxUnavailable: "50%" + + # When not set, the values defined in the global securityContext will be used + securityContext: {} + # runAsUser: 50000 + # fsGroup: 0 + # runAsGroup: 0 + + # Detailed default security context for worker deployments for container and pod level + securityContexts: + pod: {} + container: {} + + # container level lifecycle hooks + containerLifecycleHooks: {} + + # Create ServiceAccount + serviceAccount: + # default value is true + # ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ + automountServiceAccountToken: true + # Specifies whether a ServiceAccount should be created + create: true + # The name of the ServiceAccount to use. + # If not set and create is true, a name is generated using the release name + name: ~ + + # Annotations to add to worker kubernetes service account. + annotations: {} + + # Allow KEDA autoscaling. + keda: + enabled: false + namespaceLabels: {} + + # How often KEDA polls the airflow DB to report new scale requests to the HPA + pollingInterval: 5 + + # How many seconds KEDA will wait before scaling to zero. + # Note that HPA has a separate cooldown period for scale-downs + cooldownPeriod: 30 + + # Minimum number of workers created by keda + minReplicaCount: 0 + + # Maximum number of workers created by keda + maxReplicaCount: 10 + + # Specify HPA related options + advanced: {} + # horizontalPodAutoscalerConfig: + # behavior: + # scaleDown: + # stabilizationWindowSeconds: 300 + # policies: + # - type: Percent + # value: 100 + # periodSeconds: 15 + + # Query to use for KEDA autoscaling. Must return a single integer. + query: >- + SELECT ceil(COUNT(*)::decimal / {{ .Values.config.celery.worker_concurrency }}) + FROM task_instance + WHERE (state='running' OR state='queued') + {{- if eq .Values.executor "CeleryKubernetesExecutor" }} + AND queue != '{{ .Values.config.celery_kubernetes_executor.kubernetes_queue }}' + {{- end }} + + # Weather to use PGBouncer to connect to the database or not when it is enabled + # This configuration will be ignored if PGBouncer is not enabled + usePgbouncer: true + + persistence: + # Enable persistent volumes + enabled: true + # Volume size for worker StatefulSet + size: 100Gi + # If using a custom storageClass, pass name ref to all statefulSets here + storageClassName: + # Execute init container to chown log directory. + # This is currently only needed in kind, due to usage + # of local-path provisioner. + fixPermissions: false + # Annotations to add to worker volumes + annotations: {} + # Detailed default security context for persistence for container level + securityContexts: + container: {} + # container level lifecycle hooks + containerLifecycleHooks: {} + + kerberosSidecar: + # Enable kerberos sidecar + enabled: false + resources: {} + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + # Detailed default security context for kerberosSidecar for container level + securityContexts: + container: {} + # container level lifecycle hooks + containerLifecycleHooks: {} + + resources: {} + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + + # Grace period for tasks to finish after SIGTERM is sent from kubernetes + terminationGracePeriodSeconds: 600 + + # This setting tells kubernetes that its ok to evict + # when it wants to scale a node down. + safeToEvict: true + + # Launch additional containers into worker. + # Note: If used with KubernetesExecutor, you are responsible for signaling sidecars to exit when the main + # container finishes so Airflow can continue the worker shutdown process! + extraContainers: [] + # Add additional init containers into workers. + extraInitContainers: [] + + # Mount additional volumes into worker. It can be templated like in the following example: + # extraVolumes: + # - name: my-templated-extra-volume + # secret: + # secretName: '{{ include "my_secret_template" . }}' + # defaultMode: 0640 + # optional: true + # + # extraVolumeMounts: + # - name: my-templated-extra-volume + # mountPath: "{{ .Values.my_custom_path }}" + # readOnly: true + extraVolumes: [] + extraVolumeMounts: [] + + # Select certain nodes for airflow worker pods. + nodeSelector: {} + runtimeClassName: ~ + priorityClassName: ~ + affinity: {} + # default worker affinity is: + # podAntiAffinity: + # preferredDuringSchedulingIgnoredDuringExecution: + # - podAffinityTerm: + # labelSelector: + # matchLabels: + # component: worker + # topologyKey: kubernetes.io/hostname + # weight: 100 + tolerations: [] + topologySpreadConstraints: [] + # hostAliases to use in worker pods. + # See: + # https://kubernetes.io/docs/concepts/services-networking/add-entries-to-pod-etc-hosts-with-host-aliases/ + hostAliases: [] + # - ip: "127.0.0.2" + # hostnames: + # - "test.hostname.one" + # - ip: "127.0.0.3" + # hostnames: + # - "test.hostname.two" + + # annotations for the worker resource + annotations: {} + + podAnnotations: {} + + # Labels specific to workers objects and pods + labels: {} + + logGroomerSidecar: + # Whether to deploy the Airflow worker log groomer sidecar. + enabled: true + # Command to use when running the Airflow worker log groomer sidecar (templated). + command: ~ + # Args to use when running the Airflow worker log groomer sidecar (templated). + args: ["bash", "/clean-logs"] + # Number of days to retain logs + retentionDays: 15 + resources: {} + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + # Detailed default security context for logGroomerSidecar for container level + securityContexts: + container: {} + + waitForMigrations: + # Whether to create init container to wait for db migrations + enabled: true + env: [] + # Detailed default security context for waitForMigrations for container level + securityContexts: + container: {} + # container level lifecycle hooks + containerLifecycleHooks: {} + + env: [] + +# Airflow scheduler settings +scheduler: + # hostAliases for the scheduler pod + hostAliases: [] + # - ip: "127.0.0.1" + # hostnames: + # - "foo.local" + # - ip: "10.1.2.3" + # hostnames: + # - "foo.remote" + + # If the scheduler stops heartbeating for 5 minutes (5*60s) kill the + # scheduler and let Kubernetes restart it + livenessProbe: + initialDelaySeconds: 10 + timeoutSeconds: 20 + failureThreshold: 5 + periodSeconds: 60 + command: ~ + + # Wait for at most 10 minutes (6*10s) for the scheduler container to startup. + # livenessProbe kicks in after the startup + startupProbe: + failureThreshold: 6 + periodSeconds: 10 + timeoutSeconds: 20 + command: ~ + # Airflow 2.0 allows users to run multiple schedulers, + # However this feature is only recommended for MySQL 8+ and Postgres + replicas: 1 + # Max number of old replicasets to retain + revisionHistoryLimit: ~ + + # Command to use when running the Airflow scheduler (templated). + command: ~ + # Args to use when running the Airflow scheduler (templated). + args: ["bash", "-c", "exec airflow scheduler"] + + # Update Strategy when scheduler is deployed as a StatefulSet + # (when using LocalExecutor and workers.persistence) + updateStrategy: ~ + # Update Strategy when scheduler is deployed as a Deployment + # (when not using LocalExecutor and workers.persistence) + strategy: ~ + + # When not set, the values defined in the global securityContext will be used + # (deprecated, use `securityContexts` instead) + securityContext: {} + # runAsUser: 50000 + # fsGroup: 0 + # runAsGroup: 0 + + # Detailed default security context for scheduler deployments for container and pod level + securityContexts: + pod: {} + container: {} + + # container level lifecycle hooks + containerLifecycleHooks: {} + + # Create ServiceAccount + serviceAccount: + # default value is true + # ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ + automountServiceAccountToken: true + # Specifies whether a ServiceAccount should be created + create: true + # The name of the ServiceAccount to use. + # If not set and create is true, a name is generated using the release name + name: ~ + + # Annotations to add to scheduler kubernetes service account. + annotations: {} + + # Scheduler pod disruption budget + podDisruptionBudget: + enabled: false + + # PDB configuration + config: + # minAvailable and maxUnavailable are mutually exclusive + maxUnavailable: 1 + # minAvailable: 1 + + resources: {} + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + + # This setting tells kubernetes that its ok to evict + # when it wants to scale a node down. + safeToEvict: true + + # Launch additional containers into scheduler. + extraContainers: [] + # Add additional init containers into scheduler. + extraInitContainers: [] + + # Mount additional volumes into scheduler. It can be templated like in the following example: + # extraVolumes: + # - name: my-templated-extra-volume + # secret: + # secretName: '{{ include "my_secret_template" . }}' + # defaultMode: 0640 + # optional: true + # + # extraVolumeMounts: + # - name: my-templated-extra-volume + # mountPath: "{{ .Values.my_custom_path }}" + # readOnly: true + extraVolumes: [] + extraVolumeMounts: [] + + # Select certain nodes for airflow scheduler pods. + nodeSelector: {} + affinity: {} + # default scheduler affinity is: + # podAntiAffinity: + # preferredDuringSchedulingIgnoredDuringExecution: + # - podAffinityTerm: + # labelSelector: + # matchLabels: + # component: scheduler + # topologyKey: kubernetes.io/hostname + # weight: 100 + tolerations: [] + topologySpreadConstraints: [] + + priorityClassName: ~ + + # annotations for scheduler deployment + annotations: {} + + podAnnotations: {} + + # Labels specific to scheduler objects and pods + labels: {} + + logGroomerSidecar: + # Whether to deploy the Airflow scheduler log groomer sidecar. + enabled: true + # Command to use when running the Airflow scheduler log groomer sidecar (templated). + command: ~ + # Args to use when running the Airflow scheduler log groomer sidecar (templated). + args: ["bash", "/clean-logs"] + # Number of days to retain logs + retentionDays: 15 + resources: {} + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + # Detailed default security context for logGroomerSidecar for container level + securityContexts: + container: {} + # container level lifecycle hooks + containerLifecycleHooks: {} + + waitForMigrations: + # Whether to create init container to wait for db migrations + enabled: true + env: [] + # Detailed default security context for waitForMigrations for container level + securityContexts: + container: {} + # container level lifecycle hooks + containerLifecycleHooks: {} + + env: [] + +# Airflow create user job settings +createUserJob: + # Limit the lifetime of the job object after it finished execution. + ttlSecondsAfterFinished: 300 + # Command to use when running the create user job (templated). + command: ~ + # Args to use when running the create user job (templated). + args: + - "bash" + - "-c" + # The format below is necessary to get `helm lint` happy + - |- + exec \ + airflow {{ semverCompare ">=2.0.0" .Values.airflowVersion | ternary "users create" "create_user" }} "$@" + - -- + - "-r" + - "{{ .Values.webserver.defaultUser.role }}" + - "-u" + - "{{ .Values.webserver.defaultUser.username }}" + - "-e" + - "{{ .Values.webserver.defaultUser.email }}" + - "-f" + - "{{ .Values.webserver.defaultUser.firstName }}" + - "-l" + - "{{ .Values.webserver.defaultUser.lastName }}" + - "-p" + - "{{ .Values.webserver.defaultUser.password }}" + + # Annotations on the create user job pod + annotations: {} + # jobAnnotations are annotations on the create user job + jobAnnotations: {} + + # Labels specific to createUserJob objects and pods + labels: {} + + # When not set, the values defined in the global securityContext will be used + securityContext: {} + # runAsUser: 50000 + # fsGroup: 0 + # runAsGroup: 0 + + # Detailed default security context for createUserJob for container and pod level + securityContexts: + pod: {} + container: {} + + # container level lifecycle hooks + containerLifecycleHooks: {} + + # Create ServiceAccount + serviceAccount: + # default value is true + # ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ + automountServiceAccountToken: true + # Specifies whether a ServiceAccount should be created + create: true + # The name of the ServiceAccount to use. + # If not set and create is true, a name is generated using the release name + name: ~ + + # Annotations to add to create user kubernetes service account. + annotations: {} + + # Launch additional containers into user creation job + extraContainers: [] + + # Mount additional volumes into user creation job. It can be templated like in the following example: + # extraVolumes: + # - name: my-templated-extra-volume + # secret: + # secretName: '{{ include "my_secret_template" . }}' + # defaultMode: 0640 + # optional: true + # + # extraVolumeMounts: + # - name: my-templated-extra-volume + # mountPath: "{{ .Values.my_custom_path }}" + # readOnly: true + extraVolumes: [] + extraVolumeMounts: [] + + nodeSelector: {} + affinity: {} + tolerations: [] + topologySpreadConstraints: [] + # In case you need to disable the helm hooks that create the jobs after install. + # Disable this if you are using ArgoCD for example + useHelmHooks: true + applyCustomEnv: true + + env: [] + + resources: {} + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + +# Airflow database migration job settings +migrateDatabaseJob: + enabled: true + # Limit the lifetime of the job object after it finished execution. + ttlSecondsAfterFinished: 300 + # Command to use when running the migrate database job (templated). + command: ~ + # Args to use when running the migrate database job (templated). + args: + - "bash" + - "-c" + - >- + exec \ + + airflow {{ semverCompare ">=2.7.0" .Values.airflowVersion + | ternary "db migrate" (semverCompare ">=2.0.0" .Values.airflowVersion + | ternary "db upgrade" "upgradedb") }} + + # Annotations on the database migration pod + annotations: {} + # jobAnnotations are annotations on the database migration job + jobAnnotations: {} + + # When not set, the values defined in the global securityContext will be used + securityContext: {} + # runAsUser: 50000 + # fsGroup: 0 + # runAsGroup: 0 + + # Detailed default security context for migrateDatabaseJob for container and pod level + securityContexts: + pod: {} + container: {} + + # container level lifecycle hooks + containerLifecycleHooks: {} + + # Create ServiceAccount + serviceAccount: + # default value is true + # ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ + automountServiceAccountToken: true + # Specifies whether a ServiceAccount should be created + create: true + # The name of the ServiceAccount to use. + # If not set and create is true, a name is generated using the release name + name: ~ + + # Annotations to add to migrate database job kubernetes service account. + annotations: {} + + resources: {} + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + + # Launch additional containers into database migration job + extraContainers: [] + + # Mount additional volumes into database migration job. It can be templated like in the following example: + # extraVolumes: + # - name: my-templated-extra-volume + # secret: + # secretName: '{{ include "my_secret_template" . }}' + # defaultMode: 0640 + # optional: true + # + # extraVolumeMounts: + # - name: my-templated-extra-volume + # mountPath: "{{ .Values.my_custom_path }}" + # readOnly: true + extraVolumes: [] + extraVolumeMounts: [] + + nodeSelector: {} + affinity: {} + tolerations: [] + topologySpreadConstraints: [] + # In case you need to disable the helm hooks that create the jobs after install. + # Disable this if you are using ArgoCD for example + useHelmHooks: true + applyCustomEnv: true + +# Airflow webserver settings +webserver: + # Add custom annotations to the webserver configmap + configMapAnnotations: {} + # hostAliases for the webserver pod + hostAliases: [] + # - ip: "127.0.0.1" + # hostnames: + # - "foo.local" + # - ip: "10.1.2.3" + # hostnames: + # - "foo.remote" + allowPodLogReading: true + livenessProbe: + initialDelaySeconds: 15 + timeoutSeconds: 5 + failureThreshold: 5 + periodSeconds: 10 + scheme: HTTP + + readinessProbe: + initialDelaySeconds: 15 + timeoutSeconds: 5 + failureThreshold: 5 + periodSeconds: 10 + scheme: HTTP + + startupProbe: + timeoutSeconds: 20 + failureThreshold: 6 + periodSeconds: 10 + scheme: HTTP + + # Number of webservers + replicas: 1 + # Max number of old replicasets to retain + revisionHistoryLimit: ~ + + # Command to use when running the Airflow webserver (templated). + command: ~ + # Args to use when running the Airflow webserver (templated). + args: ["bash", "-c", "exec airflow webserver"] + + # Create ServiceAccount + serviceAccount: + # default value is true + # ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ + automountServiceAccountToken: true + # Specifies whether a ServiceAccount should be created + create: true + # The name of the ServiceAccount to use. + # If not set and create is true, a name is generated using the release name + name: ~ + + # Annotations to add to webserver kubernetes service account. + annotations: {} + + # Webserver pod disruption budget + podDisruptionBudget: + enabled: false + + # PDB configuration + config: + # minAvailable and maxUnavailable are mutually exclusive + maxUnavailable: 1 + # minAvailable: 1 + + # Allow overriding Update Strategy for Webserver + strategy: ~ + + # When not set, the values defined in the global securityContext will be used + # (deprecated, use `securityContexts` instead) + securityContext: {} + # runAsUser: 50000 + # fsGroup: 0 + # runAsGroup: 0 + + # Detailed default security contexts for webserver deployments for container and pod level + securityContexts: + pod: {} + container: {} + + # container level lifecycle hooks + containerLifecycleHooks: {} + + # Additional network policies as needed (Deprecated - renamed to `webserver.networkPolicy.ingress.from`) + extraNetworkPolicies: [] + networkPolicy: + ingress: + # Peers for webserver NetworkPolicy ingress + from: [] + # Ports for webserver NetworkPolicy ingress (if `from` is set) + ports: + - port: "{{ .Values.ports.airflowUI }}" + + resources: {} + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + + # Create initial user. + defaultUser: + enabled: true + role: Admin + username: admin + email: admin@example.com + firstName: admin + lastName: user + password: admin + + # Launch additional containers into webserver. + extraContainers: [] + # Add additional init containers into webserver. + extraInitContainers: [] + + # Mount additional volumes into webserver. It can be templated like in the following example: + # extraVolumes: + # - name: my-templated-extra-volume + # secret: + # secretName: '{{ include "my_secret_template" . }}' + # defaultMode: 0640 + # optional: true + # + # extraVolumeMounts: + # - name: my-templated-extra-volume + # mountPath: "{{ .Values.my_custom_path }}" + # readOnly: true + extraVolumes: [] + extraVolumeMounts: [] + + # This string (can be templated) will be mounted into the Airflow Webserver + # as a custom webserver_config.py. You can bake a webserver_config.py in to + # your image instead or specify a configmap containing the + # webserver_config.py. + webserverConfig: ~ + # webserverConfig: | + # from airflow import configuration as conf + + # # The SQLAlchemy connection string. + # SQLALCHEMY_DATABASE_URI = conf.get('database', 'SQL_ALCHEMY_CONN') + + # # Flask-WTF flag for CSRF + # CSRF_ENABLED = True + webserverConfigConfigMapName: ~ + + service: + type: ClusterIP + ## service annotations + annotations: {} + ports: + - name: airflow-ui + port: "{{ .Values.ports.airflowUI }}" + # To change the port used to access the webserver: + # ports: + # - name: airflow-ui + # port: 80 + # targetPort: airflow-ui + # To only expose a sidecar, not the webserver directly: + # ports: + # - name: only_sidecar + # port: 80 + # targetPort: 8888 + # If you have a public IP, set NodePort to set an external port. + # Service type must be 'NodePort': + # ports: + # - name: airflow-ui + # port: 8080 + # targetPort: 8080 + # nodePort: 31151 + loadBalancerIP: ~ + ## Limit load balancer source ips to list of CIDRs + # loadBalancerSourceRanges: + # - "10.123.0.0/16" + loadBalancerSourceRanges: [] + + # Select certain nodes for airflow webserver pods. + nodeSelector: {} + priorityClassName: ~ + affinity: {} + # default webserver affinity is: + # podAntiAffinity: + # preferredDuringSchedulingIgnoredDuringExecution: + # - podAffinityTerm: + # labelSelector: + # matchLabels: + # component: webserver + # topologyKey: kubernetes.io/hostname + # weight: 100 + tolerations: [] + topologySpreadConstraints: [] + + # annotations for webserver deployment + annotations: {} + + podAnnotations: {} + + # Labels specific webserver app + labels: {} + + waitForMigrations: + # Whether to create init container to wait for db migrations + enabled: true + env: [] + # Detailed default security context for waitForMigrations for container level + securityContexts: + container: {} + + # container level lifecycle hooks + containerLifecycleHooks: {} + + env: [] + +# Airflow Triggerer Config +triggerer: + enabled: true + # Number of airflow triggerers in the deployment + replicas: 1 + # Max number of old replicasets to retain + revisionHistoryLimit: ~ + + # Command to use when running Airflow triggerers (templated). + command: ~ + # Args to use when running Airflow triggerer (templated). + args: ["bash", "-c", "exec airflow triggerer"] + + # Update Strategy when triggerer is deployed as a StatefulSet + updateStrategy: ~ + # Update Strategy when triggerer is deployed as a Deployment + strategy: + rollingUpdate: + maxSurge: "100%" + maxUnavailable: "50%" + + # If the triggerer stops heartbeating for 5 minutes (5*60s) kill the + # triggerer and let Kubernetes restart it + livenessProbe: + initialDelaySeconds: 10 + timeoutSeconds: 20 + failureThreshold: 5 + periodSeconds: 60 + command: ~ + + # Create ServiceAccount + serviceAccount: + # default value is true + # ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ + automountServiceAccountToken: true + # Specifies whether a ServiceAccount should be created + create: true + # The name of the ServiceAccount to use. + # If not set and create is true, a name is generated using the release name + name: ~ + + # Annotations to add to triggerer kubernetes service account. + annotations: {} + + # When not set, the values defined in the global securityContext will be used + securityContext: {} + # runAsUser: 50000 + # fsGroup: 0 + # runAsGroup: 0 + + # Detailed default security context for triggerer for container and pod level + securityContexts: + pod: {} + container: {} + + # container level lifecycle hooks + containerLifecycleHooks: {} + + persistence: + # Enable persistent volumes + enabled: true + # Volume size for triggerer StatefulSet + size: 100Gi + # If using a custom storageClass, pass name ref to all statefulSets here + storageClassName: + # Execute init container to chown log directory. + # This is currently only needed in kind, due to usage + # of local-path provisioner. + fixPermissions: false + # Annotations to add to triggerer volumes + annotations: {} + + resources: {} + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + + # Grace period for triggerer to finish after SIGTERM is sent from kubernetes + terminationGracePeriodSeconds: 60 + + # This setting tells kubernetes that its ok to evict + # when it wants to scale a node down. + safeToEvict: true + + # Launch additional containers into triggerer. + extraContainers: [] + # Add additional init containers into triggerers. + extraInitContainers: [] + + # Mount additional volumes into triggerer. It can be templated like in the following example: + # extraVolumes: + # - name: my-templated-extra-volume + # secret: + # secretName: '{{ include "my_secret_template" . }}' + # defaultMode: 0640 + # optional: true + # + # extraVolumeMounts: + # - name: my-templated-extra-volume + # mountPath: "{{ .Values.my_custom_path }}" + # readOnly: true + extraVolumes: [] + extraVolumeMounts: [] + + # Select certain nodes for airflow triggerer pods. + nodeSelector: {} + affinity: {} + # default triggerer affinity is: + # podAntiAffinity: + # preferredDuringSchedulingIgnoredDuringExecution: + # - podAffinityTerm: + # labelSelector: + # matchLabels: + # component: triggerer + # topologyKey: kubernetes.io/hostname + # weight: 100 + tolerations: [] + topologySpreadConstraints: [] + + priorityClassName: ~ + + # annotations for the triggerer deployment + annotations: {} + + podAnnotations: {} + + # Labels specific to triggerer objects and pods + labels: {} + + logGroomerSidecar: + # Whether to deploy the Airflow triggerer log groomer sidecar. + enabled: true + # Command to use when running the Airflow triggerer log groomer sidecar (templated). + command: ~ + # Args to use when running the Airflow triggerer log groomer sidecar (templated). + args: ["bash", "/clean-logs"] + # Number of days to retain logs + retentionDays: 15 + resources: {} + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + # Detailed default security context for logGroomerSidecar for container level + securityContexts: + container: {} + + # container level lifecycle hooks + containerLifecycleHooks: {} + + waitForMigrations: + # Whether to create init container to wait for db migrations + enabled: true + env: [] + # Detailed default security context for waitForMigrations for container level + securityContexts: + container: {} + + # container level lifecycle hooks + containerLifecycleHooks: {} + + env: [] + + # Allow KEDA autoscaling. + keda: + enabled: false + namespaceLabels: {} + + # How often KEDA polls the airflow DB to report new scale requests to the HPA + pollingInterval: 5 + + # How many seconds KEDA will wait before scaling to zero. + # Note that HPA has a separate cooldown period for scale-downs + cooldownPeriod: 30 + + # Minimum number of triggerers created by keda + minReplicaCount: 0 + + # Maximum number of triggerers created by keda + maxReplicaCount: 10 + + # Specify HPA related options + advanced: {} + # horizontalPodAutoscalerConfig: + # behavior: + # scaleDown: + # stabilizationWindowSeconds: 300 + # policies: + # - type: Percent + # value: 100 + # periodSeconds: 15 + + # Query to use for KEDA autoscaling. Must return a single integer. + query: >- + SELECT ceil(COUNT(*)::decimal / {{ .Values.config.triggerer.default_capacity }}) + FROM trigger + +# Airflow Dag Processor Config +dagProcessor: + enabled: false + # Number of airflow dag processors in the deployment + replicas: 1 + # Max number of old replicasets to retain + revisionHistoryLimit: ~ + + # Command to use when running Airflow dag processors (templated). + command: ~ + # Args to use when running Airflow dag processor (templated). + args: ["bash", "-c", "exec airflow dag-processor"] + + # Update Strategy for dag processors + strategy: + rollingUpdate: + maxSurge: "100%" + maxUnavailable: "50%" + + # If the dag processor stops heartbeating for 5 minutes (5*60s) kill the + # dag processor and let Kubernetes restart it + livenessProbe: + initialDelaySeconds: 10 + timeoutSeconds: 20 + failureThreshold: 5 + periodSeconds: 60 + command: ~ + + # Create ServiceAccount + serviceAccount: + # default value is true + # ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ + automountServiceAccountToken: true + # Specifies whether a ServiceAccount should be created + create: true + # The name of the ServiceAccount to use. + # If not set and create is true, a name is generated using the release name + name: ~ + + # Annotations to add to dag processor kubernetes service account. + annotations: {} + + # When not set, the values defined in the global securityContext will be used + securityContext: {} + # runAsUser: 50000 + # fsGroup: 0 + # runAsGroup: 0 + + # Detailed default security context for dagProcessor for container and pod level + securityContexts: + pod: {} + container: {} + + # container level lifecycle hooks + containerLifecycleHooks: {} + + resources: {} + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + + # Grace period for dag processor to finish after SIGTERM is sent from kubernetes + terminationGracePeriodSeconds: 60 + + # This setting tells kubernetes that its ok to evict + # when it wants to scale a node down. + safeToEvict: true + + # Launch additional containers into dag processor. + extraContainers: [] + # Add additional init containers into dag processors. + extraInitContainers: [] + + # Mount additional volumes into dag processor. It can be templated like in the following example: + # extraVolumes: + # - name: my-templated-extra-volume + # secret: + # secretName: '{{ include "my_secret_template" . }}' + # defaultMode: 0640 + # optional: true + # + # extraVolumeMounts: + # - name: my-templated-extra-volume + # mountPath: "{{ .Values.my_custom_path }}" + # readOnly: true + extraVolumes: [] + extraVolumeMounts: [] + + # Select certain nodes for airflow dag processor pods. + nodeSelector: {} + affinity: {} + # default dag processor affinity is: + # podAntiAffinity: + # preferredDuringSchedulingIgnoredDuringExecution: + # - podAffinityTerm: + # labelSelector: + # matchLabels: + # component: dag-processor + # topologyKey: kubernetes.io/hostname + # weight: 100 + tolerations: [] + topologySpreadConstraints: [] + + priorityClassName: ~ + + # annotations for the dag processor deployment + annotations: {} + + podAnnotations: {} + + logGroomerSidecar: + # Whether to deploy the Airflow dag processor log groomer sidecar. + enabled: true + # Command to use when running the Airflow dag processor log groomer sidecar (templated). + command: ~ + # Args to use when running the Airflow dag processor log groomer sidecar (templated). + args: ["bash", "/clean-logs"] + # Number of days to retain logs + retentionDays: 15 + resources: {} + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + + waitForMigrations: + # Whether to create init container to wait for db migrations + enabled: true + env: [] + + env: [] + +# Flower settings +flower: + # Enable flower. + # If True, and using CeleryExecutor/CeleryKubernetesExecutor, will deploy flower app. + enabled: false + # Max number of old replicasets to retain + revisionHistoryLimit: ~ + + # Command to use when running flower (templated). + command: ~ + # Args to use when running flower (templated). + args: + - "bash" + - "-c" + # The format below is necessary to get `helm lint` happy + - |- + exec \ + airflow {{ semverCompare ">=2.0.0" .Values.airflowVersion | ternary "celery flower" "flower" }} + + # Additional network policies as needed (Deprecated - renamed to `flower.networkPolicy.ingress.from`) + extraNetworkPolicies: [] + networkPolicy: + ingress: + # Peers for flower NetworkPolicy ingress + from: [] + # Ports for flower NetworkPolicy ingress (if ingressPeers is set) + ports: + - port: "{{ .Values.ports.flowerUI }}" + + resources: {} + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + + # When not set, the values defined in the global securityContext will be used + securityContext: {} + # runAsUser: 50000 + # fsGroup: 0 + # runAsGroup: 0 + + # Detailed default security context for flower for container and pod level + securityContexts: + pod: {} + container: {} + + # container level lifecycle hooks + containerLifecycleHooks: {} + + # Create ServiceAccount + serviceAccount: + # default value is true + # ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ + automountServiceAccountToken: true + # Specifies whether a ServiceAccount should be created + create: true + # The name of the ServiceAccount to use. + # If not set and create is true, a name is generated using the release name + name: ~ + + # Annotations to add to worker kubernetes service account. + annotations: {} + + # A secret containing the connection + secretName: ~ + + # Else, if username and password are set, create secret from username and password + username: ~ + password: ~ + + service: + type: ClusterIP + ## service annotations + annotations: {} + ports: + - name: flower-ui + port: "{{ .Values.ports.flowerUI }}" + # To change the port used to access flower: + # ports: + # - name: flower-ui + # port: 8080 + # targetPort: flower-ui + loadBalancerIP: ~ + ## Limit load balancer source ips to list of CIDRs + # loadBalancerSourceRanges: + # - "10.123.0.0/16" + loadBalancerSourceRanges: [] + + # Launch additional containers into the flower pods. + extraContainers: [] + # Mount additional volumes into the flower pods. It can be templated like in the following example: + # extraVolumes: + # - name: my-templated-extra-volume + # secret: + # secretName: '{{ include "my_secret_template" . }}' + # defaultMode: 0640 + # optional: true + # + # extraVolumeMounts: + # - name: my-templated-extra-volume + # mountPath: "{{ .Values.my_custom_path }}" + # readOnly: true + extraVolumes: [] + extraVolumeMounts: [] + + # Select certain nodes for airflow flower pods. + nodeSelector: {} + affinity: {} + tolerations: [] + topologySpreadConstraints: [] + + priorityClassName: ~ + + # annotations for the flower deployment + annotations: {} + + podAnnotations: {} + + # Labels specific to flower objects and pods + labels: {} + env: [] + +# StatsD settings +statsd: + # Add custom annotations to the statsd configmap + configMapAnnotations: {} + + enabled: true + # Max number of old replicasets to retain + revisionHistoryLimit: ~ + + # Arguments for StatsD exporter command. + args: ["--statsd.mapping-config=/etc/statsd-exporter/mappings.yml"] + + # Annotations to add to the StatsD Deployment. + annotations: {} + + # Create ServiceAccount + serviceAccount: + # default value is true + # ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ + automountServiceAccountToken: true + # Specifies whether a ServiceAccount should be created + create: true + # The name of the ServiceAccount to use. + # If not set and create is true, a name is generated using the release name + name: ~ + + # Annotations to add to worker kubernetes service account. + annotations: {} + + uid: 65534 + # When not set, `statsd.uid` will be used + + # (deprecated, use `securityContexts` instead) + securityContext: {} + # runAsUser: 65534 + # fsGroup: 0 + # runAsGroup: 0 + + # Detailed default security context for statsd deployments for container and pod level + securityContexts: + pod: {} + container: {} + + # container level lifecycle hooks + containerLifecycleHooks: {} + + # Additional network policies as needed + extraNetworkPolicies: [] + resources: {} + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + + service: + extraAnnotations: {} + + # Select certain nodes for StatsD pods. + nodeSelector: {} + affinity: {} + tolerations: [] + topologySpreadConstraints: [] + + priorityClassName: ~ + + # Additional mappings for StatsD exporter. + # If set, will merge default mapping and extra mappings, default mapping has higher priority. + # So, if you want to change some default mapping, please use `overrideMappings` + extraMappings: [] + + # Override mappings for StatsD exporter. + # If set, will ignore setting item in default and `extraMappings`. + # So, If you use it, ensure all mapping item contains in it. + overrideMappings: [] + + podAnnotations: {} + env: [] + +# PgBouncer settings +pgbouncer: + # Enable PgBouncer + enabled: false + # Number of PgBouncer replicas to run in Deployment + replicas: 1 + # Max number of old replicasets to retain + revisionHistoryLimit: ~ + # Command to use for PgBouncer(templated). + command: ["pgbouncer", "-u", "nobody", "/etc/pgbouncer/pgbouncer.ini"] + # Args to use for PgBouncer(templated). + args: ~ + auth_type: md5 + auth_file: /etc/pgbouncer/users.txt + + # annotations to be added to the PgBouncer deployment + annotations: {} + + podAnnotations: {} + + # Create ServiceAccount + serviceAccount: + # default value is true + # ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ + automountServiceAccountToken: true + # Specifies whether a ServiceAccount should be created + create: true + # The name of the ServiceAccount to use. + # If not set and create is true, a name is generated using the release name + name: ~ + + # Annotations to add to worker kubernetes service account. + annotations: {} + + # Additional network policies as needed + extraNetworkPolicies: [] + + # Pool sizes + metadataPoolSize: 10 + resultBackendPoolSize: 5 + + # Maximum clients that can connect to PgBouncer (higher = more file descriptors) + maxClientConn: 100 + + # supply the name of existing secret with pgbouncer.ini and users.txt defined + # you can load them to a k8s secret like the one below + # apiVersion: v1 + # kind: Secret + # metadata: + # name: pgbouncer-config-secret + # data: + # pgbouncer.ini: + # users.txt: + # type: Opaque + # + # configSecretName: pgbouncer-config-secret + # + configSecretName: ~ + + # PgBouncer pod disruption budget + podDisruptionBudget: + enabled: false + + # PDB configuration + config: + # minAvailable and maxUnavailable are mutually exclusive + maxUnavailable: 1 + # minAvailable: 1 + + # Limit the resources to PgBouncer. + # When you specify the resource request the k8s scheduler uses this information to decide which node to + # place the Pod on. When you specify a resource limit for a Container, the kubelet enforces those limits so + # that the running container is not allowed to use more of that resource than the limit you set. + # See: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + # Example: + # + # resource: + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + resources: {} + + service: + extraAnnotations: {} + + # https://www.pgbouncer.org/config.html + verbose: 0 + logDisconnections: 0 + logConnections: 0 + + sslmode: "prefer" + ciphers: "normal" + + ssl: + ca: ~ + cert: ~ + key: ~ + + # Add extra PgBouncer ini configuration in the databases section: + # https://www.pgbouncer.org/config.html#section-databases + extraIniMetadata: ~ + extraIniResultBackend: ~ + # Add extra general PgBouncer ini configuration: https://www.pgbouncer.org/config.html + extraIni: ~ + + # Mount additional volumes into pgbouncer. It can be templated like in the following example: + # extraVolumes: + # - name: my-templated-extra-volume + # secret: + # secretName: '{{ include "my_secret_template" . }}' + # defaultMode: 0640 + # optional: true + # + # extraVolumeMounts: + # - name: my-templated-extra-volume + # mountPath: "{{ .Values.my_custom_path }}" + # readOnly: true + extraVolumes: [] + extraVolumeMounts: [] + + # Launch additional containers into pgbouncer. + extraContainers: [] + + # Select certain nodes for PgBouncer pods. + nodeSelector: {} + affinity: {} + tolerations: [] + topologySpreadConstraints: [] + + priorityClassName: ~ + + uid: 65534 + + # Detailed default security context for pgbouncer for container level + securityContexts: + pod: {} + container: {} + + # container level lifecycle hooks + containerLifecycleHooks: + preStop: + exec: + # Allow existing queries clients to complete within 120 seconds + command: ["/bin/sh", "-c", "killall -INT pgbouncer && sleep 120"] + + metricsExporterSidecar: + resources: {} + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + sslmode: "disable" + + # supply the name of existing secret with PGBouncer connection URI containing + # stats user and password. + # you can load them to a k8s secret like the one below + # apiVersion: v1 + # kind: Secret + # metadata: + # name: pgbouncer-stats-secret + # data: + # connection: postgresql://:@127.0.0.1:6543/pgbouncer? + # type: Opaque + # + # statsSecretName: pgbouncer-stats-secret + # + statsSecretName: ~ + + # Key containing the PGBouncer connection URI, defaults to `connection` if not defined + statsSecretKey: ~ + + # Detailed default security context for metricsExporterSidecar for container level + securityContexts: + container: {} + + # container level lifecycle hooks + containerLifecycleHooks: {} + + livenessProbe: + initialDelaySeconds: 10 + periodSeconds: 10 + timeoutSeconds: 1 + + readinessProbe: + initialDelaySeconds: 10 + periodSeconds: 10 + timeoutSeconds: 1 + + # Environment variables to add to pgbouncer container + env: [] + +# Configuration for the redis provisioned by the chart +redis: + enabled: true + terminationGracePeriodSeconds: 600 + + # Create ServiceAccount + serviceAccount: + # default value is true + # ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ + automountServiceAccountToken: true + # Specifies whether a ServiceAccount should be created + create: true + # The name of the ServiceAccount to use. + # If not set and create is true, a name is generated using the release name + name: ~ + + # Annotations to add to worker kubernetes service account. + annotations: {} + + persistence: + # Enable persistent volumes + enabled: true + # Volume size for worker StatefulSet + size: 1Gi + # If using a custom storageClass, pass name ref to all statefulSets here + storageClassName: + # Annotations to add to redis volumes + annotations: {} + + resources: {} + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + + # If set use as redis secret. Make sure to also set data.brokerUrlSecretName value. + passwordSecretName: ~ + + # Else, if password is set, create secret with it, + # Otherwise a new password will be generated on install + # Note: password can only be set during install, not upgrade. + password: ~ + + # This setting tells kubernetes that its ok to evict + # when it wants to scale a node down. + safeToEvict: true + + # Select certain nodes for redis pods. + nodeSelector: {} + affinity: {} + tolerations: [] + topologySpreadConstraints: [] + + # Set to 0 for backwards-compatiblity + uid: 0 + # If not set, `redis.uid` will be used + securityContext: {} + # runAsUser: 999 + # runAsGroup: 0 + + # Detailed default security context for redis for container and pod level + securityContexts: + pod: {} + container: {} + + # container level lifecycle hooks + containerLifecycleHooks: {} + + podAnnotations: {} +# Auth secret for a private registry +# This is used if pulling airflow images from a private registry +registry: + secretName: ~ + + # Example: + # connection: + # user: ~ + # pass: ~ + # host: ~ + # email: ~ + connection: {} + +# Elasticsearch logging configuration +elasticsearch: + # Enable elasticsearch task logging + enabled: false + # A secret containing the connection + secretName: ~ + # Or an object representing the connection + # Example: + # connection: + # user: ~ + # pass: ~ + # host: ~ + # port: ~ + connection: {} + +# All ports used by chart +ports: + flowerUI: 5555 + airflowUI: 8080 + workerLogs: 8793 + triggererLogs: 8794 + redisDB: 6379 + statsdIngest: 9125 + statsdScrape: 9102 + pgbouncer: 6543 + pgbouncerScrape: 9127 + +# Define any ResourceQuotas for namespace +quotas: {} + +# Define default/max/min values for pods and containers in namespace +limits: [] + +# This runs as a CronJob to cleanup old pods. +cleanup: + enabled: false + # Run every 15 minutes (templated). + schedule: "*/15 * * * *" + # To select a random-ish, deterministic starting minute between 3 and 12 inclusive for each release: + # '{{- add 3 (regexFind ".$" (adler32sum .Release.Name)) -}}-59/15 * * * *' + # To select the last digit of unix epoch time as the starting minute on each deploy: + # '{{- now | unixEpoch | trunc -1 -}}-59/* * * * *' + + # Command to use when running the cleanup cronjob (templated). + command: ~ + # Args to use when running the cleanup cronjob (templated). + args: ["bash", "-c", "exec airflow kubernetes cleanup-pods --namespace={{ .Release.Namespace }}"] + + # jobAnnotations are annotations on the cleanup CronJob + jobAnnotations: {} + + # Select certain nodes for airflow cleanup pods. + nodeSelector: {} + affinity: {} + tolerations: [] + topologySpreadConstraints: [] + + podAnnotations: {} + + # Labels specific to cleanup objects and pods + labels: {} + + resources: {} + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + + # Create ServiceAccount + serviceAccount: + # default value is true + # ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ + automountServiceAccountToken: true + # Specifies whether a ServiceAccount should be created + create: true + # The name of the ServiceAccount to use. + # If not set and create is true, a name is generated using the release name + name: ~ + + # Annotations to add to cleanup cronjob kubernetes service account. + annotations: {} + + # When not set, the values defined in the global securityContext will be used + securityContext: {} + # runAsUser: 50000 + # runAsGroup: 0 + env: [] + + # Detailed default security context for cleanup for container level + securityContexts: + container: {} + + # container level lifecycle hooks + containerLifecycleHooks: {} + + # Specify history limit + # When set, overwrite the default k8s number of successful and failed CronJob executions that are saved. + failedJobsHistoryLimit: ~ + successfulJobsHistoryLimit: ~ + +# Configuration for postgresql subchart +# Not recommended for production +postgresql: + enabled: true + image: + tag: "11" + auth: + enablePostgresUser: true + postgresPassword: postgres + username: "" + password: "" + +# Config settings to go into the mounted airflow.cfg +# +# Please note that these values are passed through the `tpl` function, so are +# all subject to being rendered as go templates. If you need to include a +# literal `{{` in a value, it must be expressed like this: +# +# a: '{{ "{{ not a template }}" }}' +# +# Do not set config containing secrets via plain text values, use Env Var or k8s secret object +# yamllint disable rule:line-length +config: + core: + dags_folder: '{{ include "airflow_dags" . }}' + # This is ignored when used with the official Docker image + load_examples: 'False' + executor: '{{ .Values.executor }}' + # For Airflow 1.10, backward compatibility; moved to [logging] in 2.0 + colored_console_log: 'False' + remote_logging: '{{- ternary "True" "False" .Values.elasticsearch.enabled }}' + logging: + remote_logging: '{{- ternary "True" "False" .Values.elasticsearch.enabled }}' + colored_console_log: 'False' + metrics: + statsd_on: '{{ ternary "True" "False" .Values.statsd.enabled }}' + statsd_port: 9125 + statsd_prefix: airflow + statsd_host: '{{ printf "%s-statsd" .Release.Name }}' + webserver: + enable_proxy_fix: 'True' + # For Airflow 1.10 + rbac: 'True' + celery: + flower_url_prefix: '{{ ternary "" .Values.ingress.flower.path (eq .Values.ingress.flower.path "/") }}' + worker_concurrency: 16 + scheduler: + standalone_dag_processor: '{{ ternary "True" "False" .Values.dagProcessor.enabled }}' + # statsd params included for Airflow 1.10 backward compatibility; moved to [metrics] in 2.0 + statsd_on: '{{ ternary "True" "False" .Values.statsd.enabled }}' + statsd_port: 9125 + statsd_prefix: airflow + statsd_host: '{{ printf "%s-statsd" .Release.Name }}' + # `run_duration` included for Airflow 1.10 backward compatibility; removed in 2.0. + run_duration: 41460 + elasticsearch: + json_format: 'True' + log_id_template: "{dag_id}_{task_id}_{execution_date}_{try_number}" + elasticsearch_configs: + max_retries: 3 + timeout: 30 + retry_timeout: 'True' + kerberos: + keytab: '{{ .Values.kerberos.keytabPath }}' + reinit_frequency: '{{ .Values.kerberos.reinitFrequency }}' + principal: '{{ .Values.kerberos.principal }}' + ccache: '{{ .Values.kerberos.ccacheMountPath }}/{{ .Values.kerberos.ccacheFileName }}' + celery_kubernetes_executor: + kubernetes_queue: 'kubernetes' + # The `kubernetes` section is deprecated in Airflow >= 2.5.0 due to an airflow.cfg schema change. + # The `kubernetes` section can be removed once the helm chart no longer supports Airflow < 2.5.0. + kubernetes: + namespace: '{{ .Release.Namespace }}' + # The following `airflow_` entries are for Airflow 1, and can be removed when it is no longer supported. + airflow_configmap: '{{ include "airflow_config" . }}' + airflow_local_settings_configmap: '{{ include "airflow_config" . }}' + pod_template_file: '{{ include "airflow_pod_template_file" . }}/pod_template_file.yaml' + worker_container_repository: '{{ .Values.images.airflow.repository | default .Values.defaultAirflowRepository }}' + worker_container_tag: '{{ .Values.images.airflow.tag | default .Values.defaultAirflowTag }}' + multi_namespace_mode: '{{ ternary "True" "False" .Values.multiNamespaceMode }}' + # The `kubernetes_executor` section duplicates the `kubernetes` section in Airflow >= 2.5.0 due to an airflow.cfg schema change. + kubernetes_executor: + namespace: '{{ .Release.Namespace }}' + pod_template_file: '{{ include "airflow_pod_template_file" . }}/pod_template_file.yaml' + worker_container_repository: '{{ .Values.images.airflow.repository | default .Values.defaultAirflowRepository }}' + worker_container_tag: '{{ .Values.images.airflow.tag | default .Values.defaultAirflowTag }}' + multi_namespace_mode: '{{ ternary "True" "False" .Values.multiNamespaceMode }}' + triggerer: + default_capacity: 1000 +# yamllint enable rule:line-length + +# Whether Airflow can launch workers and/or pods in multiple namespaces +# If true, it creates ClusterRole/ClusterRolebinding (with access to entire cluster) +multiNamespaceMode: false + +# `podTemplate` is a templated string containing the contents of `pod_template_file.yaml` used for +# KubernetesExecutor workers. The default `podTemplate` will use normal `workers` configuration parameters +# (e.g. `workers.resources`). As such, you normally won't need to override this directly, however, +# you can still provide a completely custom `pod_template_file.yaml` if desired. +# If not set, a default one is created using `files/pod-template-file.kubernetes-helm-yaml`. +podTemplate: ~ +# The following example is NOT functional, but meant to be illustrative of how you can provide a custom +# `pod_template_file`. You're better off starting with the default in +# `files/pod-template-file.kubernetes-helm-yaml` and modifying from there. +# We will set `priorityClassName` in this example: +# podTemplate: | +# apiVersion: v1 +# kind: Pod +# metadata: +# name: placeholder-name +# labels: +# tier: airflow +# component: worker +# release: {{ .Release.Name }} +# spec: +# priorityClassName: high-priority +# containers: +# - name: base +# ... + +# Git sync +dags: + persistence: + # Annotations for dags PVC + annotations: {} + # Enable persistent volume for storing dags + enabled: false + # Volume size for dags + size: 1Gi + # If using a custom storageClass, pass name here + storageClassName: + # access mode of the persistent volume + accessMode: ReadWriteOnce + ## the name of an existing PVC to use + existingClaim: + ## optional subpath for dag volume mount + subPath: ~ + gitSync: + enabled: false + + # git repo clone url + # ssh example: git@github.com:apache/airflow.git + # https example: https://github.com/apache/airflow.git + repo: https://github.com/apache/airflow.git + branch: v2-2-stable + rev: HEAD + depth: 1 + # the number of consecutive failures allowed before aborting + maxFailures: 0 + # subpath within the repo where dags are located + # should be "" if dags are at repo root + subPath: "tests/dags" + # if your repo needs a user name password + # you can load them to a k8s secret like the one below + # --- + # apiVersion: v1 + # kind: Secret + # metadata: + # name: git-credentials + # data: + # GIT_SYNC_USERNAME: + # GIT_SYNC_PASSWORD: + # and specify the name of the secret below + # + # credentialsSecret: git-credentials + # + # + # If you are using an ssh clone url, you can load + # the ssh private key to a k8s secret like the one below + # --- + # apiVersion: v1 + # kind: Secret + # metadata: + # name: airflow-ssh-secret + # data: + # # key needs to be gitSshKey + # gitSshKey: + # and specify the name of the secret below + # sshKeySecret: airflow-ssh-secret + # + # If you are using an ssh private key, you can additionally + # specify the content of your known_hosts file, example: + # + # knownHosts: | + # , + # , + + # interval between git sync attempts in seconds + # high values are more likely to cause DAGs to become out of sync between different components + # low values cause more traffic to the remote git repository + wait: 5 + containerName: git-sync + uid: 65533 + + # When not set, the values defined in the global securityContext will be used + securityContext: {} + # runAsUser: 65533 + # runAsGroup: 0 + + securityContexts: + container: {} + + # container level lifecycle hooks + containerLifecycleHooks: {} + + # Mount additional volumes into git-sync. It can be templated like in the following example: + # extraVolumeMounts: + # - name: my-templated-extra-volume + # mountPath: "{{ .Values.my_custom_path }}" + # readOnly: true + extraVolumeMounts: [] + env: [] + # Supported env vars for gitsync can be found at https://github.com/kubernetes/git-sync + # - name: "" + # value: "" + + resources: {} + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + +logs: + persistence: + # Enable persistent volume for storing logs + enabled: false + # Volume size for logs + size: 100Gi + # Annotations for the logs PVC + annotations: {} + # If using a custom storageClass, pass name here + storageClassName: + ## the name of an existing PVC to use + existingClaim: diff --git a/helm/airflow/values_schema.schema.json b/helm/airflow/values_schema.schema.json new file mode 100644 index 0000000..64179d5 --- /dev/null +++ b/helm/airflow/values_schema.schema.json @@ -0,0 +1,104 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "description": "This schema is used to validate `values.schema.json` to ensure each parameter has `default` and `description` set, and that top level properties have a `x-docsSection` set.", + "definitions": { + "leafs": { + "additionalProperties": { + "if": { + "not": { + "properties": { + "description": { + "pattern": "^Labels for the configmap$|^Labels for the secret$|^Annotations for the configmap$|^Annotations for the secret$" + } + } + } + }, + "then": { + "additionalProperties": { + "$ref": "#/definitions/leafs" + } + } + }, + "if": { + "oneOf": [ + { + "properties": { + "type": { + "const": "integer" + } + } + }, + { + "properties": { + "type": { + "const": "number" + } + } + }, + { + "properties": { + "type": { + "const": "string" + } + } + }, + { + "properties": { + "type": { + "const": "boolean" + } + } + }, + { + "properties": { + "type": { + "const": "object" + }, + "properties": false + } + }, + { + "properties": { + "type": { + "const": "array" + }, + "items": false + } + } + ] + }, + "then": { + "required": [ + "description", + "default" + ] + } + } + }, + "required": [ + "x-docsSectionOrder" + ], + "properties": { + "section_order": { + "type": "array", + "items": { + "type": "string" + } + }, + "properties": { + "additionalProperties": { + "allOf": [ + { + "$ref": "#/definitions/leafs" + }, + { + "required": [ + "x-docsSection" + ] + } + ] + } + } + } +} diff --git a/helm/argo-cd/.helmignore b/helm/argo-cd/.helmignore new file mode 100644 index 0000000..3a06329 --- /dev/null +++ b/helm/argo-cd/.helmignore @@ -0,0 +1,4 @@ +/*.tgz +output +ci/ +*.gotmpl diff --git a/helm/argo-cd/Chart.lock b/helm/argo-cd/Chart.lock new file mode 100644 index 0000000..a2a5011 --- /dev/null +++ b/helm/argo-cd/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: redis-ha + repository: https://dandydeveloper.github.io/charts/ + version: 4.22.4 +digest: sha256:5df60910862b364ebfb82cba2b2f0951c39ad36446647fb3f501bdeadc92fbd7 +generated: "2022-12-26T22:58:11.561184+09:00" diff --git a/helm/argo-cd/Chart.yaml b/helm/argo-cd/Chart.yaml new file mode 100644 index 0000000..ccf6f5c --- /dev/null +++ b/helm/argo-cd/Chart.yaml @@ -0,0 +1,27 @@ +apiVersion: v2 +appVersion: v2.6.5 +kubeVersion: ">=1.22.0-0" +description: A Helm chart for Argo CD, a declarative, GitOps continuous delivery tool for Kubernetes. +name: argo-cd +version: 5.26.1 +home: https://github.com/argoproj/argo-helm +icon: https://argo-cd.readthedocs.io/en/stable/assets/logo.png +sources: + - https://github.com/argoproj/argo-helm/tree/main/charts/argo-cd + - https://github.com/argoproj/argo-cd +keywords: + - argoproj + - argocd + - gitops +maintainers: + - name: argoproj + url: https://argoproj.github.io/ +dependencies: + - name: redis-ha + version: 4.22.4 + repository: https://dandydeveloper.github.io/charts/ + condition: redis-ha.enabled +annotations: + artifacthub.io/changes: | + - kind: changed + description: Upgrade Argo CD v2.6.5 diff --git a/helm/argo-cd/README.md b/helm/argo-cd/README.md new file mode 100644 index 0000000..9606ee6 --- /dev/null +++ b/helm/argo-cd/README.md @@ -0,0 +1,1176 @@ +# Argo CD Chart + +A Helm chart for Argo CD, a declarative, GitOps continuous delivery tool for Kubernetes. + +Source code can be found here: + +* +* + +This is a **community maintained** chart. This chart installs [argo-cd](https://argo-cd.readthedocs.io/en/stable/), a declarative, GitOps continuous delivery tool for Kubernetes. + +The default installation is intended to be similar to the provided Argo CD [releases](https://github.com/argoproj/argo-cd/releases). + +If you want to avoid including sensitive information unencrypted (clear text) in your version control, make use of the [declarative setup] of Argo CD. +For instance, rather than adding repositories and their keys in your Helm values, you could deploy [SealedSecrets](https://github.com/bitnami-labs/sealed-secrets) with contents as seen in this [repositories section](https://argo-cd.readthedocs.io/en/stable/operator-manual/declarative-setup/#repositories) or any other secrets manager service (i.e. HashiCorp Vault, AWS/GCP Secrets Manager, etc.). + +## High Availability + +This chart installs the non-HA version of Argo CD by default. If you want to run Argo CD in HA mode, you can use one of the example values in the next sections. +Please also have a look into the upstream [Operator Manual regarding High Availability](https://argo-cd.readthedocs.io/en/stable/operator-manual/high_availability/) to understand how scaling of Argo CD works in detail. + +> **Warning:** +> You need at least 3 worker nodes as the HA mode of redis enforces Pods to run on separate nodes. + +### HA mode with autoscaling + +```yaml +redis-ha: + enabled: true + +controller: + replicas: 1 + +server: + autoscaling: + enabled: true + minReplicas: 2 + +repoServer: + autoscaling: + enabled: true + minReplicas: 2 + +applicationSet: + replicaCount: 2 +``` + +### HA mode without autoscaling + +```yaml +redis-ha: + enabled: true + +controller: + replicas: 1 + +server: + replicas: 2 + +repoServer: + replicas: 2 + +applicationSet: + replicaCount: 2 +``` + +### Synchronizing Changes from Original Repository + +In the original [Argo CD repository](https://github.com/argoproj/argo-cd/) an [`manifests/install.yaml`](https://github.com/argoproj/argo-cd/blob/master/manifests/install.yaml) is generated using `kustomize`. It's the basis for the installation as [described in the docs](https://argo-cd.readthedocs.io/en/stable/getting_started/#1-install-argo-cd). + +When installing Argo CD using this helm chart the user should have a similar experience and configuration rolled out. Hence, it makes sense to try to achieve a similar output of rendered `.yaml` resources when calling `helm template` using the default settings in `values.yaml`. + +To update the templates and default settings in `values.yaml` it may come in handy to look up the diff of the `manifests/install.yaml` between two versions accordingly. This can either be done directly via github and look for `manifests/install.yaml`: + +https://github.com/argoproj/argo-cd/compare/v1.8.7...v2.0.0#files_bucket + +Or you clone the repository and do a local `git-diff`: + +```bash +git clone https://github.com/argoproj/argo-cd.git +cd argo-cd +git diff v1.8.7 v2.0.0 -- manifests/install.yaml +``` + +Changes in the `CustomResourceDefinition` resources shall be fixed easily by copying 1:1 from the [`manifests/crds` folder](https://github.com/argoproj/argo-cd/tree/master/manifests/crds) into this [`charts/argo-cd/templates/crds` folder](https://github.com/argoproj/argo-helm/tree/master/charts/argo-cd/templates/crds). + +### Custom resource definitions + +Some users would prefer to install the CRDs _outside_ of the chart. You can disable the CRD installation of this chart by using `--set crds.install=false` when installing the chart. + +Helm cannot upgrade custom resource definitions in the `/crds` folder [by design](https://helm.sh/docs/chart_best_practices/custom_resource_definitions/#some-caveats-and-explanations). Starting with 5.2.0, the CRDs have been moved to `/templates` to address this design decision. + +If you are using Argo CD chart version prior to 5.2.0 or have elected to manage the Argo CD CRDs outside of the chart, please use `kubectl` to upgrade CRDs manually from [templates/crds](templates/crds/) folder or via the manifests from the upstream project repo: + +```bash +kubectl apply -k "https://github.com/argoproj/argo-cd/manifests/crds?ref=" + +# Eg. version v2.4.9 +kubectl apply -k "https://github.com/argoproj/argo-cd/manifests/crds?ref=v2.4.9" +``` + +## Changelog + +For full list of changes please check ArtifactHub [changelog]. + +Highlighted versions provide information about additional steps that should be performed by user when upgrading to newer version. + +### 5.24.0 + +This versions adds additional global parameters for scheduling (`nodeSelector`, `tolerations`, `topologySpreadConstraints`). +Default `global.affinity` rules can be disabled when `none` value is used for the preset. + +### 5.22.0 + +This versions adds `global.affinity` options that are used as a presets. Override on component level works as before and replaces the default preset completely. + +### 5.19.0 + +This version consolidates config for custom repository TLS certificates and SSH known hosts. If you provide this values please move them into new `configs.ssh` and `configs.tls` sections. +You can also use new option `configs.ssh.extraHosts` to configure your SSH keys without maintaing / overwritting keys for public Git repositories. + +### 5.13.0 + +This version reduces history limit for Argo CD deployment replicas to 3 to provide more visibility for Argo CD deployments that manage itself. If you need more deployment revisions for rollbacks set `global.revisionHistoryLimit` parameter. + +### 5.12.0 + +If Argo CD is managing termination of TLS and you are using `configs.secret.argocdServerTlsConfig` option to provide custom TLS configuration for this chart, please use `server.certificate` or `server.certificateSecret` instead. +For the secrets for tls termination, please use a secret named `argocd-server-tls` instead of `argocd-secret`. +For the technical details please check the [Argo CD documentation](https://argo-cd.readthedocs.io/en/stable/operator-manual/tls/#tls-certificates-used-by-argocd-server). When transitioning from the one secret to the other pay attention to `tls.key` and `tls.crt` keys. + +### 5.10.0 + +This version hardens security by configuring default container security contexts and adds hard requirement for Kubernetes 1.22+ to work properly. +The change aligns chart with officially [supported versions](https://argo-cd.readthedocs.io/en/release-2.5/operator-manual/installation/#supported-versions) by upstream project. + +### 5.7.0 + +This version introcudes new `configs.cm` and `configs.rbac` sections that replaces `server.config` and `server.rbacConfig` respectively. +Please move your current configuration to the new place. The Argo CD RBAC config now also sets defaults in the `argocd-rbac-cm`. +If you have manually created this ConfigMap please ensure templating is disabled so you will not lose your changes. + +### 5.5.20 + +This version moved API version templates into dedicated helper. If you are using these in your umbrella +chart please migrate your templates to pattern `argo-cd.apiVersion.`. + +### 5.5.0 + +This version introduces new `configs.params` section that replaces command line arguments for containers. +Please refer to documentation in values.yaml for migrating the configuration. + +### 5.2.0 + +Custom resource definitions were moved to `templates` folder so they can be managed by Helm. + +To adopt already created CRDs, please use following command: + +```bash +YOUR_ARGOCD_NAMESPACE="" # e.g. argo-cd +YOUR_ARGOCD_RELEASENAME="" # e.g. argo-cd + +for crd in "applications.argoproj.io" "applicationsets.argoproj.io" "argocdextensions.argoproj.io" "appprojects.argoproj.io"; do + kubectl label --overwrite crd $crd app.kubernetes.io/managed-by=Helm + kubectl annotate --overwrite crd $crd meta.helm.sh/release-namespace="$YOUR_ARGOCD_NAMESPACE" + kubectl annotate --overwrite crd $crd meta.helm.sh/release-name="$YOUR_ARGOCD_RELEASENAME" +done +``` + +### 5.0.0 + +This version **removes support for**: + +- deprecated repository credentials (parameter `configs.repositoryCredentials`) +- option to run application controller as a Deployment +- the parameters `server.additionalApplications` and `server.additionalProjects` + +Please carefully read the following section if you are using these parameters! + +In order to upgrade Applications and Projects safely against CRDs' upgrade, `server.additionalApplications` and `server.additionalProjects` are moved to [argocd-apps](../argocd-apps). + +If you are using `server.additionalApplications` or `server.additionalProjects`, you can adopt to [argocd-apps](../argocd-apps) as below: + +1. Add [helm.sh/resource-policy annotation](https://helm.sh/docs/howto/charts_tips_and_tricks/#tell-helm-not-to-uninstall-a-resource) to avoid resources being removed by upgrading Helm chart + +You can keep your existing CRDs by adding `"helm.sh/resource-policy": keep` on `additionalAnnotations`, under `server.additionalApplications` and `server.additionalProjects` blocks, and running `helm upgrade`. + +e.g: + +```yaml +server: + additionalApplications: + - name: guestbook + namespace: argocd + additionalLabels: {} + additionalAnnotations: + "helm.sh/resource-policy": keep # <-- add this + finalizers: + - resources-finalizer.argocd.argoproj.io + project: guestbook + source: + repoURL: https://github.com/argoproj/argocd-example-apps.git + targetRevision: HEAD + path: guestbook + directory: + recurse: true + destination: + server: https://kubernetes.default.svc + namespace: guestbook + syncPolicy: + automated: + prune: false + selfHeal: false + ignoreDifferences: + - group: apps + kind: Deployment + jsonPointers: + - /spec/replicas + info: + - name: url + value: https://argoproj.github.io/ +``` + +You can also keep your existing CRDs by running the following scripts. + +```bash +# keep Applications +for app in "guestbook"; do + kubectl annotate --overwrite application $app helm.sh/resource-policy=keep +done + +# keep Projects +for project in "guestbook"; do + kubectl annotate --overwrite appproject $project helm.sh/resource-policy=keep +done +``` + +2. Upgrade argo-cd Helm chart to v5.0.0 + +3. Remove keep [helm.sh/resource-policy annotation](https://helm.sh/docs/howto/charts_tips_and_tricks/#tell-helm-not-to-uninstall-a-resource) + +```bash +# delete annotations from Applications +for app in "guestbook"; do + kubectl annotate --overwrite application $app helm.sh/resource-policy- +done + +# delete annotations from Projects +for project in "guestbook"; do + kubectl annotate --overwrite appproject $project helm.sh/resource-policy- +done +``` + +4. Adopt existing resources to [argocd-apps](../argocd-apps) + +### 4.9.0 + +This version starts to use upstream image with applicationset binary. Start command was changed from `applicationset-controller` to `argocd-applicationset-controller` + +### 4.3.* + +With this minor version, the notification notifier's `service.slack` is no longer configured by default. + +### 4.0.0 and above + +This helm chart version deploys Argo CD v2.3. The Argo CD Notifications and ApplicationSet are part of Argo CD now. You no longer need to install them separately. The Notifications and ApplicationSet components **are bundled into default** Argo CD installation. +Please read the [v2.2 to 2.3 upgrade instructions] in the upstream repository. + +### 3.13.0 + +This release removes the flag `--staticassets` from argocd server as it has been dropped upstream. If this flag needs to be enabled e.g for older releases of Argo CD, it can be passed via the `server.extraArgs` field + +### 3.10.2 + +Argo CD has recently deprecated the flag `--staticassets` and from chart version `3.10.2` has been disabled by default +It can be re-enabled by setting `server.staticAssets.enabled` to true + +### 3.8.1 + +This bugfix version potentially introduces a rename (and recreation) of one or more ServiceAccounts. It _only happens_ when you use one of these customization: + +```yaml +# Case 1) - only happens when you do not specify a custom name (repoServer.serviceAccount.name) +repoServer: + serviceAccount: + create: true + +# Case 2) +controller: + serviceAccount: + name: "" # or + +# Case 3) +dex: + serviceAccount: + name: "" # or + +# Case 4) +server: + serviceAccount: + name: "" # or +``` + +Please check if you are affected by one of these cases **before you upgrade**, especially when you use **cloud IAM roles for service accounts.** (eg. IRSA on AWS or Workload Identity for GKE) + +### 3.2.* + +With this minor version we introduced the evaluation for the ingress manifest (depending on the capabilities version), See [Pull Request](https://github.com/argoproj/argo-helm/pull/637). +[Issue 703](https://github.com/argoproj/argo-helm/issues/703) reported that the capabilities evaluation is **not handled correctly when deploying the chart via an Argo CD instance**, +especially deploying on clusters running a cluster version prior to `1.19` (which misses `Ingress` on apiVersion `networking.k8s.io/v1`). + +If you are running a cluster version prior to `1.19` you can avoid this issue by directly installing chart version `3.6.0` and setting `kubeVersionOverride` like: + +```yaml +kubeVersionOverride: "1.18.0" +``` + +Then you should no longer encounter this issue. + +### 3.0.0 and above + +Helm apiVersion switched to `v2`. Requires Helm `3.0.0` or above to install. [Read More](https://helm.sh/blog/migrate-from-helm-v2-to-helm-v3/) on how to migrate your release from Helm 2 to Helm 3. + +### 2.14.7 and above + +The `matchLabels` key in the Argo CD Application Controller is no longer hard-coded. Note that labels are immutable so caution should be exercised when making changes to this resource. + +### 2.10.x to 2.11.0 + +The application controller is now available as a `StatefulSet` when the `controller.enableStatefulSet` flag is set to true. Depending on your Helm deployment this may be a downtime or breaking change if enabled when using HA and will become the default in 3.x. + +### 1.8.7 to 2.x.x + +`controller.extraArgs`, `repoServer.extraArgs` and `server.extraArgs` are now arrays of strings instead of a map + +What was + +```yaml +server: + extraArgs: + insecure: "" +``` + +is now + +```yaml +server: + extraArgs: + - --insecure +``` + +## Prerequisites + +- Kubernetes: `>=1.22.0-0` +- Helm v3.0.0+ + +## Installing the Chart + +To install the chart with the release name `my-release`: + +```console +$ helm repo add argo https://argoproj.github.io/argo-helm +"argo" has been added to your repositories + +$ helm install my-release argo/argo-cd +NAME: my-release +... +``` + +## General parameters + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| apiVersionOverrides.autoscaling | string | `""` | String to override apiVersion of autoscaling rendered by this helm chart | +| apiVersionOverrides.certmanager | string | `""` | String to override apiVersion of cert-manager resources rendered by this helm chart | +| apiVersionOverrides.cloudgoogle | string | `""` | String to override apiVersion of GKE resources rendered by this helm chart | +| crds.annotations | object | `{}` | Annotations to be added to all CRDs | +| crds.install | bool | `true` | Install and upgrade CRDs | +| crds.keep | bool | `true` | Keep CRDs on chart uninstall | +| createAggregateRoles | bool | `false` | Create aggregated roles that extend existing cluster roles to interact with argo-cd resources | +| createClusterRoles | bool | `true` | Create cluster roles for cluster-wide installation. | +| extraObjects | list | `[]` | Array of extra K8s manifests to deploy | +| fullnameOverride | string | `""` | String to fully override `"argo-cd.fullname"` | +| kubeVersionOverride | string | `""` | Override the Kubernetes version, which is used to evaluate certain manifests | +| nameOverride | string | `"argocd"` | Provide a name in place of `argocd` | +| openshift.enabled | bool | `false` | enables using arbitrary uid for argo repo server | + +## Global Configs + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| global.additionalLabels | object | `{}` | Common labels for the all resources | +| global.affinity.nodeAffinity.matchExpressions | list | `[]` | Default match expressions for node affinity | +| global.affinity.nodeAffinity.type | string | `"hard"` | Default node affinity rules. Either: `none`, `soft` or `hard` | +| global.affinity.podAntiAffinity | string | `"soft"` | Default pod anti-affinity rules. Either: `none`, `soft` or `hard` | +| global.deploymentAnnotations | object | `{}` | Annotations for the all deployed Deployments | +| global.hostAliases | list | `[]` | Mapping between IP and hostnames that will be injected as entries in the pod's hosts files | +| global.image.imagePullPolicy | string | `"IfNotPresent"` | If defined, a imagePullPolicy applied to all Argo CD deployments | +| global.image.repository | string | `"quay.io/argoproj/argocd"` | If defined, a repository applied to all Argo CD deployments | +| global.image.tag | string | `""` | Overrides the global Argo CD image tag whose default is the chart appVersion | +| global.imagePullSecrets | list | `[]` | Secrets with credentials to pull images from a private registry | +| global.logging.format | string | `"text"` | Set the global logging format. Either: `text` or `json` | +| global.logging.level | string | `"info"` | Set the global logging level. One of: `debug`, `info`, `warn` or `error` | +| global.networkPolicy.create | bool | `false` | Create NetworkPolicy objects for all components | +| global.networkPolicy.defaultDenyIngress | bool | `false` | Default deny all ingress traffic | +| global.nodeSelector | object | `{}` | Default node selector for all components | +| global.podAnnotations | object | `{}` | Annotations for the all deployed pods | +| global.podLabels | object | `{}` | Labels for the all deployed pods | +| global.priorityClassName | string | `""` | Default priority class for all components | +| global.revisionHistoryLimit | int | `3` | Number of old deployment ReplicaSets to retain. The rest will be garbage collected. | +| global.securityContext | object | `{}` (See [values.yaml]) | Toggle and define pod-level security context. | +| global.statefulsetAnnotations | object | `{}` | Annotations for the all deployed Statefulsets | +| global.tolerations | object | `{}` | Default tolerations for all components | +| global.topologySpreadConstraints | list | `[]` | Default [TopologySpreadConstraints] rules for all components | + +## Argo CD Configs + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| configs.clusterCredentials | list | `[]` (See [values.yaml]) | Provide one or multiple [external cluster credentials] | +| configs.cm."admin.enabled" | bool | `true` | Enable local admin user | +| configs.cm."application.instanceLabelKey" | string | Defaults to app.kubernetes.io/instance | The name of tracking label used by Argo CD for resource pruning | +| configs.cm."exec.enabled" | bool | `false` | Enable exec feature in Argo UI | +| configs.cm."server.rbac.log.enforce.enable" | bool | `false` | Enable logs RBAC enforcement | +| configs.cm."timeout.hard.reconciliation" | string | `"0s"` | Timeout to refresh application data as well as target manifests cache | +| configs.cm."timeout.reconciliation" | string | `"180s"` | Timeout to discover if a new manifests version got published to the repository | +| configs.cm.annotations | object | `{}` | Annotations to be added to argocd-cm configmap | +| configs.cm.create | bool | `true` | Create the argocd-cm configmap for [declarative setup] | +| configs.cm.url | string | `""` | Argo CD's externally facing base URL (optional). Required when configuring SSO | +| configs.cmp.annotations | object | `{}` | Annotations to be added to argocd-cmp-cm configmap | +| configs.cmp.create | bool | `false` | Create the argocd-cmp-cm configmap | +| configs.cmp.plugins | object | `{}` | Plugin yaml files to be added to argocd-cmp-cm | +| configs.credentialTemplates | object | `{}` | Repository credentials to be used as Templates for other repos | +| configs.credentialTemplatesAnnotations | object | `{}` | Annotations to be added to `configs.credentialTemplates` Secret | +| configs.gpg.annotations | object | `{}` | Annotations to be added to argocd-gpg-keys-cm configmap | +| configs.gpg.keys | object | `{}` (See [values.yaml]) | [GnuPG] public keys to add to the keyring | +| configs.params."applicationsetcontroller.enable.progressive.syncs" | bool | `false` | Enables use of the Progressive Syncs capability | +| configs.params."applicationsetcontroller.policy" | string | `"sync"` | Modify how application is synced between the generator and the cluster. One of: `sync`, `create-only`, `create-update`, `create-delete` | +| configs.params."controller.operation.processors" | int | `10` | Number of application operation processors | +| configs.params."controller.repo.server.timeout.seconds" | int | `60` | Repo server RPC call timeout seconds. | +| configs.params."controller.self.heal.timeout.seconds" | int | `5` | Specifies timeout between application self heal attempts | +| configs.params."controller.status.processors" | int | `20` | Number of application status processors | +| configs.params."otlp.address" | string | `""` | Open-Telemetry collector address: (e.g. "otel-collector:4317") | +| configs.params."reposerver.parallelism.limit" | int | `0` | Limit on number of concurrent manifests generate requests. Any value less the 1 means no limit. | +| configs.params."server.basehref" | string | `"/"` | Value for base href in index.html. Used if Argo CD is running behind reverse proxy under subpath different from / | +| configs.params."server.disable.auth" | bool | `false` | Disable Argo CD RBAC for user authentication | +| configs.params."server.enable.gzip" | bool | `false` | Enable GZIP compression | +| configs.params."server.insecure" | bool | `false` | Run server without TLS | +| configs.params."server.rootpath" | string | `""` | Used if Argo CD is running behind reverse proxy under subpath different from / | +| configs.params."server.staticassets" | string | `"/shared/app"` | Directory path that contains additional static assets | +| configs.params."server.x.frame.options" | string | `"sameorigin"` | Set X-Frame-Options header in HTTP responses to value. To disable, set to "". | +| configs.params.annotations | object | `{}` | Annotations to be added to the argocd-cmd-params-cm ConfigMap | +| configs.rbac."policy.csv" | string | `''` (See [values.yaml]) | File containing user-defined policies and role definitions. | +| configs.rbac."policy.default" | string | `""` | The name of the default role which Argo CD will falls back to, when authorizing API requests (optional). If omitted or empty, users may be still be able to login, but will see no apps, projects, etc... | +| configs.rbac.annotations | object | `{}` | Annotations to be added to argocd-rbac-cm configmap | +| configs.rbac.create | bool | `true` | Create the argocd-rbac-cm configmap with ([Argo CD RBAC policy]) definitions. If false, it is expected the configmap will be created by something else. Argo CD will not work if there is no configmap created with the name above. | +| configs.rbac.scopes | string | `"[groups]"` | OIDC scopes to examine during rbac enforcement (in addition to `sub` scope). The scope value can be a string, or a list of strings. | +| configs.repositories | object | `{}` | Repositories list to be used by applications | +| configs.repositoriesAnnotations | object | `{}` | Annotations to be added to `configs.repositories` Secret | +| configs.secret.annotations | object | `{}` | Annotations to be added to argocd-secret | +| configs.secret.argocdServerAdminPassword | string | `""` | Bcrypt hashed admin password | +| configs.secret.argocdServerAdminPasswordMtime | string | `""` (defaults to current time) | Admin password modification time. Eg. `"2006-01-02T15:04:05Z"` | +| configs.secret.bitbucketServerSecret | string | `""` | Shared secret for authenticating BitbucketServer webhook events | +| configs.secret.bitbucketUUID | string | `""` | UUID for authenticating Bitbucket webhook events | +| configs.secret.createSecret | bool | `true` | Create the argocd-secret | +| configs.secret.extra | object | `{}` | add additional secrets to be added to argocd-secret | +| configs.secret.githubSecret | string | `""` | Shared secret for authenticating GitHub webhook events | +| configs.secret.gitlabSecret | string | `""` | Shared secret for authenticating GitLab webhook events | +| configs.secret.gogsSecret | string | `""` | Shared secret for authenticating Gogs webhook events | +| configs.secret.labels | object | `{}` | Labels to be added to argocd-secret | +| configs.ssh.annotations | object | `{}` | Annotations to be added to argocd-ssh-known-hosts-cm configmap | +| configs.ssh.extraHosts | string | `""` | Additional known hosts for private repositories | +| configs.ssh.knownHosts | string | See [values.yaml] | Known hosts to be added to the known host list by default. | +| configs.styles | string | `""` (See [values.yaml]) | Define custom [CSS styles] for your argo instance. This setting will automatically mount the provided CSS and reference it in the argo configuration. | +| configs.tls.annotations | object | `{}` | Annotations to be added to argocd-tls-certs-cm configmap | +| configs.tls.certificates | object | `{}` (See [values.yaml]) | TLS certificates for Git repositories | + +## Argo CD Controller + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| controller.affinity | object | `{}` (defaults to global.affinity preset) | Assign custom [affinity] rules to the deployment | +| controller.args | object | `{}` | DEPRECATED - Application controller commandline flags | +| controller.clusterRoleRules.enabled | bool | `false` | Enable custom rules for the application controller's ClusterRole resource | +| controller.clusterRoleRules.rules | list | `[]` | List of custom rules for the application controller's ClusterRole resource | +| controller.containerPorts.metrics | int | `8082` | Metrics container port | +| controller.containerSecurityContext | object | See [values.yaml] | Application controller container-level security context | +| controller.dnsConfig | object | `{}` | [DNS configuration] | +| controller.dnsPolicy | string | `"ClusterFirst"` | Alternative DNS policy for application controller pods | +| controller.env | list | `[]` | Environment variables to pass to application controller | +| controller.envFrom | list | `[]` (See [values.yaml]) | envFrom to pass to application controller | +| controller.extraArgs | list | `[]` | Additional command line arguments to pass to application controller | +| controller.extraContainers | list | `[]` | Additional containers to be added to the application controller pod | +| controller.hostNetwork | bool | `false` | Host Network for application controller pods | +| controller.image.imagePullPolicy | string | `""` (defaults to global.image.imagePullPolicy) | Image pull policy for the application controller | +| controller.image.repository | string | `""` (defaults to global.image.repository) | Repository to use for the application controller | +| controller.image.tag | string | `""` (defaults to global.image.tag) | Tag to use for the application controller | +| controller.imagePullSecrets | list | `[]` (defaults to global.imagePullSecrets) | Secrets with credentials to pull images from a private registry | +| controller.initContainers | list | `[]` | Init containers to add to the application controller pod | +| controller.metrics.applicationLabels.enabled | bool | `false` | Enables additional labels in argocd_app_labels metric | +| controller.metrics.applicationLabels.labels | list | `[]` | Additional labels | +| controller.metrics.enabled | bool | `false` | Deploy metrics service | +| controller.metrics.rules.additionalLabels | object | `{}` | PrometheusRule labels | +| controller.metrics.rules.annotations | object | `{}` | PrometheusRule annotations | +| controller.metrics.rules.enabled | bool | `false` | Deploy a PrometheusRule for the application controller | +| controller.metrics.rules.namespace | string | `""` | PrometheusRule namespace | +| controller.metrics.rules.selector | object | `{}` | PrometheusRule selector | +| controller.metrics.rules.spec | list | `[]` | PrometheusRule.Spec for the application controller | +| controller.metrics.service.annotations | object | `{}` | Metrics service annotations | +| controller.metrics.service.labels | object | `{}` | Metrics service labels | +| controller.metrics.service.portName | string | `"http-metrics"` | Metrics service port name | +| controller.metrics.service.servicePort | int | `8082` | Metrics service port | +| controller.metrics.serviceMonitor.additionalLabels | object | `{}` | Prometheus ServiceMonitor labels | +| controller.metrics.serviceMonitor.annotations | object | `{}` | Prometheus ServiceMonitor annotations | +| controller.metrics.serviceMonitor.enabled | bool | `false` | Enable a prometheus ServiceMonitor | +| controller.metrics.serviceMonitor.interval | string | `"30s"` | Prometheus ServiceMonitor interval | +| controller.metrics.serviceMonitor.metricRelabelings | list | `[]` | Prometheus [MetricRelabelConfigs] to apply to samples before ingestion | +| controller.metrics.serviceMonitor.namespace | string | `""` | Prometheus ServiceMonitor namespace | +| controller.metrics.serviceMonitor.relabelings | list | `[]` | Prometheus [RelabelConfigs] to apply to samples before scraping | +| controller.metrics.serviceMonitor.scheme | string | `""` | Prometheus ServiceMonitor scheme | +| controller.metrics.serviceMonitor.selector | object | `{}` | Prometheus ServiceMonitor selector | +| controller.metrics.serviceMonitor.tlsConfig | object | `{}` | Prometheus ServiceMonitor tlsConfig | +| controller.name | string | `"application-controller"` | Application controller name string | +| controller.nodeSelector | object | `{}` (defaults to global.nodeSelector) | [Node selector] | +| controller.pdb.annotations | object | `{}` | Annotations to be added to application controller pdb | +| controller.pdb.enabled | bool | `false` | Deploy a [PodDisruptionBudget] for the application controller | +| controller.pdb.labels | object | `{}` | Labels to be added to application controller pdb | +| controller.pdb.maxUnavailable | string | `""` | Number of pods that are unavailable after eviction as number or percentage (eg.: 50%). | +| controller.pdb.minAvailable | string | `""` (defaults to 0 if not specified) | Number of pods that are available after eviction as number or percentage (eg.: 50%) | +| controller.podAnnotations | object | `{}` | Annotations to be added to application controller pods | +| controller.podLabels | object | `{}` | Labels to be added to application controller pods | +| controller.priorityClassName | string | `""` (defaults to global.priorityClassName) | Priority class for the application controller pods | +| controller.readinessProbe.failureThreshold | int | `3` | Minimum consecutive failures for the [probe] to be considered failed after having succeeded | +| controller.readinessProbe.initialDelaySeconds | int | `10` | Number of seconds after the container has started before [probe] is initiated | +| controller.readinessProbe.periodSeconds | int | `10` | How often (in seconds) to perform the [probe] | +| controller.readinessProbe.successThreshold | int | `1` | Minimum consecutive successes for the [probe] to be considered successful after having failed | +| controller.readinessProbe.timeoutSeconds | int | `1` | Number of seconds after which the [probe] times out | +| controller.replicas | int | `1` | The number of application controller pods to run. Additional replicas will cause sharding of managed clusters across number of replicas. | +| controller.resources | object | `{}` | Resource limits and requests for the application controller pods | +| controller.serviceAccount.annotations | object | `{}` | Annotations applied to created service account | +| controller.serviceAccount.automountServiceAccountToken | bool | `true` | Automount API credentials for the Service Account | +| controller.serviceAccount.create | bool | `true` | Create a service account for the application controller | +| controller.serviceAccount.labels | object | `{}` | Labels applied to created service account | +| controller.serviceAccount.name | string | `"argocd-application-controller"` | Service account name | +| controller.statefulsetAnnotations | object | `{}` | Annotations for the application controller StatefulSet | +| controller.tolerations | list | `[]` (defaults to global.tolerations) | [Tolerations] for use with node taints | +| controller.topologySpreadConstraints | list | `[]` (defaults to global.topologySpreadConstraints) | Assign custom [TopologySpreadConstraints] rules to the application controller | +| controller.volumeMounts | list | `[]` | Additional volumeMounts to the application controller main container | +| controller.volumes | list | `[]` | Additional volumes to the application controller pod | + +## Argo Repo Server + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| repoServer.affinity | object | `{}` (defaults to global.affinity preset) | Assign custom [affinity] rules to the deployment | +| repoServer.autoscaling.behavior | object | `{}` | Configures the scaling behavior of the target in both Up and Down directions. This is only available on HPA apiVersion `autoscaling/v2beta2` and newer | +| repoServer.autoscaling.enabled | bool | `false` | Enable Horizontal Pod Autoscaler ([HPA]) for the repo server | +| repoServer.autoscaling.maxReplicas | int | `5` | Maximum number of replicas for the repo server [HPA] | +| repoServer.autoscaling.minReplicas | int | `1` | Minimum number of replicas for the repo server [HPA] | +| repoServer.autoscaling.targetCPUUtilizationPercentage | int | `50` | Average CPU utilization percentage for the repo server [HPA] | +| repoServer.autoscaling.targetMemoryUtilizationPercentage | int | `50` | Average memory utilization percentage for the repo server [HPA] | +| repoServer.certificateSecret.annotations | object | `{}` | Annotations to be added to argocd-repo-server-tls secret | +| repoServer.certificateSecret.ca | string | `""` | Certificate authority. Required for self-signed certificates. | +| repoServer.certificateSecret.crt | string | `""` | Certificate data. Must contain SANs of Repo service (ie: argocd-repo-server, argocd-repo-server.argo-cd.svc) | +| repoServer.certificateSecret.enabled | bool | `false` | Create argocd-repo-server-tls secret | +| repoServer.certificateSecret.key | string | `""` | Certificate private key | +| repoServer.certificateSecret.labels | object | `{}` | Labels to be added to argocd-repo-server-tls secret | +| repoServer.clusterRoleRules.enabled | bool | `false` | Enable custom rules for the Repo server's Cluster Role resource | +| repoServer.clusterRoleRules.rules | list | `[]` | List of custom rules for the Repo server's Cluster Role resource | +| repoServer.containerPorts.metrics | int | `8084` | Metrics container port | +| repoServer.containerPorts.server | int | `8081` | Repo server container port | +| repoServer.containerSecurityContext | object | See [values.yaml] | Repo server container-level security context | +| repoServer.deploymentAnnotations | object | `{}` | Annotations to be added to repo server Deployment | +| repoServer.dnsConfig | object | `{}` | [DNS configuration] | +| repoServer.dnsPolicy | string | `"ClusterFirst"` | Alternative DNS policy for Repo server pods | +| repoServer.env | list | `[]` | Environment variables to pass to repo server | +| repoServer.envFrom | list | `[]` (See [values.yaml]) | envFrom to pass to repo server | +| repoServer.extraArgs | list | `[]` | Additional command line arguments to pass to repo server | +| repoServer.extraContainers | list | `[]` | Additional containers to be added to the repo server pod | +| repoServer.hostNetwork | bool | `false` | Host Network for Repo server pods | +| repoServer.image.imagePullPolicy | string | `""` (defaults to global.image.imagePullPolicy) | Image pull policy for the repo server | +| repoServer.image.repository | string | `""` (defaults to global.image.repository) | Repository to use for the repo server | +| repoServer.image.tag | string | `""` (defaults to global.image.tag) | Tag to use for the repo server | +| repoServer.imagePullSecrets | list | `[]` (defaults to global.imagePullSecrets) | Secrets with credentials to pull images from a private registry | +| repoServer.initContainers | list | `[]` | Init containers to add to the repo server pods | +| repoServer.livenessProbe.failureThreshold | int | `3` | Minimum consecutive failures for the [probe] to be considered failed after having succeeded | +| repoServer.livenessProbe.initialDelaySeconds | int | `10` | Number of seconds after the container has started before [probe] is initiated | +| repoServer.livenessProbe.periodSeconds | int | `10` | How often (in seconds) to perform the [probe] | +| repoServer.livenessProbe.successThreshold | int | `1` | Minimum consecutive successes for the [probe] to be considered successful after having failed | +| repoServer.livenessProbe.timeoutSeconds | int | `1` | Number of seconds after which the [probe] times out | +| repoServer.metrics.enabled | bool | `false` | Deploy metrics service | +| repoServer.metrics.service.annotations | object | `{}` | Metrics service annotations | +| repoServer.metrics.service.labels | object | `{}` | Metrics service labels | +| repoServer.metrics.service.portName | string | `"http-metrics"` | Metrics service port name | +| repoServer.metrics.service.servicePort | int | `8084` | Metrics service port | +| repoServer.metrics.serviceMonitor.additionalLabels | object | `{}` | Prometheus ServiceMonitor labels | +| repoServer.metrics.serviceMonitor.annotations | object | `{}` | Prometheus ServiceMonitor annotations | +| repoServer.metrics.serviceMonitor.enabled | bool | `false` | Enable a prometheus ServiceMonitor | +| repoServer.metrics.serviceMonitor.interval | string | `"30s"` | Prometheus ServiceMonitor interval | +| repoServer.metrics.serviceMonitor.metricRelabelings | list | `[]` | Prometheus [MetricRelabelConfigs] to apply to samples before ingestion | +| repoServer.metrics.serviceMonitor.namespace | string | `""` | Prometheus ServiceMonitor namespace | +| repoServer.metrics.serviceMonitor.relabelings | list | `[]` | Prometheus [RelabelConfigs] to apply to samples before scraping | +| repoServer.metrics.serviceMonitor.scheme | string | `""` | Prometheus ServiceMonitor scheme | +| repoServer.metrics.serviceMonitor.selector | object | `{}` | Prometheus ServiceMonitor selector | +| repoServer.metrics.serviceMonitor.tlsConfig | object | `{}` | Prometheus ServiceMonitor tlsConfig | +| repoServer.name | string | `"repo-server"` | Repo server name | +| repoServer.nodeSelector | object | `{}` (defaults to global.nodeSelector) | [Node selector] | +| repoServer.pdb.annotations | object | `{}` | Annotations to be added to repo server pdb | +| repoServer.pdb.enabled | bool | `false` | Deploy a [PodDisruptionBudget] for the repo server | +| repoServer.pdb.labels | object | `{}` | Labels to be added to repo server pdb | +| repoServer.pdb.maxUnavailable | string | `""` | Number of pods that are unavailable after eviction as number or percentage (eg.: 50%). | +| repoServer.pdb.minAvailable | string | `""` (defaults to 0 if not specified) | Number of pods that are available after eviction as number or percentage (eg.: 50%) | +| repoServer.podAnnotations | object | `{}` | Annotations to be added to repo server pods | +| repoServer.podLabels | object | `{}` | Labels to be added to repo server pods | +| repoServer.priorityClassName | string | `""` (defaults to global.priorityClassName) | Priority class for the repo server pods | +| repoServer.rbac | list | `[]` | Repo server rbac rules | +| repoServer.readinessProbe.failureThreshold | int | `3` | Minimum consecutive failures for the [probe] to be considered failed after having succeeded | +| repoServer.readinessProbe.initialDelaySeconds | int | `10` | Number of seconds after the container has started before [probe] is initiated | +| repoServer.readinessProbe.periodSeconds | int | `10` | How often (in seconds) to perform the [probe] | +| repoServer.readinessProbe.successThreshold | int | `1` | Minimum consecutive successes for the [probe] to be considered successful after having failed | +| repoServer.readinessProbe.timeoutSeconds | int | `1` | Number of seconds after which the [probe] times out | +| repoServer.replicas | int | `1` | The number of repo server pods to run | +| repoServer.resources | object | `{}` | Resource limits and requests for the repo server pods | +| repoServer.service.annotations | object | `{}` | Repo server service annotations | +| repoServer.service.labels | object | `{}` | Repo server service labels | +| repoServer.service.port | int | `8081` | Repo server service port | +| repoServer.service.portName | string | `"https-repo-server"` | Repo server service port name | +| repoServer.serviceAccount.annotations | object | `{}` | Annotations applied to created service account | +| repoServer.serviceAccount.automountServiceAccountToken | bool | `true` | Automount API credentials for the Service Account | +| repoServer.serviceAccount.create | bool | `true` | Create repo server service account | +| repoServer.serviceAccount.labels | object | `{}` | Labels applied to created service account | +| repoServer.serviceAccount.name | string | `""` | Repo server service account name | +| repoServer.tolerations | list | `[]` (defaults to global.tolerations) | [Tolerations] for use with node taints | +| repoServer.topologySpreadConstraints | list | `[]` (defaults to global.topologySpreadConstraints) | Assign custom [TopologySpreadConstraints] rules to the repo server | +| repoServer.volumeMounts | list | `[]` | Additional volumeMounts to the repo server main container | +| repoServer.volumes | list | `[]` | Additional volumes to the repo server pod | + +## Argo Server + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| server.GKEbackendConfig.enabled | bool | `false` | Enable BackendConfig custom resource for Google Kubernetes Engine | +| server.GKEbackendConfig.spec | object | `{}` | [BackendConfigSpec] | +| server.GKEfrontendConfig.enabled | bool | `false` | Enable FrontConfig custom resource for Google Kubernetes Engine | +| server.GKEfrontendConfig.spec | object | `{}` | [FrontendConfigSpec] | +| server.GKEmanagedCertificate.domains | list | `["argocd.example.com"]` | Domains for the Google Managed Certificate | +| server.GKEmanagedCertificate.enabled | bool | `false` | Enable ManagedCertificate custom resource for Google Kubernetes Engine. | +| server.affinity | object | `{}` (defaults to global.affinity preset) | Assign custom [affinity] rules to the deployment | +| server.autoscaling.behavior | object | `{}` | Configures the scaling behavior of the target in both Up and Down directions. This is only available on HPA apiVersion `autoscaling/v2beta2` and newer | +| server.autoscaling.enabled | bool | `false` | Enable Horizontal Pod Autoscaler ([HPA]) for the Argo CD server | +| server.autoscaling.maxReplicas | int | `5` | Maximum number of replicas for the Argo CD server [HPA] | +| server.autoscaling.minReplicas | int | `1` | Minimum number of replicas for the Argo CD server [HPA] | +| server.autoscaling.targetCPUUtilizationPercentage | int | `50` | Average CPU utilization percentage for the Argo CD server [HPA] | +| server.autoscaling.targetMemoryUtilizationPercentage | int | `50` | Average memory utilization percentage for the Argo CD server [HPA] | +| server.certificate.additionalHosts | list | `[]` | Certificate Subject Alternate Names (SANs) | +| server.certificate.domain | string | `"argocd.example.com"` | Certificate primary domain (commonName) | +| server.certificate.duration | string | `""` (defaults to 2160h = 90d if not specified) | The requested 'duration' (i.e. lifetime) of the certificate. | +| server.certificate.enabled | bool | `false` | Deploy a Certificate resource (requires cert-manager) | +| server.certificate.issuer.group | string | `""` | Certificate issuer group. Set if using an external issuer. Eg. `cert-manager.io` | +| server.certificate.issuer.kind | string | `""` | Certificate issuer kind. Either `Issuer` or `ClusterIssuer` | +| server.certificate.issuer.name | string | `""` | Certificate issuer name. Eg. `letsencrypt` | +| server.certificate.privateKey.algorithm | string | `"RSA"` | Algorithm used to generate certificate private key. One of: `RSA`, `Ed25519` or `ECDSA` | +| server.certificate.privateKey.encoding | string | `"PKCS1"` | The private key cryptography standards (PKCS) encoding for private key. Either: `PCKS1` or `PKCS8` | +| server.certificate.privateKey.rotationPolicy | string | `"Never"` | Rotation policy of private key when certificate is re-issued. Either: `Never` or `Always` | +| server.certificate.privateKey.size | int | `2048` | Key bit size of the private key. If algorithm is set to `Ed25519`, size is ignored. | +| server.certificate.renewBefore | string | `""` (defaults to 360h = 15d if not specified) | How long before the expiry a certificate should be renewed. | +| server.certificate.secretName | string | `"argocd-server-tls"` | The name of the Secret that will be automatically created and managed by this Certificate resource | +| server.certificateSecret.annotations | object | `{}` | Annotations to be added to argocd-server-tls secret | +| server.certificateSecret.crt | string | `""` | Certificate data | +| server.certificateSecret.enabled | bool | `false` | Create argocd-server-tls secret | +| server.certificateSecret.key | string | `""` | Private Key of the certificate | +| server.certificateSecret.labels | object | `{}` | Labels to be added to argocd-server-tls secret | +| server.containerPorts.metrics | int | `8082` | Metrics container port | +| server.containerPorts.server | int | `8080` | Server container port | +| server.containerSecurityContext | object | See [values.yaml] | Server container-level security context | +| server.deploymentAnnotations | object | `{}` | Annotations to be added to server Deployment | +| server.dnsConfig | object | `{}` | [DNS configuration] | +| server.dnsPolicy | string | `"ClusterFirst"` | Alternative DNS policy for Server pods | +| server.env | list | `[]` | Environment variables to pass to Argo CD server | +| server.envFrom | list | `[]` (See [values.yaml]) | envFrom to pass to Argo CD server | +| server.extensions.containerSecurityContext | object | See [values.yaml] | Server UI extensions container-level security context | +| server.extensions.enabled | bool | `false` | Enable support for Argo UI extensions | +| server.extensions.image.imagePullPolicy | string | `""` (defaults to global.image.imagePullPolicy) | Image pull policy for extensions | +| server.extensions.image.repository | string | `"ghcr.io/argoproj-labs/argocd-extensions"` | Repository to use for extensions image | +| server.extensions.image.tag | string | `"v0.2.1"` | Tag to use for extensions image | +| server.extensions.resources | object | `{}` | Resource limits and requests for the argocd-extensions container | +| server.extraArgs | list | `[]` | Additional command line arguments to pass to Argo CD server | +| server.extraContainers | list | `[]` | Additional containers to be added to the server pod | +| server.hostNetwork | bool | `false` | Host Network for Server pods | +| server.image.imagePullPolicy | string | `""` (defaults to global.image.imagePullPolicy) | Image pull policy for the Argo CD server | +| server.image.repository | string | `""` (defaults to global.image.repository) | Repository to use for the Argo CD server | +| server.image.tag | string | `""` (defaults to global.image.tag) | Tag to use for the Argo CD server | +| server.imagePullSecrets | list | `[]` (defaults to global.imagePullSecrets) | Secrets with credentials to pull images from a private registry | +| server.ingress.annotations | object | `{}` | Additional ingress annotations | +| server.ingress.enabled | bool | `false` | Enable an ingress resource for the Argo CD server | +| server.ingress.extraPaths | list | `[]` | Additional ingress paths | +| server.ingress.hosts | list | `[]` | List of ingress hosts | +| server.ingress.https | bool | `false` | Uses `server.service.servicePortHttps` instead `server.service.servicePortHttp` | +| server.ingress.ingressClassName | string | `""` | Defines which ingress controller will implement the resource | +| server.ingress.labels | object | `{}` | Additional ingress labels | +| server.ingress.pathType | string | `"Prefix"` | Ingress path type. One of `Exact`, `Prefix` or `ImplementationSpecific` | +| server.ingress.paths | list | `["/"]` | List of ingress paths | +| server.ingress.tls | list | `[]` | Ingress TLS configuration | +| server.ingressGrpc.annotations | object | `{}` | Additional ingress annotations for dedicated [gRPC-ingress] | +| server.ingressGrpc.awsALB.backendProtocolVersion | string | `"HTTP2"` | Backend protocol version for the AWS ALB gRPC service | +| server.ingressGrpc.awsALB.serviceType | string | `"NodePort"` | Service type for the AWS ALB gRPC service | +| server.ingressGrpc.enabled | bool | `false` | Enable an ingress resource for the Argo CD server for dedicated [gRPC-ingress] | +| server.ingressGrpc.extraPaths | list | `[]` | Additional ingress paths for dedicated [gRPC-ingress] | +| server.ingressGrpc.hosts | list | `[]` | List of ingress hosts for dedicated [gRPC-ingress] | +| server.ingressGrpc.https | bool | `false` | Uses `server.service.servicePortHttps` instead `server.service.servicePortHttp` | +| server.ingressGrpc.ingressClassName | string | `""` | Defines which ingress controller will implement the resource [gRPC-ingress] | +| server.ingressGrpc.isAWSALB | bool | `false` | Setup up gRPC ingress to work with an AWS ALB | +| server.ingressGrpc.labels | object | `{}` | Additional ingress labels for dedicated [gRPC-ingress] | +| server.ingressGrpc.pathType | string | `"Prefix"` | Ingress path type for dedicated [gRPC-ingress]. One of `Exact`, `Prefix` or `ImplementationSpecific` | +| server.ingressGrpc.paths | list | `["/"]` | List of ingress paths for dedicated [gRPC-ingress] | +| server.ingressGrpc.tls | list | `[]` | Ingress TLS configuration for dedicated [gRPC-ingress] | +| server.initContainers | list | `[]` | Init containers to add to the server pod | +| server.lifecycle | object | `{}` | Specify postStart and preStop lifecycle hooks for your argo-cd-server container | +| server.livenessProbe.failureThreshold | int | `3` | Minimum consecutive failures for the [probe] to be considered failed after having succeeded | +| server.livenessProbe.initialDelaySeconds | int | `10` | Number of seconds after the container has started before [probe] is initiated | +| server.livenessProbe.periodSeconds | int | `10` | How often (in seconds) to perform the [probe] | +| server.livenessProbe.successThreshold | int | `1` | Minimum consecutive successes for the [probe] to be considered successful after having failed | +| server.livenessProbe.timeoutSeconds | int | `1` | Number of seconds after which the [probe] times out | +| server.metrics.enabled | bool | `false` | Deploy metrics service | +| server.metrics.service.annotations | object | `{}` | Metrics service annotations | +| server.metrics.service.labels | object | `{}` | Metrics service labels | +| server.metrics.service.portName | string | `"http-metrics"` | Metrics service port name | +| server.metrics.service.servicePort | int | `8083` | Metrics service port | +| server.metrics.serviceMonitor.additionalLabels | object | `{}` | Prometheus ServiceMonitor labels | +| server.metrics.serviceMonitor.annotations | object | `{}` | Prometheus ServiceMonitor annotations | +| server.metrics.serviceMonitor.enabled | bool | `false` | Enable a prometheus ServiceMonitor | +| server.metrics.serviceMonitor.interval | string | `"30s"` | Prometheus ServiceMonitor interval | +| server.metrics.serviceMonitor.metricRelabelings | list | `[]` | Prometheus [MetricRelabelConfigs] to apply to samples before ingestion | +| server.metrics.serviceMonitor.namespace | string | `""` | Prometheus ServiceMonitor namespace | +| server.metrics.serviceMonitor.relabelings | list | `[]` | Prometheus [RelabelConfigs] to apply to samples before scraping | +| server.metrics.serviceMonitor.scheme | string | `""` | Prometheus ServiceMonitor scheme | +| server.metrics.serviceMonitor.selector | object | `{}` | Prometheus ServiceMonitor selector | +| server.metrics.serviceMonitor.tlsConfig | object | `{}` | Prometheus ServiceMonitor tlsConfig | +| server.name | string | `"server"` | Argo CD server name | +| server.nodeSelector | object | `{}` (defaults to global.nodeSelector) | [Node selector] | +| server.pdb.annotations | object | `{}` | Annotations to be added to Argo CD server pdb | +| server.pdb.enabled | bool | `false` | Deploy a [PodDisruptionBudget] for the Argo CD server | +| server.pdb.labels | object | `{}` | Labels to be added to Argo CD server pdb | +| server.pdb.maxUnavailable | string | `""` | Number of pods that are unavailable after eviction as number or percentage (eg.: 50%). | +| server.pdb.minAvailable | string | `""` (defaults to 0 if not specified) | Number of pods that are available after eviction as number or percentage (eg.: 50%) | +| server.podAnnotations | object | `{}` | Annotations to be added to server pods | +| server.podLabels | object | `{}` | Labels to be added to server pods | +| server.priorityClassName | string | `""` (defaults to global.priorityClassName) | Priority class for the Argo CD server pods | +| server.readinessProbe.failureThreshold | int | `3` | Minimum consecutive failures for the [probe] to be considered failed after having succeeded | +| server.readinessProbe.initialDelaySeconds | int | `10` | Number of seconds after the container has started before [probe] is initiated | +| server.readinessProbe.periodSeconds | int | `10` | How often (in seconds) to perform the [probe] | +| server.readinessProbe.successThreshold | int | `1` | Minimum consecutive successes for the [probe] to be considered successful after having failed | +| server.readinessProbe.timeoutSeconds | int | `1` | Number of seconds after which the [probe] times out | +| server.replicas | int | `1` | The number of server pods to run | +| server.resources | object | `{}` | Resource limits and requests for the Argo CD server | +| server.route.annotations | object | `{}` | Openshift Route annotations | +| server.route.enabled | bool | `false` | Enable an OpenShift Route for the Argo CD server | +| server.route.hostname | string | `""` | Hostname of OpenShift Route | +| server.route.termination_policy | string | `"None"` | Termination policy of Openshift Route | +| server.route.termination_type | string | `"passthrough"` | Termination type of Openshift Route | +| server.service.annotations | object | `{}` | Server service annotations | +| server.service.externalIPs | list | `[]` | Server service external IPs | +| server.service.externalTrafficPolicy | string | `""` | Denotes if this Service desires to route external traffic to node-local or cluster-wide endpoints | +| server.service.labels | object | `{}` | Server service labels | +| server.service.loadBalancerIP | string | `""` | LoadBalancer will get created with the IP specified in this field | +| server.service.loadBalancerSourceRanges | list | `[]` | Source IP ranges to allow access to service from | +| server.service.nodePortHttp | int | `30080` | Server service http port for NodePort service type (only if `server.service.type` is set to "NodePort") | +| server.service.nodePortHttps | int | `30443` | Server service https port for NodePort service type (only if `server.service.type` is set to "NodePort") | +| server.service.servicePortHttp | int | `80` | Server service http port | +| server.service.servicePortHttpName | string | `"http"` | Server service http port name, can be used to route traffic via istio | +| server.service.servicePortHttps | int | `443` | Server service https port | +| server.service.servicePortHttpsName | string | `"https"` | Server service https port name, can be used to route traffic via istio | +| server.service.sessionAffinity | string | `""` | Used to maintain session affinity. Supports `ClientIP` and `None` | +| server.service.type | string | `"ClusterIP"` | Server service type | +| server.serviceAccount.annotations | object | `{}` | Annotations applied to created service account | +| server.serviceAccount.automountServiceAccountToken | bool | `true` | Automount API credentials for the Service Account | +| server.serviceAccount.create | bool | `true` | Create server service account | +| server.serviceAccount.labels | object | `{}` | Labels applied to created service account | +| server.serviceAccount.name | string | `"argocd-server"` | Server service account name | +| server.tolerations | list | `[]` (defaults to global.tolerations) | [Tolerations] for use with node taints | +| server.topologySpreadConstraints | list | `[]` (defaults to global.topologySpreadConstraints) | Assign custom [TopologySpreadConstraints] rules to the Argo CD server | +| server.volumeMounts | list | `[]` | Additional volumeMounts to the server main container | +| server.volumes | list | `[]` | Additional volumes to the server pod | + +### Using AWS ALB Ingress Controller With GRPC + +If you are using an AWS ALB Ingress controller, you will need to set `server.ingressGrpc.isAWSALB` to `true`. This will create a second service with the annotation `alb.ingress.kubernetes.io/backend-protocol-version: HTTP2` and modify the server ingress to add a condition annotation to route GRPC traffic to the new service. + +Example: + +```yaml +server: + ingress: + enabled: true + annotations: + alb.ingress.kubernetes.io/backend-protocol: HTTPS + alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}]' + alb.ingress.kubernetes.io/scheme: internal + alb.ingress.kubernetes.io/target-type: ip + ingressGrpc: + enabled: true + isAWSALB: true + awsALB: + serviceType: ClusterIP +``` + +## Dex + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| dex.affinity | object | `{}` (defaults to global.affinity preset) | Assign custom [affinity] rules to the deployment | +| dex.certificateSecret.annotations | object | `{}` | Annotations to be added to argocd-dex-server-tls secret | +| dex.certificateSecret.ca | string | `""` | Certificate authority. Required for self-signed certificates. | +| dex.certificateSecret.crt | string | `""` | Certificate data. Must contain SANs of Dex service (ie: argocd-dex-server, argocd-dex-server.argo-cd.svc) | +| dex.certificateSecret.enabled | bool | `false` | Create argocd-dex-server-tls secret | +| dex.certificateSecret.key | string | `""` | Certificate private key | +| dex.certificateSecret.labels | object | `{}` | Labels to be added to argocd-dex-server-tls secret | +| dex.containerPorts.grpc | int | `5557` | gRPC container port | +| dex.containerPorts.http | int | `5556` | HTTP container port | +| dex.containerPorts.metrics | int | `5558` | Metrics container port | +| dex.containerSecurityContext | object | See [values.yaml] | Dex container-level security context | +| dex.deploymentAnnotations | object | `{}` | Annotations to be added to the Dex server Deployment | +| dex.dnsConfig | object | `{}` | [DNS configuration] | +| dex.dnsPolicy | string | `"ClusterFirst"` | Alternative DNS policy for Dex server pods | +| dex.enabled | bool | `true` | Enable dex | +| dex.env | list | `[]` | Environment variables to pass to the Dex server | +| dex.envFrom | list | `[]` (See [values.yaml]) | envFrom to pass to the Dex server | +| dex.extraArgs | list | `[]` | Additional command line arguments to pass to the Dex server | +| dex.extraContainers | list | `[]` | Additional containers to be added to the dex pod | +| dex.image.imagePullPolicy | string | `""` (defaults to global.image.imagePullPolicy) | Dex imagePullPolicy | +| dex.image.repository | string | `"ghcr.io/dexidp/dex"` | Dex image repository | +| dex.image.tag | string | `"v2.35.3"` | Dex image tag | +| dex.imagePullSecrets | list | `[]` (defaults to global.imagePullSecrets) | Secrets with credentials to pull images from a private registry | +| dex.initContainers | list | `[]` | Init containers to add to the dex pod | +| dex.initImage.imagePullPolicy | string | `""` (defaults to global.image.imagePullPolicy) | Argo CD init image imagePullPolicy | +| dex.initImage.repository | string | `""` (defaults to global.image.repository) | Argo CD init image repository | +| dex.initImage.tag | string | `""` (defaults to global.image.tag) | Argo CD init image tag | +| dex.livenessProbe.enabled | bool | `false` | Enable Kubernetes liveness probe for Dex >= 2.28.0 | +| dex.livenessProbe.failureThreshold | int | `3` | Minimum consecutive failures for the [probe] to be considered failed after having succeeded | +| dex.livenessProbe.initialDelaySeconds | int | `10` | Number of seconds after the container has started before [probe] is initiated | +| dex.livenessProbe.periodSeconds | int | `10` | How often (in seconds) to perform the [probe] | +| dex.livenessProbe.successThreshold | int | `1` | Minimum consecutive successes for the [probe] to be considered successful after having failed | +| dex.livenessProbe.timeoutSeconds | int | `1` | Number of seconds after which the [probe] times out | +| dex.metrics.enabled | bool | `false` | Deploy metrics service | +| dex.metrics.service.annotations | object | `{}` | Metrics service annotations | +| dex.metrics.service.labels | object | `{}` | Metrics service labels | +| dex.metrics.service.portName | string | `"http-metrics"` | Metrics service port name | +| dex.metrics.serviceMonitor.additionalLabels | object | `{}` | Prometheus ServiceMonitor labels | +| dex.metrics.serviceMonitor.annotations | object | `{}` | Prometheus ServiceMonitor annotations | +| dex.metrics.serviceMonitor.enabled | bool | `false` | Enable a prometheus ServiceMonitor | +| dex.metrics.serviceMonitor.interval | string | `"30s"` | Prometheus ServiceMonitor interval | +| dex.metrics.serviceMonitor.metricRelabelings | list | `[]` | Prometheus [MetricRelabelConfigs] to apply to samples before ingestion | +| dex.metrics.serviceMonitor.namespace | string | `""` | Prometheus ServiceMonitor namespace | +| dex.metrics.serviceMonitor.relabelings | list | `[]` | Prometheus [RelabelConfigs] to apply to samples before scraping | +| dex.metrics.serviceMonitor.scheme | string | `""` | Prometheus ServiceMonitor scheme | +| dex.metrics.serviceMonitor.selector | object | `{}` | Prometheus ServiceMonitor selector | +| dex.metrics.serviceMonitor.tlsConfig | object | `{}` | Prometheus ServiceMonitor tlsConfig | +| dex.name | string | `"dex-server"` | Dex name | +| dex.nodeSelector | object | `{}` (defaults to global.nodeSelector) | [Node selector] | +| dex.pdb.annotations | object | `{}` | Annotations to be added to Dex server pdb | +| dex.pdb.enabled | bool | `false` | Deploy a [PodDisruptionBudget] for the Dex server | +| dex.pdb.labels | object | `{}` | Labels to be added to Dex server pdb | +| dex.pdb.maxUnavailable | string | `""` | Number of pods that are unavailble after eviction as number or percentage (eg.: 50%). | +| dex.pdb.minAvailable | string | `""` (defaults to 0 if not specified) | Number of pods that are available after eviction as number or percentage (eg.: 50%) | +| dex.podAnnotations | object | `{}` | Annotations to be added to the Dex server pods | +| dex.podLabels | object | `{}` | Labels to be added to the Dex server pods | +| dex.priorityClassName | string | `""` (defaults to global.priorityClassName) | Priority class for the dex pods | +| dex.readinessProbe.enabled | bool | `false` | Enable Kubernetes readiness probe for Dex >= 2.28.0 | +| dex.readinessProbe.failureThreshold | int | `3` | Minimum consecutive failures for the [probe] to be considered failed after having succeeded | +| dex.readinessProbe.initialDelaySeconds | int | `10` | Number of seconds after the container has started before [probe] is initiated | +| dex.readinessProbe.periodSeconds | int | `10` | How often (in seconds) to perform the [probe] | +| dex.readinessProbe.successThreshold | int | `1` | Minimum consecutive successes for the [probe] to be considered successful after having failed | +| dex.readinessProbe.timeoutSeconds | int | `1` | Number of seconds after which the [probe] times out | +| dex.resources | object | `{}` | Resource limits and requests for dex | +| dex.serviceAccount.annotations | object | `{}` | Annotations applied to created service account | +| dex.serviceAccount.automountServiceAccountToken | bool | `true` | Automount API credentials for the Service Account | +| dex.serviceAccount.create | bool | `true` | Create dex service account | +| dex.serviceAccount.name | string | `"argocd-dex-server"` | Dex service account name | +| dex.servicePortGrpc | int | `5557` | Service port for gRPC access | +| dex.servicePortGrpcName | string | `"grpc"` | Service port name for gRPC access | +| dex.servicePortHttp | int | `5556` | Service port for HTTP access | +| dex.servicePortHttpName | string | `"http"` | Service port name for HTTP access | +| dex.servicePortMetrics | int | `5558` | Service port for metrics access | +| dex.tolerations | list | `[]` (defaults to global.tolerations) | [Tolerations] for use with node taints | +| dex.topologySpreadConstraints | list | `[]` (defaults to global.topologySpreadConstraints) | Assign custom [TopologySpreadConstraints] rules to dex | +| dex.volumeMounts | list | `[]` | Additional volumeMounts to the dex main container | +| dex.volumes | list | `[]` | Additional volumes to the dex pod | + +## Redis + +### Option 1 - Single Redis instance (default option) + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| redis.affinity | object | `{}` (defaults to global.affinity preset) | Assign custom [affinity] rules to the deployment | +| redis.containerPorts.metrics | int | `9121` | Metrics container port | +| redis.containerPorts.redis | int | `6379` | Redis container port | +| redis.containerSecurityContext | object | See [values.yaml] | Redis container-level security context | +| redis.deploymentAnnotations | object | `{}` | Annotations to be added to the Redis server Deployment | +| redis.dnsConfig | object | `{}` | [DNS configuration] | +| redis.dnsPolicy | string | `"ClusterFirst"` | Alternative DNS policy for Redis server pods | +| redis.enabled | bool | `true` | Enable redis | +| redis.env | list | `[]` | Environment variables to pass to the Redis server | +| redis.envFrom | list | `[]` (See [values.yaml]) | envFrom to pass to the Redis server | +| redis.exporter.containerSecurityContext | object | See [values.yaml] | Redis exporter security context | +| redis.exporter.enabled | bool | `false` | Enable Prometheus redis-exporter sidecar | +| redis.exporter.env | list | `[]` | Environment variables to pass to the Redis exporter | +| redis.exporter.image.imagePullPolicy | string | `""` (defaults to global.image.imagePullPolicy) | Image pull policy for the redis-exporter | +| redis.exporter.image.repository | string | `"public.ecr.aws/bitnami/redis-exporter"` | Repository to use for the redis-exporter | +| redis.exporter.image.tag | string | `"1.45.0"` | Tag to use for the redis-exporter | +| redis.exporter.resources | object | `{}` | Resource limits and requests for redis-exporter sidecar | +| redis.extraArgs | list | `[]` | Additional command line arguments to pass to redis-server | +| redis.extraContainers | list | `[]` | Additional containers to be added to the redis pod | +| redis.image.imagePullPolicy | string | `""` (defaults to global.image.imagePullPolicy) | Redis image pull policy | +| redis.image.repository | string | `"public.ecr.aws/docker/library/redis"` | Redis repository | +| redis.image.tag | string | `"7.0.7-alpine"` | Redis tag | +| redis.imagePullSecrets | list | `[]` (defaults to global.imagePullSecrets) | Secrets with credentials to pull images from a private registry | +| redis.initContainers | list | `[]` | Init containers to add to the redis pod | +| redis.metrics.enabled | bool | `false` | Deploy metrics service | +| redis.metrics.service.annotations | object | `{}` | Metrics service annotations | +| redis.metrics.service.clusterIP | string | `"None"` | Metrics service clusterIP. `None` makes a "headless service" (no virtual IP) | +| redis.metrics.service.labels | object | `{}` | Metrics service labels | +| redis.metrics.service.portName | string | `"http-metrics"` | Metrics service port name | +| redis.metrics.service.servicePort | int | `9121` | Metrics service port | +| redis.metrics.service.type | string | `"ClusterIP"` | Metrics service type | +| redis.metrics.serviceMonitor.additionalLabels | object | `{}` | Prometheus ServiceMonitor labels | +| redis.metrics.serviceMonitor.annotations | object | `{}` | Prometheus ServiceMonitor annotations | +| redis.metrics.serviceMonitor.enabled | bool | `false` | Enable a prometheus ServiceMonitor | +| redis.metrics.serviceMonitor.interval | string | `"30s"` | Interval at which metrics should be scraped | +| redis.metrics.serviceMonitor.metricRelabelings | list | `[]` | Prometheus [MetricRelabelConfigs] to apply to samples before ingestion | +| redis.metrics.serviceMonitor.namespace | string | `""` | Prometheus ServiceMonitor namespace | +| redis.metrics.serviceMonitor.relabelings | list | `[]` | Prometheus [RelabelConfigs] to apply to samples before scraping | +| redis.metrics.serviceMonitor.scheme | string | `""` | Prometheus ServiceMonitor scheme | +| redis.metrics.serviceMonitor.selector | object | `{}` | Prometheus ServiceMonitor selector | +| redis.metrics.serviceMonitor.tlsConfig | object | `{}` | Prometheus ServiceMonitor tlsConfig | +| redis.name | string | `"redis"` | Redis name | +| redis.nodeSelector | object | `{}` (defaults to global.nodeSelector) | [Node selector] | +| redis.pdb.annotations | object | `{}` | Annotations to be added to Redis pdb | +| redis.pdb.enabled | bool | `false` | Deploy a [PodDisruptionBudget] for the Redis | +| redis.pdb.labels | object | `{}` | Labels to be added to Redis pdb | +| redis.pdb.maxUnavailable | string | `""` | Number of pods that are unavailble after eviction as number or percentage (eg.: 50%). | +| redis.pdb.minAvailable | string | `""` (defaults to 0 if not specified) | Number of pods that are available after eviction as number or percentage (eg.: 50%) | +| redis.podAnnotations | object | `{}` | Annotations to be added to the Redis server pods | +| redis.podLabels | object | `{}` | Labels to be added to the Redis server pods | +| redis.priorityClassName | string | `""` (defaults to global.priorityClassName) | Priority class for redis pods | +| redis.resources | object | `{}` | Resource limits and requests for redis | +| redis.securityContext | object | See [values.yaml] | Redis pod-level security context | +| redis.service.annotations | object | `{}` | Redis service annotations | +| redis.service.labels | object | `{}` | Additional redis service labels | +| redis.serviceAccount.annotations | object | `{}` | Annotations applied to created service account | +| redis.serviceAccount.automountServiceAccountToken | bool | `false` | Automount API credentials for the Service Account | +| redis.serviceAccount.create | bool | `false` | Create a service account for the redis pod | +| redis.serviceAccount.name | string | `""` | Service account name for redis pod | +| redis.servicePort | int | `6379` | Redis service port | +| redis.tolerations | list | `[]` (defaults to global.tolerations) | [Tolerations] for use with node taints | +| redis.topologySpreadConstraints | list | `[]` (defaults to global.topologySpreadConstraints) | Assign custom [TopologySpreadConstraints] rules to redis | +| redis.volumeMounts | list | `[]` | Additional volumeMounts to the redis container | +| redis.volumes | list | `[]` | Additional volumes to the redis pod | + +### Option 2 - Redis HA + +This option uses the following third-party chart to bootstrap a clustered Redis: https://github.com/DandyDeveloper/charts/tree/master/charts/redis-ha. +For all available configuration options, please read upstream README and/or chart source. +The main options are listed here: + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| redis-ha.enabled | bool | `false` | Enables the Redis HA subchart and disables the custom Redis single node deployment | +| redis-ha.exporter.enabled | bool | `false` | Enable Prometheus redis-exporter sidecar | +| redis-ha.exporter.image | string | `"public.ecr.aws/bitnami/redis-exporter"` | Repository to use for the redis-exporter | +| redis-ha.exporter.tag | string | `"1.45.0"` | Tag to use for the redis-exporter | +| redis-ha.haproxy.enabled | bool | `true` | Enabled HAProxy LoadBalancing/Proxy | +| redis-ha.haproxy.metrics.enabled | bool | `true` | HAProxy enable prometheus metric scraping | +| redis-ha.image.tag | string | `"7.0.7-alpine"` | Redis tag | +| redis-ha.persistentVolume.enabled | bool | `false` | Configures persistence on Redis nodes | +| redis-ha.redis.config | object | See [values.yaml] | Any valid redis config options in this section will be applied to each server (see `redis-ha` chart) | +| redis-ha.redis.config.save | string | `'""'` | Will save the DB if both the given number of seconds and the given number of write operations against the DB occurred. `""` is disabled | +| redis-ha.redis.masterGroupName | string | `"argocd"` | Redis convention for naming the cluster group: must match `^[\\w-\\.]+$` and can be templated | +| redis-ha.topologySpreadConstraints.enabled | bool | `false` | Enable Redis HA topology spread constraints | +| redis-ha.topologySpreadConstraints.maxSkew | string | `""` (defaults to `1`) | Max skew of pods tolerated | +| redis-ha.topologySpreadConstraints.topologyKey | string | `""` (defaults to `topology.kubernetes.io/zone`) | Topology key for spread | +| redis-ha.topologySpreadConstraints.whenUnsatisfiable | string | `""` (defaults to `ScheduleAnyway`) | Enforcement policy, hard or soft | +| redis-ha.exporter.image | string | `nil` (follows subchart default) | Exporter image | +| redis-ha.exporter.tag | string | `nil` (follows subchart default) | Exporter tag | +| redis-ha.haproxy.image.repository | string | `nil` (follows subchart default) | HAProxy Image Repository | +| redis-ha.haproxy.image.tag | string | `nil` (follows subchart default) | HAProxy Image Tag | +| redis-ha.image.repository | string | `nil` (follows subchart default) | Redis image repository | + +### Option 3 - External Redis + +If you want to use an existing Redis (eg. a managed service from a cloud provider), you can use these parameters: + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| externalRedis.existingSecret | string | `""` | The name of an existing secret with Redis credentials (must contain key `redis-password`). When it's set, the `externalRedis.password` parameter is ignored | +| externalRedis.host | string | `""` | External Redis server host | +| externalRedis.password | string | `""` | External Redis password | +| externalRedis.port | int | `6379` | External Redis server port | +| externalRedis.secretAnnotations | object | `{}` | External Redis Secret annotations | +| externalRedis.username | string | `""` | External Redis username | + +## ApplicationSet + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| applicationSet.affinity | object | `{}` (defaults to global.affinity preset) | Assign custom [affinity] rules | +| applicationSet.args | object | `{}` | DEPRECATED - ApplicationSet controller command line flags | +| applicationSet.containerPorts.metrics | int | `8080` | Metrics container port | +| applicationSet.containerPorts.probe | int | `8081` | Probe container port | +| applicationSet.containerPorts.webhook | int | `7000` | Webhook container port | +| applicationSet.containerSecurityContext | object | See [values.yaml] | ApplicationSet controller container-level security context | +| applicationSet.deploymentAnnotations | object | `{}` | Annotations to be added to ApplicationSet controller Deployment | +| applicationSet.dnsConfig | object | `{}` | [DNS configuration] | +| applicationSet.dnsPolicy | string | `"ClusterFirst"` | Alternative DNS policy for ApplicationSet controller pods | +| applicationSet.enabled | bool | `true` | Enable ApplicationSet controller | +| applicationSet.extraArgs | list | `[]` | List of extra cli args to add | +| applicationSet.extraContainers | list | `[]` | Additional containers to be added to the ApplicationSet controller pod | +| applicationSet.extraEnv | list | `[]` | Environment variables to pass to the ApplicationSet controller | +| applicationSet.extraEnvFrom | list | `[]` (See [values.yaml]) | envFrom to pass to the ApplicationSet controller | +| applicationSet.extraVolumeMounts | list | `[]` | List of extra mounts to add (normally used with extraVolumes) | +| applicationSet.extraVolumes | list | `[]` | List of extra volumes to add | +| applicationSet.image.imagePullPolicy | string | `""` (defaults to global.image.imagePullPolicy) | Image pull policy for the ApplicationSet controller | +| applicationSet.image.repository | string | `""` (defaults to global.image.repository) | Repository to use for the ApplicationSet controller | +| applicationSet.image.tag | string | `""` (defaults to global.image.tag) | Tag to use for the ApplicationSet controller | +| applicationSet.imagePullSecrets | list | `[]` (defaults to global.imagePullSecrets) | If defined, uses a Secret to pull an image from a private Docker registry or repository. | +| applicationSet.initContainers | list | `[]` | Init containers to add to the ApplicationSet controller pod | +| applicationSet.livenessProbe.enabled | bool | `false` | Enable Kubernetes liveness probe for ApplicationSet controller | +| applicationSet.livenessProbe.failureThreshold | int | `3` | Minimum consecutive failures for the [probe] to be considered failed after having succeeded | +| applicationSet.livenessProbe.initialDelaySeconds | int | `10` | Number of seconds after the container has started before [probe] is initiated | +| applicationSet.livenessProbe.periodSeconds | int | `10` | How often (in seconds) to perform the [probe] | +| applicationSet.livenessProbe.successThreshold | int | `1` | Minimum consecutive successes for the [probe] to be considered successful after having failed | +| applicationSet.livenessProbe.timeoutSeconds | int | `1` | Number of seconds after which the [probe] times out | +| applicationSet.metrics.enabled | bool | `false` | Deploy metrics service | +| applicationSet.metrics.service.annotations | object | `{}` | Metrics service annotations | +| applicationSet.metrics.service.labels | object | `{}` | Metrics service labels | +| applicationSet.metrics.service.portName | string | `"http-metrics"` | Metrics service port name | +| applicationSet.metrics.service.servicePort | int | `8085` | Metrics service port | +| applicationSet.metrics.serviceMonitor.additionalLabels | object | `{}` | Prometheus ServiceMonitor labels | +| applicationSet.metrics.serviceMonitor.annotations | object | `{}` | Prometheus ServiceMonitor annotations | +| applicationSet.metrics.serviceMonitor.enabled | bool | `false` | Enable a prometheus ServiceMonitor | +| applicationSet.metrics.serviceMonitor.interval | string | `"30s"` | Prometheus ServiceMonitor interval | +| applicationSet.metrics.serviceMonitor.metricRelabelings | list | `[]` | Prometheus [MetricRelabelConfigs] to apply to samples before ingestion | +| applicationSet.metrics.serviceMonitor.namespace | string | `""` | Prometheus ServiceMonitor namespace | +| applicationSet.metrics.serviceMonitor.relabelings | list | `[]` | Prometheus [RelabelConfigs] to apply to samples before scraping | +| applicationSet.metrics.serviceMonitor.scheme | string | `""` | Prometheus ServiceMonitor scheme | +| applicationSet.metrics.serviceMonitor.selector | object | `{}` | Prometheus ServiceMonitor selector | +| applicationSet.metrics.serviceMonitor.tlsConfig | object | `{}` | Prometheus ServiceMonitor tlsConfig | +| applicationSet.name | string | `"applicationset-controller"` | ApplicationSet controller name string | +| applicationSet.nodeSelector | object | `{}` (defaults to global.nodeSelector) | [Node selector] | +| applicationSet.pdb.annotations | object | `{}` | Annotations to be added to ApplicationSet controller pdb | +| applicationSet.pdb.enabled | bool | `false` | Deploy a [PodDisruptionBudget] for the ApplicationSet controller | +| applicationSet.pdb.labels | object | `{}` | Labels to be added to ApplicationSet controller pdb | +| applicationSet.pdb.maxUnavailable | string | `""` | Number of pods that are unavailable after eviction as number or percentage (eg.: 50%). | +| applicationSet.pdb.minAvailable | string | `""` (defaults to 0 if not specified) | Number of pods that are available after eviction as number or percentage (eg.: 50%) | +| applicationSet.podAnnotations | object | `{}` | Annotations for the ApplicationSet controller pods | +| applicationSet.podLabels | object | `{}` | Labels for the ApplicationSet controller pods | +| applicationSet.priorityClassName | string | `""` (defaults to global.priorityClassName) | Priority class for the ApplicationSet controller pods | +| applicationSet.readinessProbe.enabled | bool | `false` | Enable Kubernetes liveness probe for ApplicationSet controller | +| applicationSet.readinessProbe.failureThreshold | int | `3` | Minimum consecutive failures for the [probe] to be considered failed after having succeeded | +| applicationSet.readinessProbe.initialDelaySeconds | int | `10` | Number of seconds after the container has started before [probe] is initiated | +| applicationSet.readinessProbe.periodSeconds | int | `10` | How often (in seconds) to perform the [probe] | +| applicationSet.readinessProbe.successThreshold | int | `1` | Minimum consecutive successes for the [probe] to be considered successful after having failed | +| applicationSet.readinessProbe.timeoutSeconds | int | `1` | Number of seconds after which the [probe] times out | +| applicationSet.replicaCount | int | `1` | The number of ApplicationSet controller pods to run | +| applicationSet.resources | object | `{}` | Resource limits and requests for the ApplicationSet controller pods. | +| applicationSet.service.annotations | object | `{}` | ApplicationSet service annotations | +| applicationSet.service.labels | object | `{}` | ApplicationSet service labels | +| applicationSet.service.port | int | `7000` | ApplicationSet service port | +| applicationSet.service.portName | string | `"webhook"` | ApplicationSet service port name | +| applicationSet.serviceAccount.annotations | object | `{}` | Annotations applied to created service account | +| applicationSet.serviceAccount.automountServiceAccountToken | bool | `true` | Automount API credentials for the Service Account | +| applicationSet.serviceAccount.create | bool | `true` | Create ApplicationSet controller service account | +| applicationSet.serviceAccount.labels | object | `{}` | Labels applied to created service account | +| applicationSet.serviceAccount.name | string | `"argocd-applicationset-controller"` | ApplicationSet controller service account name | +| applicationSet.tolerations | list | `[]` (defaults to global.tolerations) | [Tolerations] for use with node taints | +| applicationSet.topologySpreadConstraints | list | `[]` (defaults to global.topologySpreadConstraints) | Assign custom [TopologySpreadConstraints] rules to the ApplicationSet controller | +| applicationSet.webhook.ingress.annotations | object | `{}` | Additional ingress annotations | +| applicationSet.webhook.ingress.enabled | bool | `false` | Enable an ingress resource for Webhooks | +| applicationSet.webhook.ingress.extraPaths | list | `[]` | Additional ingress paths | +| applicationSet.webhook.ingress.hosts | list | `[]` | List of ingress hosts | +| applicationSet.webhook.ingress.ingressClassName | string | `""` | Defines which ingress ApplicationSet controller will implement the resource | +| applicationSet.webhook.ingress.labels | object | `{}` | Additional ingress labels | +| applicationSet.webhook.ingress.pathType | string | `"Prefix"` | Ingress path type. One of `Exact`, `Prefix` or `ImplementationSpecific` | +| applicationSet.webhook.ingress.paths | list | `["/api/webhook"]` | List of ingress paths | +| applicationSet.webhook.ingress.tls | list | `[]` | Ingress TLS configuration | + +## Notifications + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| notifications.affinity | object | `{}` (defaults to global.affinity preset) | Assign custom [affinity] rules | +| notifications.argocdUrl | string | `nil` | Argo CD dashboard url; used in place of {{.context.argocdUrl}} in templates | +| notifications.cm.create | bool | `true` | Whether helm chart creates notifications controller config map | +| notifications.containerPorts.metrics | int | `9001` | Metrics container port | +| notifications.containerSecurityContext | object | See [values.yaml] | Notification controller container-level security Context | +| notifications.context | object | `{}` | Define user-defined context | +| notifications.deploymentAnnotations | object | `{}` | Annotations to be applied to the notifications controller Deployment | +| notifications.dnsConfig | object | `{}` | [DNS configuration] | +| notifications.dnsPolicy | string | `"ClusterFirst"` | Alternative DNS policy for notifications controller Pods | +| notifications.enabled | bool | `true` | Enable notifications controller | +| notifications.extraArgs | list | `[]` | Extra arguments to provide to the notifications controller | +| notifications.extraContainers | list | `[]` | Additional containers to be added to the notifications controller pod | +| notifications.extraEnv | list | `[]` | Additional container environment variables | +| notifications.extraEnvFrom | list | `[]` (See [values.yaml]) | envFrom to pass to the notifications controller | +| notifications.extraVolumeMounts | list | `[]` | List of extra mounts to add (normally used with extraVolumes) | +| notifications.extraVolumes | list | `[]` | List of extra volumes to add | +| notifications.image.imagePullPolicy | string | `""` (defaults to global.image.imagePullPolicy) | Image pull policy for the notifications controller | +| notifications.image.repository | string | `""` (defaults to global.image.repository) | Repository to use for the notifications controller | +| notifications.image.tag | string | `""` (defaults to global.image.tag) | Tag to use for the notifications controller | +| notifications.imagePullSecrets | list | `[]` (defaults to global.imagePullSecrets) | Secrets with credentials to pull images from a private registry | +| notifications.initContainers | list | `[]` | Init containers to add to the notifications controller pod | +| notifications.logFormat | string | `""` (defaults to global.logging.format) | Notifications controller log format. Either `text` or `json` | +| notifications.logLevel | string | `""` (defaults to global.logging.level) | Notifications controller log level. One of: `debug`, `info`, `warn`, `error` | +| notifications.metrics.enabled | bool | `false` | Enables prometheus metrics server | +| notifications.metrics.port | int | `9001` | Metrics port | +| notifications.metrics.service.annotations | object | `{}` | Metrics service annotations | +| notifications.metrics.service.labels | object | `{}` | Metrics service labels | +| notifications.metrics.service.portName | string | `"http-metrics"` | Metrics service port name | +| notifications.metrics.serviceMonitor.additionalLabels | object | `{}` | Prometheus ServiceMonitor labels | +| notifications.metrics.serviceMonitor.annotations | object | `{}` | Prometheus ServiceMonitor annotations | +| notifications.metrics.serviceMonitor.enabled | bool | `false` | Enable a prometheus ServiceMonitor | +| notifications.metrics.serviceMonitor.metricRelabelings | list | `[]` | Prometheus [MetricRelabelConfigs] to apply to samples before ingestion | +| notifications.metrics.serviceMonitor.relabelings | list | `[]` | Prometheus [RelabelConfigs] to apply to samples before scraping | +| notifications.metrics.serviceMonitor.scheme | string | `""` | Prometheus ServiceMonitor scheme | +| notifications.metrics.serviceMonitor.selector | object | `{}` | Prometheus ServiceMonitor selector | +| notifications.metrics.serviceMonitor.tlsConfig | object | `{}` | Prometheus ServiceMonitor tlsConfig | +| notifications.name | string | `"notifications-controller"` | Notifications controller name string | +| notifications.nodeSelector | object | `{}` (defaults to global.nodeSelector) | [Node selector] | +| notifications.notifiers | object | See [values.yaml] | Configures notification services such as slack, email or custom webhook | +| notifications.pdb.annotations | object | `{}` | Annotations to be added to notifications controller pdb | +| notifications.pdb.enabled | bool | `false` | Deploy a [PodDisruptionBudget] for the notifications controller | +| notifications.pdb.labels | object | `{}` | Labels to be added to notifications controller pdb | +| notifications.pdb.maxUnavailable | string | `""` | Number of pods that are unavailable after eviction as number or percentage (eg.: 50%). | +| notifications.pdb.minAvailable | string | `""` (defaults to 0 if not specified) | Number of pods that are available after eviction as number or percentage (eg.: 50%) | +| notifications.podAnnotations | object | `{}` | Annotations to be applied to the notifications controller Pods | +| notifications.podLabels | object | `{}` | Labels to be applied to the notifications controller Pods | +| notifications.priorityClassName | string | `""` (defaults to global.priorityClassName) | Priority class for the notifications controller pods | +| notifications.resources | object | `{}` | Resource limits and requests for the notifications controller | +| notifications.secret.annotations | object | `{}` | key:value pairs of annotations to be added to the secret | +| notifications.secret.create | bool | `true` | Whether helm chart creates notifications controller secret | +| notifications.secret.items | object | `{}` | Generic key:value pairs to be inserted into the secret | +| notifications.serviceAccount.annotations | object | `{}` | Annotations applied to created service account | +| notifications.serviceAccount.automountServiceAccountToken | bool | `true` | Automount API credentials for the Service Account | +| notifications.serviceAccount.create | bool | `true` | Create notifications controller service account | +| notifications.serviceAccount.labels | object | `{}` | Labels applied to created service account | +| notifications.serviceAccount.name | string | `"argocd-notifications-controller"` | Notification controller service account name | +| notifications.subscriptions | list | `[]` | Contains centrally managed global application subscriptions | +| notifications.templates | object | `{}` | The notification template is used to generate the notification content | +| notifications.tolerations | list | `[]` (defaults to global.tolerations) | [Tolerations] for use with node taints | +| notifications.topologySpreadConstraints | list | `[]` (defaults to global.topologySpreadConstraints) | Assign custom [TopologySpreadConstraints] rules to the application controller | +| notifications.triggers | object | `{}` | The trigger defines the condition when the notification should be sent | + +---------------------------------------------- +Autogenerated from chart metadata using [helm-docs](https://github.com/norwoodj/helm-docs) + +[Argo CD RBAC policy]: https://argo-cd.readthedocs.io/en/stable/operator-manual/rbac/ +[affinity]: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ +[BackendConfigSpec]: https://cloud.google.com/kubernetes-engine/docs/concepts/backendconfig#backendconfigspec_v1beta1_cloudgooglecom +[CSS styles]: https://argo-cd.readthedocs.io/en/stable/operator-manual/custom-styles/ +[changelog]: https://artifacthub.io/packages/helm/argo/argo-cd?modal=changelog +[DNS configuration]: https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/ +[external cluster credentials]: https://argo-cd.readthedocs.io/en/stable/operator-manual/declarative-setup/#clusters +[FrontendConfigSpec]: https://cloud.google.com/kubernetes-engine/docs/how-to/ingress-features#configuring_ingress_features_through_frontendconfig_parameters +[declarative setup]: https://argo-cd.readthedocs.io/en/stable/operator-manual/declarative-setup +[gRPC-ingress]: https://argo-cd.readthedocs.io/en/stable/operator-manual/ingress/ +[GnuPG]: https://argo-cd.readthedocs.io/en/stable/user-guide/gpg-verification/ +[HPA]: https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/ +[MetricRelabelConfigs]: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#metric_relabel_configs +[Node selector]: https://kubernetes.io/docs/user-guide/node-selection/ +[PodDisruptionBudget]: https://kubernetes.io/docs/concepts/workloads/pods/disruptions/#pod-disruption-budgets +[probe]: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#container-probes +[RelabelConfigs]: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config +[Tolerations]: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ +[TopologySpreadConstraints]: https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ +[values.yaml]: values.yaml +[v2.2 to 2.3 upgrade instructions]: https://github.com/argoproj/argo-cd/blob/v2.3.0/docs/operator-manual/upgrading/2.2-2.3.md diff --git a/helm/argo-cd/README.md.gotmpl b/helm/argo-cd/README.md.gotmpl new file mode 100644 index 0000000..945bab7 --- /dev/null +++ b/helm/argo-cd/README.md.gotmpl @@ -0,0 +1,548 @@ +# Argo CD Chart + +A Helm chart for Argo CD, a declarative, GitOps continuous delivery tool for Kubernetes. + +Source code can be found here: + +{{ template "chart.sourcesList" . }} + +This is a **community maintained** chart. This chart installs [argo-cd](https://argo-cd.readthedocs.io/en/stable/), a declarative, GitOps continuous delivery tool for Kubernetes. + +The default installation is intended to be similar to the provided Argo CD [releases](https://github.com/argoproj/argo-cd/releases). + +If you want to avoid including sensitive information unencrypted (clear text) in your version control, make use of the [declarative setup] of Argo CD. +For instance, rather than adding repositories and their keys in your Helm values, you could deploy [SealedSecrets](https://github.com/bitnami-labs/sealed-secrets) with contents as seen in this [repositories section](https://argo-cd.readthedocs.io/en/stable/operator-manual/declarative-setup/#repositories) or any other secrets manager service (i.e. HashiCorp Vault, AWS/GCP Secrets Manager, etc.). + +## High Availability + +This chart installs the non-HA version of Argo CD by default. If you want to run Argo CD in HA mode, you can use one of the example values in the next sections. +Please also have a look into the upstream [Operator Manual regarding High Availability](https://argo-cd.readthedocs.io/en/stable/operator-manual/high_availability/) to understand how scaling of Argo CD works in detail. + +> **Warning:** +> You need at least 3 worker nodes as the HA mode of redis enforces Pods to run on separate nodes. + +### HA mode with autoscaling + +```yaml +redis-ha: + enabled: true + +controller: + replicas: 1 + +server: + autoscaling: + enabled: true + minReplicas: 2 + +repoServer: + autoscaling: + enabled: true + minReplicas: 2 + +applicationSet: + replicaCount: 2 +``` + +### HA mode without autoscaling + +```yaml +redis-ha: + enabled: true + +controller: + replicas: 1 + +server: + replicas: 2 + +repoServer: + replicas: 2 + +applicationSet: + replicaCount: 2 +``` + +### Synchronizing Changes from Original Repository + +In the original [Argo CD repository](https://github.com/argoproj/argo-cd/) an [`manifests/install.yaml`](https://github.com/argoproj/argo-cd/blob/master/manifests/install.yaml) is generated using `kustomize`. It's the basis for the installation as [described in the docs](https://argo-cd.readthedocs.io/en/stable/getting_started/#1-install-argo-cd). + +When installing Argo CD using this helm chart the user should have a similar experience and configuration rolled out. Hence, it makes sense to try to achieve a similar output of rendered `.yaml` resources when calling `helm template` using the default settings in `values.yaml`. + +To update the templates and default settings in `values.yaml` it may come in handy to look up the diff of the `manifests/install.yaml` between two versions accordingly. This can either be done directly via github and look for `manifests/install.yaml`: + +https://github.com/argoproj/argo-cd/compare/v1.8.7...v2.0.0#files_bucket + +Or you clone the repository and do a local `git-diff`: + +```bash +git clone https://github.com/argoproj/argo-cd.git +cd argo-cd +git diff v1.8.7 v2.0.0 -- manifests/install.yaml +``` + +Changes in the `CustomResourceDefinition` resources shall be fixed easily by copying 1:1 from the [`manifests/crds` folder](https://github.com/argoproj/argo-cd/tree/master/manifests/crds) into this [`charts/argo-cd/templates/crds` folder](https://github.com/argoproj/argo-helm/tree/master/charts/argo-cd/templates/crds). + +### Custom resource definitions + +Some users would prefer to install the CRDs _outside_ of the chart. You can disable the CRD installation of this chart by using `--set crds.install=false` when installing the chart. + +Helm cannot upgrade custom resource definitions in the `/crds` folder [by design](https://helm.sh/docs/chart_best_practices/custom_resource_definitions/#some-caveats-and-explanations). Starting with 5.2.0, the CRDs have been moved to `/templates` to address this design decision. + +If you are using Argo CD chart version prior to 5.2.0 or have elected to manage the Argo CD CRDs outside of the chart, please use `kubectl` to upgrade CRDs manually from [templates/crds](templates/crds/) folder or via the manifests from the upstream project repo: + +```bash +kubectl apply -k "https://github.com/argoproj/argo-cd/manifests/crds?ref=" + +# Eg. version v2.4.9 +kubectl apply -k "https://github.com/argoproj/argo-cd/manifests/crds?ref=v2.4.9" +``` + +## Changelog + +For full list of changes please check ArtifactHub [changelog]. + +Highlighted versions provide information about additional steps that should be performed by user when upgrading to newer version. + +### 5.24.0 + +This versions adds additional global parameters for scheduling (`nodeSelector`, `tolerations`, `topologySpreadConstraints`). +Default `global.affinity` rules can be disabled when `none` value is used for the preset. + +### 5.22.0 + +This versions adds `global.affinity` options that are used as a presets. Override on component level works as before and replaces the default preset completely. + +### 5.19.0 + +This version consolidates config for custom repository TLS certificates and SSH known hosts. If you provide this values please move them into new `configs.ssh` and `configs.tls` sections. +You can also use new option `configs.ssh.extraHosts` to configure your SSH keys without maintaing / overwritting keys for public Git repositories. + +### 5.13.0 + +This version reduces history limit for Argo CD deployment replicas to 3 to provide more visibility for Argo CD deployments that manage itself. If you need more deployment revisions for rollbacks set `global.revisionHistoryLimit` parameter. + +### 5.12.0 + +If Argo CD is managing termination of TLS and you are using `configs.secret.argocdServerTlsConfig` option to provide custom TLS configuration for this chart, please use `server.certificate` or `server.certificateSecret` instead. +For the secrets for tls termination, please use a secret named `argocd-server-tls` instead of `argocd-secret`. +For the technical details please check the [Argo CD documentation](https://argo-cd.readthedocs.io/en/stable/operator-manual/tls/#tls-certificates-used-by-argocd-server). When transitioning from the one secret to the other pay attention to `tls.key` and `tls.crt` keys. + +### 5.10.0 + +This version hardens security by configuring default container security contexts and adds hard requirement for Kubernetes 1.22+ to work properly. +The change aligns chart with officially [supported versions](https://argo-cd.readthedocs.io/en/release-2.5/operator-manual/installation/#supported-versions) by upstream project. + +### 5.7.0 + +This version introcudes new `configs.cm` and `configs.rbac` sections that replaces `server.config` and `server.rbacConfig` respectively. +Please move your current configuration to the new place. The Argo CD RBAC config now also sets defaults in the `argocd-rbac-cm`. +If you have manually created this ConfigMap please ensure templating is disabled so you will not lose your changes. + +### 5.5.20 + +This version moved API version templates into dedicated helper. If you are using these in your umbrella +chart please migrate your templates to pattern `argo-cd.apiVersion.`. + +### 5.5.0 + +This version introduces new `configs.params` section that replaces command line arguments for containers. +Please refer to documentation in values.yaml for migrating the configuration. + +### 5.2.0 + +Custom resource definitions were moved to `templates` folder so they can be managed by Helm. + +To adopt already created CRDs, please use following command: + +```bash +YOUR_ARGOCD_NAMESPACE="" # e.g. argo-cd +YOUR_ARGOCD_RELEASENAME="" # e.g. argo-cd + +for crd in "applications.argoproj.io" "applicationsets.argoproj.io" "argocdextensions.argoproj.io" "appprojects.argoproj.io"; do + kubectl label --overwrite crd $crd app.kubernetes.io/managed-by=Helm + kubectl annotate --overwrite crd $crd meta.helm.sh/release-namespace="$YOUR_ARGOCD_NAMESPACE" + kubectl annotate --overwrite crd $crd meta.helm.sh/release-name="$YOUR_ARGOCD_RELEASENAME" +done +``` + +### 5.0.0 + +This version **removes support for**: + +- deprecated repository credentials (parameter `configs.repositoryCredentials`) +- option to run application controller as a Deployment +- the parameters `server.additionalApplications` and `server.additionalProjects` + +Please carefully read the following section if you are using these parameters! + +In order to upgrade Applications and Projects safely against CRDs' upgrade, `server.additionalApplications` and `server.additionalProjects` are moved to [argocd-apps](../argocd-apps). + +If you are using `server.additionalApplications` or `server.additionalProjects`, you can adopt to [argocd-apps](../argocd-apps) as below: + +1. Add [helm.sh/resource-policy annotation](https://helm.sh/docs/howto/charts_tips_and_tricks/#tell-helm-not-to-uninstall-a-resource) to avoid resources being removed by upgrading Helm chart + +You can keep your existing CRDs by adding `"helm.sh/resource-policy": keep` on `additionalAnnotations`, under `server.additionalApplications` and `server.additionalProjects` blocks, and running `helm upgrade`. + +e.g: + +```yaml +server: + additionalApplications: + - name: guestbook + namespace: argocd + additionalLabels: {} + additionalAnnotations: + "helm.sh/resource-policy": keep # <-- add this + finalizers: + - resources-finalizer.argocd.argoproj.io + project: guestbook + source: + repoURL: https://github.com/argoproj/argocd-example-apps.git + targetRevision: HEAD + path: guestbook + directory: + recurse: true + destination: + server: https://kubernetes.default.svc + namespace: guestbook + syncPolicy: + automated: + prune: false + selfHeal: false + ignoreDifferences: + - group: apps + kind: Deployment + jsonPointers: + - /spec/replicas + info: + - name: url + value: https://argoproj.github.io/ +``` + +You can also keep your existing CRDs by running the following scripts. + +```bash +# keep Applications +for app in "guestbook"; do + kubectl annotate --overwrite application $app helm.sh/resource-policy=keep +done + +# keep Projects +for project in "guestbook"; do + kubectl annotate --overwrite appproject $project helm.sh/resource-policy=keep +done +``` + +2. Upgrade argo-cd Helm chart to v5.0.0 + +3. Remove keep [helm.sh/resource-policy annotation](https://helm.sh/docs/howto/charts_tips_and_tricks/#tell-helm-not-to-uninstall-a-resource) + +```bash +# delete annotations from Applications +for app in "guestbook"; do + kubectl annotate --overwrite application $app helm.sh/resource-policy- +done + +# delete annotations from Projects +for project in "guestbook"; do + kubectl annotate --overwrite appproject $project helm.sh/resource-policy- +done +``` + +4. Adopt existing resources to [argocd-apps](../argocd-apps) + +### 4.9.0 + +This version starts to use upstream image with applicationset binary. Start command was changed from `applicationset-controller` to `argocd-applicationset-controller` + +### 4.3.* + +With this minor version, the notification notifier's `service.slack` is no longer configured by default. + +### 4.0.0 and above + +This helm chart version deploys Argo CD v2.3. The Argo CD Notifications and ApplicationSet are part of Argo CD now. You no longer need to install them separately. The Notifications and ApplicationSet components **are bundled into default** Argo CD installation. +Please read the [v2.2 to 2.3 upgrade instructions] in the upstream repository. + +### 3.13.0 + +This release removes the flag `--staticassets` from argocd server as it has been dropped upstream. If this flag needs to be enabled e.g for older releases of Argo CD, it can be passed via the `server.extraArgs` field + +### 3.10.2 + +Argo CD has recently deprecated the flag `--staticassets` and from chart version `3.10.2` has been disabled by default +It can be re-enabled by setting `server.staticAssets.enabled` to true + +### 3.8.1 + +This bugfix version potentially introduces a rename (and recreation) of one or more ServiceAccounts. It _only happens_ when you use one of these customization: + +```yaml +# Case 1) - only happens when you do not specify a custom name (repoServer.serviceAccount.name) +repoServer: + serviceAccount: + create: true + +# Case 2) +controller: + serviceAccount: + name: "" # or + +# Case 3) +dex: + serviceAccount: + name: "" # or + +# Case 4) +server: + serviceAccount: + name: "" # or +``` + +Please check if you are affected by one of these cases **before you upgrade**, especially when you use **cloud IAM roles for service accounts.** (eg. IRSA on AWS or Workload Identity for GKE) + +### 3.2.* + +With this minor version we introduced the evaluation for the ingress manifest (depending on the capabilities version), See [Pull Request](https://github.com/argoproj/argo-helm/pull/637). +[Issue 703](https://github.com/argoproj/argo-helm/issues/703) reported that the capabilities evaluation is **not handled correctly when deploying the chart via an Argo CD instance**, +especially deploying on clusters running a cluster version prior to `1.19` (which misses `Ingress` on apiVersion `networking.k8s.io/v1`). + +If you are running a cluster version prior to `1.19` you can avoid this issue by directly installing chart version `3.6.0` and setting `kubeVersionOverride` like: + +```yaml +kubeVersionOverride: "1.18.0" +``` + +Then you should no longer encounter this issue. + + +### 3.0.0 and above + +Helm apiVersion switched to `v2`. Requires Helm `3.0.0` or above to install. [Read More](https://helm.sh/blog/migrate-from-helm-v2-to-helm-v3/) on how to migrate your release from Helm 2 to Helm 3. + +### 2.14.7 and above + +The `matchLabels` key in the Argo CD Application Controller is no longer hard-coded. Note that labels are immutable so caution should be exercised when making changes to this resource. + +### 2.10.x to 2.11.0 + +The application controller is now available as a `StatefulSet` when the `controller.enableStatefulSet` flag is set to true. Depending on your Helm deployment this may be a downtime or breaking change if enabled when using HA and will become the default in 3.x. + +### 1.8.7 to 2.x.x + +`controller.extraArgs`, `repoServer.extraArgs` and `server.extraArgs` are now arrays of strings instead of a map + +What was + +```yaml +server: + extraArgs: + insecure: "" +``` + +is now + +```yaml +server: + extraArgs: + - --insecure +``` + +## Prerequisites + +- {{ template "chart.kubeVersionLine" . }} +- Helm v3.0.0+ + +## Installing the Chart + +To install the chart with the release name `my-release`: + +```console +$ helm repo add argo https://argoproj.github.io/argo-helm +"argo" has been added to your repositories + +$ helm install my-release argo/argo-cd +NAME: my-release +... +``` + +## General parameters + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +{{- range .Values }} + {{- if not (or (hasPrefix "global" .Key) (hasPrefix "configs" .Key) (hasPrefix "controller" .Key) (hasPrefix "repoServer" .Key) (hasPrefix "server" .Key) (hasPrefix "applicationSet" .Key) (hasPrefix "notifications" .Key) (hasPrefix "dex" .Key) (hasPrefix "redis" .Key) (hasPrefix "externalRedis" .Key) ) }} +| {{ .Key }} | {{ .Type }} | {{ if .Default }}{{ .Default }}{{ else }}{{ .AutoDefault }}{{ end }} | {{ if .Description }}{{ .Description }}{{ else }}{{ .AutoDescription }}{{ end }} | + {{- end }} +{{- end }} + +## Global Configs + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +{{- range .Values }} + {{- if hasPrefix "global" .Key }} +| {{ .Key }} | {{ .Type }} | {{ if .Default }}{{ .Default }}{{ else }}{{ .AutoDefault }}{{ end }} | {{ if .Description }}{{ .Description }}{{ else }}{{ .AutoDescription }}{{ end }} | + {{- end }} +{{- end }} + +## Argo CD Configs + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +{{- range .Values }} + {{- if hasPrefix "configs" .Key }} +| {{ .Key }} | {{ .Type }} | {{ if .Default }}{{ .Default }}{{ else }}{{ .AutoDefault }}{{ end }} | {{ if .Description }}{{ .Description }}{{ else }}{{ .AutoDescription }}{{ end }} | + {{- end }} +{{- end }} + +## Argo CD Controller + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +{{- range .Values }} + {{- if hasPrefix "controller" .Key }} +| {{ .Key }} | {{ .Type }} | {{ if .Default }}{{ .Default }}{{ else }}{{ .AutoDefault }}{{ end }} | {{ if .Description }}{{ .Description }}{{ else }}{{ .AutoDescription }}{{ end }} | + {{- end }} +{{- end }} + +## Argo Repo Server + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +{{- range .Values }} + {{- if hasPrefix "repoServer" .Key }} +| {{ .Key }} | {{ .Type }} | {{ if .Default }}{{ .Default }}{{ else }}{{ .AutoDefault }}{{ end }} | {{ if .Description }}{{ .Description }}{{ else }}{{ .AutoDescription }}{{ end }} | + {{- end }} +{{- end }} + +## Argo Server + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +{{- range .Values }} + {{- if and (hasPrefix "server" .Key) (not (hasPrefix "server.additional" .Key)) }} +| {{ .Key }} | {{ .Type }} | {{ if .Default }}{{ .Default }}{{ else }}{{ .AutoDefault }}{{ end }} | {{ if .Description }}{{ .Description }}{{ else }}{{ .AutoDescription }}{{ end }} | + {{- end }} +{{- end }} + +### Using AWS ALB Ingress Controller With GRPC + +If you are using an AWS ALB Ingress controller, you will need to set `server.ingressGrpc.isAWSALB` to `true`. This will create a second service with the annotation `alb.ingress.kubernetes.io/backend-protocol-version: HTTP2` and modify the server ingress to add a condition annotation to route GRPC traffic to the new service. + +Example: + +```yaml +server: + ingress: + enabled: true + annotations: + alb.ingress.kubernetes.io/backend-protocol: HTTPS + alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}]' + alb.ingress.kubernetes.io/scheme: internal + alb.ingress.kubernetes.io/target-type: ip + ingressGrpc: + enabled: true + isAWSALB: true + awsALB: + serviceType: ClusterIP +``` + +## Dex + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +{{- range .Values }} + {{- if hasPrefix "dex" .Key }} +| {{ .Key }} | {{ .Type }} | {{ if .Default }}{{ .Default }}{{ else }}{{ .AutoDefault }}{{ end }} | {{ if .Description }}{{ .Description }}{{ else }}{{ .AutoDescription }}{{ end }} | + {{- end }} +{{- end }} + +## Redis + +### Option 1 - Single Redis instance (default option) + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +{{- range .Values }} + {{- if hasPrefix "redis." .Key }} +| {{ .Key }} | {{ .Type }} | {{ if .Default }}{{ .Default }}{{ else }}{{ .AutoDefault }}{{ end }} | {{ if .Description }}{{ .Description }}{{ else }}{{ .AutoDescription }}{{ end }} | + {{- end }} +{{- end }} + +### Option 2 - Redis HA + +This option uses the following third-party chart to bootstrap a clustered Redis: https://github.com/DandyDeveloper/charts/tree/master/charts/redis-ha. +For all available configuration options, please read upstream README and/or chart source. +The main options are listed here: + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +{{- range .Values }} + {{- if hasPrefix "redis-ha" .Key }} +| {{ .Key }} | {{ .Type }} | {{ if .Default }}{{ .Default }}{{ else }}{{ .AutoDefault }}{{ end }} | {{ if .Description }}{{ .Description }}{{ else }}{{ .AutoDescription }}{{ end }} | + {{- end }} +{{- end }} +| redis-ha.exporter.image | string | `nil` (follows subchart default) | Exporter image | +| redis-ha.exporter.tag | string | `nil` (follows subchart default) | Exporter tag | +| redis-ha.haproxy.image.repository | string | `nil` (follows subchart default) | HAProxy Image Repository | +| redis-ha.haproxy.image.tag | string | `nil` (follows subchart default) | HAProxy Image Tag | +| redis-ha.image.repository | string | `nil` (follows subchart default) | Redis image repository | + +### Option 3 - External Redis + +If you want to use an existing Redis (eg. a managed service from a cloud provider), you can use these parameters: + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +{{- range .Values }} + {{- if hasPrefix "externalRedis" .Key }} +| {{ .Key }} | {{ .Type }} | {{ if .Default }}{{ .Default }}{{ else }}{{ .AutoDefault }}{{ end }} | {{ if .Description }}{{ .Description }}{{ else }}{{ .AutoDescription }}{{ end }} | + {{- end }} +{{- end }} + +## ApplicationSet + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +{{- range .Values }} + {{- if hasPrefix "applicationSet" .Key }} +| {{ .Key }} | {{ .Type }} | {{ if .Default }}{{ .Default }}{{ else }}{{ .AutoDefault }}{{ end }} | {{ if .Description }}{{ .Description }}{{ else }}{{ .AutoDescription }}{{ end }} | + {{- end }} +{{- end }} + +## Notifications + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +{{- range .Values }} + {{- if hasPrefix "notifications" .Key }} +| {{ .Key }} | {{ .Type }} | {{ if .Default }}{{ .Default }}{{ else }}{{ .AutoDefault }}{{ end }} | {{ if .Description }}{{ .Description }}{{ else }}{{ .AutoDescription }}{{ end }} | + {{- end }} +{{- end }} + +---------------------------------------------- +Autogenerated from chart metadata using [helm-docs](https://github.com/norwoodj/helm-docs) + +[Argo CD RBAC policy]: https://argo-cd.readthedocs.io/en/stable/operator-manual/rbac/ +[affinity]: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ +[BackendConfigSpec]: https://cloud.google.com/kubernetes-engine/docs/concepts/backendconfig#backendconfigspec_v1beta1_cloudgooglecom +[CSS styles]: https://argo-cd.readthedocs.io/en/stable/operator-manual/custom-styles/ +[changelog]: https://artifacthub.io/packages/helm/argo/argo-cd?modal=changelog +[DNS configuration]: https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/ +[external cluster credentials]: https://argo-cd.readthedocs.io/en/stable/operator-manual/declarative-setup/#clusters +[FrontendConfigSpec]: https://cloud.google.com/kubernetes-engine/docs/how-to/ingress-features#configuring_ingress_features_through_frontendconfig_parameters +[declarative setup]: https://argo-cd.readthedocs.io/en/stable/operator-manual/declarative-setup +[gRPC-ingress]: https://argo-cd.readthedocs.io/en/stable/operator-manual/ingress/ +[GnuPG]: https://argo-cd.readthedocs.io/en/stable/user-guide/gpg-verification/ +[HPA]: https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/ +[MetricRelabelConfigs]: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#metric_relabel_configs +[Node selector]: https://kubernetes.io/docs/user-guide/node-selection/ +[PodDisruptionBudget]: https://kubernetes.io/docs/concepts/workloads/pods/disruptions/#pod-disruption-budgets +[probe]: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#container-probes +[RelabelConfigs]: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config +[Tolerations]: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ +[TopologySpreadConstraints]: https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ +[values.yaml]: values.yaml +[v2.2 to 2.3 upgrade instructions]: https://github.com/argoproj/argo-cd/blob/v2.3.0/docs/operator-manual/upgrading/2.2-2.3.md diff --git a/helm/argo-cd/charts/redis-ha-4.22.4.tgz b/helm/argo-cd/charts/redis-ha-4.22.4.tgz new file mode 100644 index 0000000000000000000000000000000000000000..3e66c2449bbbc7ba323cde668c810f371f080626 GIT binary patch literal 30769 zcmV)RK(oIeiwG0|00000|0w_~VMtOiV@ORlOnEsqVl!4SWK%V1T2nbTPgYhoO;>Dc zVQyr3R8em|NM&qo0PMZ{TjMsmIDUT4U!hN!vjZ)5!ey8?d#2}5pdFqv42Ll7*{9P5 z#a0q6j^#=+kOJSo{rl)<%eL$!+~%@)pY0G^*H^FJyIxTgV&;uuXJ-s4_or|Y{l`N; z-EOzLwYe$(?RLB6f7jMG*8XE{b7OOJed|?sWBot6YwKHEul@scAABT^CuJPc|LESk zukz%+kOwCCS40^maSvRqw_uWFKVSP@f3p=L7EqjU`RZhh8F-7L2?zwbfP|6@93loF z7~|16ngVzMaRdhu0>=Wg0G=cfnxL3N(E_-{eB1&6f(c|C(GH8?1p)zyhj^4yRR+c( zNEu?Fk7ABv6aj`q6hO+rkWes$I3gE_f(eY_NVeS?lL_j9G3QCI(~&6cW728iKnz;E zX1z`)O(FtA{}P|$2?{av2_1FBuSERnpt!@w>15E^>TC@w|Q z!3d^^{m)3e^8+$z0T4qmBc?y)6(FP}_9HkQVibjrDj|%+X^1XRL=r?>>ZRG`Ek;rr zAUOg9mJD1Wxr_ybtZyUC$LT<{-`N%I?wWQxa{XCn5RpMgucdyK_2q1aMEC;HZg)$S zJ4IIsp&ZfHg+aSbe|_EGY<=pD@o(~E^j{(@dlUxHO#fePtarO5`oFQZzV%H1pW<0s z0y~=eB0!O%4}hXSQ^Yuvv^c^O%voz`2~af5sO)(kZh`t!nF&ZL@;s60o0ErPG6if(3fT4gQ&cy2h66_=dmtz#m)^I!mawx?~ zG54%EWaq47SQPRS5_$pAw7etQ^JHUQLh%KZa~@&F=~PTvaZLIBD2<}N9u;PQ#L-mp zGphNd9#5-WxCeg!qqPJ)P2bzPGtsY_WV@xNkwiFv48-YVfT(O5!C(x;Qjk~x%oOQ? z4OwL;Wt>d#UkLCq0*phBhH1nQ2MGx+_6iaO{&}DkkT^gIXPrwz&jmM;uQ(-9gedD+ zophE2B=cT8*$YOjm5}gV_S!7{dm18&!ea!(sh%(lJqblKFYy+~A-X~#kb(sRBg8?B zgtU-QG9es=8Y2|X%4&$&Q_iG(0=mEhmt!1^#X6~ifW!dDn9B-2@42d-~x zimRfcHyogr{`bJDrS{VVCW0Ky=rJqX0w8j=ae^4v?d*%)kq<%4IV* z3ei?V1Z)QZNn?J0I+VZH!1kbOx?`ZPyV7v#Cn&%}jF=#ce2gf7W>C5yU}KU-p+Mt+ zBFIrFYqo&?*#n%WNVRq{MhfA`P=cb=5+{NJ`+9|jASN6LG9xyPYE0}j(cCJ4sv#`) zZj7kt7o<#(Y#WjNVH!oUAV-rVf?N(nkx11INjSi9hooE#3Z|S)#8^Z_+eiDN+feK) z7%_ljPCy1qRsAs*0_4LuA?GOWfgy|-l31}93#CaYQg64x5hYiOISddN)aQV}@JATI zI1uCSRE^aN zRt*%{j9yVUn;L7Xct3eeHu8uPnWkV)8B45Tqm%^zjANoK8EVpH`VIh^Bz(GysRffG z5`taKXex~;;Kwu^A->2=X&QSlk&7)_uxB0)vNI?>47!#9>?4E+g4!@GLD1uDPV{R&D|n1F$oa^7g!LpBaMDbOW;>Tr()@c zX(aI}BJs$J@P%0afW$EhBxC^;BpC#d$&m_LN2i)f!ATNHk|Dd!NMgQ6<`#*Hh+HcS zDQ2m;wWyoVNRutK=lC>1J+Pyw<^GX;7iCmiyi(@_3S?T5;KosJVFY?^FeFQd}vvR7_5BO1h2yG-w%g4z%Vkv z0BABmVJL_kB@-b|qzp_Dr#KKoAQxPh`5A@ixeP;kJ+gl}MJTf@2@L`dI(h3}W;fE< zuY0SdoJ;o5Bq{zIU;%{*0tu8hNkd(~U+b=AKNWz)aI+pg@sHvZvc6^mdH^lWLnIjA zkywynH7GHL-vr4Ml8=C;K*LzKV`ijv_SSh)%t1QA7>-8gV);!P;)I#HWfAUzK3yLN4G0glLFkB)Bv+ zI3R1w%GRXbCqn)tH0!6dc{8x%2@-Oqs9u7A{?r3&5&%MlG(5VwOB_|K0(orD89fE8lgQFzz8ZQLqQY^$Rs(U zWQZeVwvi&W$3mE&pj|YCX{7dJ024UC5#|^%Q#hm~F@Jkt``|#6^xw4BQ(^_o+9E?j z14VLaDg{i25-1cB#oq)y8$%jy#~g1Dhhk}`IZT$8z;+m7F(ViOsJ?4i9EP&ha@V3k znAO?Ns#v1L`wK)V4v~N!AWCi1U1xOG#o@GJ0|Lgyu9iJzL%t~re2VaRy0#w-M?gTI zDWOe>b!HHuf_+Zmg>EM|nWzA;7U!5&HA6-4#LyglzyYxgCwLSSibBaVKp+RE)axF& z@ial-Rol4eJQ^danbc7vh#-uo7EnutnUXk4YhtEV9i$u$y5bZrFc=M7vqwOLhbWi^ z5t5b&=HQA=X0>duS$}$2lb&o+h=kcI3wsQ=mgWhHBB_=TDKAO`EMlCws8d1cGmVI? zFhN2!lrlYzL#57>m(vpMh)XoLL^N>K`Pjk1w68#)mj4o&<(`oQu3t| zG4@p**-C^i5QQVnyD|bdZOsOS(j6o~u#loWt;%;)^Vv@U8TD%4sE`#ALr+YrNk*OO zfsh2}i29h6Z2E(gO$X%4SoPQZjZJ^8WXs=XrWVizg7yrqrzVf74WAv2hB58WV zz}CpnyH=qQo|CMI0)c*sFS0vLg15_=(L=PRN`ZOmp| z3&*-qMcgRz*i`uiw2U94OXY_2rC&x`{Vt)LazfFCpqo;fP|C34^#XOzBS8Tyimk@T z;Dz8x-*>xUt=+Qh7+OkL1tF#=;E_;4Bsm-_+9!jw#E(l%CGl2v?o~NXp)cod9nrfo z`w6h35KH#Xi4cA2U?&FZnPE#9^gvti81*$A2-T4)+hqBR(1uw$F|P~yPreZzUhm1< z#t*CUI4sdiAPeK@shmF;0LL9RZm)uNN3aR86SOzD!zmt(5cNznp@)Z__KvY}`wu-)%RF21Nn3#o z4!?k^tyF+Mr;wwOvS2GQv9Bxl=k)_D5>=sk^_c1wOQ%Y4B(}x+m`MN22U)<(I%h-5 zZzkPc%$k5L3rKzVSF2p+Ov$_{(kYT5l;t~9A6nAHZel%~MQ9TYkxS9*Qj9K1ta7DZ z3a#{|CQtYRWs0g0*g&K$>@ng3s*3guVW7NFvS1H%efhttKy1b_pHRK-ma40b+)J=F z&3zHFbuAdSKb*V;%Yt-aiV`S9k3iFyFsAs)=rn34{F0C&xfhU&mH=1VfXG*A$8`c|zcY7L5^1Bb- zOP8!JAml&Onh+k*m6TtQL>7TXLqaD|?92&<5tMGCmswv|S69Fo4#ba_QnWDb30PB- zAR0|`LxJc41zd>GYSS}47Qdib+(WAOtGz>p->Z9xJo4Eo`Pz(Vt1oE*6RS;&F8 zkkurt^j+lS0pt~j_ssI0ttsTod}sQ%%Xik~Ijgql^rX%9qq)3jH9oYe2QBxX+1|5l z#?p!4T+)XsmNr6M4TS;BS2G*AqFUm;4DyK?r>TzeuzlQxy%IQ#=Gx1@q(5o2H0u>3 z?gxY-pAoUONgV6NlT@PzUdm1WQVN=fB-HL+wwgJ?R;3-4lL%2u+D}LbAY*tG%R@$s z$mxZx*-?$iIHj0`sIw#;h$unC~PTMhPx>h z5}mT#;CQsJ=&pLbCtW-8Fq&YADj-tXPlkv}^1L8@YXYOxJml|sfR@*=Rp)x1)A3vZ zzb{=IOJGmMSjk|2AmN?$pk9F-3iH7*t0!p4CBmaI?}1m{{H|Gf< z4l8{YEuKqpIU&6K2>_x4IC|ia@cp=2KplFjG^!eI3xKvYSRQJv8@9~SQmfwmzo_%S zy1hyf0M*sDBLXBq5>mu41E$5cP+|Ec;mzoRW3BZWf%1yLBr8Y7?JN>puz)u3 z!R>9i5=GLuDl7WO>W6;_C#Y1GlY~TMG?j{1ac#$hanZp;qW)U9i2Eco5I#Y4Qkr@b zz?wm(fwnNz=7(Dea$05bLNb9k_65Q6i_rXw#FBOuVo&bw05iRNERlzS0wUxK$pSkq z^RX|#?c|@F4(Yt-a9r0b5mV9$LM)8N3L5|rFt7uqxRK^Y$%c9t3n6OMa=Ri~# zH>f=(Yfhr9`I{T^C`w}#_spP26Y{ve*0KX0%dw7ik&cqr2-@6vOBlBdgcV0hPdPTk zep12mSD2}A@Bq^wok+I?W-LXTQpo_4FlJJpi4-%I4iXXsDP=+`2oMzl4?yt+rbG&9 znWU&gPwZ|@EHBRj0i{jNj@K`S*D6adj}+{b_{pNZVx)>x(~`8K-AmaKN~Jz^jOta5 zXwcBhI5i#F-d1bDrNXjJM^?QLS{{+Q34q|>!?xF#$Mj{?wN@-AFfoVe0amM{*Uk$_ z6sh1RH7!|JY)2(Gd!FG8`V$C9B9z!6B@<`(ZXLoFPl)R{UM8D9)q^-yUHDN7tKI7| zW*A})p8i|yr@V@k2r1$zjhTQ+3V}32XwIj@Mzr-$9c|Tzp7S<-Bz#={tb#8FNV871 zDh)8&{sO_Zm5&);mHG!10g>4L{|2XNY0xj0*9{ap=#)5OvT6j6`F) zLFE@zoq#u5wa+`-4nrvyl*cX>3@|c5U<}z9;24AhX$4u5gkHL%U=%I4`+Em_J16Z` z@M@*lBY0CNr>EOq1#Qu+Cz|yHggwR~XKhm(4*>=L-y0C)NSZ$MYq5Z*s~2J*IDwe5 zWx4`FqQA=Z@^Q=%<;!ZWtKecqOt4}7bY&EW#lLdsh)q8vL@e0mdQ)HRAtBim+$A>G z+j2nKWoytvhZqy}Yk5TgAVw%e_D~dd>Q%JD@e6_C4-qErjDWvShTf!#52k#qya2|DWxKGJR3k^miIs&pF7CN1G_)dzDq|%Xk#Q6VZ2#5= z{S81U==a}d$MK|NK`M&UkyUYZ$q_Xaa2OMRUfT{)hDmnzn^I9!)vRLimaMc8lSf{!E%YOAkR>Sx!y|$}TyS=J+pZ1P2 z5Kdz_!GX$s#4w2!%~h?Xu^s_fwnE8Qfb?z2j^Z?mRzXZEok_JJ^BV}(z*j*qCM1uN z(JqIqXGDDfmPg6DkcPK^>x&t{ID|9=N-z@b{QS$_s$BiQ3Cb1sISkHMEQ6{wjGh34 z5T51UdPhQ(#jqVC82&~vNAKf68kO;1VpDW~#?E7r7Ev^3UdjQz;Dl(dCZuygz$LX5 z%e^XrRYnwFV~K#G**`)E&~)3h;tT%Zx0b+fkj7HRk{CV_%C~gi$WXQ%O@|~3ky0q+ zsR^OTuqoqc^8Z?+i|Yeqm4!2peQgOI8O5Kx6;s_H$^?uaRN z9J;k~jSImc7?aD`IuoywPvnPOwJDPj38e|v2QV=M5lrJ?EP=jz z-xbq7Ip`PS4)npnld(BPY{Ur-4yNQm(Sx)Aw|T^T(ZEkQLT%uw6DN6ttE$8~n%V{Q zSz*zZE)c+-`bOm0%x#H(vT!&)k_6r^9*%PthV%+%6Jgm@jN5O7VmsG?aym-kU3ALK zGU1_iA(}JlKpwZv(Rj6TCLaM&iS{qF%_Z7fZFO|I!SyQ4o=mA z5{gGysQh@Ss1U1f$he!!O|_OX7B0w)tQ)FC7M3+cfTq--XUd{DAR!Wr0-S#*MsU3M zzaRFG_jZ-cx?x7tlf2`lVhN|`X!=s(*-O>EdLb&95tJl|))LtJzwLKN2YWz6u-yDh zw$bZ!25E4Pcs9S6l>xD_RYmriYbrRFQe7n20FHwwmEy_Hu}anR(i6{*dq3|Vg5&-+ zI6B_{b^Bxw{Id5C`Q>Bm`@a1j`F8Jc*ID{y&5R1;6J+#%^r_8`Ap6$DOeyQoC)kqy zU8On{;g^}IG?g?IFbgZFKwQNWNV`!nYAN#vZz!g&MqgABg$N@FP_go=GQH`}r9DKW zlu=o?f9s$2_jZo=PENOXcJ})H(_i-f(F6bWkM|#r?KeMI<@494`@5#B`t?IT9z)%X z^eM1!e^+o`ZI4m0G-@C@nr6v6azxEuQ8ZFP!Qv-l<2rblI#!OOTn{`>RoI-=lqJJ# zX)dK>RZ4OK%p`?Xz{skd&|pwPX@V2nZ%Gd=u(YKVDep-?n*DY^GkU&v{}m- zNVO)fATAIB$6$gu6m+q8boRj3$Sd9C)(_8<3`G4)I=`kefVi49 z<_yv5TXG4=kfRvTRPb>fzBQsGO;lu8h8W937)4B;84y!D8%1OQBVQN5BtA6_pGk|7 z+6*hcJWQS)@$NF$kW}ZM2ae?*QoqQg)nyaJRl*?$@;KkwcHLbPq*;#F4ot8=3716g za-4D)I><(u{G)=DmMFwx$*Vmfj z+s-YM97;L3+PC1%8_>;~7!uk8uO``Vt*cmFFm!>a^iKs8%VbK~M_bjgY80~M9-BOA z;QAVf5x!7e_~O;=Z5!O)3hWB)c>=)F$pq5rV%1yHIj|pNp2cFBgn@Z9lPS`Y9cd4f z%CXoormjBrZ2CQ@V{$#K3^DF*Peay)Jzy50D zRVn}T=Em#S&-tI9;?c}aA5D-Dp$F(zX+1E0=nS#Rz{Uv zUpu~o+uQ4FAoQ5qTcBGjmNHhV+uQsARi&xCP~MtQ0rS}IxyPQL?x`Jqp-9sVvVt=v z;V5UdNy-t@yN7+9rjC+{wDRIuSw?k!ieAed&s7w8{jzmg={UEyKD!8f-IOmK{H@kW zA?QVRW=9Y9TCMAA&z`$K zOn^r~`(KR23FPB9*S^s9et#)O@bZt_Hn;%;$k5g%@VpQOBt$E%*18XN^7-V!kosth zkfNoKWn$E&6GAAmN)GVBk6DfyS$m#g>cq-kS2myJEKaHR5sXd7>7GmwXMlmOPyjqU zA1LxZ*cfj<)-K z@2BJU?>uGQ`9UHBiWt%uaGb^fS~^P;XrE;A>y4A|DaUj+(eYfpFS4H`eB}QA5`-HE z|36i@%Y2?Z%vBK0{Qq@#v%68^|F70xJ>UQHB+vDA=NoW=Cp~FW8{!D@X@cHN1XzMG z>Va=MVp9pE)+$3==S9nN8MFnimw1H!YMozGg#b^Yrb0frks0}84mM4*hT2F&3#QtG zs!X|!@`o%@8kmD2tKgG4B#^9NfGGFmIlqqi$vRd=+XHFWJ4e%5)wB<-X7puOquqEo z_EeC`tS(#)SX8T~+uWO0fCQWm7?sNI4$+@r+3;SOo1?TA)@kw;d79iBiumT4bF49O z^-?}LUn7-TXXe4}?G!N~vMD5tNhZF{0XOZfET#pr%Tnp~oU1rRf**N0K2)NqkdL%W z!!eH1Pu0~6>EC{#d=0%f<*k_QR8>nB7rlr-Rh?=FHPRu-Pm0KpC>;vn>E)HnrBCB# zky6ewrLL-fx~Nm(kgbbAQ|8Vc%^yvNZNgH_RPtXN_{N0=%$e)4&*M4!`-#h+we`oKu4ZKAC z)(xE;^krkW?K&LSfDtOMRdM^n$y?Ey7ZbIgE>$pLZoA1%Op9+-;CWp7w*x2$#k?d# zRG3k`P*~vjJTx|+REC@*#C19>4~8N222<&P5g>ZE-9OnoKK=Rl{fDF5Hn{m%SeX$; z3Gnv7%jM;Neq`S)FE9Vz^}he(=Jz%4`#;p5Yx1A#_1l~E-@D$Xe!Kqa_pbNqkCl)9 z%Js(WqP12&vTt6j+}M3?dp|*M_{a6y>gH{4<@)t)x=+7)8X17w`^Q+tCPNTv7^Cae4diwGKwdrkKvtIj z)BkqmzXjn~d6^M0lwYc`Ag_5GKJ!eHpGopFNq#2D|HdSFh%=qRQ?&WERi|N`QpD*r z(=&4W(wmoggR;z<7uRc+au^|$yxGY6BottPWAI{`p+CWzAhWXCZF}YK>cDdT=pIDT z%79i1C8eU{#iBL!`L^v;aKtm92%Z<-YCsgm3|=fRt3SR4cqQ*GByrBiqz~5W(*`1z z_h1gEWfd*2x35d!c%&V?+LgLo!;@Bgzg=nrXlGo;&X(u#yREER{7**DN|sks*QqhD zhP6~0rhE?8LELF8;vCIr#EQgSz74Q>D%}JaLQdtvL`xQ~6+|Vu#)oBwv zS9=;g%9}$a|8=aZO!`|`6lI8Ut)2-;woBs>EPu2Fp#9y`7uWlTyLg$ zD)*-S@rA2ewckQ#FRqKtl<*_T!J=iMl~tXwQ+)Z~5ATmZyt7BfPzXE>+H0)y&n#6X zm`rg9DqVg27V__D z_io!)(-dkKa-K2XXMA&vtw_;KP}8Qx{PY9NUg z$gpNRO4zi`>k=-P8u7|tcC}S#YBmBaFwF(0_)ycEHMQ!7FE&=U+skcf1Pn+r)zL8y z{M#Xk6p@TQxDE{scsT(t3thd;%LECiTv=dUOi>3l_dw=g?`kZ?T{vSn#VpA+R5z1F zc$%D=$ax3s`Z{Z8nq=|y4KieY-GOw%UI}DW0z_GQYiE)Lcq6Z#so&Q9EODrgWP=&5 z=V`fM9On6(eHXf#LDo^v(k8KKniy>X8B2_^AkQ@yHe;E{d@(6SB|JBW8=&6Z%VwL# z^4jhi9?d%c^uN(1{ck#o*}4(YO;di>FfLFMoYX;b5aBqCrU06B!^^q(E#JglnO?*G zWMTzZB>mENsTF$I-TP_#!@v$L$HDY-Jr(jU*a0Or~L6;`ur0Qm~WF$snk@n->WxHg!Fna{$EmH>mtX)%E-X(1$ zDw$W4*D_~Ci?}RJ??rQQ(MmkqI;>346<+^UIw!3=u;(z-KRkRjYzxDvHBIH%-@%8gZMue$D_PLeUHB9#tMmRZbG z)MuPUbgIv8bM(~me`8y_;KG)OKE#>MxE*zH6w>s_{(6 zn}I3}#!^LJL|j@Nw)4VuCQMxlEG2VU%wg!s?6|XxmX;AxC_OKA6uFmBOk{${?#pte zYLR9ut8IxX3|iXygqqazGCyOkFsWo4Z`v*s(Ti(Y*8-Jj{mqMliA8`^w{qKFspui1 zOpWK<^mB@n2KRYx62wU@6De9noc6BF)>&ira@ayG)8Cttsmp2Tstm_6Ak8pr)`y2* zK+5d+@VD>#Cx_eb_5_7A_pGesrS-u_r&>P{F}+Ls9aW}b+VYA+5apJ>TwS~6+V97kVD zfLW;3nuCS2&amMab9=)SIb)wg$}{FCcZ^AdmhChN5z9iAwyK5Asg1ns#}9DOqPdt3@=cDn!bE-ZT-A`sjuUaMDwNLEt<*WVa6WqI=0?sdEiQLE6FDH7$7wy;R@uVlD1oe`ot>Z}(KR_2$L08Nb$7ZTq%1dXg`1(pI7ia;pRx?=>xsibvvB(wQG|I*PyAvd8v8xk9>RKJd$Vk z1vl6^*xx%mIemX5_`#d@=Vg*}3PC~>H5)Lpbpy;!vvAhpR+W~b{AfYL8AtUr`&ddX zSwqvc$NAM=)n03tuGmIWn;N3red(;IyRMb%>BV(r-79UzVWCBN6_g>20eC3@-_w>C zaC2ksz7Wrf7Nx5zl~D*mBC@qorj|AEN0CIRO(gHdib*J$aF9}}uIEuTR|OByn+L#5 zyUysPn8=Hghzfdd97$K5a%{`s4@*eQ(1JMSJiTfo*DPb>10q>z|2N=DSyfmN)m)jy z?tpCuG`V&4`ntN3Srw!58PqZ>rhH8Ae`$k1{wOnWO{24-F8Rr_yXb7^Z#Ilo@^UN) zlpB-(_BZgtT%zQSIOs~;w)~vh!kPVcY!kcF7t708b6_p=PFfyEHJi*@tS=ZErcuV2 z>Uhr(UwJb3r8l4u#}$UtAeJA$KiD(MqLLAE1#)4z-9gXq6R{x2rX7!RpFW2w%9ZB>%otOEWkF?XVEiPr-ep$)fuMfF-$1An)<x5Rf?*{PF0C&%`pnj8!O5JW~W5* zIz%u=FyiA=`R#Pfd2*W4NVjbA!#Ngb|L9^XyUOSG_V-@zkBo-(zWeUG@5(u@YbsuB zUTl@=ty~W=lSU;2}}wp;xjl9)$i6sJ*?YdA0Dy@tIvxdB1G9i~xK zZ+&ohfmB<@q%Lc5u*^wcUK?eZc2tR#LcM#MJgnqrSkz5pjw5R{nSp;tE^t3TEEi_? znD8;0$^#5Bnc!I7h+19UiGfl=iB$cSe+NJt<=TQ{^8H_G z@Mm`mW^fGHsbNc{bt#SHe?RP>SdGq!N5D|8W7E1EZ?E(!kp3n>^{p9LHD$0_vvtT7-Q^(pX)vDuq*5v2!%li*t9nn`dKu z;JFu#<@Xq0Y3rs8of=FSoL5)6W}Stm^*)ZK<;7l-2ajqHDF1dZxYUm2-q3LZBOi4M zc!pWPDAHR>ZF+eV5kp8{4m%Y>ete#@4+qn5LB1CDjN{;Z`Xh{B90-Dzw# zR1FvUEV&PkhvXx$^0Cg*oaH>4i;>JX&$(Dl%8*xK zH+TrH0izeEGD2}V`>+CT!8M2nj9x6y6jfHh2!VBQ51!Uc#_q!Fz);{Egy*Cc@+JbBE~baivwg`^y;B2(T%zq{u(4g;%pca3n)yGmP>O&E8wE9EiAl} z>bng!^_rp~MQp6^oo&i|ZTdIYj9O{Fm+Z@Z&2>p~TeTb$up4mLiyCuOHyE@|%Q2R3 zw~vnB|KC6CP*%(KC5za}Fzk<@{lc!@{zRsWIcUR>P!JK4*yoAYy7oEZLR|bzx&i+7 zx561=eb5NX^BL-Tbd9*Pn^N~X3;0gK@(VG_72x}RTl8W3{4>wJW$rbNR08{FcH3@< zgU{nm9bJ`;uOhl&JnKU3|2D0pK(oN-pCvwajqz(`-H<)!;`Wc z3f2xQ#~kT%?PA~muCg7duf1;X^{py$@P2!DUzKuf!b)ILbsL!jN@i8_8qM24kSF}S z51#kI6Yhhj!tm@g;xnyZ6vu1hRTqp_y(iK;?zyeO-`Y^s*{Hv8nCiW-|1pvOQ(wXO zNgvn!pJNmyh(6W*pWRol*4Hcde{MbB|NSJ--1mQWzG>}H1UUjQKjoN4(G>id!bl$t zPE>+!zxA7p4vGU=o`bCo5R4&ZV1NRcG6WczAn;2%Kr}`iF@5JXMp4M5&mzJT%u%Q= zaK;QQ52jLu()VM_^G*p0R{WM6UqwO_dbQH2z5KHrv%fQjl*>zeGg>A}zP~_};t+uw zHF7a#@h6`2)8P`aR_Os#;dMq&)&U7(FEv%trPo;dMWqfP+Df? zS*nzw5a1Y05Qib;P;5V&@~G?aiXE#3gh|q?xd70z362rP9F9=0aPN6v8`W;WpDE!| zR-@`uuW~=ST}T3=)T?|)(NK5zSim>k7^p)@|G1)aFb=^5q70MRZ|!ps62!m+$9MuG zfLH(%V@?#L62~^7G>f%&1t&>_07-e0@?HyozX&-;C_&U)^Vj{2766xoh6zQCc^m$^ zzjnIbU3=YKU;Ey*XgORwDY;4ut2*%t+TXT8`?PK7*RN{m;HE-AEc({SK?Dv;NRXkz zN4>x>2uK=p6FO5*+I59(RsOJ!$QO(Gf$H7Mbi8c;FE?7NSLzy!_0h5dWi2(`)_=6; zYQ#l8oe-#mA3Nw!5QD36N ziWXeVM(lx$wbnU~!yZrtT1E^K>{pQSIti!Z`4m4`0t1HtBVXH64A4BkC#YY3Dz+?S zm5&#Ixvr*`?&bp}>*c&l-x}Ssu7WNMs9?DhdUOxGPvD;^Y8hx)1~dWYU-I?})cOcA zCZrT_0|r~0C=Tp?9+cSB?*B2&{gIk8-<1x`*#8?Fuh)wEf4%$adH+Anvv_<$royWo zDK<@YpIW-%BsZtSRfgI6nqpGgZpRq{B&sDCEdXV;PCzp*T#4(AavQ&1oua?(Q=oN`}un zGsnQlKj0*qS-1=%YYHquff#v`4kFCPhlI zdaa7Xq$buabD4M=TX>M@h*t?YQKnakX{)BuODN$aAW;vT>>SBA9MTcuN3y;w-zu$= z3#N{oduCud<0FsQ%z>41>di4W-K=YTP5`>yPDL215)FfO=2>hWtkvpFSh`aT=HS$+ ztC|5?m#1*PVK#uZwCh!1Uoo1|3{{2(nj#Hj&03iso{df9Sz`(lU?@TXC$y(sr@0kM zHB~T0=}{QdSC!)^ZlkECF5I>*eJT;FgoN^pR=Y~p_5R3+x;5rc&3HePr%C=(p^_7r z+*1LZA^)wt-g;Hm|JGk`Jj;Ji@i^rs6=(YnCU?~2a?H82PAB$!v(-Bb)2Op}>jJs8 z+qT2r-g@~PW1}h&rumZ1&Q>P#eH6_l#APCKeenCEYp-U}^9;g0aHFhkhFt4N>byjr zi>i?Lx2|HLP+nI@WY^Wo0=7;0YWA&4Rab&8Uk5%pqt$JWYejh1jj50w!7nkItcBAV zGpmH8YZPltZCPn-Mj}kV#QU1)zhV3y3n)(bo%z8```@cl{KxwG=EkdM`u`M9$upG6 zdTPl*ouTjE9HJJtzA`JI0galb0*+FJ>p-3jbiGJO9%ucV_P@&8aepyzmi)K2)veh7 z)}Q6SCwU%ccb75eSqyvxsmu=0u80AS<2rh%)e{Ugm5YZQe52@Bqr)rp-67;<(c}5~ z44x+XA0vKA=((r7-*-0x%%K09uQn_6e`BrtO#h$aDan6&$&b{ETY6B{F{4<;pRditS^EsGxBl9gVUWE}S(*)_(J+L2-C}K?i+A}|p{KFLD#0jpn zQ=B88d;E*d!r1Sve!SeEU+-bkH7n-)ng*QCmAW>HFv>Pu4yo%IBY(BwZ2!YtXzm1s{lO`H|1ZRre0)uMM*43cp0l^KkU9L;74(M#ZD zj7&B%H7Ou-LUKT2(AVJ-eZ&Q$WMGhTd2FAL5ja6iz0I2X4S`FjPME+8f z09HZ%DtJFT**$xudS;{#tpZdH>Mk618`ZzOaQz2=8tH$YWlZwsyYhmW_W#X|vi)cC z)z&lpe~PC}|Fb0*BA_jU+Z;e=cgOL_4+uqs$zy++`{1b1$lXr^G>`m_B1G>_x_m-}>ZreF_X zVBVG3g8T$iJ|-0ZB`x5V?V0{R#dDn}^vqo-j1!7Vr~W~fN&SV)aB{3l^*01TZ2yyO^g12?+nay()gQ(5 zRC)3KTUFlw_J90ud#0Rm4iO5LW$~YI99C<(4iBrbGB);=z_hYb-^4~!3mbU@cS&zB z>)f>7P0x{#kCt6Q`~Mn7G9MbMacuwA zKke`B9Pgc+Ztv{u_4^H@+VB;QomR%C+Q}O@-QTTk1Il~vt8KXbn~xr#{`@@Z)6D-E;N{r^dx#q(x-CK_7Z!KG5zka^$J*V}|;I`;6KYM~DF9=m%N zm59}vTz_>LIqsK?qnc|YFn{;Jp}L}_F8jtk5^p?4&W(Gd+jxRZ8~07J@p$<)?weZU zv9fB+MIfB%G(7Q-dyscar_q>6W6nGpjVUymLnNB${~Y{ZXCHmE^B-$l8=IB$ADhqi z-zRx$xJA+STdxlnOqKJB3$;eeXWjTgbmQEZQb_4odrOJZ8g+=Sn|hj}Rv5#gIfAR^ zr26hELv;0PWmz`m+p|WqQte`qammcu8@x zqyOu#)~e_Kwx07pJjrAE|CVQEQLYR7YJ(Lkjdq^TK%vh&jXp;1a+b|ME*5ImFZA(X z3hRui*r_11ODw)x#96JCkOK!lTt9BM}}^a^GjnaN4`0u<>sk8hl)|E%~6CV zh|{UQcULJ5kdNo;yHfiO1HcnR(oA1bmjIurm-CGwZ=irQ{~`m4cZ=^c#~D$%aZFUp z9Ma#+2>C@$#LW?p-e^kt)O7r=Pb2@gQZ7DT{Lib6&8@Qk_x0B6Xa4^r&to}sZ5|Gj zgjp;*KbdmZQ$LwW@b2p3;%8Q#NOfCCIw+Wat7?a`N5Wc@?%ZdM9`L}v<}8PcNM|P5 zcgfglUuvF^@Ewfd2u)DT)nV3R9DMb=s+cAr`U4TRid3h#tduXz zXw-pLfOVueKTx5P84G#0-5~I`YicT~&dSg3Y`$LVl+|qs)d7mAbf|u=L^XLxtxC035h%MgSmNvqf5)Cmaq19iQg8iEJya{%8vpm)J7>+6Ba5k_hd^zu+N zMD)(ky+n94<~^|1?Usfm)?F{>38IrKaAz#c%%!>e;w-#8_gkO^m#DORi$4owOEub0 zgbcSsV#b9a$XPj*ChxyeG*53dfmi)=bXi~{^*!j)mKk-;hFoF3b2Vtyuy1ZOuS+*a z{6%8awmZBWqxeJ2AjfQo#pLJgwo=dTT<-<69ZxUew9sEI?$+Y$;ZEI zpLTSuRpFv&UC>&wwQgBxu7QFC=Ka41jga4$?0OXQ=0>?1A`U)S_GGEnkK7T$Z;T0Oi|3%7usX>Z7?R6aTT@1 zcTvHU-yPUh*yZ*W;J3HE%4ZHoPXmg4wJc01PQfc^DRuq$G>x~}2Zm@tY4<=UgdEO^ ze1)P##FL*Y$Yv^9HlGIuebY|IbM0}5ULb8#_U3kO0LRL(ac*azqXGmwf=iP)nrib} zM;pMN1c^|5(OdimL~p(e56f86-#a|nKioSw-QPX6E-=hcOmveQ7iGxI$5{MdOyQ~r z{xft2&gg5nR>1O$g5an8guAR388Khm*JE@%~iE_NbSOBK`}S z>T|96Q*ncqBYHsL$vh47Rd6djg@)!$>0&ilfR9Dol~4d9B&!t`JcBSrBNe#ndHPTH3BatJ_^wdh^M-^52)wL0cPJqO zZf{>I?CXT-B=KoDI4utIZ+`<~m4L@)mczrEqJJ;X9PlxUL689NqExip388rOcQC}2 z&L$Vt%BQ8@ZJW3MRLVuHsAh>|R<>T-om zMIo$xrb$FJf*c31LlP7-Hui!DqnLj+)PhccHxz73U@;2D1b7I1Y`?hH=a+9kw!shL za~b1<@q~n6v)cu(uZGMlM1iC;CjlO=Hkmyh0b+pzsfPc8raNO4oa1=(CMNYYgbwvf zOfF+liT#8l^rjP{i%y(IQB5r;oyt&15-NAae*^OM$ZF3sX}lY0EU7S@!u^7o&y=cM zA6G4zuhN!NVht*`!<>?;1Cr|bv<3qQWmHRLod^Xkysm#}LGNy=)Nfgd(tX!ek+z{d@rD*=<$`y*up{qP*MLm^Wt)7C^V_tbd!llB z=1*y0#_8g-7Duj}cX3~6QWK9hpP|PZLUtT~zF|0;`{d@ZTFV!3NnuZE4s*Aq@U+s9 ze(fBel<|JGpjsmf)|IZ$&27dI;UNm9L4@kJMpneVHOh$|K35^q79&d|Eeet)QL+$V z{ixF9BFDF@(&e+u<>AE6xze3HyIr2d?NWb1rh4wI31po;m@-h);@u>_n#S%d`_;5} z59zO_#ZM&vxlWrrfNqdY^5N8jx+d?5Cl940)HV1JnDTk33NuipL0PaS@*w(xJF8bd z;u_HkG>YuCml)1g9_n&&xyMsdBIX*?{WOWsROYX5Y$2iFV$}1={S6iFDf(Nqy+-;k zi~spiLT`w#K4&eU*3IS&9;=>{d{iaC{P7$|_8dp{97pB`_m{2EI4WCV@U3DmWwI;? z(T{=-?IMl>d6UQN(D-M&oSn3Mj^x2*W2q@u=4#I4+VWe8sbwD(Uu)0B*zyD5PTp4J zT?-^}lET6^9kH@>=Xv=NXgjS1uJYKt%oDPpX&#I=}PPl)URJW&7Dd&_4F{bjme2K3Q( zzyI6&}OJD1~<#O3k*Z8P3T;|8(bIfA8=_UNiC2{=uGeY#Dj(*yk%F=AWbK zPdGx0cDA#3d~%20#LLCH+rD#GaL3WvB8JQ{=gH5A7dO*l2|aY3xw2ZTXO>+otGb}| zw84^9(`1t&tKP^~(^##It=>ZTd4qpZv*bMRU%-+$#{$f2;$~) zNOZj+t9H%YLiVDx-WGCIiNd(FtwnzDCioY_{Q0> zjb63=gkmD4%m^}8T;0m2Vy-Y(#R^o_LRTUvOA3iE2kNeVwz(=nVDB)rCIZ@ zk@mgXy`jY72Erg@1y!g@kn;D%yc7*p+=6haq1g}@6PXtm6Pfy6L}-aF+~=jH;6LKIEuNdTeK!9a*Gcm5r=^Np%W1msP6LrOvrl@||!@#yPQMj``KkC$CjB5Q&{p zO{Z3wNa==cpff}vR^;1^6Iym%RK~*aU(T$aP1vCumQ1EpXBqto+FpCUy4HCp`?XG| z)^53}fTL*R1dD^UT6J=H*_WM|tB^sWLLLg1z7yLdn(C3sDl0=>*;50-)yn&ud$ouU?h!f7n{ve9r&;6wh@zgPvS< zn{}zI&AS;II8!^{F_E+G?rXc#-K14^Bo#g;QH0~s2boG(rZ&F70+esDAhFW}Ji)vN z*6NZToAoJraUUiVzO@=)cHXe&oX2;<0pQ3mdzX>Vne)tmUb8+^>{!1p_-AJ0jaiv5 zKhJEfz*$a$Y^FRxoZ^7hutIS zh9h^w6^@d1P&1jQ7F?Vf|LoIPU8s)@erdB&;blQ zhIpFz(@B&y=NfJ8^>eDy{S)$)D1}2Vc6ZS{&?052V8k4*(Y)O`@)F)Vlkq*15;x`` z&hTkgE@D@~2h2&FH9vQ5;>H>en4?(r@`dLruCQEt>f9JQKW0`)wL5|CV!1O7A)gV)Tr9RgJae()9r6!l4LoLU%}z-` zwH+Pv3O)12g=KBe6UgYPLN=~C;u#Ap_W||8?FO!@21ndDMNJ2FhXgLu#>v-B(u zXACI{Jw}4_LJUViC`#k3e$5K-s1f=JnhbGNBXl{~zKOwoXG%FEt!A82%q;J9M-*%3 za_9K4#s=!+#1;W*9YCw$Lp3o$cI(C1pxPiEx7_^D0c_0(+2oqfe3LaU`i32IpJu;S z&%b(R`u~$~aIedsXZruUYipa8`=8ggp6`EtlBbR~l5iI@nkF2R_{TIHAudDSY~R0o z`#Wm-c`dCjsF;GIYSDWJ5(sSlT7wCm>W*eF7Xj)>r3*VU@T`}^BtJEZKR*r6O!`kr zgzm`zX43z)^)mh6c=b&GpX8Yx|8?!S5UkN%pT))xU|_lMZPp<_!IX~)#eYdpvw!}b zbah;;Y36WDBJ{gY1Lg(eAk4PmRgX&t0Cm=>Gu6A&y6PWdpP5|HgVH{`d9T)-(Nois!SY|350c zdu9U4TBZ>Hfju~BXL}M78P&gdozz(2serlXSLt~FV5gU4asgE9u zox!ThV1I26r=QVs9v8Ikm}KUr&(8A)NkM3G@`tn09*6!{%xPN4 z4+fJ96Vf=FzVyuvd9M-Y4+S6txUs9LZqIiQ}8{$}6ylAI$$5 zanM$&=mY2nl()eR7;J5#IHj4^jJx9|;dkx1&kirS8 z?YdN;vHx(~(EVqnay#gMcC8;w`S>Atzzq7|eZ5(s|68x0>Hm{F4*Fj_WnG~EHOHA3 zV+40Q()@2g`kT&TyU%JTkg-cb!<^VSJpbP9ZTvOPx8#AoBqn2_^!4@hj*Hy3BdghC!Y zM-)LRk6v8t(@vu2s9a2rLsfLZpR z*K3vYAM5MS{+}m#?il}j4+%kAfxk5QVD3D-4)I{#9J`IuLEB+GE&#J#BQ-2~(RwKp zpp^&E1748*sn$1$F!06;*{p$=fVvAy0gi`6CSlgM>^2GnS&|b$vHo2Jg8P}1GWvhK zx4rvr&!2=3Ph%SC|9bcJ+Ge+8|5;yOe?I^BB+n8!mXXJ;-{rr5ERQ))dL3=Y#H6zV zFat0KFuZ_qfI@JNrk*lz1TYvQX*yz@P~?MsE(((&M=>y2mH{UKG5}>l9>6$F1D;Z( z_c&lU4v=V*fdIya^oepf9}&wpxFyIw5Tp>mFa#lt!)b^vWI8z3>vYTu6p;i`e}wrs z9SA7MSTClk zjz<70+6pF+aYPk>wZ$jr4PcohDoeR_kAVpn2Ihu5z;K8HNCCWnI1)U4rS%QqmqZN% z!C>s_nMLpd)pX1j>zUbIixt_AIVE8#FRgF2PI3?p2;q!Vxt732M`q#U3K-+jIGX0I zYA|)wm>Gv04bzAr0dvvNFIg((47m&0l~+KZPMzqR3-}m;w_=?W7@WhAXg`J{L=`?A zQ6zJ-Gt3ba>z6kV*8K0jRXOf|L>z+cqkRUnAl3Q?9Q`W5rE(Js@T7_4c{r9mrg4a9 zG!+BD@sPr7qsU%ABqIt#GddYt*lHa~Q2@k3IO1a{&<#-p#sUljgv8|IbTU8`kf8vv zJn+EqB#H2FYT7cGCZ;$Me8*f`1D1z`f&t9`mdVtFLn3Bx zlI6=gDMVYxKW^^;LQA2ifRYF?A8a#;=1go*bzwyY+#w~CY$89rS@*mCnxJ1lyxH)( zez!QcRd9ApB6Ozz)n}E@RwaziihZBuatvT&l13pIAP}Mm2|6}`aSEeoDlx3Q*lKUc zkqIz!0yh1tR;w=rfy$WAHvOwJ@OJx1%2{Ub=esn!ITKJcAr~l=gQX~mpdjsosq7L> z1}F?s2!1y$Wt&@v-{kA0Nu*dKEsbUWa*9w#Z%#oyC?0eiLs?l>{9%qI$pIkbIWA|M zX)LB*nzeN)ah%AV!Kq4UjgRq=ID$%pYP7rX;1Zh-N1Hiinr?;R(s8d$wRt z%5hFauS#eK>bf?jxH=$ee_Axk&^oad-2LGp;YSn+=I{{1&Btij zX9{B+B8r6a%8BHNgn|i?imfu`D5)Z4=3X>0k(@_rG4?ZfZouzhSa z0~x=B=TSF|grd3fv(oepILy>MTL9}=!qgY?+<>!BK*V2(^k)zM+xdCVIX^1Eaj}Z*3(|xdhB$kp>H=^Ev9U+?nhJ+9(L{1?i3Y?W_ z%E09q2V)SU3q-+4z?_l^;hB1-aM}kuQkR!@aHgczt`D|_^oc?(FM>7idmmsQ`Cwyp z6L?^QkEL+A$;SmfLv=QR=Lle4=x0^XY?`S#f?&rXx)Oa!fS$?8I#0-+$rAkp1$c<% zyoAC_0W8}iay?a53?FM@?)3=zP1A>#08HZ!C<=|{Om{8zq4;gIg%Sig(V%;j!9C=2 z1Aay^Qh1-687q#m+=;eO;|?goloJ_&b3)EhdYM<&0XmTN=>}~^etoOQZKa8x3|d z2a#0fL(HVHGLS{3kr@Ptay%3hLQL?^v0#;YdQ!V@TaCAYL;tyca9P)Hmq>F)au|eDIl}w$Ky1kEO`eLa}h2TaH0T^0f^m-%nN+1jfohoV0AT?FF|&b}UYRcVD4QtZx zzZ5tMC_b`f!U4r0#8FC78Hzut*Iy(Q9}N|4C>Af)yc2uLn)n>S`BeO+1jjoum@**$ z9XU)1jtj7u&l(N0=M%wkAtv)BK=P@$ObLz)v6(Lfj!(j8l=)rWBXOwB!p3J9koZC< zVI-DNi{T`TnA0InBX#}6BxPJB@BwH4{Qcv{OYh@H|Br89oJqTq4*4;5*C(ZxH{fhC zRa1O;U|LYr3hj=H4Ppw4+mynoQtWlm5VMuv&+NGYXTP_9I{46kyZd8%RsFSnaM1qa z!Cd{haRL{;)i+=}o`MS);ZR#cR3V_EpqUD#lN!H@FEb1nCP{>q|4PQP>4^7bh7cH_ zh+M8bz}Od?C=h+?psFdHL=W1y1;vzcGTE_Vd82%Eis`EFwmoQwBVSiZor;+sS_Be1Q7}+kH4I~tR5kcJc#U(x2Sx$Cb3V&|K#vJ<#F&|ko!r1ZvD~R zctt1vaL(eBV#F^AJy-c(hw#gBJ>P({CjfHU zTUzTX{qoTDCX4gR=UVWV7F?y-{2sW#-xAfD& z@$2%IKK@axIyin^-qI)JGeWN_nmhJn_8A5UHL9AWrfz>Yc?*`0Rq_;O8=rJm=`-z+ zVTeDutE%)o#lert>`m9(Aj`9@(nRDsKLlqw`-~`ZX3}a%mEB5q;DWMPt)9sbboL|w zuIRnRH1228TL8>UeUiDDAL<;*)F3!k>0-{xsmjkPAbKDGt%5+hH?l+3SY`|RR~j3y zD<6Zi+6?JuD{c#i9CEhOCu5n53<&aK!U?kdk|6<(0jz+@e~Ja1`?03!l@a>>jTfN! zXG&-~vHf=MaEvGE#L7OUT;B}DNU%akr-HIfAXdrVR0|I^x(9r2z}fl}(e85K!43FT zMjY5_a~26YfR!+XJPbj%_*8)ikMI4=p;!t$a77&y?Wzj|9#q!qNn;Nx)TDLo z7CI&&`ceW8lhtSSJR$TJa`N^+bGQ|sNAmE>ixeC&L)GmoN?Mrs z1#RNTN5HbCV|DFPc~qcAS>KUwk3K(LM?a6R@{|BzcfEkhBhy`~2sgDXvqk(TRDBHF zEX(@VTwOxH!k8~f;#U|`yD{$HxPW3=U$nYjRB@bBU%WSVEv7dXw?wWp+Nu6a(ZPp; zFzefm1>H`FkiHon#WGjWm-9S6*|sh{D5rWj$v%DIuzYyA!ERhYaSUm=9do=r910o1 zwqN|Fa}DL0HFeOrOahiC92ycDsK|7h#(>0GRwfml{OKv%<0s63VTe^0a}7s~Oq|Ph z_6fl3n+#?OCCr@A{q!)aK2Ml6%5(W>Ufd*DZd|*_?Qr`t}~kx?h=Z1H;>#6oO!1H&lQ>uaILD`@JAG1 z{QvBI?{eEV)^|ViD$Y3X%qAX-lJjrhYTC}@I&R}h>Uu19`*gCM5F#N7Yl`3kpk%e` z9qc9TJ?$+#g9CsBDJf1irXqEM4^1tCAn?NhaBy(&J1nJRdM0CH_?G*CYVeWPDq=p( zF9jd5l=k6wFmW`micGO7bIz`T%}~59u7zoMx+* z{5YdRu!JJbGB+%5Hn-kLXkEy1rw|*_Vi$YFbjra&s}n`KiI%FQpmKK;j1cEM*-@-E zr}n4YDhz7_&kZP6`CF=03u%iet_`Ev{PYs8DjH|YLs*so7&sFHcVY}N!|S^PXfFYx z8%|O(C0Vzsr!L?p zm@sJfU(t_E8pYOzv|;t7LNcjnri?K8NjM=G%`+ewRpi+IT4oi$Rm0+sWKlK>mJY21+Wn`djXhq z=K&@jP{v`xB?hQAfulxj7Z{kg0Iv;{IWieE(Da3YvXrll~AfBni zM3huo37x@=2#BuEUYrl!p8fCTk5|`cS8oTWSLc`4(T7_@miLUES8^RiLxS)F&zRyX z%J>p~lGG6;OidmW3)NG~c}@k<4|XhVQTuM7s8;})lei2ZbK!oluKb30!U4);8G489 zT;#|lL^cd&>w04YMI<_zk+hs82WEkBzaQz1V#bvofo7-ZEk-VMr>wtI`ciK>Eg{NS z+NSMs6N-waRL^0HOQI%`Ua^UqpvwhD{V6BFGG9lpd+k*8W786%ZW%NA-V1*higy{$ z8dGFWq%;eRCz3zz$UM2tHM${-<}Powy1e9b!05|GrdSHZ4Oi<|4EhBLyino$jdlI5 z{Ycv*z5Nkgh7@lY$V%_xqztkCnv>*Pl9DWD*|=+d+l$ox8tqVA2?yxMt8_TJ-QZsB zT()sZ+M#F%bc1Q@2cEFeq6+wL^_x92_Ou$;sR?B19rbP~tN82Qb(MX^)o=fbyTh_< z^Euk9uQms*-t|;9vn`dmj-qF^ZlZX-zgFudM32L#VLLZp*P!Ty0B@prSw3o`F0G~( zLXvxhub}7$DgTJzCRUl681(wmPOl;YC)nXD>6mt^3r39iF&> zR9;@vco>#bpZ+rZED?K?)=0z(oqDxAm2sN)^w4Dswun;UZU%!`N6KK_AUowdqp^{n z_aSC*RtU>?;SL-4jEcEnineIkb=Lz+i@~iD#E*MXwpDS+Qxa=|SwMC7sJ!@S))2?$ zQNL?cZ(t3iEv9B$SA12g(Xp2?n*FrB(Xry}_D(0amTL3?X?w`5+!$H0{W@{W`3^Xt zZ4Vf0d*3_eE4bu7G;M7FLI=?(Pf`iIzNyUNQ92{Km1dU5uV&LACmJpQ{ZO5ge ziDG6O-n@|9MA79lL`Lv%U2m9JV?zoK%}+!nv2+&uRtjI;!CMSY;#lj)s3NWa=sj$s zR;{MmQS3S)qPL2QjHK6sj7BV8v1T|STAS~^B+4JL+mWj636X2?n(#$yhvGiz+}mFk z)~uUN04>A9j;Ad`r&xTmD9`aCA2NIdDJKaGT?Va~8!tvnm++FNxpcu4v&?Am66B;% z37==5@=n(F4*K-Jlq5M9%39K*>c|ubQuUhq8F-H3MbJvgY{&Nsp9aO!M|TM?ts%*S z&Y`(CAesZI|KAc@d<{kCJXo{nR-@XQa6Ml-^MY}M&?9_@)AnT1p_tc?O3Qs$6Fynt zxARA(c%h)z=7oZFD3<2a3dQx%?a3_z-AtwOPAk_6)}m+}m8^aK&m)U1yVtFtc#q!4 zdNpba^QTDLpBF#Q`*<@sL+K(^mkje$)NOzkO zDLvEJ%I~OfSHAt;<&2$8+dMv9M;iQojKQndU3QBxl2`toM`hoa{5V^SNYk}QF5$Z(O&55nrNmOu zloCk|nj}m11KjpeT)(Y+*Ur*V@=Qoa+E6r-wnUD2Uug^5OUsTN=A;=`{wGPzJuEyj zQjQMm*vJyq_ z5!gqDrIE&k+VxTFr}ha0d=v#8GpTIMm^zB*b!l`tTdUi>rX@rPk8h|58E@wrRvkqz z_Rc#|+;P>Wk(Lk*3%MBb+qPV(d=zUG>hDBxzZlh*5FLk4j>A^YBvw%L$Y}0BQRjqw zU&v{e5S^rRvS{UaYz0N+$#}`78Z2bAgda-U3{(=MuGIAy@iZ~(bkx4nnvzB5hAt!)j)B4t952szETsp~X_D+5 znH)EC;b+JNo9RBjp$nTKCa0SV(aktLK^qEYP9~Q`kg4>uCzC4PxFIK5f~CaptJpAp zU09I(kL?*Vj!8>vB?;rU;zm?LXFIcbLglc$p^N>*(4`W~8`=g_A^2GOqU=+!S}b3% z(TLH`OPZ!rlEK3lFCQVk^fsQ5Y)t(a`#XvGGHM&aYUZd-feyjblRY2YONe69_OKRI zDlTX!pM*wpscf=W=26pr(}9zp2QYX7DUVAkoTQlM&;b_G5ag47w>vE28>+hc_fRCm zc3SYh4Q*XJbSTnWCKb!ZhJLMrazJtIRidD74X$S`4^%C-T)<%P5@JCUnkhy;Eh|9# z04kpIl#dq!ykvdKGpPh&nX26sE{%#VH%QE`h12D4qlWjCmKMZ28aySpgBv#pmaPnLiXjyl)%rB! z-QRe2XP?g}H2W!&L@_yHmZ1T~9sQ%wq0(41j$lGWqNfMRN4w}{xr_#O`*xBo=425y zR~Zt=RLZwEuEXEC%AEW>czbesdNvrmeRcNB+w&Lbv4bVR%F6Z0TfWj(vyu9Mwhqot zugwBo+T- z+|BwJUhNYrOxx3xG>Wxd)*UE%h66l;jdNJ-5dEb7b_lQN!t*y}8Paa2ETg5XX=1!4 z|DJ`WQ#v|*d-nbL1zZhI;PUGHZztDh@apUreDe1!3`6@L{Ne24#oCOmY=LYz8AE4k zotb?Q&1J;O(b+%}r$vH|A6P$%K|4q5_n4N^n_r`(lJ8|JU23%Ub(0wlyer+vS? zGV)%r5f1! z>Yc64xlmOA+iT9J9R@zM>J2}50|xhpQ=AwvRwo+WbIyv@t#d2e%DSGYjX8(=l# z?rSGdP3plQr!gBXfRflhSuLcCA`*2vk}ACu`x+UN-yD_y`)dS5j0-eaDGt$urc)C` zFioQnzT*PuEt%#iJqm&-iiSi^g8v7YP0-xj#!5(*ED}0{iBh@jcf0Nfn(~~AaLm-C z7>0~@(XU>*0_=C-?*V|RBC=qAZG^4*Rgv-6&%$2#tV7aV&nx;7l%MT7r*mDwAkd?f z4Ee0`zr^^~8i*?^#VELX56Lo*q^o2d3xmKpH?SE^7e_$gmy;h}+ejLy-y-ICBW*$r z?{qa2cqe@^$+Qxj3qE5B#)#5I*oM3QK~y$@T|=rfvfm09WSVY5;2StRyk_~~VIO|s z1=gXEv=#y5jaSUC54}Gg1;K*{aB6~y7`!xu12^(*Y!G_^N~6uBy)HqjU?fv6m7O!V zsHTnj%l6{0<#r+x2pS6viFZzz22=22JTXG-RWgDiOQxWIX%NzyC$Uao7*^SE}zlfOEINJPU9C z^Y4F2O3SH4khz^d3P}ZC8P8N0^J$l4iV6Cgfv)>3?0G$)i=DEp<3gr(6z^aNn?4+` zJe!i+PD;jocosCO^EA9gp)!9x`L8SYv{pGR@^1kRo&JqFoHS;wS~w>z{D%6ELb$ZI)3~y$kD5?ft~wZ|sl3icvPB~l zlIv*maW$b#X#FPFAkL@*v(abP2hHm78){}6y}pn1Zg8A&L6Z_Wno^ zm<47^7RXqqfs;71pvR1Kl6YfYv)zrJuTv6Fbj=h8t-b5jgWl>U(d0|dSR*#6(L6Bq^3d;>aj$f%xk1Px1YzCOm`VKUNq!XcwtYx)LC7vrw! zm+o}h^+0>8LDQIZZJo^!(;`qt0w6*ac@X@p#itBhEnOpzfGH!@L@7GWQ8Tr~a(I_U z>$xP$c#*}l_&h?{=SAjA|wzWun5L_{NqjRTh%Jh6bq%qNY-%1;h*-@7l<;5^%a&p1d z6(z~yBuVrhmRgaDj)0_UqT7Xos;u)-En<|56DO#11Wo`a+&K}b1b8h%!p<-VE?4i0 zOCSO#xpMw8Duh*8&A8K3g`S$-tv(!FB@5EJ3+UB`h-Ee9Sxb`fPGQQ-QP!MiPVO0% zxG-!o|Kdi%Y?>@qW(k0(W)+Oey`)b`j1z;?#mzN%V;|>pLl)LquX%e4_DcmFOBnwo)oB_reuMKwxc3V7hw?SjRAI?L(@(5zL6}#XnRylnKCZOXw0`K zqkeVDI36Kxzaq~}G)#GXQ$Ntton|xzEy4ueq%|{=QIoZDRQJnBcr3dy&tjS@+0`rF zjL~^lW6iR0M`POI!++3N$*wV4cOT%tow7QQ!r&9k zX)LR_mk7;#O{Qs36O(dE_R)0na#?!cPOqJ6>p8H`+#{W)M8y+hX!m~xe5()BMaS$O z4Bug=EUV0$^W=ldeNaW^wChssG0F3OwTQU%`|lkHPx3rOcg{clu#X=+ux2tN2U>Z` zEv?H#I{@rPFy-?{M@|fNFPJwJuiw>oFS+tf@%{2o4X3enK7aDpFTJ0kZtYz2!s9#M zFbcGhWE>8LV#O#fUMNb>5-9x^>3zJOAgDjW^pc*iT;hydLGTl5f_kPk+G@Ihn~cvhSWpEq6LB#$tEOCM_tVR0 z%!O7VxmlKK-xOwf)}zG$;#AhkPEe=`N83o6!hu)E19*rIWD_pbBXhHX53yK1b4D>iw5>t*us+aC7J_;^Ez=Qyksx@AE2#Yzkuaxe8rI6wUHRT+nyKIFiHb_I z)k9Iz6PSKCL{n z`skc2fT_PoNO(peDTGt{w3?+0eRPCFu-tdmzKaKNW(KheQW-VtTE9@Ors#>IWzMv! zlomFf(u5I3QAG$Iz^S>q@S2Ztrg<73KMlWx4jdlB<&W2A7uV+}ui@LPvy)fn7vIC_ z%ae=m&q6pn49@jNIw@ikS{Mw49ZqESHUzT#S^BOQ6$_ zS{&+>AO3m!`nx|47X8P^VGlY@zz6W~Rn@gGXfCKx(Hc;AZphjf%_9l+e(Z!~pex~R@z5v7*w*!w$O~o1)s)W& znjE6=Z)Vf5iQ6))lQ~*5w0r9=X3UkhAD)la?1>)*UwlqGo!qR@jak>t4Yu<--nR3j zzR~OTde5Ie#eaLfUi07HC?y0pY@(R{-SsM{CV&37tp)6R=y(@dP(`B z_tD>KHf~Q+r_<4sw7u}+MzG>AB^eo;xU*13#tf{8th4QTE=XouL$XDf@F`(g_l7R| zaDei35I`d&u*q#~43(wOgc32&>Yw`5kbO>{)93U#{VCG_1pom5|G|4*s{kMa0CwAW AlmGw# literal 0 HcmV?d00001 diff --git a/helm/argo-cd/ci/default-values.yaml b/helm/argo-cd/ci/default-values.yaml new file mode 100644 index 0000000..ffc41c8 --- /dev/null +++ b/helm/argo-cd/ci/default-values.yaml @@ -0,0 +1,3 @@ +# Test with default values +crds: + keep: false diff --git a/helm/argo-cd/ci/external-redis-values.yaml b/helm/argo-cd/ci/external-redis-values.yaml new file mode 100644 index 0000000..74409b7 --- /dev/null +++ b/helm/argo-cd/ci/external-redis-values.yaml @@ -0,0 +1,12 @@ +crds: + keep: false + +redis: + enabled: false + +redis-ha: + enabled: false + +externalRedis: + host: "redis-master.redis.svc.cluster.local" + password: "argocd" diff --git a/helm/argo-cd/ci/ha-autoscaling-values.yaml b/helm/argo-cd/ci/ha-autoscaling-values.yaml new file mode 100644 index 0000000..6e994e3 --- /dev/null +++ b/helm/argo-cd/ci/ha-autoscaling-values.yaml @@ -0,0 +1,16 @@ +# Test High Availability with autoscaling +crds: + keep: false + +redis-ha: + enabled: true + +server: + autoscaling: + enabled: true + minReplicas: 2 + +repoServer: + autoscaling: + enabled: true + minReplicas: 2 diff --git a/helm/argo-cd/ci/ha-static-values.yaml b/helm/argo-cd/ci/ha-static-values.yaml new file mode 100644 index 0000000..ad5efd3 --- /dev/null +++ b/helm/argo-cd/ci/ha-static-values.yaml @@ -0,0 +1,12 @@ +# Test High Availability without autoscaling +crds: + keep: false + +redis-ha: + enabled: true + +server: + replicas: 2 + +repoServer: + replicas: 2 diff --git a/helm/argo-cd/override-values.yaml b/helm/argo-cd/override-values.yaml new file mode 100644 index 0000000..bb9dfce --- /dev/null +++ b/helm/argo-cd/override-values.yaml @@ -0,0 +1,29 @@ +controller: + metrics: + enabled: true + +redis-ha: + enabled: true + +server: + autoscaling: + enabled: true + minReplicas: 3 + service: + type: NodePort + nodePortHttp: 30080 + nodePortHttps: 30443 + metrics: + enabled: true + +repoServer: + autoscaling: + enabled: true + minReplicas: 3 + metrics: + enabled: true + +applicationSet: + replicaCount: 3 + metrics: + enabled: true \ No newline at end of file diff --git a/helm/argo-cd/templates/NOTES.txt b/helm/argo-cd/templates/NOTES.txt new file mode 100644 index 0000000..d79d95f --- /dev/null +++ b/helm/argo-cd/templates/NOTES.txt @@ -0,0 +1,143 @@ +{{- if .Values.controller.args.statusProcessors }} +DEPRECATED option controller.args.statusProcessors - Use configs.params.controller.status.processors +{{- end }} +{{- if .Values.controller.args.operationProcessors }} +DEPRECATED option controller.args.operationProcessors - Use configs.params.controller.operation.processors +{{- end }} +{{- if .Values.controller.args.appResyncPeriod }} +DEPRECATED option controller.args.appResyncPeriod - Use server.config.timeout.reconciliation +{{- end }} +{{- if .Values.controller.args.appHardResyncPeriod }} +DEPRECATED option controller.args.appHardResyncPeriod - Use server.config.timeout.hard.reconciliation +{{- end }} +{{- if .Values.controller.args.selfHealTimeout }} +DEPRECATED option controller.args.selfHealTimeout - Use configs.params.controller.self.heal.timeout.seconds +{{- end }} +{{- if .Values.controller.args.repoServerTimeoutSeconds }} +DEPRECATED option controller.args.repoServerTimeoutSeconds - Use configs.params.controller.repo.server.timeout.seconds +{{- end }} +{{- if .Values.controller.logFormat }} +DEPRECATED option controller.logFormat - Use configs.params.controller.log.format +{{- end }} +{{- if .Values.controller.logLevel }} +DEPRECATED option controller.logLevel - Use configs.params.controller.log.level +{{- end }} +{{- if .Values.server.logFormat }} +DEPRECATED option server.logFormat - Use configs.params.server.log.format +{{- end }} +{{- if .Values.server.logLevel }} +DEPRECATED option server.logLevel - Use configs.params.server.log.level +{{- end }} +{{- if has "--insecure" .Values.server.extraArgs }} +DEPRECATED option server.extraArgs."--insecure" - Use configs.params.server.insecure +{{- end }} +{{- if .Values.repoServer.logFormat }} +DEPRECATED option repoServer.logFormat - Use configs.params.repoServer.log.format +{{- end }} +{{- if .Values.repoServer.logLevel }} +DEPRECATED option repoServer.logLevel - Use configs.params.repoServer.log.level +{{- end }} +{{- if or .Values.server.config (hasKey .Values.server "configEnabled") .Values.server.configAnnotations }} +DEPRECATED option server.config - Use configs.cm +{{- end }} +{{- if or .Values.server.rbacConfig (hasKey .Values.server "rbacConfigCreate") .Values.server.rbacConfigAnnotations }} +DEPRECATED option server.rbacConfig - Use configs.rbac +{{- end }} +{{- if .Values.configs.secret.argocdServerTlsConfig }} +DEPRECATED option config.secret.argocdServerTlsConfig - Use server.certificate or server.certificateSecret +{{- end }} +{{- if .Values.configs.gpgKeys }} +DEPRECATED option configs.gpgKeys - Use config.gpg.keys +{{- end }} +{{- if .Values.configs.gpgKeysAnnotations }} +DEPRECATED option configs.gpgKeysAnnotations - Use config.gpg.annotations +{{- end }} +{{- if hasKey (.Values.controller.clusterAdminAccess | default dict) "enabled" }} +DEPRECATED option .controller.clusterAdminAccess.enabled - Use createClusterRoles +{{- end }} +{{- if hasKey (.Values.server.clusterAdminAccess | default dict) "enabled" }} +DEPRECATED option .server.clusterAdminAccess.enabled - Use createClusterRoles +{{- end }} +{{- if hasKey (.Values.repoServer.clusterAdminAccess | default dict) "enabled" }} +DEPRECATED option .server.clusterAdminAccess.enabled - Use createClusterRoles +{{- end }} +{{- if .Values.configs.knownHostsAnnotations }} +DEPRECATED option configs.knownHostsAnnotations - Use configs.ssh.annotations +{{- end }} +{{- if hasKey .Values.configs "knownHosts" }} +DEPRECATED option configs.knownHosts.data.ssh_known_hosts - Use configs.ssh.knownHosts +{{- end }} +{{- if .Values.configs.tlsCertsAnnotations }} +DEPRECATED option configs.tlsCertsAnnotations - Use configs.tls.annotations +{{- end }} +{{- if hasKey .Values.configs "tlsCerts" }} +DEPRECATED option configs.tlsCerts.data - Use configs.tls.certificates +{{- end }} +{{- if .Values.applicationSet.logFormat }} +DEPRECATED option applicationSet.logFormat - Use configs.params.applicationsetcontroller.log.format +{{- end }} +{{- if .Values.applicationSet.logLevel }} +DEPRECATED option applicationSet.logLevel - Use configs.params.applicationsetcontroller.log.level +{{- end }} +{{- if .Values.applicationSet.args.policy }} +DEPRECATED option applicationSet.args.policy - Use configs.params.applicationsetcontroller.policy +{{- end }} +{{- if .Values.applicationSet.args.dryRun }} +DEPRECATED option applicationSet.args.dryRun - Use configs.params.applicationsetcontroller.dryRun +{{- end }} +{{- if .Values.controller.service }} +REMOVED option controller.service - Use controller.metrics +{{- end }} +{{- if .Values.repoServer.copyutil }} +REMOVED option repoSever.copyutil.resources - Use repoServer.resources +{{- end }} +{{- if .Values.applicationSet.args.debug }} +REMOVED option applicationSet.args.debug - Use applicationSet.logLevel: debug +{{- end }} +{{- if .Values.applicationSet.args.enableLeaderElection }} +REMOVED option applicationSet.args.enableLeaderElection - Value determined based on replicas +{{- end }} +{{- if .Values.controller.containerPort }} +REMOVED option controller.containerPort - Use controller.containerPorts +{{- end }} +{{- if .Values.server.containerPort }} +REMOVED option server.containerPort - Use server.containerPorts +{{- end }} +{{- if .Values.repoServer.containerPort }} +REMOVED option repoServer.containerPort - Use repoServer.containerPorts +{{- end }} +{{- if .Values.applicationSet.args.metricsAddr }} +REMOVED option applicationSet.args.metricsAddr - Use applicationSet.containerPorts +{{- end }} +{{- if .Values.applicationSet.args.probeBindAddr }} +REMOVED option applicationSet.args.probeBindAddr - Use applicationSet.containerPorts +{{- end }} +{{- if .Values.redis.containerPort }} +REMOVED option redis.containerPort - Use redis.containerPorts +{{- end }} +{{- if .Values.redis.metrics.containerPort }} +REMOVED option redis.metrics.containerPort - Use redis.containerPorts +{{- end }} + +In order to access the server UI you have the following options: + +1. kubectl port-forward service/{{ include "argo-cd.fullname" . }}-server -n {{ .Release.Namespace }} 8080:443 + + and then open the browser on http://localhost:8080 and accept the certificate + +2. enable ingress in the values file `server.ingress.enabled` and either + - Add the annotation for ssl passthrough: https://argo-cd.readthedocs.io/en/stable/operator-manual/ingress/#option-1-ssl-passthrough + - Set the `configs.params."server.insecure"` in the values file and terminate SSL at your ingress: https://argo-cd.readthedocs.io/en/stable/operator-manual/ingress/#option-2-multiple-ingress-objects-and-hosts + + +{{ if eq (toString (index (coalesce .Values.server.config .Values.configs.cm) "admin.enabled")) "true" -}} +After reaching the UI the first time you can login with username: admin and the random password generated during the installation. You can find the password by running: + +kubectl -n {{ .Release.Namespace }} get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d + +(You should delete the initial secret afterwards as suggested by the Getting Started Guide: https://argo-cd.readthedocs.io/en/stable/getting_started/#4-login-using-the-cli) +{{ else if or (index .Values.configs.cm "dex.config") (index .Values.configs.cm "oidc.config") -}} +After reaching the UI the first time you can login using Dex or OIDC. +{{ else -}} +After reaching the UI the first time you cannot login with username and password since you've disabled it. You should enable admin back or configure Dex via `configs.cm.dex.config` or OIDC via `configs.cm.oidc.config`. +{{ end -}} diff --git a/helm/argo-cd/templates/_common.tpl b/helm/argo-cd/templates/_common.tpl new file mode 100644 index 0000000..dd43d0d --- /dev/null +++ b/helm/argo-cd/templates/_common.tpl @@ -0,0 +1,122 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "argo-cd.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 "argo-cd.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 "argo-cd.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create Argo CD app version +*/}} +{{- define "argo-cd.defaultTag" -}} +{{- default .Chart.AppVersion .Values.global.image.tag }} +{{- end -}} + +{{/* +Common labels +*/}} +{{- define "argo-cd.labels" -}} +helm.sh/chart: {{ include "argo-cd.chart" .context }} +{{ include "argo-cd.selectorLabels" (dict "context" .context "component" .component "name" .name) }} +app.kubernetes.io/managed-by: {{ .context.Release.Service }} +app.kubernetes.io/part-of: argocd +{{- with .context.Values.global.additionalLabels }} +{{ toYaml . }} +{{- end }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "argo-cd.selectorLabels" -}} +{{- if .name -}} +app.kubernetes.io/name: {{ include "argo-cd.name" .context }}-{{ .name }} +{{ end -}} +app.kubernetes.io/instance: {{ .context.Release.Name }} +{{- if .component }} +app.kubernetes.io/component: {{ .component }} +{{- end }} +{{- end }} + +{{/* +Common affinity definition +Pod affinity + - Soft prefers different nodes + - Hard requires different nodes and prefers different availibility zones +Node affinity + - Soft prefers given user expressions + - Hard requires given user expressions +*/}} +{{- define "argo-cd.affinity" -}} +{{- with .component.affinity -}} + {{- toYaml . -}} +{{- else -}} +{{- $preset := .context.Values.global.affinity -}} +{{- if (eq $preset.podAntiAffinity "soft") }} +podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 100 + podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/name: {{ include "argo-cd.name" .context }}-{{ .component.name }} + topologyKey: kubernetes.io/hostname +{{- else if (eq $preset.podAntiAffinity "hard") }} +podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 100 + podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/name: {{ include "argo-cd.name" .context }}-{{ .component.name }} + topologyKey: topology.kubernetes.io/zone + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/name: {{ include "argo-cd.name" .context }}-{{ .component.name }} + topologyKey: kubernetes.io/hostname +{{- end }} +{{- with $preset.nodeAffinity.matchExpressions }} +{{- if (eq $preset.nodeAffinity.type "soft") }} +nodeAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 1 + preference: + matchExpressions: + {{- toYaml . | nindent 6 }} +{{- else if (eq $preset.nodeAffinity.type "hard") }} +nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + {{- toYaml . | nindent 6 }} +{{- end }} +{{- end -}} +{{- end -}} +{{- end -}} diff --git a/helm/argo-cd/templates/_helpers.tpl b/helm/argo-cd/templates/_helpers.tpl new file mode 100644 index 0000000..2338d1c --- /dev/null +++ b/helm/argo-cd/templates/_helpers.tpl @@ -0,0 +1,215 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Create controller name and version as used by the chart label. +Truncated at 52 chars because StatefulSet label 'controller-revision-hash' is limited +to 63 chars and it includes 10 chars of hash and a separating '-'. +*/}} +{{- define "argo-cd.controller.fullname" -}} +{{- printf "%s-%s" (include "argo-cd.fullname" .) .Values.controller.name | trunc 52 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create the name of the controller service account to use +*/}} +{{- define "argo-cd.controllerServiceAccountName" -}} +{{- if .Values.controller.serviceAccount.create -}} + {{ default (include "argo-cd.controller.fullname" .) .Values.controller.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.controller.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +Create dex name and version as used by the chart label. +*/}} +{{- define "argo-cd.dex.fullname" -}} +{{- printf "%s-%s" (include "argo-cd.fullname" .) .Values.dex.name | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create Dex server endpoint +*/}} +{{- define "argo-cd.dex.server" -}} +{{- $insecure := index .Values.configs.params "dexserver.disable.tls" | toString -}} +{{- $scheme := (eq $insecure "true") | ternary "http" "https" -}} +{{- $host := include "argo-cd.dex.fullname" . -}} +{{- $port := int .Values.dex.servicePortHttp -}} +{{- printf "%s://%s:%d" $scheme $host $port }} +{{- end }} + +{{/* +Create the name of the dex service account to use +*/}} +{{- define "argo-cd.dexServiceAccountName" -}} +{{- if .Values.dex.serviceAccount.create -}} + {{ default (include "argo-cd.dex.fullname" .) .Values.dex.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.dex.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +Create redis name and version as used by the chart label. +*/}} +{{- define "argo-cd.redis.fullname" -}} +{{- $redisHa := (index .Values "redis-ha") -}} +{{- $redisHaContext := dict "Chart" (dict "Name" "redis-ha") "Release" .Release "Values" $redisHa -}} +{{- if $redisHa.enabled -}} + {{- if $redisHa.haproxy.enabled -}} + {{- printf "%s-haproxy" (include "redis-ha.fullname" $redisHaContext) | trunc 63 | trimSuffix "-" -}} + {{- end -}} +{{- else -}} +{{- printf "%s-%s" (include "argo-cd.fullname" .) .Values.redis.name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} + +{{/* +Return Redis server endpoint +*/}} +{{- define "argo-cd.redis.server" -}} +{{- $redisHa := (index .Values "redis-ha") -}} +{{- if or (and .Values.redis.enabled (not $redisHa.enabled)) (and $redisHa.enabled $redisHa.haproxy.enabled) }} + {{- printf "%s:%s" (include "argo-cd.redis.fullname" .) (toString .Values.redis.servicePort) }} +{{- else if and .Values.externalRedis.host .Values.externalRedis.port }} + {{- printf "%s:%s" .Values.externalRedis.host (toString .Values.externalRedis.port) }} +{{- end }} +{{- end -}} + +{{/* +Create the name of the redis service account to use +*/}} +{{- define "argo-cd.redisServiceAccountName" -}} +{{- if .Values.redis.serviceAccount.create -}} + {{ default (include "argo-cd.redis.fullname" .) .Values.redis.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.redis.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +Create argocd server name and version as used by the chart label. +*/}} +{{- define "argo-cd.server.fullname" -}} +{{- printf "%s-%s" (include "argo-cd.fullname" .) .Values.server.name | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create the name of the Argo CD server service account to use +*/}} +{{- define "argo-cd.serverServiceAccountName" -}} +{{- if .Values.server.serviceAccount.create -}} + {{ default (include "argo-cd.server.fullname" .) .Values.server.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.server.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +Create argocd repo-server name and version as used by the chart label. +*/}} +{{- define "argo-cd.repoServer.fullname" -}} +{{- printf "%s-%s" (include "argo-cd.fullname" .) .Values.repoServer.name | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create the name of the repo-server service account to use +*/}} +{{- define "argo-cd.repoServerServiceAccountName" -}} +{{- if .Values.repoServer.serviceAccount.create -}} + {{ default (include "argo-cd.repoServer.fullname" .) .Values.repoServer.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.repoServer.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +Create argocd application set name and version as used by the chart label. +*/}} +{{- define "argo-cd.applicationSet.fullname" -}} +{{- printf "%s-%s" (include "argo-cd.fullname" .) .Values.applicationSet.name | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create the name of the application set service account to use +*/}} +{{- define "argo-cd.applicationSetServiceAccountName" -}} +{{- if .Values.applicationSet.serviceAccount.create -}} + {{ default (include "argo-cd.applicationSet.fullname" .) .Values.applicationSet.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.applicationSet.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +Create argocd notifications name and version as used by the chart label. +*/}} +{{- define "argo-cd.notifications.fullname" -}} +{{- printf "%s-%s" (include "argo-cd.fullname" .) .Values.notifications.name | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create the name of the notifications service account to use +*/}} +{{- define "argo-cd.notificationsServiceAccountName" -}} +{{- if .Values.notifications.serviceAccount.create -}} + {{ default (include "argo-cd.notifications.fullname" .) .Values.notifications.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.notifications.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +Argo Configuration Preset Values (Incluenced by Values configuration) +*/}} +{{- define "argo-cd.config.cm.presets" -}} +{{- if .Values.configs.styles -}} +ui.cssurl: "./custom/custom.styles.css" +{{- end -}} +{{- end -}} + +{{/* +Merge Argo Configuration with Preset Configuration +*/}} +{{- define "argo-cd.config.cm" -}} +{{- $config := (mergeOverwrite (deepCopy (omit .Values.configs.cm "create" "annotations")) (.Values.server.config | default dict)) -}} +{{- $preset := include "argo-cd.config.cm.presets" . | fromYaml | default dict -}} +{{- range $key, $value := mergeOverwrite $preset $config }} +{{- $fmted := $value | toString }} +{{- if not (eq $fmted "") }} +{{ $key }}: {{ $fmted | toYaml }} +{{- end }} +{{- end }} +{{- end -}} + +{{/* +Argo Params Default Configuration Presets +*/}} +{{- define "argo-cd.config.params.presets" -}} +repo.server: "{{ include "argo-cd.repoServer.fullname" . }}:{{ .Values.repoServer.service.port }}" +server.repo.server.strict.tls: {{ .Values.repoServer.certificateSecret.enabled | toString }} +{{- with include "argo-cd.redis.server" . }} +redis.server: {{ . | quote }} +{{- end }} +{{- if .Values.dex.enabled }} +server.dex.server: {{ include "argo-cd.dex.server" . | quote }} +server.dex.server.strict.tls: {{ .Values.dex.certificateSecret.enabled | toString }} +{{- end }} +{{- range $component := tuple "applicationsetcontroller" "controller" "server" "reposerver" }} +{{ $component }}.log.format: {{ $.Values.global.logging.format | quote }} +{{ $component }}.log.level: {{ $.Values.global.logging.level | quote }} +{{- end }} +{{- if .Values.applicationSet.enabled }} +applicationsetcontroller.enable.leader.election: {{ gt (.Values.applicationSet.replicaCount | int64) 1 }} +{{- end }} +{{- end -}} + +{{/* +Merge Argo Params Configuration with Preset Configuration +*/}} +{{- define "argo-cd.config.params" -}} +{{- $config := omit .Values.configs.params "annotations" }} +{{- $preset := include "argo-cd.config.params.presets" . | fromYaml | default dict -}} +{{- range $key, $value := mergeOverwrite $preset $config }} +{{ $key }}: {{ toString $value | toYaml }} +{{- end }} +{{- end -}} diff --git a/helm/argo-cd/templates/_versions.tpl b/helm/argo-cd/templates/_versions.tpl new file mode 100644 index 0000000..8240c4b --- /dev/null +++ b/helm/argo-cd/templates/_versions.tpl @@ -0,0 +1,52 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Return the target Kubernetes version +*/}} +{{- define "argo-cd.kubeVersion" -}} +{{- default .Capabilities.KubeVersion.Version .Values.kubeVersionOverride }} +{{- end }} + +{{/* +Return the appropriate apiVersion for autoscaling +*/}} +{{- define "argo-cd.apiVersion.autoscaling" -}} +{{- if .Values.apiVersionOverrides.autoscaling -}} +{{- print .Values.apiVersionOverrides.autoscaling -}} +{{- else if semverCompare "<1.23-0" (include "argo-cd.kubeVersion" .) -}} +{{- print "autoscaling/v2beta1" -}} +{{- else -}} +{{- print "autoscaling/v2" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for cert-manager +*/}} +{{- define "argo-cd.apiVersion.cert-manager" -}} +{{- if .Values.apiVersionOverrides.certmanager -}} +{{- print .Values.apiVersionOverrides.certmanager -}} +{{- else if .Capabilities.APIVersions.Has "cert-manager.io/v1" -}} +{{- print "cert-manager.io/v1" -}} +{{- else if .Capabilities.APIVersions.Has "cert-manager.io/v1beta1" -}} +{{- print "cert-manager.io/v1beta1" -}} +{{- else if .Capabilities.APIVersions.Has "cert-manager.io/v1alpha3" -}} +{{- print "cert-manager.io/v1alpha3" -}} +{{- else if .Capabilities.APIVersions.Has "cert-manager.io/v1alpha2" -}} +{{- print "cert-manager.io/v1alpha2" -}} +{{- else -}} +{{- print "certmanager.k8s.io/v1alpha1" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for GKE resources +*/}} +{{- define "argo-cd.apiVersions.cloudgoogle" -}} +{{- if .Values.apiVersionOverrides.cloudgoogle -}} +{{- print .Values.apiVersionOverrides.cloudgoogle -}} +{{- else if .Capabilities.APIVersions.Has "cloud.google.com/v1" -}} +{{- print "cloud.google.com/v1" -}} +{{- else -}} +{{- print "cloud.google.com/v1beta1" -}} +{{- end -}} +{{- end -}} diff --git a/helm/argo-cd/templates/aggregate-roles.yaml b/helm/argo-cd/templates/aggregate-roles.yaml new file mode 100644 index 0000000..b389392 --- /dev/null +++ b/helm/argo-cd/templates/aggregate-roles.yaml @@ -0,0 +1,85 @@ +{{- if .Values.createAggregateRoles }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "argo-cd.fullname" . }}-aggregate-to-view + labels: + rbac.authorization.k8s.io/aggregate-to-view: "true" + {{- include "argo-cd.labels" (dict "context" .) | nindent 4 }} +rules: +- apiGroups: + - argoproj.io + resources: + - applications + {{- if .Values.applicationSet.enabled }} + - applicationsets + {{- end }} + {{- if .Values.server.extensions.enabled }} + - argocdextensions + {{- end }} + - appprojects + verbs: + - get + - list + - watch + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "argo-cd.fullname" . }}-aggregate-to-edit + labels: + rbac.authorization.k8s.io/aggregate-to-edit: "true" + {{- include "argo-cd.labels" (dict "context" .) | nindent 4 }} +rules: +- apiGroups: + - argoproj.io + resources: + - applications + {{- if .Values.applicationSet.enabled }} + - applicationsets + {{- end }} + {{- if .Values.server.extensions.enabled }} + - argocdextensions + {{- end }} + - appprojects + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "argo-cd.fullname" . }}-aggregate-to-admin + labels: + rbac.authorization.k8s.io/aggregate-to-admin: "true" + {{- include "argo-cd.labels" (dict "context" .) | nindent 4 }} +rules: +- apiGroups: + - argoproj.io + resources: + - applications + {{- if .Values.applicationSet.enabled }} + - applicationsets + {{- end }} + {{- if .Values.server.extensions.enabled }} + - argocdextensions + {{- end }} + - appprojects + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch +{{- end }} diff --git a/helm/argo-cd/templates/argocd-application-controller/clusterrole.yaml b/helm/argo-cd/templates/argocd-application-controller/clusterrole.yaml new file mode 100644 index 0000000..5ebe00b --- /dev/null +++ b/helm/argo-cd/templates/argocd-application-controller/clusterrole.yaml @@ -0,0 +1,24 @@ +{{- $config := .Values.controller.clusterAdminAccess | default dict -}} +{{- if hasKey $config "enabled" | ternary $config.enabled .Values.createClusterRoles }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "argo-cd.controller.fullname" . }} + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.controller.name "name" .Values.controller.name) | nindent 4 }} +rules: + {{- if .Values.controller.clusterRoleRules.enabled }} + {{- toYaml .Values.controller.clusterRoleRules.rules | nindent 2 }} + {{- else }} + - apiGroups: + - '*' + resources: + - '*' + verbs: + - '*' + - nonResourceURLs: + - '*' + verbs: + - '*' + {{- end }} +{{- end }} diff --git a/helm/argo-cd/templates/argocd-application-controller/clusterrolebinding.yaml b/helm/argo-cd/templates/argocd-application-controller/clusterrolebinding.yaml new file mode 100644 index 0000000..39ee80a --- /dev/null +++ b/helm/argo-cd/templates/argocd-application-controller/clusterrolebinding.yaml @@ -0,0 +1,17 @@ +{{- $config := .Values.controller.clusterAdminAccess | default dict -}} +{{- if hasKey $config "enabled" | ternary $config.enabled .Values.createClusterRoles }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "argo-cd.controller.fullname" . }} + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.controller.name "name" .Values.controller.name) | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ include "argo-cd.controller.fullname" . }} +subjects: +- kind: ServiceAccount + name: {{ include "argo-cd.controllerServiceAccountName" . }} + namespace: {{ .Release.Namespace }} +{{- end }} diff --git a/helm/argo-cd/templates/argocd-application-controller/metrics.yaml b/helm/argo-cd/templates/argocd-application-controller/metrics.yaml new file mode 100644 index 0000000..88827a8 --- /dev/null +++ b/helm/argo-cd/templates/argocd-application-controller/metrics.yaml @@ -0,0 +1,25 @@ +{{- if .Values.controller.metrics.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "argo-cd.controller.fullname" . }}-metrics + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.controller.name "name" "metrics") | nindent 4 }} + {{- with .Values.controller.metrics.service.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.controller.metrics.service.annotations }} + annotations: + {{- range $key, $value := . }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} +spec: + ports: + - name: {{ .Values.controller.metrics.service.portName }} + protocol: TCP + port: {{ .Values.controller.metrics.service.servicePort }} + targetPort: metrics + selector: + {{- include "argo-cd.selectorLabels" (dict "context" . "name" .Values.controller.name) | nindent 4 }} +{{- end }} diff --git a/helm/argo-cd/templates/argocd-application-controller/networkpolicy.yaml b/helm/argo-cd/templates/argocd-application-controller/networkpolicy.yaml new file mode 100644 index 0000000..bbb6b32 --- /dev/null +++ b/helm/argo-cd/templates/argocd-application-controller/networkpolicy.yaml @@ -0,0 +1,19 @@ +{{- if .Values.global.networkPolicy.create }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.controller.name "name" .Values.controller.name) | nindent 4 }} + name: {{ template "argo-cd.controller.fullname" . }} +spec: + ingress: + - from: + - namespaceSelector: {} + ports: + - port: metrics + podSelector: + matchLabels: + {{- include "argo-cd.selectorLabels" (dict "context" . "name" .Values.controller.name) | nindent 6 }} + policyTypes: + - Ingress +{{- end }} diff --git a/helm/argo-cd/templates/argocd-application-controller/pdb.yaml b/helm/argo-cd/templates/argocd-application-controller/pdb.yaml new file mode 100644 index 0000000..b6804c5 --- /dev/null +++ b/helm/argo-cd/templates/argocd-application-controller/pdb.yaml @@ -0,0 +1,26 @@ +{{- if .Values.controller.pdb.enabled }} +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: {{ include "argo-cd.controller.fullname" . }} + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.controller.name "name" .Values.controller.name) | nindent 4 }} + {{- with .Values.controller.pdb.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.controller.pdb.annotations }} + annotations: + {{- range $key, $value := . }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} +spec: + {{- with .Values.controller.pdb.maxUnavailable }} + maxUnavailable: {{ . }} + {{- else }} + minAvailable: {{ .Values.controller.pdb.minAvailable | default 0 }} + {{- end }} + selector: + matchLabels: + {{- include "argo-cd.selectorLabels" (dict "context" . "name" .Values.controller.name) | nindent 6 }} +{{- end }} diff --git a/helm/argo-cd/templates/argocd-application-controller/prometheusrule.yaml b/helm/argo-cd/templates/argocd-application-controller/prometheusrule.yaml new file mode 100644 index 0000000..c44a63f --- /dev/null +++ b/helm/argo-cd/templates/argocd-application-controller/prometheusrule.yaml @@ -0,0 +1,26 @@ +{{- if and .Values.controller.metrics.enabled .Values.controller.metrics.rules.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: {{ template "argo-cd.controller.fullname" . }} + {{- if .Values.controller.metrics.rules.namespace }} + namespace: {{ .Values.controller.metrics.rules.namespace }} + {{- end }} + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.controller.name "name" .Values.controller.name) | nindent 4 }} + {{- if .Values.controller.metrics.rules.selector }} +{{- toYaml .Values.controller.metrics.rules.selector | nindent 4 }} + {{- end }} + {{- if .Values.controller.metrics.rules.additionalLabels }} +{{- toYaml .Values.controller.metrics.rules.additionalLabels | nindent 4 }} + {{- end }} + {{- with .Values.controller.metrics.rules.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + groups: + - name: argocd + rules: +{{- toYaml .Values.controller.metrics.rules.spec | nindent 4 }} +{{- end }} diff --git a/helm/argo-cd/templates/argocd-application-controller/role.yaml b/helm/argo-cd/templates/argocd-application-controller/role.yaml new file mode 100644 index 0000000..75aec8d --- /dev/null +++ b/helm/argo-cd/templates/argocd-application-controller/role.yaml @@ -0,0 +1,36 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ template "argo-cd.controller.fullname" . }} + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.controller.name "name" .Values.controller.name) | nindent 4 }} +rules: +- apiGroups: + - "" + resources: + - secrets + - configmaps + verbs: + - get + - list + - watch +- apiGroups: + - argoproj.io + resources: + - applications + - appprojects + verbs: + - create + - get + - list + - watch + - update + - patch + - delete +- apiGroups: + - "" + resources: + - events + verbs: + - create + - list \ No newline at end of file diff --git a/helm/argo-cd/templates/argocd-application-controller/rolebinding.yaml b/helm/argo-cd/templates/argocd-application-controller/rolebinding.yaml new file mode 100644 index 0000000..f37f4b0 --- /dev/null +++ b/helm/argo-cd/templates/argocd-application-controller/rolebinding.yaml @@ -0,0 +1,14 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ template "argo-cd.controller.fullname" . }} + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.controller.name "name" .Values.controller.name) | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "argo-cd.controller.fullname" . }} +subjects: +- kind: ServiceAccount + name: {{ template "argo-cd.controllerServiceAccountName" . }} + namespace: {{ .Release.Namespace }} \ No newline at end of file diff --git a/helm/argo-cd/templates/argocd-application-controller/serviceaccount.yaml b/helm/argo-cd/templates/argocd-application-controller/serviceaccount.yaml new file mode 100644 index 0000000..96d786c --- /dev/null +++ b/helm/argo-cd/templates/argocd-application-controller/serviceaccount.yaml @@ -0,0 +1,18 @@ +{{- if .Values.controller.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +automountServiceAccountToken: {{ .Values.controller.serviceAccount.automountServiceAccountToken }} +metadata: + name: {{ template "argo-cd.controllerServiceAccountName" . }} +{{- if .Values.controller.serviceAccount.annotations }} + annotations: + {{- range $key, $value := .Values.controller.serviceAccount.annotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} +{{- end }} + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.controller.name "name" .Values.controller.name) | nindent 4 }} + {{- range $key, $value := .Values.controller.serviceAccount.labels }} + {{ $key }}: {{ $value | quote }} + {{- end }} +{{- end }} diff --git a/helm/argo-cd/templates/argocd-application-controller/servicemonitor.yaml b/helm/argo-cd/templates/argocd-application-controller/servicemonitor.yaml new file mode 100644 index 0000000..3c8b0ca --- /dev/null +++ b/helm/argo-cd/templates/argocd-application-controller/servicemonitor.yaml @@ -0,0 +1,49 @@ +{{- if and .Values.controller.metrics.enabled .Values.controller.metrics.serviceMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "argo-cd.controller.fullname" . }} + {{- with .Values.controller.metrics.serviceMonitor.namespace }} + namespace: {{ . }} + {{- end }} + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.controller.name "name" .Values.controller.name) | nindent 4 }} + {{- with .Values.controller.metrics.serviceMonitor.selector }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.controller.metrics.serviceMonitor.additionalLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.controller.metrics.serviceMonitor.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + endpoints: + - port: {{ .Values.controller.metrics.service.portName }} + {{- with .Values.controller.metrics.serviceMonitor.interval }} + interval: {{ . }} + {{- end }} + path: /metrics + {{- with .Values.controller.metrics.serviceMonitor.relabelings }} + relabelings: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.controller.metrics.serviceMonitor.metricRelabelings }} + metricRelabelings: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.controller.metrics.serviceMonitor.scheme }} + scheme: {{ . }} + {{- end }} + {{- with .Values.controller.metrics.serviceMonitor.tlsConfig }} + tlsConfig: + {{- toYaml . | nindent 8 }} + {{- end }} + namespaceSelector: + matchNames: + - {{ .Release.Namespace }} + selector: + matchLabels: + {{- include "argo-cd.selectorLabels" (dict "context" . "component" .Values.controller.name "name" "metrics") | nindent 6 }} +{{- end }} diff --git a/helm/argo-cd/templates/argocd-application-controller/statefulset.yaml b/helm/argo-cd/templates/argocd-application-controller/statefulset.yaml new file mode 100644 index 0000000..ad8cbc1 --- /dev/null +++ b/helm/argo-cd/templates/argocd-application-controller/statefulset.yaml @@ -0,0 +1,320 @@ +apiVersion: apps/v1 +kind: StatefulSet +metadata: + {{- with (mergeOverwrite (deepCopy .Values.global.statefulsetAnnotations) .Values.controller.statefulsetAnnotations) }} + annotations: + {{- range $key, $value := . }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} + name: {{ template "argo-cd.controller.fullname" . }} + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.controller.name "name" .Values.controller.name) | nindent 4 }} +spec: + replicas: {{ .Values.controller.replicas }} + # TODO: Remove for breaking release as history limit cannot be patched + revisionHistoryLimit: 5 + serviceName: {{ include "argo-cd.controller.fullname" . }} + selector: + matchLabels: + {{- include "argo-cd.selectorLabels" (dict "context" . "name" .Values.controller.name) | nindent 6 }} + template: + metadata: + annotations: + checksum/cmd-params: {{ include (print $.Template.BasePath "/argocd-configs/argocd-cmd-params-cm.yaml") . | sha256sum }} + {{- with (mergeOverwrite (deepCopy .Values.global.podAnnotations) .Values.controller.podAnnotations) }} + {{- range $key, $value := . }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.controller.name "name" .Values.controller.name) | nindent 8 }} + {{- with (mergeOverwrite (deepCopy .Values.global.podLabels) .Values.controller.podLabels) }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- with .Values.controller.imagePullSecrets | default .Values.global.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.global.hostAliases }} + hostAliases: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.global.securityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.controller.priorityClassName | default .Values.global.priorityClassName }} + priorityClassName: {{ . }} + {{- end }} + serviceAccountName: {{ include "argo-cd.controllerServiceAccountName" . }} + containers: + - command: + - argocd-application-controller + - --metrics-port={{ .Values.controller.containerPorts.metrics }} + {{- if .Values.controller.metrics.applicationLabels.enabled }} + {{- range .Values.controller.metrics.applicationLabels.labels }} + - --metrics-application-labels + - {{ . }} + {{- end }} + {{- end }} + {{- with .Values.controller.args.statusProcessors }} + - --status-processors + - {{ . | quote }} + {{- end }} + {{- with .Values.controller.args.operationProcessors }} + - --operation-processors + - {{ . | quote }} + {{- end }} + {{- with .Values.controller.args.appResyncPeriod }} + - --app-resync + - {{ . | quote }} + {{- end }} + {{- with .Values.controller.args.appHardResyncPeriod }} + - --app-hard-resync + - {{ . | quote }} + {{- end }} + {{- with .Values.controller.args.selfHealTimeout }} + - --self-heal-timeout-seconds + - {{ . | quote }} + {{- end }} + {{- with .Values.controller.args.repoServerTimeoutSeconds }} + - --repo-server-timeout-seconds + - {{ . | quote }} + {{- end }} + {{- with .Values.controller.logFormat }} + - --logformat + - {{ . | quote }} + {{- end }} + {{- with .Values.controller.logLevel }} + - --loglevel + - {{ . | quote }} + {{- end }} + {{- with .Values.controller.extraArgs }} + {{- toYaml . | nindent 8 }} + {{- end }} + image: {{ default .Values.global.image.repository .Values.controller.image.repository }}:{{ default (include "argo-cd.defaultTag" .) .Values.controller.image.tag }} + imagePullPolicy: {{ default .Values.global.image.imagePullPolicy .Values.controller.image.imagePullPolicy }} + name: {{ .Values.controller.name }} + env: + {{- with .Values.controller.env }} + {{- toYaml . | nindent 10 }} + {{- end }} + - name: ARGOCD_CONTROLLER_REPLICAS + value: {{ .Values.controller.replicas | quote }} + - name: ARGOCD_RECONCILIATION_TIMEOUT + valueFrom: + configMapKeyRef: + name: argocd-cm + key: timeout.reconciliation + optional: true + - name: ARGOCD_HARD_RECONCILIATION_TIMEOUT + valueFrom: + configMapKeyRef: + name: argocd-cm + key: timeout.hard.reconciliation + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: repo.server + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER_TIMEOUT_SECONDS + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: controller.repo.server.timeout.seconds + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_STATUS_PROCESSORS + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: controller.status.processors + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_OPERATION_PROCESSORS + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: controller.operation.processors + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_LOGFORMAT + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: controller.log.format + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_LOGLEVEL + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: controller.log.level + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_METRICS_CACHE_EXPIRATION + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: controller.metrics.cache.expiration + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_TIMEOUT_SECONDS + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: controller.self.heal.timeout.seconds + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER_PLAINTEXT + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: controller.repo.server.plaintext + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER_STRICT_TLS + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: controller.repo.server.strict.tls + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_PERSIST_RESOURCE_HEALTH + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: controller.resource.health.persist + optional: true + - name: ARGOCD_APP_STATE_CACHE_EXPIRATION + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: controller.app.state.cache.expiration + optional: true + - name: REDIS_SERVER + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: redis.server + optional: true + - name: REDIS_COMPRESSION + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: redis.compression + optional: true + - name: REDISDB + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: redis.db + optional: true + - name: REDIS_USERNAME + valueFrom: + secretKeyRef: + name: {{ default (include "argo-cd.redis.fullname" .) .Values.externalRedis.existingSecret }} + key: redis-username + optional: true + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + name: {{ default (include "argo-cd.redis.fullname" .) .Values.externalRedis.existingSecret }} + key: redis-password + optional: true + - name: ARGOCD_DEFAULT_CACHE_EXPIRATION + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: controller.default.cache.expiration + optional: true + - name: ARGOCD_APPLICATION_CONTROLLER_OTLP_ADDRESS + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: otlp.address + optional: true + - name: ARGOCD_APPLICATION_NAMESPACES + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: application.namespaces + optional: true + {{- with .Values.controller.envFrom }} + envFrom: + {{- toYaml . | nindent 10 }} + {{- end }} + ports: + - name: metrics + containerPort: {{ .Values.controller.containerPorts.metrics }} + protocol: TCP + readinessProbe: + httpGet: + path: /healthz + port: metrics + initialDelaySeconds: {{ .Values.controller.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.controller.readinessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.controller.readinessProbe.timeoutSeconds }} + successThreshold: {{ .Values.controller.readinessProbe.successThreshold }} + failureThreshold: {{ .Values.controller.readinessProbe.failureThreshold }} + resources: + {{- toYaml .Values.controller.resources | nindent 10 }} + securityContext: + {{- toYaml .Values.controller.containerSecurityContext | nindent 10 }} + workingDir: /home/argocd + volumeMounts: + {{- with .Values.controller.volumeMounts }} + {{- toYaml . | nindent 8 }} + {{- end }} + - mountPath: /app/config/controller/tls + name: argocd-repo-server-tls + - mountPath: /home/argocd + name: argocd-home + {{- with .Values.controller.extraContainers }} + {{- tpl (toYaml .) $ | nindent 6 }} + {{- end }} + {{- with .Values.controller.initContainers }} + initContainers: + {{- tpl (toYaml .) $ | nindent 6 }} + {{- end }} + {{- with include "argo-cd.affinity" (dict "context" . "component" .Values.controller) }} + affinity: + {{- trim . | nindent 8 }} + {{- end }} + {{- with .Values.controller.nodeSelector | default .Values.global.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.controller.tolerations | default .Values.global.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.controller.topologySpreadConstraints | default .Values.global.topologySpreadConstraints }} + topologySpreadConstraints: + {{- range $constraint := . }} + - {{ toYaml $constraint | nindent 8 | trim }} + {{- if not $constraint.labelSelector }} + labelSelector: + matchLabels: + {{- include "argo-cd.selectorLabels" (dict "context" $ "name" $.Values.controller.name) | nindent 12 }} + {{- end }} + {{- end }} + {{- end }} + volumes: + {{- with .Values.controller.volumes }} + {{- toYaml . | nindent 6 }} + {{- end }} + - name: argocd-home + emptyDir: {} + - name: argocd-repo-server-tls + secret: + secretName: argocd-repo-server-tls + optional: true + items: + - key: tls.crt + path: tls.crt + - key: tls.key + path: tls.key + - key: ca.crt + path: ca.crt + hostNetwork: {{ .Values.controller.hostNetwork }} + {{- with .Values.controller.dnsConfig }} + dnsConfig: + {{- toYaml . | nindent 8 }} + {{- end }} + dnsPolicy: {{ .Values.controller.dnsPolicy }} diff --git a/helm/argo-cd/templates/argocd-applicationset/deployment.yaml b/helm/argo-cd/templates/argocd-applicationset/deployment.yaml new file mode 100644 index 0000000..c737fb5 --- /dev/null +++ b/helm/argo-cd/templates/argocd-applicationset/deployment.yaml @@ -0,0 +1,249 @@ +{{- if .Values.applicationSet.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + {{- with (mergeOverwrite (deepCopy .Values.global.deploymentAnnotations) .Values.applicationSet.deploymentAnnotations) }} + annotations: + {{- range $key, $value := . }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} + name: {{ include "argo-cd.applicationSet.fullname" . }} + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.applicationSet.name "name" .Values.applicationSet.name) | nindent 4 }} +spec: + replicas: {{ .Values.applicationSet.replicaCount }} + revisionHistoryLimit: {{ .Values.global.revisionHistoryLimit }} + selector: + matchLabels: + {{- include "argo-cd.selectorLabels" (dict "context" . "name" .Values.applicationSet.name) | nindent 6 }} + template: + metadata: + {{- with (mergeOverwrite (deepCopy .Values.global.podAnnotations) .Values.applicationSet.podAnnotations) }} + annotations: + {{- range $key, $value := . }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.applicationSet.name "name" .Values.applicationSet.name) | nindent 8 }} + {{- with (mergeOverwrite (deepCopy .Values.global.podLabels) .Values.applicationSet.podLabels) }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- with .Values.applicationSet.imagePullSecrets | default .Values.global.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.global.hostAliases }} + hostAliases: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.global.securityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.applicationSet.priorityClassName | default .Values.global.priorityClassName }} + priorityClassName: {{ . }} + {{- end }} + serviceAccountName: {{ include "argo-cd.applicationSetServiceAccountName" . }} + containers: + - name: {{ .Values.applicationSet.name }} + image: {{ default .Values.global.image.repository .Values.applicationSet.image.repository }}:{{ default (include "argo-cd.defaultTag" .) .Values.applicationSet.image.tag }} + imagePullPolicy: {{ default .Values.global.image.imagePullPolicy .Values.applicationSet.image.imagePullPolicy }} + command: + - entrypoint.sh + - argocd-applicationset-controller + - --metrics-addr=:{{ .Values.applicationSet.containerPorts.metrics }} + - --probe-addr=:{{ .Values.applicationSet.containerPorts.probe }} + - --webhook-addr=:{{ .Values.applicationSet.containerPorts.webhook }} + {{- with .Values.applicationSet.args.policy }} + - --policy={{ . }} + {{- end }} + {{- with .Values.applicationSet.args.dryRun }} + - --dry-run={{ . }} + {{- end }} + {{- with .Values.applicationSet.logFormat }} + - --logformat + - {{ . }} + {{- end }} + {{- with .Values.applicationSet.logLevel }} + - --loglevel + - {{ . }} + {{- end }} + {{- with .Values.applicationSet.extraArgs }} + {{- toYaml . | nindent 12 }} + {{- end }} + env: + {{- with .Values.applicationSet.extraEnv }} + {{- toYaml . | nindent 12 }} + {{- end }} + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_LEADER_ELECTION + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.enable.leader.election + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_NAMESPACE + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.namespace + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_REPO_SERVER + valueFrom: + configMapKeyRef: + key: repo.server + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_POLICY + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.policy + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_DEBUG + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.debug + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_LOGFORMAT + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.log.format + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_LOGLEVEL + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.log.level + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_DRY_RUN + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.dryrun + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_GIT_MODULES_ENABLED + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.enable.git.submodule + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_APPLICATIONSET_CONTROLLER_ENABLE_PROGRESSIVE_SYNCS + valueFrom: + configMapKeyRef: + key: applicationsetcontroller.enable.progressive.syncs + name: argocd-cmd-params-cm + optional: true + {{- with .Values.applicationSet.extraEnvFrom }} + envFrom: + {{- toYaml . | nindent 12 }} + {{- end }} + ports: + - name: metrics + containerPort: {{ .Values.applicationSet.containerPorts.metrics }} + protocol: TCP + - name: probe + containerPort: {{ .Values.applicationSet.containerPorts.probe }} + protocol: TCP + - name: webhook + containerPort: {{ .Values.applicationSet.containerPorts.webhook }} + protocol: TCP + {{- if .Values.applicationSet.livenessProbe.enabled }} + livenessProbe: + tcpSocket: + port: probe + initialDelaySeconds: {{ .Values.applicationSet.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.applicationSet.livenessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.applicationSet.livenessProbe.timeoutSeconds }} + successThreshold: {{ .Values.applicationSet.livenessProbe.successThreshold }} + failureThreshold: {{ .Values.applicationSet.livenessProbe.failureThreshold }} + {{- end }} + {{- if .Values.applicationSet.readinessProbe.enabled }} + readinessProbe: + tcpSocket: + port: probe + initialDelaySeconds: {{ .Values.applicationSet.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.applicationSet.readinessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.applicationSet.readinessProbe.timeoutSeconds }} + successThreshold: {{ .Values.applicationSet.readinessProbe.successThreshold }} + failureThreshold: {{ .Values.applicationSet.readinessProbe.failureThreshold }} + {{- end }} + resources: + {{- toYaml .Values.applicationSet.resources | nindent 12 }} + securityContext: + {{- toYaml .Values.applicationSet.containerSecurityContext | nindent 12 }} + volumeMounts: + {{- with .Values.applicationSet.extraVolumeMounts }} + {{- toYaml . | nindent 12 }} + {{- end }} + - mountPath: /app/config/ssh + name: ssh-known-hosts + - mountPath: /app/config/tls + name: tls-certs + - mountPath: /app/config/gpg/source + name: gpg-keys + - mountPath: /app/config/gpg/keys + name: gpg-keyring + - mountPath: /tmp + name: tmp + {{- with .Values.applicationSet.extraContainers }} + {{- tpl (toYaml .) $ | nindent 8 }} + {{- end }} + {{- with .Values.applicationSet.initContainers }} + initContainers: + {{- tpl (toYaml .) $ | nindent 6 }} + {{- end }} + {{- with include "argo-cd.affinity" (dict "context" . "component" .Values.applicationSet) }} + affinity: + {{- trim . | nindent 8 }} + {{- end }} + {{- with .Values.applicationSet.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.applicationSet.tolerations | default .Values.global.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.applicationSet.topologySpreadConstraints | default .Values.global.topologySpreadConstraints }} + topologySpreadConstraints: + {{- range $constraint := . }} + - {{ toYaml $constraint | nindent 8 | trim }} + {{- if not $constraint.labelSelector }} + labelSelector: + matchLabels: + {{- include "argo-cd.selectorLabels" (dict "context" $ "name" $.Values.applicationSet.name) | nindent 12 }} + {{- end }} + {{- end }} + {{- end }} + volumes: + {{- with .Values.applicationSet.extraVolumes }} + {{- toYaml . | nindent 8 }} + {{- end }} + - name: ssh-known-hosts + configMap: + name: argocd-ssh-known-hosts-cm + - name: tls-certs + configMap: + name: argocd-tls-certs-cm + - name: gpg-keys + configMap: + name: argocd-gpg-keys-cm + - name: gpg-keyring + emptyDir: {} + - name: tmp + emptyDir: {} + {{- with .Values.applicationSet.dnsConfig }} + dnsConfig: + {{- toYaml . | nindent 8 }} + {{- end }} + dnsPolicy: {{ .Values.applicationSet.dnsPolicy }} +{{- end }} diff --git a/helm/argo-cd/templates/argocd-applicationset/metrics.yaml b/helm/argo-cd/templates/argocd-applicationset/metrics.yaml new file mode 100644 index 0000000..7a9397c --- /dev/null +++ b/helm/argo-cd/templates/argocd-applicationset/metrics.yaml @@ -0,0 +1,25 @@ +{{- if and .Values.applicationSet.enabled .Values.applicationSet.metrics.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "argo-cd.applicationSet.fullname" . }}-metrics + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.applicationSet.name "name" "metrics") | nindent 4 }} + {{- with .Values.applicationSet.metrics.service.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.applicationSet.metrics.service.annotations }} + annotations: + {{- range $key, $value := . }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} +spec: + ports: + - name: {{ .Values.applicationSet.metrics.service.portName }} + protocol: TCP + port: {{ .Values.applicationSet.metrics.service.servicePort }} + targetPort: metrics + selector: + {{- include "argo-cd.selectorLabels" (dict "context" . "name" .Values.applicationSet.name) | nindent 4 }} +{{- end }} diff --git a/helm/argo-cd/templates/argocd-applicationset/networkpolicy.yaml b/helm/argo-cd/templates/argocd-applicationset/networkpolicy.yaml new file mode 100644 index 0000000..176de64 --- /dev/null +++ b/helm/argo-cd/templates/argocd-applicationset/networkpolicy.yaml @@ -0,0 +1,25 @@ +{{- if and .Values.applicationSet.enabled .Values.global.networkPolicy.create (or .Values.applicationSet.metrics.enabled .Values.applicationSet.webhook.ingress.enabled) }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ template "argo-cd.applicationSet.fullname" . }} + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.applicationSet.name "name" .Values.applicationSet.name) | nindent 4 }} +spec: + ingress: + {{- if .Values.applicationSet.webhook.ingress.enabled }} + - ports: + - port: webhook + {{- end }} + {{- if .Values.applicationSet.metrics.enabled }} + - from: + - namespaceSelector: {} + ports: + - port: metrics + {{- end }} + podSelector: + matchLabels: + {{- include "argo-cd.selectorLabels" (dict "context" . "name" .Values.applicationSet.name) | nindent 6 }} + policyTypes: + - Ingress +{{- end }} diff --git a/helm/argo-cd/templates/argocd-applicationset/pdb.yaml b/helm/argo-cd/templates/argocd-applicationset/pdb.yaml new file mode 100644 index 0000000..5197435 --- /dev/null +++ b/helm/argo-cd/templates/argocd-applicationset/pdb.yaml @@ -0,0 +1,26 @@ +{{- if and .Values.applicationSet.enabled .Values.applicationSet.pdb.enabled }} +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: {{ include "argo-cd.applicationSet.fullname" . }} + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.applicationSet.name "name" .Values.applicationSet.name) | nindent 4 }} + {{- with .Values.applicationSet.pdb.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.applicationSet.pdb.annotations }} + annotations: + {{- range $key, $value := . }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} +spec: + {{- with .Values.applicationSet.pdb.maxUnavailable }} + maxUnavailable: {{ . }} + {{- else }} + minAvailable: {{ .Values.applicationSet.pdb.minAvailable | default 0 }} + {{- end }} + selector: + matchLabels: + {{- include "argo-cd.selectorLabels" (dict "context" . "name" .Values.applicationSet.name) | nindent 6 }} +{{- end }} diff --git a/helm/argo-cd/templates/argocd-applicationset/role.yaml b/helm/argo-cd/templates/argocd-applicationset/role.yaml new file mode 100644 index 0000000..a9ec2f9 --- /dev/null +++ b/helm/argo-cd/templates/argocd-applicationset/role.yaml @@ -0,0 +1,88 @@ +{{- if .Values.applicationSet.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ include "argo-cd.applicationSet.fullname" . }} + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.applicationSet.name "name" .Values.applicationSet.name) | nindent 4 }} +rules: + - apiGroups: + - argoproj.io + resources: + - applications + - applicationsets + - applicationsets/finalizers + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - argoproj.io + resources: + - applicationsets/status + verbs: + - get + - patch + - update + - apiGroups: + - argoproj.io + resources: + - appprojects + verbs: + - get + - apiGroups: + - "" + resources: + - events + verbs: + - create + - get + - list + - patch + - watch + - apiGroups: + - "" + resources: + - configmaps + verbs: + - create + - update + - delete + - get + - list + - patch + - watch + - apiGroups: + - "" + resources: + - secrets + verbs: + - get + - list + - watch + - apiGroups: + - apps + - extensions + resources: + - deployments + verbs: + - get + - list + - watch + - apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +{{- end }} diff --git a/helm/argo-cd/templates/argocd-applicationset/rolebinding.yaml b/helm/argo-cd/templates/argocd-applicationset/rolebinding.yaml new file mode 100644 index 0000000..91cddea --- /dev/null +++ b/helm/argo-cd/templates/argocd-applicationset/rolebinding.yaml @@ -0,0 +1,16 @@ +{{- if .Values.applicationSet.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ template "argo-cd.applicationSet.fullname" . }} + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.applicationSet.name "name" .Values.applicationSet.name) | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "argo-cd.applicationSet.fullname" . }} +subjects: + - kind: ServiceAccount + name: {{ template "argo-cd.applicationSetServiceAccountName" . }} + namespace: {{ .Release.Namespace }} +{{- end }} diff --git a/helm/argo-cd/templates/argocd-applicationset/service.yaml b/helm/argo-cd/templates/argocd-applicationset/service.yaml new file mode 100644 index 0000000..9e0de53 --- /dev/null +++ b/helm/argo-cd/templates/argocd-applicationset/service.yaml @@ -0,0 +1,24 @@ +{{- if .Values.applicationSet.enabled }} +apiVersion: v1 +kind: Service +metadata: +{{- if .Values.applicationSet.service.annotations }} + annotations: + {{- range $key, $value := .Values.applicationSet.service.annotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} +{{- end }} + name: {{ template "argo-cd.applicationSet.fullname" . }} + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.applicationSet.name "name" .Values.applicationSet.name) | nindent 4 }} +{{- with .Values.applicationSet.service.labels }} +{{- toYaml . | nindent 4 }} +{{- end }} +spec: + ports: + - name: {{ .Values.applicationSet.service.portName }} + port: {{ .Values.applicationSet.service.port }} + targetPort: webhook + selector: + {{- include "argo-cd.selectorLabels" (dict "context" . "name" .Values.applicationSet.name) | nindent 4 }} +{{- end }} diff --git a/helm/argo-cd/templates/argocd-applicationset/serviceaccount.yaml b/helm/argo-cd/templates/argocd-applicationset/serviceaccount.yaml new file mode 100644 index 0000000..cf5c0ef --- /dev/null +++ b/helm/argo-cd/templates/argocd-applicationset/serviceaccount.yaml @@ -0,0 +1,18 @@ +{{- if and .Values.applicationSet.enabled .Values.applicationSet.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +automountServiceAccountToken: {{ .Values.applicationSet.serviceAccount.automountServiceAccountToken }} +metadata: + name: {{ template "argo-cd.applicationSetServiceAccountName" . }} +{{- if .Values.applicationSet.serviceAccount.annotations }} + annotations: + {{- range $key, $value := .Values.applicationSet.serviceAccount.annotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} +{{- end }} + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.applicationSet.name "name" .Values.applicationSet.name) | nindent 4 }} + {{- range $key, $value := .Values.applicationSet.serviceAccount.labels }} + {{ $key }}: {{ $value | quote }} + {{- end }} +{{- end }} diff --git a/helm/argo-cd/templates/argocd-applicationset/servicemonitor.yaml b/helm/argo-cd/templates/argocd-applicationset/servicemonitor.yaml new file mode 100644 index 0000000..b836ccc --- /dev/null +++ b/helm/argo-cd/templates/argocd-applicationset/servicemonitor.yaml @@ -0,0 +1,51 @@ +{{- if .Values.applicationSet.enabled }} +{{- if and .Values.applicationSet.metrics.enabled .Values.applicationSet.metrics.serviceMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "argo-cd.applicationSet.fullname" . }} + {{- with .Values.applicationSet.metrics.serviceMonitor.namespace }} + namespace: {{ . }} + {{- end }} + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.applicationSet.name "name" .Values.applicationSet.name) | nindent 4 }} + {{- with .Values.applicationSet.metrics.serviceMonitor.selector }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.applicationSet.metrics.serviceMonitor.additionalLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.applicationSet.metrics.serviceMonitor.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + endpoints: + - port: {{ .Values.applicationSet.metrics.service.portName }} + {{- with .Values.applicationSet.metrics.serviceMonitor.interval }} + interval: {{ . }} + {{- end }} + path: /metrics + {{- with .Values.applicationSet.metrics.serviceMonitor.relabelings }} + relabelings: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.applicationSet.metrics.serviceMonitor.metricRelabelings }} + metricRelabelings: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.applicationSet.metrics.serviceMonitor.scheme }} + scheme: {{ . }} + {{- end }} + {{- with .Values.applicationSet.metrics.serviceMonitor.tlsConfig }} + tlsConfig: + {{- toYaml . | nindent 8 }} + {{- end }} + namespaceSelector: + matchNames: + - {{ .Release.Namespace }} + selector: + matchLabels: + {{- include "argo-cd.selectorLabels" (dict "context" . "component" .Values.applicationSet.name "name" "metrics") | nindent 6 }} +{{- end }} +{{- end }} diff --git a/helm/argo-cd/templates/argocd-applicationset/webhook-ingress.yaml b/helm/argo-cd/templates/argocd-applicationset/webhook-ingress.yaml new file mode 100644 index 0000000..5285c6f --- /dev/null +++ b/helm/argo-cd/templates/argocd-applicationset/webhook-ingress.yaml @@ -0,0 +1,72 @@ +{{- if and .Values.applicationSet.enabled .Values.applicationSet.webhook.ingress.enabled -}} +{{- $servicePort := .Values.applicationSet.service.portName -}} +{{- $paths := .Values.applicationSet.webhook.ingress.paths -}} +{{- $extraPaths := .Values.applicationSet.webhook.ingress.extraPaths -}} +{{- $pathType := .Values.applicationSet.webhook.ingress.pathType -}} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ include "argo-cd.applicationSet.fullname" . }} + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.applicationSet.name "name" .Values.applicationSet.name) | nindent 4 }} + {{- with .Values.applicationSet.webhook.ingress.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.applicationSet.webhook.ingress.annotations }} + annotations: + {{- range $key, $value := . }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} +spec: + {{- with .Values.applicationSet.webhook.ingress.ingressClassName }} + ingressClassName: {{ . }} + {{- end }} + rules: + {{- if .Values.applicationSet.webhook.ingress.hosts }} + {{- range $host := .Values.applicationSet.webhook.ingress.hosts }} + - host: {{ $host }} + http: + paths: + {{- with $extraPaths }} + {{- toYaml . | nindent 10 }} + {{- end }} + {{- range $p := $paths }} + - path: {{ $p }} + pathType: {{ $pathType }} + backend: + service: + name: {{ include "argo-cd.applicationSet.fullname" $ }} + port: + {{- if kindIs "float64" $servicePort }} + number: {{ $servicePort }} + {{- else }} + name: {{ $servicePort }} + {{- end }} + {{- end -}} + {{- end -}} + {{- else }} + - http: + paths: + {{- with $extraPaths }} + {{- toYaml . | nindent 10 }} + {{- end }} + {{- range $p := $paths }} + - path: {{ $p }} + pathType: {{ $pathType }} + backend: + service: + name: {{ include "argo-cd.applicationSet.fullname" $ }} + port: + {{- if kindIs "float64" $servicePort }} + number: {{ $servicePort }} + {{- else }} + name: {{ $servicePort }} + {{- end }} + {{- end -}} + {{- end -}} + {{- with .Values.applicationSet.webhook.ingress.tls }} + tls: + {{- toYaml . | nindent 4 }} + {{- end -}} +{{- end -}} diff --git a/helm/argo-cd/templates/argocd-configs/argocd-cm.yaml b/helm/argo-cd/templates/argocd-configs/argocd-cm.yaml new file mode 100644 index 0000000..a9ff71d --- /dev/null +++ b/helm/argo-cd/templates/argocd-configs/argocd-cm.yaml @@ -0,0 +1,16 @@ +{{- if (hasKey .Values.server "configEnabled") | ternary .Values.server.configEnabled .Values.configs.cm.create }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: argocd-cm + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.server.name "name" "cm") | nindent 4 }} + {{- with (mergeOverwrite (deepCopy .Values.configs.cm.annotations) (.Values.server.configAnnotations | default dict)) }} + annotations: + {{- range $key, $value := . }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} +data: + {{- include "argo-cd.config.cm" . | trim | nindent 2 }} +{{- end }} diff --git a/helm/argo-cd/templates/argocd-configs/argocd-cmd-params-cm.yaml b/helm/argo-cd/templates/argocd-configs/argocd-cmd-params-cm.yaml new file mode 100644 index 0000000..0628ff9 --- /dev/null +++ b/helm/argo-cd/templates/argocd-configs/argocd-cmd-params-cm.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: argocd-cmd-params-cm + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.server.name "name" "cmd-params-cm") | nindent 4 }} + {{- if .Values.configs.params.annotations }} + annotations: + {{- range $key, $value := .Values.configs.params.annotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} +data: + {{- include "argo-cd.config.params" . | trim | nindent 2 }} diff --git a/helm/argo-cd/templates/argocd-configs/argocd-cmp-cm.yaml b/helm/argo-cd/templates/argocd-configs/argocd-cmp-cm.yaml new file mode 100644 index 0000000..39a6db6 --- /dev/null +++ b/helm/argo-cd/templates/argocd-configs/argocd-cmp-cm.yaml @@ -0,0 +1,24 @@ +{{- if .Values.configs.cmp.create }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: argocd-cmp-cm + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.repoServer.name "name" "cmp-cm") | nindent 4 }} + {{- with .Values.configs.cmp.annotations }} + annotations: + {{- range $key, $value := . }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} +data: + {{- range $cmp_plugin, $cmp_plugin_config := .Values.configs.cmp.plugins }} + {{ $cmp_plugin }}.yaml: | + apiVersion: argoproj.io/v1alpha1 + kind: ConfigManagementPlugin + metadata: + name: {{ $cmp_plugin }} + spec: + {{- toYaml $cmp_plugin_config | nindent 6 }} + {{- end }} +{{- end }} diff --git a/helm/argo-cd/templates/argocd-configs/argocd-dex-server-tls-secret.yaml b/helm/argo-cd/templates/argocd-configs/argocd-dex-server-tls-secret.yaml new file mode 100644 index 0000000..7e3ae6b --- /dev/null +++ b/helm/argo-cd/templates/argocd-configs/argocd-dex-server-tls-secret.yaml @@ -0,0 +1,24 @@ +{{- if and .Values.dex.enabled .Values.dex.certificateSecret.enabled }} +apiVersion: v1 +kind: Secret +metadata: + name: argocd-dex-server-tls + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.dex.name "name" "dex-server-tls") | nindent 4 }} + {{- with .Values.dex.certificateSecret.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.dex.certificateSecret.annotations }} + annotations: + {{- range $key, $value := . }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} +type: kubernetes.io/tls +data: + {{- with .Values.dex.certificateSecret.ca }} + ca.crt: {{ . | b64enc | quote }} + {{- end }} + tls.crt: {{ .Values.dex.certificateSecret.crt | b64enc | quote }} + tls.key: {{ .Values.dex.certificateSecret.key | b64enc | quote }} +{{- end }} diff --git a/helm/argo-cd/templates/argocd-configs/argocd-gpg-keys-cm.yaml b/helm/argo-cd/templates/argocd-configs/argocd-gpg-keys-cm.yaml new file mode 100644 index 0000000..72f9823 --- /dev/null +++ b/helm/argo-cd/templates/argocd-configs/argocd-gpg-keys-cm.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: argocd-gpg-keys-cm + labels: + {{- include "argo-cd.labels" (dict "context" . "name" "gpg-keys-cm") | nindent 4 }} + {{ with (mergeOverwrite (deepCopy .Values.configs.gpg.annotations) (.Values.configs.gpgKeysAnnotations | default dict)) -}} + annotations: + {{- range $key, $value := . }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} +{{ with (mergeOverwrite (deepCopy .Values.configs.gpg.keys) (.Values.configs.gpgKeys | default dict)) -}} +data: + {{- toYaml . | nindent 2 }} +{{- end }} diff --git a/helm/argo-cd/templates/argocd-configs/argocd-notifications-cm.yaml b/helm/argo-cd/templates/argocd-configs/argocd-notifications-cm.yaml new file mode 100644 index 0000000..593da72 --- /dev/null +++ b/helm/argo-cd/templates/argocd-configs/argocd-notifications-cm.yaml @@ -0,0 +1,27 @@ +{{- if and .Values.notifications.enabled .Values.notifications.cm.create }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: argocd-notifications-cm + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.notifications.name "name" .Values.notifications.name) | nindent 4 }} +data: + context: | + argocdUrl: {{ .Values.notifications.argocdUrl | quote }} + {{- with .Values.notifications.context }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.notifications.notifiers }} + {{- toYaml . | nindent 2 }} + {{- end }} + {{- with .Values.notifications.subscriptions }} + subscriptions: | + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.notifications.templates }} + {{- toYaml . | nindent 2 }} + {{- end }} + {{- with .Values.notifications.triggers }} + {{- toYaml . | nindent 2 }} + {{- end }} +{{- end }} diff --git a/helm/argo-cd/templates/argocd-configs/argocd-notifications-secret.yaml b/helm/argo-cd/templates/argocd-configs/argocd-notifications-secret.yaml new file mode 100644 index 0000000..dc5bd38 --- /dev/null +++ b/helm/argo-cd/templates/argocd-configs/argocd-notifications-secret.yaml @@ -0,0 +1,19 @@ +{{- if and .Values.notifications.enabled .Values.notifications.secret.create }} +apiVersion: v1 +kind: Secret +metadata: + name: argocd-notifications-secret + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.notifications.name "name" .Values.notifications.name) | nindent 4 }} + {{- with .Values.notifications.secret.annotations }} + annotations: + {{- range $key, $value := . }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} +type: Opaque +stringData: + {{- with .Values.notifications.secret.items }} + {{- toYaml . | nindent 2 }} + {{- end }} +{{- end }} diff --git a/helm/argo-cd/templates/argocd-configs/argocd-rbac-cm.yaml b/helm/argo-cd/templates/argocd-configs/argocd-rbac-cm.yaml new file mode 100644 index 0000000..8ebb43d --- /dev/null +++ b/helm/argo-cd/templates/argocd-configs/argocd-rbac-cm.yaml @@ -0,0 +1,18 @@ +{{- if (hasKey .Values.server "rbacConfigCreate") | ternary .Values.server.rbacConfigCreate .Values.configs.rbac.create }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: argocd-rbac-cm + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.server.name "name" "rbac-cm") | nindent 4 }} + {{- with (mergeOverwrite (deepCopy .Values.configs.rbac.annotations) (.Values.server.rbacConfigAnnotations | default dict)) }} + annotations: + {{- range $key, $value := . }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} +{{- with (mergeOverwrite (deepCopy (omit .Values.configs.rbac "create" "annotations")) (.Values.server.rbacConfig | default dict)) }} +data: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- end }} diff --git a/helm/argo-cd/templates/argocd-configs/argocd-repo-server-tls-secret.yaml b/helm/argo-cd/templates/argocd-configs/argocd-repo-server-tls-secret.yaml new file mode 100644 index 0000000..b0f35aa --- /dev/null +++ b/helm/argo-cd/templates/argocd-configs/argocd-repo-server-tls-secret.yaml @@ -0,0 +1,24 @@ +{{- if .Values.repoServer.certificateSecret.enabled }} +apiVersion: v1 +kind: Secret +metadata: + name: argocd-repo-server-tls + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.repoServer.name "name" "repo-server-tls") | nindent 4 }} + {{- with .Values.repoServer.certificateSecret.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.repoServer.certificateSecret.annotations }} + annotations: + {{- range $key, $value := . }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} +type: kubernetes.io/tls +data: + {{- with .Values.repoServer.certificateSecret.ca }} + ca.crt: {{ . | b64enc | quote }} + {{- end }} + tls.crt: {{ .Values.repoServer.certificateSecret.crt | b64enc | quote }} + tls.key: {{ .Values.repoServer.certificateSecret.key | b64enc | quote }} +{{- end }} diff --git a/helm/argo-cd/templates/argocd-configs/argocd-secret.yaml b/helm/argo-cd/templates/argocd-configs/argocd-secret.yaml new file mode 100644 index 0000000..84a5119 --- /dev/null +++ b/helm/argo-cd/templates/argocd-configs/argocd-secret.yaml @@ -0,0 +1,48 @@ +{{- if .Values.configs.secret.createSecret }} +apiVersion: v1 +kind: Secret +metadata: + name: argocd-secret + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.server.name "name" "secret") | nindent 4 }} + {{- with .Values.configs.secret.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.configs.secret.annotations }} + annotations: + {{- range $key, $value := . }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} +type: Opaque +{{- if or .Values.configs.secret.githubSecret (or .Values.configs.secret.gitlabSecret .Values.configs.secret.bitbucketUUID .Values.configs.secret.bitbucketServerSecret .Values.configs.secret.gogsSecret .Values.configs.secret.argocdServerAdminPassword .Values.configs.secret.argocdServerTlsConfig .Values.configs.secret.extra) }} +# Setting a blank data again will wipe admin password/key/cert +data: + {{- with .Values.configs.secret.githubSecret }} + webhook.github.secret: {{ . | b64enc }} + {{- end }} + {{- with .Values.configs.secret.gitlabSecret }} + webhook.gitlab.secret: {{ . | b64enc }} + {{- end }} + {{- with .Values.configs.secret.bitbucketServerSecret }} + webhook.bitbucketserver.secret: {{ . | b64enc }} + {{- end }} + {{- with .Values.configs.secret.bitbucketUUID }} + webhook.bitbucket.uuid: {{ . | b64enc }} + {{- end }} + {{- with .Values.configs.secret.gogsSecret }} + webhook.gogs.secret: {{ . | b64enc }} + {{- end }} + {{- with .Values.configs.secret.argocdServerTlsConfig }} + tls.key: {{ .key | b64enc }} + tls.crt: {{ .crt | b64enc }} + {{- end }} + {{- if .Values.configs.secret.argocdServerAdminPassword }} + admin.password: {{ .Values.configs.secret.argocdServerAdminPassword | b64enc }} + admin.passwordMtime: {{ default (dateInZone "2006-01-02T15:04:05Z" (now) "UTC") .Values.configs.secret.argocdServerAdminPasswordMtime | b64enc }} + {{- end }} + {{- range $key, $value := .Values.configs.secret.extra }} + {{ $key }}: {{ $value | b64enc }} + {{- end }} +{{- end }} +{{- end }} diff --git a/helm/argo-cd/templates/argocd-configs/argocd-server-tls-secret.yaml b/helm/argo-cd/templates/argocd-configs/argocd-server-tls-secret.yaml new file mode 100644 index 0000000..1e9f8dd --- /dev/null +++ b/helm/argo-cd/templates/argocd-configs/argocd-server-tls-secret.yaml @@ -0,0 +1,21 @@ +{{- if and .Values.server.certificateSecret.enabled (not .Values.server.certificate.enabled) }} +apiVersion: v1 +kind: Secret +metadata: + name: argocd-server-tls + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.server.name "name" "server-tls") | nindent 4 }} + {{- with .Values.server.certificateSecret.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.server.certificateSecret.annotations }} + annotations: + {{- range $key, $value := . }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} +type: kubernetes.io/tls +data: + tls.crt: {{ .Values.server.certificateSecret.crt | b64enc | quote }} + tls.key: {{ .Values.server.certificateSecret.key | b64enc | quote }} +{{- end }} diff --git a/helm/argo-cd/templates/argocd-configs/argocd-ssh-known-hosts-cm.yaml b/helm/argo-cd/templates/argocd-configs/argocd-ssh-known-hosts-cm.yaml new file mode 100644 index 0000000..7b8e5d0 --- /dev/null +++ b/helm/argo-cd/templates/argocd-configs/argocd-ssh-known-hosts-cm.yaml @@ -0,0 +1,22 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: argocd-ssh-known-hosts-cm + labels: + {{- include "argo-cd.labels" (dict "context" . "name" "ssh-known-hosts-cm") | nindent 4 }} + {{- with (mergeOverwrite (deepCopy .Values.configs.ssh.annotations) (.Values.configs.knownHostsAnnotations | default dict)) }} + annotations: + {{- range $key, $value := . }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} +data: + ssh_known_hosts: | + {{- if hasKey .Values.configs "knownHosts" }} + {{- .Values.configs.knownHosts.data.ssh_known_hosts | nindent 4 }} + {{- else }} + {{- .Values.configs.ssh.knownHosts | nindent 4 }} + {{- end }} + {{- with .Values.configs.ssh.extraHosts }} + {{- . | nindent 4 }} + {{- end }} diff --git a/helm/argo-cd/templates/argocd-configs/argocd-styles-cm.yaml b/helm/argo-cd/templates/argocd-configs/argocd-styles-cm.yaml new file mode 100644 index 0000000..149104f --- /dev/null +++ b/helm/argo-cd/templates/argocd-configs/argocd-styles-cm.yaml @@ -0,0 +1,11 @@ +{{- if .Values.configs.styles }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: argocd-styles-cm + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.repoServer.name "name" .Values.repoServer.name) | nindent 4 }} +data: + custom.styles.css: | + {{- .Values.configs.styles | nindent 4 }} +{{- end }} diff --git a/helm/argo-cd/templates/argocd-configs/argocd-tls-certs-cm.yaml b/helm/argo-cd/templates/argocd-configs/argocd-tls-certs-cm.yaml new file mode 100644 index 0000000..1ba0176 --- /dev/null +++ b/helm/argo-cd/templates/argocd-configs/argocd-tls-certs-cm.yaml @@ -0,0 +1,22 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: argocd-tls-certs-cm + labels: + {{- include "argo-cd.labels" (dict "context" . "name" "tls-certs-cm") | nindent 4 }} + {{- with (mergeOverwrite (deepCopy .Values.configs.tls.annotations) (.Values.configs.tlsCertsAnnotations | default dict)) }} + annotations: + {{- range $key, $value := . }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} +{{- if hasKey .Values.configs "tlsCerts" }} + {{- with .Values.configs.tlsCerts }} + {{- toYaml . | nindent 0 }} + {{- end }} +{{- else }} +{{- with .Values.configs.tls.certificates }} +data: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- end }} diff --git a/helm/argo-cd/templates/argocd-configs/cluster-secrets.yaml b/helm/argo-cd/templates/argocd-configs/cluster-secrets.yaml new file mode 100644 index 0000000..aba14db --- /dev/null +++ b/helm/argo-cd/templates/argocd-configs/cluster-secrets.yaml @@ -0,0 +1,31 @@ +{{- range .Values.configs.clusterCredentials }} +--- +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "argo-cd.name" $ }}-cluster-{{ .name }} + labels: + {{- include "argo-cd.labels" (dict "context" $) | nindent 4 }} + {{- with .labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + argocd.argoproj.io/secret-type: cluster + {{- with .annotations }} + annotations: + {{- range $key, $value := . }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} +type: Opaque +stringData: + name: {{ required "A valid .Values.configs.clusterCredentials[].name entry is required!" .name }} + server: {{ required "A valid .Values.configs.clusterCredentials[].server entry is required!" .server }} + {{- if .namespaces }} + namespaces: {{ .namespaces }} + {{- if .clusterResources }} + clusterResources: {{ .clusterResources | quote }} + {{- end }} + {{- end }} + config: | + {{- required "A valid .Values.configs.clusterCredentials[].config entry is required!" .config | toRawJson | nindent 4 }} +{{- end }} diff --git a/helm/argo-cd/templates/argocd-configs/externalredis-secret.yaml b/helm/argo-cd/templates/argocd-configs/externalredis-secret.yaml new file mode 100644 index 0000000..80dfc47 --- /dev/null +++ b/helm/argo-cd/templates/argocd-configs/externalredis-secret.yaml @@ -0,0 +1,22 @@ +{{- if and (or .Values.externalRedis.username .Values.externalRedis.password) (not .Values.externalRedis.existingSecret) }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "argo-cd.redis.fullname" . }} + labels: + {{- include "argo-cd.labels" (dict "context" $) | nindent 4 }} + {{- with .Values.externalRedis.secretAnnotations }} + annotations: + {{- range $key, $value := . }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} +type: Opaque +data: + {{- with .Values.externalRedis.username }} + redis-username: {{ . | b64enc }} + {{- end }} + {{- with .Values.externalRedis.password }} + redis-password: {{ . | b64enc }} + {{- end }} +{{- end }} diff --git a/helm/argo-cd/templates/argocd-configs/repository-credentials-secret.yaml b/helm/argo-cd/templates/argocd-configs/repository-credentials-secret.yaml new file mode 100644 index 0000000..96efd67 --- /dev/null +++ b/helm/argo-cd/templates/argocd-configs/repository-credentials-secret.yaml @@ -0,0 +1,20 @@ +{{- range $repo_cred_key, $repo_cred_value := .Values.configs.credentialTemplates }} +--- +apiVersion: v1 +kind: Secret +metadata: + name: argocd-repo-creds-{{ $repo_cred_key }} + labels: + argocd.argoproj.io/secret-type: repo-creds + {{- include "argo-cd.labels" (dict "context" $) | nindent 4 }} + {{- with $.Values.configs.credentialTemplatesAnnotations }} + annotations: + {{- range $key, $value := . }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} +data: + {{- range $key, $value := $repo_cred_value }} + {{ $key }}: {{ $value | toString | b64enc }} + {{- end }} +{{- end }} diff --git a/helm/argo-cd/templates/argocd-configs/repository-secret.yaml b/helm/argo-cd/templates/argocd-configs/repository-secret.yaml new file mode 100644 index 0000000..bd0c067 --- /dev/null +++ b/helm/argo-cd/templates/argocd-configs/repository-secret.yaml @@ -0,0 +1,20 @@ +{{- range $repo_key, $repo_value := .Values.configs.repositories }} +--- +apiVersion: v1 +kind: Secret +metadata: + name: argocd-repo-{{ $repo_key }} + labels: + argocd.argoproj.io/secret-type: repository + {{- include "argo-cd.labels" (dict "context" $) | nindent 4 }} + {{- with $.Values.configs.repositoriesAnnotations }} + annotations: + {{- range $key, $value := . }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} +data: + {{- range $key, $value := $repo_value }} + {{ $key }}: {{ $value | b64enc }} + {{- end }} +{{- end }} diff --git a/helm/argo-cd/templates/argocd-notifications/deployment.yaml b/helm/argo-cd/templates/argocd-notifications/deployment.yaml new file mode 100644 index 0000000..45ba1de --- /dev/null +++ b/helm/argo-cd/templates/argocd-notifications/deployment.yaml @@ -0,0 +1,144 @@ +{{- if .Values.notifications.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + {{- with (mergeOverwrite (deepCopy .Values.global.deploymentAnnotations) .Values.notifications.deploymentAnnotations) }} + annotations: + {{- range $key, $value := . }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} + name: {{ include "argo-cd.notifications.fullname" . }} + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.notifications.name "name" .Values.notifications.name) | nindent 4 }} +spec: + replicas: 1 + revisionHistoryLimit: {{ .Values.global.revisionHistoryLimit }} + strategy: + type: Recreate + selector: + matchLabels: + {{- include "argo-cd.selectorLabels" (dict "context" . "name" .Values.notifications.name) | nindent 6 }} + template: + metadata: + {{- with (mergeOverwrite (deepCopy .Values.global.podAnnotations) .Values.notifications.podAnnotations) }} + annotations: + {{- range $key, $value := . }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.notifications.name "name" .Values.notifications.name) | nindent 8 }} + {{- with (mergeOverwrite (deepCopy .Values.global.podLabels) .Values.notifications.podLabels) }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- with .Values.notifications.imagePullSecrets | default .Values.global.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.global.hostAliases }} + hostAliases: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.global.securityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.notifications.priorityClassName | default .Values.global.priorityClassName }} + priorityClassName: {{ . }} + {{- end }} + serviceAccountName: {{ include "argo-cd.notificationsServiceAccountName" . }} + containers: + - name: {{ .Values.notifications.name }} + image: {{ default .Values.global.image.repository .Values.notifications.image.repository }}:{{ default (include "argo-cd.defaultTag" .) .Values.notifications.image.tag }} + imagePullPolicy: {{ default .Values.global.image.imagePullPolicy .Values.notifications.image.imagePullPolicy }} + command: + - argocd-notifications + - --metrics-port={{ .Values.notifications.containerPorts.metrics }} + - --loglevel={{ default .Values.global.logging.level .Values.notifications.logLevel }} + - --logformat={{ default .Values.global.logging.format .Values.notifications.logFormat }} + - --namespace={{ .Release.Namespace }} + - --argocd-repo-server={{ template "argo-cd.repoServer.fullname" . }}:{{ .Values.repoServer.service.port }} + {{- range .Values.notifications.extraArgs }} + - {{ . | squote }} + {{- end }} + {{- with .Values.notifications.extraEnv }} + env: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.notifications.extraEnvFrom }} + envFrom: + {{- toYaml . | nindent 12 }} + {{- end }} + ports: + - name: metrics + containerPort: {{ .Values.notifications.containerPorts.metrics }} + protocol: TCP + resources: + {{- toYaml .Values.notifications.resources | nindent 12 }} + securityContext: + {{- toYaml .Values.notifications.containerSecurityContext | nindent 12 }} + workingDir: /app + volumeMounts: + - name: tls-certs + mountPath: /app/config/tls + - name: argocd-repo-server-tls + mountPath: /app/config/reposerver/tls + {{- with .Values.notifications.extraVolumeMounts }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.notifications.extraContainers }} + {{- tpl (toYaml . ) $ | nindent 8 }} + {{- end }} + {{- with .Values.notifications.initContainers }} + initContainers: + {{- tpl (toYaml . ) $ | nindent 8 }} + {{- end }} + {{- with include "argo-cd.affinity" (dict "context" . "component" .Values.notifications) }} + affinity: + {{- trim . | nindent 8 }} + {{- end }} + {{- with .Values.notifications.nodeSelector | default .Values.global.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.notifications.tolerations | default .Values.global.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.notifications.topologySpreadConstraints | default .Values.global.topologySpreadConstraints }} + topologySpreadConstraints: + {{- range $constraint := . }} + - {{ toYaml $constraint | nindent 8 | trim }} + {{- if not $constraint.labelSelector }} + labelSelector: + matchLabels: + {{- include "argo-cd.selectorLabels" (dict "context" $ "name" $.Values.notifications.name) | nindent 12 }} + {{- end }} + {{- end }} + {{- end }} + volumes: + {{- with .Values.notifications.extraVolumes }} + {{- toYaml . | nindent 8 }} + {{- end }} + - name: tls-certs + configMap: + name: argocd-tls-certs-cm + - name: argocd-repo-server-tls + secret: + secretName: argocd-repo-server-tls + optional: true + items: + - key: tls.crt + path: tls.crt + - key: tls.key + path: tls.key + - key: ca.crt + path: ca.crt + {{- with .Values.notifications.dnsConfig }} + dnsConfig: + {{- toYaml . | nindent 8 }} + {{- end }} + dnsPolicy: {{ .Values.notifications.dnsPolicy }} +{{- end }} diff --git a/helm/argo-cd/templates/argocd-notifications/metrics.yaml b/helm/argo-cd/templates/argocd-notifications/metrics.yaml new file mode 100644 index 0000000..3b80e97 --- /dev/null +++ b/helm/argo-cd/templates/argocd-notifications/metrics.yaml @@ -0,0 +1,25 @@ +{{- if and .Values.notifications.enabled .Values.notifications.metrics.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "argo-cd.notifications.fullname" . }}-metrics + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.notifications.name "name" "metrics") | nindent 4 }} + {{- with .Values.notifications.metrics.service.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.notifications.metrics.service.annotations }} + annotations: + {{- range $key, $value := . }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} +spec: + selector: + {{- include "argo-cd.selectorLabels" (dict "context" . "name" .Values.notifications.name) | nindent 6 }} + ports: + - name: {{ .Values.notifications.metrics.service.portName }} + protocol: TCP + port: {{ .Values.notifications.metrics.port }} + targetPort: metrics +{{- end }} diff --git a/helm/argo-cd/templates/argocd-notifications/networkpolicy.yaml b/helm/argo-cd/templates/argocd-notifications/networkpolicy.yaml new file mode 100644 index 0000000..6bd0c04 --- /dev/null +++ b/helm/argo-cd/templates/argocd-notifications/networkpolicy.yaml @@ -0,0 +1,19 @@ +{{- if and .Values.notifications.enabled .Values.global.networkPolicy.create .Values.notifications.metrics.enabled }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ template "argo-cd.notifications.fullname" . }} + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.notifications.name "name" .Values.notifications.name) | nindent 4 }} +spec: + ingress: + - from: + - namespaceSelector: {} + ports: + - port: metrics + podSelector: + matchLabels: + {{- include "argo-cd.selectorLabels" (dict "context" . "name" .Values.notifications.name) | nindent 6 }} + policyTypes: + - Ingress +{{- end }} diff --git a/helm/argo-cd/templates/argocd-notifications/pdb.yaml b/helm/argo-cd/templates/argocd-notifications/pdb.yaml new file mode 100644 index 0000000..f1f3271 --- /dev/null +++ b/helm/argo-cd/templates/argocd-notifications/pdb.yaml @@ -0,0 +1,26 @@ +{{- if and .Values.notifications.enabled .Values.notifications.pdb.enabled }} +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: {{ include "argo-cd.notifications.fullname" . }} + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.notifications.name "name" .Values.notifications.name) | nindent 4 }} + {{- with .Values.notifications.pdb.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.notifications.pdb.annotations }} + annotations: + {{- range $key, $value := . }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} +spec: + {{- with .Values.notifications.pdb.maxUnavailable }} + maxUnavailable: {{ . }} + {{- else }} + minAvailable: {{ .Values.notifications.pdb.minAvailable | default 0 }} + {{- end }} + selector: + matchLabels: + {{- include "argo-cd.selectorLabels" (dict "context" . "name" .Values.notifications.name) | nindent 6 }} +{{- end }} diff --git a/helm/argo-cd/templates/argocd-notifications/role.yaml b/helm/argo-cd/templates/argocd-notifications/role.yaml new file mode 100644 index 0000000..52df9ad --- /dev/null +++ b/helm/argo-cd/templates/argocd-notifications/role.yaml @@ -0,0 +1,44 @@ +{{- if .Values.notifications.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ template "argo-cd.notifications.fullname" . }} + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.notifications.name "name" .Values.notifications.name) | nindent 4 }} +rules: +- apiGroups: + - argoproj.io + resources: + - applications + - appprojects + verbs: + - get + - list + - watch + - update + - patch +- apiGroups: + - "" + resources: + - configmaps + - secrets + verbs: + - list + - watch +- apiGroups: + - "" + resourceNames: + - argocd-notifications-cm + resources: + - configmaps + verbs: + - get +- apiGroups: + - "" + resourceNames: + - argocd-notifications-secret + resources: + - secrets + verbs: + - get +{{- end }} diff --git a/helm/argo-cd/templates/argocd-notifications/rolebinding.yaml b/helm/argo-cd/templates/argocd-notifications/rolebinding.yaml new file mode 100644 index 0000000..e78ac5c --- /dev/null +++ b/helm/argo-cd/templates/argocd-notifications/rolebinding.yaml @@ -0,0 +1,16 @@ +{{- if .Values.notifications.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ template "argo-cd.notifications.fullname" . }} + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.notifications.name "name" .Values.notifications.name) | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "argo-cd.notifications.fullname" . }} +subjects: + - kind: ServiceAccount + name: {{ template "argo-cd.notificationsServiceAccountName" . }} + namespace: {{ .Release.Namespace }} +{{- end }} diff --git a/helm/argo-cd/templates/argocd-notifications/serviceaccount.yaml b/helm/argo-cd/templates/argocd-notifications/serviceaccount.yaml new file mode 100644 index 0000000..d621928 --- /dev/null +++ b/helm/argo-cd/templates/argocd-notifications/serviceaccount.yaml @@ -0,0 +1,18 @@ +{{- if and .Values.notifications.enabled .Values.notifications.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +automountServiceAccountToken: {{ .Values.notifications.serviceAccount.automountServiceAccountToken }} +metadata: + name: {{ template "argo-cd.notificationsServiceAccountName" . }} +{{- if .Values.notifications.serviceAccount.annotations }} + annotations: + {{- range $key, $value := .Values.notifications.serviceAccount.annotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} +{{- end }} + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.notifications.name "name" .Values.notifications.name) | nindent 4 }} + {{- range $key, $value := .Values.notifications.serviceAccount.labels }} + {{ $key }}: {{ $value | quote }} + {{- end }} +{{- end }} diff --git a/helm/argo-cd/templates/argocd-notifications/servicemonitor.yaml b/helm/argo-cd/templates/argocd-notifications/servicemonitor.yaml new file mode 100644 index 0000000..2dd280b --- /dev/null +++ b/helm/argo-cd/templates/argocd-notifications/servicemonitor.yaml @@ -0,0 +1,52 @@ +{{- if and .Values.notifications.enabled .Values.notifications.metrics.enabled .Values.notifications.metrics.serviceMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "argo-cd.notifications.fullname" . }} + {{- if .Values.notifications.metrics.serviceMonitor.namespace }} + namespace: {{ .Values.notifications.metrics.serviceMonitor.namespace }} + {{- end }} + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.notifications.name "name" .Values.notifications.name) | nindent 4 }} + {{- with .Values.notifications.metrics.serviceMonitor.selector }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if .Values.notifications.metrics.serviceMonitor.additionalLabels }} + {{- toYaml .Values.notifications.metrics.serviceMonitor.additionalLabels | nindent 4 }} + {{- end }} + {{- with .Values.notifications.metrics.serviceMonitor.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + endpoints: + - port: {{ .Values.notifications.metrics.service.portName }} + path: /metrics + {{- if .Values.notifications.metrics.serviceMonitor.interval }} + interval: {{ .Values.notifications.metrics.serviceMonitor.interval }} + {{- end }} + {{- if .Values.notifications.metrics.serviceMonitor.scrapeTimeout }} + scrapeTimeout: {{ .Values.notifications.metrics.serviceMonitor.scrapeTimeout }} + {{- end }} + {{- with .Values.notifications.metrics.serviceMonitor.scheme }} + scheme: {{ . }} + {{- end }} + {{- with .Values.notifications.metrics.serviceMonitor.tlsConfig }} + tlsConfig: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.notifications.metrics.serviceMonitor.relabelings }} + relabelings: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.notifications.metrics.serviceMonitor.metricRelabelings }} + metricRelabelings: + {{- toYaml . | nindent 8 }} + {{- end }} + namespaceSelector: + matchNames: + - {{ .Release.Namespace }} + selector: + matchLabels: + {{- include "argo-cd.selectorLabels" (dict "context" . "component" .Values.notifications.name "name" "metrics") | nindent 6 }} +{{- end }} diff --git a/helm/argo-cd/templates/argocd-repo-server/clusterrole.yaml b/helm/argo-cd/templates/argocd-repo-server/clusterrole.yaml new file mode 100644 index 0000000..21dff1a --- /dev/null +++ b/helm/argo-cd/templates/argocd-repo-server/clusterrole.yaml @@ -0,0 +1,24 @@ +{{- $config := .Values.repoServer.clusterAdminAccess | default dict -}} +{{- if hasKey $config "enabled" | ternary $config.enabled .Values.createClusterRoles }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "argo-cd.repoServer.fullname" . }} + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.repoServer.name "name" .Values.repoServer.name) | nindent 4 }} +rules: + {{- if .Values.repoServer.clusterRoleRules.enabled }} + {{- toYaml .Values.repoServer.clusterRoleRules.rules | nindent 2 }} + {{- else }} + - apiGroups: + - '*' + resources: + - '*' + verbs: + - '*' + - nonResourceURLs: + - '*' + verbs: + - '*' + {{- end }} +{{- end }} diff --git a/helm/argo-cd/templates/argocd-repo-server/clusterrolebinding.yaml b/helm/argo-cd/templates/argocd-repo-server/clusterrolebinding.yaml new file mode 100644 index 0000000..c3e21ed --- /dev/null +++ b/helm/argo-cd/templates/argocd-repo-server/clusterrolebinding.yaml @@ -0,0 +1,17 @@ +{{- $config := .Values.repoServer.clusterAdminAccess | default dict -}} +{{- if hasKey $config "enabled" | ternary $config.enabled .Values.createClusterRoles }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "argo-cd.repoServer.fullname" . }} + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.repoServer.name "name" .Values.repoServer.name) | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ include "argo-cd.repoServer.fullname" . }} +subjects: +- kind: ServiceAccount + name: {{ include "argo-cd.repoServerServiceAccountName" . }} + namespace: {{ .Release.Namespace }} +{{- end }} diff --git a/helm/argo-cd/templates/argocd-repo-server/deployment.yaml b/helm/argo-cd/templates/argocd-repo-server/deployment.yaml new file mode 100755 index 0000000..3e22a00 --- /dev/null +++ b/helm/argo-cd/templates/argocd-repo-server/deployment.yaml @@ -0,0 +1,363 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + {{- with (mergeOverwrite (deepCopy .Values.global.deploymentAnnotations) .Values.repoServer.deploymentAnnotations) }} + annotations: + {{- range $key, $value := . }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} + name: {{ template "argo-cd.repoServer.fullname" . }} + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.repoServer.name "name" .Values.repoServer.name) | nindent 4 }} +spec: + {{- if not .Values.repoServer.autoscaling.enabled }} + replicas: {{ .Values.repoServer.replicas }} + {{- end }} + revisionHistoryLimit: {{ .Values.global.revisionHistoryLimit }} + selector: + matchLabels: + {{- include "argo-cd.selectorLabels" (dict "context" . "name" .Values.repoServer.name) | nindent 6 }} + template: + metadata: + annotations: + checksum/cmd-params: {{ include (print $.Template.BasePath "/argocd-configs/argocd-cmd-params-cm.yaml") . | sha256sum }} + {{- if .Values.repoServer.certificateSecret.enabled }} + checksum/repo-server-tls: {{ include (print $.Template.BasePath "/argocd-configs/argocd-repo-server-tls-secret.yaml") . | sha256sum }} + {{- end }} + {{- with (mergeOverwrite (deepCopy .Values.global.podAnnotations) .Values.repoServer.podAnnotations) }} + {{- range $key, $value := . }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.repoServer.name "name" .Values.repoServer.name) | nindent 8 }} + {{- with (mergeOverwrite (deepCopy .Values.global.podLabels) .Values.repoServer.podLabels) }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- with .Values.repoServer.imagePullSecrets | default .Values.global.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.global.hostAliases }} + hostAliases: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.global.securityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.repoServer.priorityClassName | default .Values.global.priorityClassName }} + priorityClassName: {{ . }} + {{- end }} + serviceAccountName: {{ include "argo-cd.repoServerServiceAccountName" . }} + containers: + - name: {{ .Values.repoServer.name }} + image: {{ default .Values.global.image.repository .Values.repoServer.image.repository }}:{{ default (include "argo-cd.defaultTag" .) .Values.repoServer.image.tag }} + imagePullPolicy: {{ default .Values.global.image.imagePullPolicy .Values.repoServer.image.imagePullPolicy }} + command: + - entrypoint.sh + args: + - argocd-repo-server + - --port={{ .Values.repoServer.containerPorts.server }} + - --metrics-port={{ .Values.repoServer.containerPorts.metrics }} + {{- with .Values.repoServer.logFormat }} + - --logformat + - {{ . | quote }} + {{- end }} + {{- with .Values.repoServer.logLevel }} + - --loglevel + - {{ . | quote }} + {{- end }} + {{- with .Values.repoServer.extraArgs }} + {{- toYaml . | nindent 8 }} + {{- end }} + env: + {{- with .Values.repoServer.env }} + {{- toYaml . | nindent 10 }} + {{- end }} + {{- if .Values.openshift.enabled }} + - name: USER_NAME + value: argocd + {{- end }} + - name: ARGOCD_RECONCILIATION_TIMEOUT + valueFrom: + configMapKeyRef: + name: argocd-cm + key: timeout.reconciliation + optional: true + - name: ARGOCD_REPO_SERVER_LOGFORMAT + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: reposerver.log.format + optional: true + - name: ARGOCD_REPO_SERVER_LOGLEVEL + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: reposerver.log.level + optional: true + - name: ARGOCD_REPO_SERVER_PARALLELISM_LIMIT + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: reposerver.parallelism.limit + optional: true + - name: ARGOCD_REPO_SERVER_DISABLE_TLS + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: reposerver.disable.tls + optional: true + - name: ARGOCD_TLS_MIN_VERSION + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: reposerver.tls.minversion + optional: true + - name: ARGOCD_TLS_MAX_VERSION + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: reposerver.tls.maxversion + optional: true + - name: ARGOCD_TLS_CIPHERS + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: reposerver.tls.ciphers + optional: true + - name: ARGOCD_REPO_CACHE_EXPIRATION + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: reposerver.repo.cache.expiration + optional: true + - name: REDIS_SERVER + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: redis.server + optional: true + - name: REDIS_COMPRESSION + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: redis.compression + optional: true + - name: REDISDB + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: redis.db + optional: true + - name: REDIS_USERNAME + valueFrom: + secretKeyRef: + name: {{ default (include "argo-cd.redis.fullname" .) .Values.externalRedis.existingSecret }} + key: redis-username + optional: true + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + name: {{ default (include "argo-cd.redis.fullname" .) .Values.externalRedis.existingSecret }} + key: redis-password + optional: true + - name: ARGOCD_DEFAULT_CACHE_EXPIRATION + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: reposerver.default.cache.expiration + optional: true + - name: ARGOCD_REPO_SERVER_OTLP_ADDRESS + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: otlp.address + optional: true + - name: ARGOCD_REPO_SERVER_MAX_COMBINED_DIRECTORY_MANIFESTS_SIZE + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: reposerver.max.combined.directory.manifests.size + optional: true + - name: ARGOCD_REPO_SERVER_PLUGIN_TAR_EXCLUSIONS + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: reposerver.plugin.tar.exclusions + optional: true + - name: ARGOCD_REPO_SERVER_ALLOW_OUT_OF_BOUNDS_SYMLINKS + valueFrom: + configMapKeyRef: + key: reposerver.allow.oob.symlinks + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_STREAMED_MANIFEST_MAX_TAR_SIZE + valueFrom: + configMapKeyRef: + key: reposerver.streamed.manifest.max.tar.size + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_REPO_SERVER_STREAMED_MANIFEST_MAX_EXTRACTED_SIZE + valueFrom: + configMapKeyRef: + key: reposerver.streamed.manifest.max.extracted.size + name: argocd-cmd-params-cm + optional: true + - name: ARGOCD_GIT_MODULES_ENABLED + valueFrom: + configMapKeyRef: + key: reposerver.enable.git.submodule + name: argocd-cmd-params-cm + optional: true + - name: HELM_CACHE_HOME + value: /helm-working-dir + - name: HELM_CONFIG_HOME + value: /helm-working-dir + - name: HELM_DATA_HOME + value: /helm-working-dir + {{- with .Values.repoServer.envFrom }} + envFrom: + {{- toYaml . | nindent 10 }} + {{- end }} + volumeMounts: + {{- if .Values.repoServer.volumeMounts }} + {{- toYaml .Values.repoServer.volumeMounts | nindent 8 }} + {{- end }} + - mountPath: /app/config/ssh + name: ssh-known-hosts + - mountPath: /app/config/tls + name: tls-certs + - mountPath: /app/config/gpg/source + name: gpg-keys + - mountPath: /app/config/gpg/keys + name: gpg-keyring + - mountPath: /app/config/reposerver/tls + name: argocd-repo-server-tls + - mountPath: /helm-working-dir + name: helm-working-dir + - mountPath: /home/argocd/cmp-server/plugins + name: plugins + - mountPath: /tmp + name: tmp + ports: + - name: repo-server + containerPort: {{ .Values.repoServer.containerPorts.server }} + protocol: TCP + - name: metrics + containerPort: {{ .Values.repoServer.containerPorts.metrics }} + protocol: TCP + livenessProbe: + httpGet: + path: /healthz?full=true + port: metrics + initialDelaySeconds: {{ .Values.repoServer.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.repoServer.livenessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.repoServer.livenessProbe.timeoutSeconds }} + successThreshold: {{ .Values.repoServer.livenessProbe.successThreshold }} + failureThreshold: {{ .Values.repoServer.livenessProbe.failureThreshold }} + readinessProbe: + httpGet: + path: /healthz + port: metrics + initialDelaySeconds: {{ .Values.repoServer.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.repoServer.readinessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.repoServer.readinessProbe.timeoutSeconds }} + successThreshold: {{ .Values.repoServer.readinessProbe.successThreshold }} + failureThreshold: {{ .Values.repoServer.readinessProbe.failureThreshold }} + resources: + {{- toYaml .Values.repoServer.resources | nindent 10 }} + securityContext: + {{- toYaml .Values.repoServer.containerSecurityContext | nindent 10 }} + {{- with .Values.repoServer.extraContainers }} + {{- tpl (toYaml .) $ | nindent 6 }} + {{- end }} + initContainers: + - command: + - cp + - -n + - /usr/local/bin/argocd + - /var/run/argocd/argocd-cmp-server + image: {{ default .Values.global.image.repository .Values.repoServer.image.repository }}:{{ default (include "argo-cd.defaultTag" .) .Values.repoServer.image.tag }} + imagePullPolicy: {{ default .Values.global.image.imagePullPolicy .Values.repoServer.image.imagePullPolicy }} + name: copyutil + {{- with .Values.repoServer.resources }} + resources: + {{- toYaml . | nindent 10 }} + {{- end }} + {{- with .Values.repoServer.containerSecurityContext }} + securityContext: + {{- toYaml . | nindent 10 }} + {{- end }} + volumeMounts: + - mountPath: /var/run/argocd + name: var-files + {{- with .Values.repoServer.initContainers }} + {{- tpl (toYaml .) $ | nindent 6 }} + {{- end }} + {{- with include "argo-cd.affinity" (dict "context" . "component" .Values.repoServer) }} + affinity: + {{- trim . | nindent 8 }} + {{- end }} + {{- with .Values.repoServer.nodeSelector | default .Values.global.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.repoServer.tolerations | default .Values.global.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.repoServer.topologySpreadConstraints | default .Values.global.topologySpreadConstraints }} + topologySpreadConstraints: + {{- range $constraint := . }} + - {{ toYaml $constraint | nindent 8 | trim }} + {{- if not $constraint.labelSelector }} + labelSelector: + matchLabels: + {{- include "argo-cd.selectorLabels" (dict "context" $ "name" $.Values.repoServer.name) | nindent 12 }} + {{- end }} + {{- end }} + {{- end }} + volumes: + {{- with .Values.repoServer.volumes }} + {{- toYaml . | nindent 6 }} + {{- end }} + - name: helm-working-dir + emptyDir: {} + - name: plugins + emptyDir: {} + - name: var-files + emptyDir: {} + - name: tmp + emptyDir: {} + - name: ssh-known-hosts + configMap: + name: argocd-ssh-known-hosts-cm + - name: tls-certs + configMap: + name: argocd-tls-certs-cm + - name: gpg-keys + configMap: + name: argocd-gpg-keys-cm + - name: gpg-keyring + emptyDir: {} + - name: argocd-repo-server-tls + secret: + secretName: argocd-repo-server-tls + optional: true + items: + - key: tls.crt + path: tls.crt + - key: tls.key + path: tls.key + - key: ca.crt + path: ca.crt + hostNetwork: {{ .Values.repoServer.hostNetwork }} + {{- with .Values.repoServer.dnsConfig }} + dnsConfig: + {{- toYaml . | nindent 8 }} + {{- end }} + dnsPolicy: {{ .Values.repoServer.dnsPolicy }} diff --git a/helm/argo-cd/templates/argocd-repo-server/hpa.yaml b/helm/argo-cd/templates/argocd-repo-server/hpa.yaml new file mode 100644 index 0000000..d7f7432 --- /dev/null +++ b/helm/argo-cd/templates/argocd-repo-server/hpa.yaml @@ -0,0 +1,44 @@ +{{- if .Values.repoServer.autoscaling.enabled }} +apiVersion: {{ include "argo-cd.apiVersion.autoscaling" . }} +kind: HorizontalPodAutoscaler +metadata: + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.repoServer.name "name" (printf "%s-hpa" .Values.repoServer.name)) | nindent 4 }} + name: {{ template "argo-cd.repoServer.fullname" . }}-hpa +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ template "argo-cd.repoServer.fullname" . }} + minReplicas: {{ .Values.repoServer.autoscaling.minReplicas }} + maxReplicas: {{ .Values.repoServer.autoscaling.maxReplicas }} + metrics: + {{- with .Values.repoServer.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + {{- if eq (include "argo-cd.apiVersion.autoscaling" $) "autoscaling/v2beta1" }} + targetAverageUtilization: {{ . }} + {{- else }} + target: + averageUtilization: {{ . }} + type: Utilization + {{- end }} + {{- end }} + {{- with .Values.repoServer.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + {{- if eq (include "argo-cd.apiVersion.autoscaling" $) "autoscaling/v2beta1" }} + targetAverageUtilization: {{ . }} + {{- else }} + target: + averageUtilization: {{ . }} + type: Utilization + {{- end }} + {{- end }} + {{- with .Values.repoServer.autoscaling.behavior }} + behavior: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/helm/argo-cd/templates/argocd-repo-server/metrics.yaml b/helm/argo-cd/templates/argocd-repo-server/metrics.yaml new file mode 100644 index 0000000..1124057 --- /dev/null +++ b/helm/argo-cd/templates/argocd-repo-server/metrics.yaml @@ -0,0 +1,25 @@ +{{- if .Values.repoServer.metrics.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "argo-cd.repoServer.fullname" . }}-metrics + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.repoServer.name "name" (printf "%s-metrics" .Values.repoServer.name)) | nindent 4 }} + {{- with .Values.repoServer.metrics.service.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.repoServer.metrics.service.annotations }} + annotations: + {{- range $key, $value := . }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} +spec: + ports: + - name: {{ .Values.repoServer.metrics.service.portName }} + protocol: TCP + port: {{ .Values.repoServer.metrics.service.servicePort }} + targetPort: metrics + selector: + {{- include "argo-cd.selectorLabels" (dict "context" . "name" .Values.repoServer.name) | nindent 4 }} +{{- end }} diff --git a/helm/argo-cd/templates/argocd-repo-server/networkpolicy.yaml b/helm/argo-cd/templates/argocd-repo-server/networkpolicy.yaml new file mode 100644 index 0000000..619a65c --- /dev/null +++ b/helm/argo-cd/templates/argocd-repo-server/networkpolicy.yaml @@ -0,0 +1,41 @@ +{{- if .Values.global.networkPolicy.create }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.repoServer.name "name" .Values.repoServer.name) | nindent 4 }} + name: {{ template "argo-cd.repoServer.fullname" . }} +spec: + ingress: + - from: + - podSelector: + matchLabels: + {{- include "argo-cd.selectorLabels" (dict "context" . "name" .Values.server.name) | nindent 10 }} + - podSelector: + matchLabels: + {{- include "argo-cd.selectorLabels" (dict "context" . "name" .Values.controller.name) | nindent 10 }} + {{- if .Values.notifications.enabled }} + - podSelector: + matchLabels: + {{- include "argo-cd.selectorLabels" (dict "context" . "name" .Values.notifications.name) | nindent 10 }} + {{- end }} + {{- if .Values.applicationSet.enabled }} + - podSelector: + matchLabels: + {{- include "argo-cd.selectorLabels" (dict "context" . "name" .Values.applicationSet.name) | nindent 10 }} + {{- end }} + ports: + - port: repo-server + protocol: TCP + {{- if .Values.repoServer.metrics.enabled }} + - from: + - namespaceSelector: {} + ports: + - port: metrics + {{- end }} + podSelector: + matchLabels: + {{- include "argo-cd.selectorLabels" (dict "context" . "name" .Values.repoServer.name) | nindent 6 }} + policyTypes: + - Ingress +{{- end }} diff --git a/helm/argo-cd/templates/argocd-repo-server/pdb.yaml b/helm/argo-cd/templates/argocd-repo-server/pdb.yaml new file mode 100644 index 0000000..318671f --- /dev/null +++ b/helm/argo-cd/templates/argocd-repo-server/pdb.yaml @@ -0,0 +1,26 @@ +{{- if .Values.repoServer.pdb.enabled }} +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: {{ include "argo-cd.repoServer.fullname" . }} + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.repoServer.name "name" .Values.repoServer.name) | nindent 4 }} + {{- with .Values.repoServer.pdb.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.repoServer.pdb.annotations }} + annotations: + {{- range $key, $value := . }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} +spec: + {{- with .Values.repoServer.pdb.maxUnavailable }} + maxUnavailable: {{ . }} + {{- else }} + minAvailable: {{ .Values.repoServer.pdb.minAvailable | default 0 }} + {{- end }} + selector: + matchLabels: + {{- include "argo-cd.selectorLabels" (dict "context" . "name" .Values.repoServer.name) | nindent 6 }} +{{- end }} diff --git a/helm/argo-cd/templates/argocd-repo-server/role.yaml b/helm/argo-cd/templates/argocd-repo-server/role.yaml new file mode 100644 index 0000000..bc422c4 --- /dev/null +++ b/helm/argo-cd/templates/argocd-repo-server/role.yaml @@ -0,0 +1,12 @@ +{{- if .Values.repoServer.serviceAccount.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ template "argo-cd.repoServer.fullname" . }} + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.repoServer.name "name" .Values.repoServer.name) | nindent 4 }} +rules: +{{- if .Values.repoServer.rbac }} +{{toYaml .Values.repoServer.rbac }} +{{- end }} +{{- end }} diff --git a/helm/argo-cd/templates/argocd-repo-server/rolebinding.yaml b/helm/argo-cd/templates/argocd-repo-server/rolebinding.yaml new file mode 100644 index 0000000..3cfa312 --- /dev/null +++ b/helm/argo-cd/templates/argocd-repo-server/rolebinding.yaml @@ -0,0 +1,16 @@ +{{- if .Values.repoServer.serviceAccount.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ template "argo-cd.repoServer.fullname" . }} + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.repoServer.name "name" .Values.repoServer.name) | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "argo-cd.repoServer.fullname" . }} +subjects: +- kind: ServiceAccount + name: {{ template "argo-cd.repoServerServiceAccountName" . }} + namespace: {{ .Release.Namespace }} +{{- end }} \ No newline at end of file diff --git a/helm/argo-cd/templates/argocd-repo-server/service.yaml b/helm/argo-cd/templates/argocd-repo-server/service.yaml new file mode 100644 index 0000000..541ea41 --- /dev/null +++ b/helm/argo-cd/templates/argocd-repo-server/service.yaml @@ -0,0 +1,23 @@ +apiVersion: v1 +kind: Service +metadata: +{{- if .Values.repoServer.service.annotations }} + annotations: + {{- range $key, $value := .Values.repoServer.service.annotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} +{{- end }} + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.repoServer.name "name" .Values.repoServer.name) | nindent 4 }} +{{- with .Values.repoServer.service.labels }} +{{- toYaml . | nindent 4 }} +{{- end }} + name: {{ template "argo-cd.repoServer.fullname" . }} +spec: + ports: + - name: {{ .Values.repoServer.service.portName }} + protocol: TCP + port: {{ .Values.repoServer.service.port }} + targetPort: repo-server + selector: + {{- include "argo-cd.selectorLabels" (dict "context" . "name" .Values.repoServer.name) | nindent 4 }} \ No newline at end of file diff --git a/helm/argo-cd/templates/argocd-repo-server/serviceaccount.yaml b/helm/argo-cd/templates/argocd-repo-server/serviceaccount.yaml new file mode 100644 index 0000000..71f7558 --- /dev/null +++ b/helm/argo-cd/templates/argocd-repo-server/serviceaccount.yaml @@ -0,0 +1,18 @@ +{{- if .Values.repoServer.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +automountServiceAccountToken: {{ .Values.repoServer.serviceAccount.automountServiceAccountToken }} +metadata: + name: {{ template "argo-cd.repoServerServiceAccountName" . }} +{{- if .Values.repoServer.serviceAccount.annotations }} + annotations: + {{- range $key, $value := .Values.repoServer.serviceAccount.annotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} +{{- end }} + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.repoServer.name "name" .Values.repoServer.name) | nindent 4 }} + {{- range $key, $value := .Values.repoServer.serviceAccount.labels }} + {{ $key }}: {{ $value | quote }} + {{- end }} +{{- end }} diff --git a/helm/argo-cd/templates/argocd-repo-server/servicemonitor.yaml b/helm/argo-cd/templates/argocd-repo-server/servicemonitor.yaml new file mode 100644 index 0000000..82937d9 --- /dev/null +++ b/helm/argo-cd/templates/argocd-repo-server/servicemonitor.yaml @@ -0,0 +1,49 @@ +{{- if and .Values.repoServer.metrics.enabled .Values.repoServer.metrics.serviceMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "argo-cd.repoServer.fullname" . }} + {{- with .Values.repoServer.metrics.serviceMonitor.namespace }} + namespace: {{ . }} + {{- end }} + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.repoServer.name "name" .Values.repoServer.name) | nindent 4 }} + {{- with .Values.repoServer.metrics.serviceMonitor.selector }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.repoServer.metrics.serviceMonitor.additionalLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.repoServer.metrics.serviceMonitor.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + endpoints: + - port: {{ .Values.repoServer.metrics.service.portName }} + {{- with .Values.repoServer.metrics.serviceMonitor.interval }} + interval: {{ . }} + {{- end }} + path: /metrics + {{- with .Values.repoServer.metrics.serviceMonitor.relabelings }} + relabelings: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.repoServer.metrics.serviceMonitor.metricRelabelings }} + metricRelabelings: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.repoServer.metrics.serviceMonitor.scheme }} + scheme: {{ . }} + {{- end }} + {{- with .Values.repoServer.metrics.serviceMonitor.tlsConfig }} + tlsConfig: + {{- toYaml . | nindent 8 }} + {{- end }} + namespaceSelector: + matchNames: + - {{ .Release.Namespace }} + selector: + matchLabels: + {{- include "argo-cd.selectorLabels" (dict "context" . "component" .Values.repoServer.name "name" (printf "%s-metrics" .Values.repoServer.name)) | nindent 6 }} +{{- end }} diff --git a/helm/argo-cd/templates/argocd-server/aws/service.yaml b/helm/argo-cd/templates/argocd-server/aws/service.yaml new file mode 100644 index 0000000..a036802 --- /dev/null +++ b/helm/argo-cd/templates/argocd-server/aws/service.yaml @@ -0,0 +1,24 @@ +{{- if and .Values.server.ingressGrpc.enabled .Values.server.ingressGrpc.isAWSALB -}} +apiVersion: v1 +kind: Service +metadata: + annotations: + alb.ingress.kubernetes.io/backend-protocol-version: {{ .Values.server.ingressGrpc.awsALB.backendProtocolVersion }} + labels: + {{- include "argo-cd.labels" (dict "context" . "component" (print .Values.server.name "-gprc") "name" (print .Values.server.name "-grpc")) | nindent 4 }} + name: {{ template "argo-cd.server.fullname" . }}-grpc +spec: + ports: + - name: {{ .Values.server.service.servicePortHttpName }} + protocol: TCP + port: {{ .Values.server.service.servicePortHttp }} + targetPort: server + - name: {{ .Values.server.service.servicePortHttpsName }} + protocol: TCP + port: {{ .Values.server.service.servicePortHttps }} + targetPort: server + selector: + {{- include "argo-cd.selectorLabels" (dict "context" . "name" .Values.server.name) | nindent 4 }} + sessionAffinity: None + type: {{ .Values.server.ingressGrpc.awsALB.serviceType }} +{{- end -}} diff --git a/helm/argo-cd/templates/argocd-server/certificate.yaml b/helm/argo-cd/templates/argocd-server/certificate.yaml new file mode 100644 index 0000000..ed844aa --- /dev/null +++ b/helm/argo-cd/templates/argocd-server/certificate.yaml @@ -0,0 +1,32 @@ +{{- if .Values.server.certificate.enabled -}} +apiVersion: {{ include "argo-cd.apiVersion.cert-manager" . }} +kind: Certificate +metadata: + name: {{ include "argo-cd.server.fullname" . }} + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.server.name "name" .Values.server.name) | nindent 4 }} +spec: + secretName: {{ .Values.server.certificate.secretName }} + commonName: {{ .Values.server.certificate.domain | quote }} + dnsNames: + - {{ .Values.server.certificate.domain | quote }} + {{- range .Values.server.certificate.additionalHosts }} + - {{ . | quote }} + {{- end }} + {{- with .Values.server.certificate.duration }} + duration: {{ . | quote }} + {{- end }} + {{- with .Values.server.certificate.renewBefore }} + renewBefore: {{ . | quote }} + {{- end }} + issuerRef: + {{- with .Values.server.certificate.issuer.group }} + group: {{ . | quote }} + {{- end }} + kind: {{ .Values.server.certificate.issuer.kind | quote }} + name: {{ .Values.server.certificate.issuer.name | quote }} + {{- with .Values.server.certificate.privateKey }} + privateKey: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/helm/argo-cd/templates/argocd-server/clusterrole.yaml b/helm/argo-cd/templates/argocd-server/clusterrole.yaml new file mode 100644 index 0000000..0f26d47 --- /dev/null +++ b/helm/argo-cd/templates/argocd-server/clusterrole.yaml @@ -0,0 +1,48 @@ +{{- $config := .Values.server.clusterAdminAccess | default dict -}} +{{- if hasKey $config "enabled" | ternary $config.enabled .Values.createClusterRoles }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "argo-cd.server.fullname" . }} + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.server.name "name" .Values.server.name) | nindent 4 }} +rules: + - apiGroups: + - '*' + resources: + - '*' + verbs: + - delete + - get + - patch + - apiGroups: + - "" + resources: + - events + verbs: + - list + - apiGroups: + - "" + resources: + - pods + - pods/log + verbs: + - get + {{- if eq (toString (index (coalesce .Values.server.config .Values.configs.cm) "exec.enabled")) "true" }} + - apiGroups: + - "" + resources: + - pods/exec + verbs: + - create + {{- end }} + - apiGroups: + - argoproj.io + resources: + - applications + verbs: + - get + - list + - update + - watch +{{- end }} diff --git a/helm/argo-cd/templates/argocd-server/clusterrolebinding.yaml b/helm/argo-cd/templates/argocd-server/clusterrolebinding.yaml new file mode 100644 index 0000000..72e4d45 --- /dev/null +++ b/helm/argo-cd/templates/argocd-server/clusterrolebinding.yaml @@ -0,0 +1,17 @@ +{{- $config := .Values.server.clusterAdminAccess | default dict -}} +{{- if hasKey $config "enabled" | ternary $config.enabled .Values.createClusterRoles }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "argo-cd.server.fullname" . }} + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.server.name "name" .Values.server.name) | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ include "argo-cd.server.fullname" . }} +subjects: +- kind: ServiceAccount + name: {{ include "argo-cd.serverServiceAccountName" . }} + namespace: {{ .Release.Namespace }} +{{- end }} diff --git a/helm/argo-cd/templates/argocd-server/deployment.yaml b/helm/argo-cd/templates/argocd-server/deployment.yaml new file mode 100755 index 0000000..bb2f750 --- /dev/null +++ b/helm/argo-cd/templates/argocd-server/deployment.yaml @@ -0,0 +1,429 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + {{- with (mergeOverwrite (deepCopy .Values.global.deploymentAnnotations) .Values.server.deploymentAnnotations) }} + annotations: + {{- range $key, $value := . }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} + name: {{ template "argo-cd.server.fullname" . }} + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.server.name "name" .Values.server.name) | nindent 4 }} +spec: + {{- if not .Values.server.autoscaling.enabled }} + replicas: {{ .Values.server.replicas }} + {{- end }} + revisionHistoryLimit: {{ .Values.global.revisionHistoryLimit }} + selector: + matchLabels: + {{- include "argo-cd.selectorLabels" (dict "context" . "name" .Values.server.name) | nindent 6 }} + template: + metadata: + annotations: + checksum/cmd-params: {{ include (print $.Template.BasePath "/argocd-configs/argocd-cmd-params-cm.yaml") . | sha256sum }} + {{- with (mergeOverwrite (deepCopy .Values.global.podAnnotations) .Values.server.podAnnotations) }} + {{- range $key, $value := . }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.server.name "name" .Values.server.name) | nindent 8 }} + {{- with (mergeOverwrite (deepCopy .Values.global.podLabels) .Values.server.podLabels) }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- with .Values.server.imagePullSecrets | default .Values.global.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.global.hostAliases }} + hostAliases: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.global.securityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.server.priorityClassName | default .Values.global.priorityClassName }} + priorityClassName: {{ . }} + {{- end }} + serviceAccountName: {{ include "argo-cd.serverServiceAccountName" . }} + containers: + - name: {{ .Values.server.name }} + image: {{ default .Values.global.image.repository .Values.server.image.repository }}:{{ default (include "argo-cd.defaultTag" .) .Values.server.image.tag }} + imagePullPolicy: {{ default .Values.global.image.imagePullPolicy .Values.server.image.imagePullPolicy }} + command: + - argocd-server + - --port={{ .Values.server.containerPorts.server }} + - --metrics-port={{ .Values.server.containerPorts.metrics }} + {{- with .Values.server.logFormat }} + - --logformat + - {{ . | quote }} + {{- end }} + {{- with .Values.server.logLevel }} + - --loglevel + - {{ . | quote }} + {{- end }} + {{- with .Values.server.extraArgs }} + {{- toYaml . | nindent 8 }} + {{- end }} + env: + {{- with .Values.server.env }} + {{- toYaml . | nindent 10 }} + {{- end }} + - name: ARGOCD_SERVER_INSECURE + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.insecure + optional: true + - name: ARGOCD_SERVER_BASEHREF + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.basehref + optional: true + - name: ARGOCD_SERVER_ROOTPATH + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.rootpath + optional: true + - name: ARGOCD_SERVER_LOGFORMAT + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.log.format + optional: true + - name: ARGOCD_SERVER_LOG_LEVEL + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.log.level + optional: true + - name: ARGOCD_SERVER_REPO_SERVER + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: repo.server + optional: true + - name: ARGOCD_SERVER_DEX_SERVER + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.dex.server + optional: true + - name: ARGOCD_SERVER_DISABLE_AUTH + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.disable.auth + optional: true + - name: ARGOCD_SERVER_ENABLE_GZIP + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.enable.gzip + optional: true + - name: ARGOCD_SERVER_REPO_SERVER_TIMEOUT_SECONDS + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.repo.server.timeout.seconds + optional: true + - name: ARGOCD_SERVER_X_FRAME_OPTIONS + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.x.frame.options + optional: true + - name: ARGOCD_SERVER_CONTENT_SECURITY_POLICY + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.content.security.policy + optional: true + - name: ARGOCD_SERVER_REPO_SERVER_PLAINTEXT + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.repo.server.plaintext + optional: true + - name: ARGOCD_SERVER_REPO_SERVER_STRICT_TLS + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.repo.server.strict.tls + optional: true + - name: ARGOCD_SERVER_DEX_SERVER_PLAINTEXT + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.dex.server.plaintext + optional: true + - name: ARGOCD_SERVER_DEX_SERVER_STRICT_TLS + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.dex.server.strict.tls + optional: true + - name: ARGOCD_TLS_MIN_VERSION + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.tls.minversion + optional: true + - name: ARGOCD_TLS_MAX_VERSION + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.tls.maxversion + optional: true + - name: ARGOCD_TLS_CIPHERS + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.tls.ciphers + optional: true + - name: ARGOCD_SERVER_CONNECTION_STATUS_CACHE_EXPIRATION + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.connection.status.cache.expiration + optional: true + - name: ARGOCD_SERVER_OIDC_CACHE_EXPIRATION + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.oidc.cache.expiration + optional: true + - name: ARGOCD_SERVER_LOGIN_ATTEMPTS_EXPIRATION + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.login.attempts.expiration + optional: true + - name: ARGOCD_SERVER_STATIC_ASSETS + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.staticassets + optional: true + - name: ARGOCD_APP_STATE_CACHE_EXPIRATION + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.app.state.cache.expiration + optional: true + - name: REDIS_SERVER + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: redis.server + optional: true + - name: REDIS_COMPRESSION + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: redis.compression + optional: true + - name: REDISDB + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: redis.db + optional: true + - name: REDIS_USERNAME + valueFrom: + secretKeyRef: + name: {{ default (include "argo-cd.redis.fullname" .) .Values.externalRedis.existingSecret }} + key: redis-username + optional: true + - name: REDIS_PASSWORD + valueFrom: + secretKeyRef: + name: {{ default (include "argo-cd.redis.fullname" .) .Values.externalRedis.existingSecret }} + key: redis-password + optional: true + - name: ARGOCD_DEFAULT_CACHE_EXPIRATION + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.default.cache.expiration + optional: true + - name: ARGOCD_MAX_COOKIE_NUMBER + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.http.cookie.maxnumber + optional: true + - name: ARGOCD_SERVER_OTLP_ADDRESS + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: otlp.address + optional: true + - name: ARGOCD_APPLICATION_NAMESPACES + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: application.namespaces + optional: true + - name: ARGOCD_SERVER_ENABLE_PROXY_EXTENSION + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: server.enable.proxy.extension + optional: true + {{- with .Values.server.envFrom }} + envFrom: + {{- toYaml . | nindent 10 }} + {{- end }} + volumeMounts: + {{- with .Values.server.volumeMounts }} + {{- toYaml . | nindent 8 }} + {{- end }} + - mountPath: /app/config/ssh + name: ssh-known-hosts + - mountPath: /app/config/tls + name: tls-certs + - mountPath: /app/config/server/tls + name: argocd-repo-server-tls + - mountPath: /app/config/dex/tls + name: argocd-dex-server-tls + - mountPath: /home/argocd + name: plugins-home + - mountPath: /shared/app/custom + name: styles + - mountPath: /tmp + name: tmp + {{- if .Values.server.extensions.enabled }} + - mountPath: /tmp/extensions + name: extensions + {{- end }} + ports: + - name: server + containerPort: {{ .Values.server.containerPorts.server }} + protocol: TCP + - name: metrics + containerPort: {{ .Values.server.containerPorts.metrics }} + protocol: TCP + livenessProbe: + httpGet: + path: /healthz?full=true + port: server + initialDelaySeconds: {{ .Values.server.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.server.livenessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.server.livenessProbe.timeoutSeconds }} + successThreshold: {{ .Values.server.livenessProbe.successThreshold }} + failureThreshold: {{ .Values.server.livenessProbe.failureThreshold }} + readinessProbe: + httpGet: + path: /healthz + port: server + initialDelaySeconds: {{ .Values.server.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.server.readinessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.server.readinessProbe.timeoutSeconds }} + successThreshold: {{ .Values.server.readinessProbe.successThreshold }} + failureThreshold: {{ .Values.server.readinessProbe.failureThreshold }} + resources: + {{- toYaml .Values.server.resources | nindent 10 }} + securityContext: + {{- toYaml .Values.server.containerSecurityContext | nindent 10 }} + {{- with .Values.server.lifecycle }} + lifecycle: + {{- toYaml . | nindent 10 }} + {{- end }} + {{- if .Values.server.extensions.enabled }} + - name: argocd-extensions + image: {{ .Values.server.extensions.image.repository }}:{{ .Values.server.extensions.image.tag }} + imagePullPolicy: {{ .Values.server.extensions.image.imagePullPolicy }} + resources: + {{- toYaml .Values.server.extensions.resources | nindent 10 }} + securityContext: + {{- toYaml .Values.server.extensions.containerSecurityContext | nindent 10 }} + volumeMounts: + - name: extensions + mountPath: /tmp/extensions/ + - name: tmp + mountPath: /tmp + {{- end }} + {{- with .Values.server.extraContainers }} + {{- tpl (toYaml .) $ | nindent 6 }} + {{- end }} + {{- with .Values.server.initContainers }} + initContainers: + {{- tpl (toYaml .) $ | nindent 6 }} + {{- end }} + {{- with include "argo-cd.affinity" (dict "context" . "component" .Values.server) }} + affinity: + {{- trim . | nindent 8 }} + {{- end }} + {{- with .Values.server.nodeSelector | default .Values.global.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.server.tolerations | default .Values.global.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.server.topologySpreadConstraints | default .Values.global.topologySpreadConstraints }} + topologySpreadConstraints: + {{- range $constraint := . }} + - {{ toYaml $constraint | nindent 8 | trim }} + {{- if not $constraint.labelSelector }} + labelSelector: + matchLabels: + {{- include "argo-cd.selectorLabels" (dict "context" $ "name" $.Values.server.name) | nindent 12 }} + {{- end }} + {{- end }} + {{- end }} + volumes: + {{- with .Values.server.volumes }} + {{- toYaml . | nindent 6}} + {{- end }} + {{- if .Values.server.extensions.enabled }} + - name: extensions + emptyDir: {} + {{- end }} + - name: plugins-home + emptyDir: {} + - name: tmp + emptyDir: {} + - name: ssh-known-hosts + configMap: + name: argocd-ssh-known-hosts-cm + - name: tls-certs + configMap: + name: argocd-tls-certs-cm + - name: styles + configMap: + name: argocd-styles-cm + optional: true + - name: argocd-repo-server-tls + secret: + secretName: argocd-repo-server-tls + optional: true + items: + - key: tls.crt + path: tls.crt + - key: tls.key + path: tls.key + - key: ca.crt + path: ca.crt + - name: argocd-dex-server-tls + secret: + secretName: argocd-dex-server-tls + optional: true + items: + - key: tls.crt + path: tls.crt + - key: ca.crt + path: ca.crt + hostNetwork: {{ .Values.server.hostNetwork }} + {{- with .Values.server.dnsConfig }} + dnsConfig: + {{- toYaml . | nindent 8 }} + {{- end }} + dnsPolicy: {{ .Values.server.dnsPolicy }} diff --git a/helm/argo-cd/templates/argocd-server/gke/backendconfig.yaml b/helm/argo-cd/templates/argocd-server/gke/backendconfig.yaml new file mode 100644 index 0000000..69a4209 --- /dev/null +++ b/helm/argo-cd/templates/argocd-server/gke/backendconfig.yaml @@ -0,0 +1,10 @@ +{{- if .Values.server.GKEbackendConfig.enabled }} +apiVersion: {{ include "argo-cd.apiVersions.cloudgoogle" . }} +kind: BackendConfig +metadata: + name: {{ template "argo-cd.server.fullname" . }} + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.server.name "name" .Values.server.name) | nindent 4 }} +spec: + {{- toYaml .Values.server.GKEbackendConfig.spec | nindent 2 }} +{{- end }} diff --git a/helm/argo-cd/templates/argocd-server/gke/frontendconfig.yaml b/helm/argo-cd/templates/argocd-server/gke/frontendconfig.yaml new file mode 100644 index 0000000..46fc43a --- /dev/null +++ b/helm/argo-cd/templates/argocd-server/gke/frontendconfig.yaml @@ -0,0 +1,10 @@ +{{- if .Values.server.GKEfrontendConfig.enabled }} +apiVersion: networking.gke.io/v1beta1 +kind: FrontendConfig +metadata: + name: {{ template "argo-cd.server.fullname" . }} + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.server.name "name" .Values.server.name) | nindent 4 }} +spec: + {{- toYaml .Values.server.GKEfrontendConfig.spec | nindent 2 }} +{{- end }} diff --git a/helm/argo-cd/templates/argocd-server/gke/managedcertificate.yaml b/helm/argo-cd/templates/argocd-server/gke/managedcertificate.yaml new file mode 100644 index 0000000..81e1e71 --- /dev/null +++ b/helm/argo-cd/templates/argocd-server/gke/managedcertificate.yaml @@ -0,0 +1,11 @@ +{{- if .Values.server.GKEmanagedCertificate.enabled }} +apiVersion: networking.gke.io/v1 +kind: ManagedCertificate +metadata: + name: {{ template "argo-cd.server.fullname" . }} +spec: + domains: + {{- with .Values.server.GKEmanagedCertificate.domains }} + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/helm/argo-cd/templates/argocd-server/hpa.yaml b/helm/argo-cd/templates/argocd-server/hpa.yaml new file mode 100644 index 0000000..af107b7 --- /dev/null +++ b/helm/argo-cd/templates/argocd-server/hpa.yaml @@ -0,0 +1,44 @@ +{{- if .Values.server.autoscaling.enabled }} +apiVersion: {{ include "argo-cd.apiVersion.autoscaling" . }} +kind: HorizontalPodAutoscaler +metadata: + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.server.name "name" (printf "%s-hpa" .Values.server.name)) | nindent 4 }} + name: {{ template "argo-cd.server.fullname" . }}-hpa +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ template "argo-cd.server.fullname" . }} + minReplicas: {{ .Values.server.autoscaling.minReplicas }} + maxReplicas: {{ .Values.server.autoscaling.maxReplicas }} + metrics: + {{- with .Values.server.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + {{- if eq (include "argo-cd.apiVersion.autoscaling" $) "autoscaling/v2beta1" }} + targetAverageUtilization: {{ . }} + {{- else }} + target: + averageUtilization: {{ . }} + type: Utilization + {{- end }} + {{- end }} + {{- with .Values.server.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + {{- if eq (include "argo-cd.apiVersion.autoscaling" $) "autoscaling/v2beta1" }} + targetAverageUtilization: {{ . }} + {{- else }} + target: + averageUtilization: {{ . }} + type: Utilization + {{- end }} + {{- end }} + {{- with .Values.server.autoscaling.behavior }} + behavior: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/helm/argo-cd/templates/argocd-server/ingress-grpc.yaml b/helm/argo-cd/templates/argocd-server/ingress-grpc.yaml new file mode 100644 index 0000000..b728a11 --- /dev/null +++ b/helm/argo-cd/templates/argocd-server/ingress-grpc.yaml @@ -0,0 +1,72 @@ +{{- if and .Values.server.ingressGrpc.enabled (not .Values.server.ingressGrpc.isAWSALB) -}} +{{- $servicePort := ternary .Values.server.service.servicePortHttps .Values.server.service.servicePortHttp .Values.server.ingressGrpc.https -}} +{{- $paths := .Values.server.ingressGrpc.paths -}} +{{- $extraPaths := .Values.server.ingressGrpc.extraPaths -}} +{{- $pathType := .Values.server.ingressGrpc.pathType -}} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ include "argo-cd.server.fullname" . }}-grpc + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.server.name "name" .Values.server.name) | nindent 4 }} + {{- with .Values.server.ingressGrpc.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.server.ingressGrpc.annotations }} + annotations: + {{- range $key, $value := . }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} +spec: + {{- with .Values.server.ingressGrpc.ingressClassName }} + ingressClassName: {{ . }} + {{- end }} + rules: + {{- if .Values.server.ingressGrpc.hosts }} + {{- range $host := .Values.server.ingressGrpc.hosts }} + - host: {{ $host }} + http: + paths: + {{- with $extraPaths }} + {{- toYaml . | nindent 10 }} + {{- end }} + {{- range $p := $paths }} + - path: {{ $p }} + pathType: {{ $pathType }} + backend: + service: + name: {{ include "argo-cd.server.fullname" $ }} + port: + {{- if kindIs "float64" $servicePort }} + number: {{ $servicePort }} + {{- else }} + name: {{ $servicePort }} + {{- end }} + {{- end -}} + {{- end -}} + {{- else }} + - http: + paths: + {{- with $extraPaths }} + {{- toYaml . | nindent 10 }} + {{- end }} + {{- range $p := $paths }} + - path: {{ $p }} + pathType: {{ $pathType }} + backend: + service: + name: {{ include "argo-cd.server.fullname" $ }} + port: + {{- if kindIs "float64" $servicePort }} + number: {{ $servicePort }} + {{- else }} + name: {{ $servicePort }} + {{- end }} + {{- end -}} + {{- end -}} + {{- with .Values.server.ingressGrpc.tls }} + tls: + {{- toYaml . | nindent 4 }} + {{- end -}} +{{- end -}} diff --git a/helm/argo-cd/templates/argocd-server/ingress.yaml b/helm/argo-cd/templates/argocd-server/ingress.yaml new file mode 100644 index 0000000..0e064b0 --- /dev/null +++ b/helm/argo-cd/templates/argocd-server/ingress.yaml @@ -0,0 +1,89 @@ +{{- if .Values.server.ingress.enabled -}} +{{- $servicePort := ternary .Values.server.service.servicePortHttps .Values.server.service.servicePortHttp .Values.server.ingress.https -}} +{{- $paths := .Values.server.ingress.paths -}} +{{- $extraPaths := .Values.server.ingress.extraPaths -}} +{{- $pathType := .Values.server.ingress.pathType -}} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ include "argo-cd.server.fullname" . }} + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.server.name "name" .Values.server.name) | nindent 4 }} + {{- with .Values.server.ingress.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if .Values.server.ingress.annotations }} + annotations: + {{- range $key, $value := .Values.server.ingress.annotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- if and .Values.server.ingressGrpc.isAWSALB .Values.server.ingressGrpc.enabled }} + alb.ingress.kubernetes.io/conditions.{{ template "argo-cd.server.fullname" . }}-grpc: | + [{"field":"http-header","httpHeaderConfig":{"httpHeaderName": "Content-Type", "values":["application/grpc"]}}] + {{- end }} + {{- end }} +spec: + {{- with .Values.server.ingress.ingressClassName }} + ingressClassName: {{ . }} + {{- end }} + rules: + {{- if .Values.server.ingress.hosts }} + {{- range $host := .Values.server.ingress.hosts }} + - host: {{ $host | quote }} + http: + paths: + {{- with $extraPaths }} + {{- toYaml . | nindent 10 }} + {{- end }} + {{- range $p := $paths }} + {{- if and $.Values.server.ingressGrpc.isAWSALB $.Values.server.ingressGrpc.enabled }} + - path: {{ $p }} + pathType: Prefix + backend: + service: + name: {{ template "argo-cd.server.fullname" $ }}-grpc + port: + {{- if kindIs "float64" $servicePort }} + number: {{ $servicePort }} + {{- else }} + name: {{ $servicePort }} + {{- end }} + {{- end }} + - path: {{ $p }} + pathType: {{ $pathType }} + backend: + service: + name: {{ include "argo-cd.server.fullname" $ }} + port: + {{- if kindIs "float64" $servicePort }} + number: {{ $servicePort }} + {{- else }} + name: {{ $servicePort }} + {{- end }} + {{- end -}} + {{- end -}} + {{- else }} + - http: + paths: + {{- with $extraPaths }} + {{- toYaml . | nindent 10 }} + {{- end }} + {{- range $p := $paths }} + - path: {{ $p }} + pathType: {{ $pathType }} + backend: + service: + name: {{ include "argo-cd.server.fullname" $ }} + port: + {{- if kindIs "float64" $servicePort }} + number: {{ $servicePort }} + {{- else }} + name: {{ $servicePort }} + {{- end }} + {{- end -}} + {{- end -}} + {{- with .Values.server.ingress.tls }} + tls: + {{- toYaml . | nindent 4 }} + {{- end -}} +{{- end -}} diff --git a/helm/argo-cd/templates/argocd-server/metrics.yaml b/helm/argo-cd/templates/argocd-server/metrics.yaml new file mode 100644 index 0000000..bf8ee08 --- /dev/null +++ b/helm/argo-cd/templates/argocd-server/metrics.yaml @@ -0,0 +1,25 @@ +{{- if .Values.server.metrics.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "argo-cd.server.fullname" . }}-metrics + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.server.name "name" (printf "%s-metrics" .Values.server.name)) | nindent 4 }} + {{- with .Values.server.metrics.service.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.server.metrics.service.annotations }} + annotations: + {{- range $key, $value := . }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} +spec: + ports: + - name: {{ .Values.server.metrics.service.portName }} + protocol: TCP + port: {{ .Values.server.metrics.service.servicePort }} + targetPort: metrics + selector: + {{- include "argo-cd.selectorLabels" (dict "context" . "name" .Values.server.name) | nindent 4 }} +{{- end }} diff --git a/helm/argo-cd/templates/argocd-server/networkpolicy.yaml b/helm/argo-cd/templates/argocd-server/networkpolicy.yaml new file mode 100644 index 0000000..8300d69 --- /dev/null +++ b/helm/argo-cd/templates/argocd-server/networkpolicy.yaml @@ -0,0 +1,16 @@ +{{- if .Values.global.networkPolicy.create }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.server.name "name" .Values.server.name) | nindent 4 }} + name: {{ template "argo-cd.server.fullname" . }} +spec: + ingress: + - {} + podSelector: + matchLabels: + {{- include "argo-cd.selectorLabels" (dict "context" . "name" .Values.server.name) | nindent 6 }} + policyTypes: + - Ingress +{{- end }} diff --git a/helm/argo-cd/templates/argocd-server/openshift/route.yaml b/helm/argo-cd/templates/argocd-server/openshift/route.yaml new file mode 100644 index 0000000..f1fc801 --- /dev/null +++ b/helm/argo-cd/templates/argocd-server/openshift/route.yaml @@ -0,0 +1,26 @@ +{{- if .Values.server.route.enabled -}} +apiVersion: route.openshift.io/v1 +kind: Route +metadata: + name: {{ template "argo-cd.server.fullname" . }} + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.server.name "name" .Values.server.name) | nindent 4 }} +{{- with .Values.server.route.annotations }} + annotations: + {{- range $key, $value := . }} + {{ $key }}: {{ $value | quote }} + {{- end }} +{{- end }} +spec: + host: {{ .Values.server.route.hostname | quote }} + to: + kind: Service + name: {{ template "argo-cd.server.fullname" . }} + weight: 100 + port: + targetPort: https + tls: + termination: {{ .Values.server.route.termination_type | quote }} + insecureEdgeTerminationPolicy: {{ .Values.server.route.termination_policy | quote }} + wildcardPolicy: None +{{- end }} diff --git a/helm/argo-cd/templates/argocd-server/pdb.yaml b/helm/argo-cd/templates/argocd-server/pdb.yaml new file mode 100644 index 0000000..89c54c6 --- /dev/null +++ b/helm/argo-cd/templates/argocd-server/pdb.yaml @@ -0,0 +1,26 @@ +{{- if .Values.server.pdb.enabled }} +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: {{ include "argo-cd.server.fullname" . }} + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.server.name "name" .Values.server.name) | nindent 4 }} + {{- with .Values.server.pdb.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.server.pdb.annotations }} + annotations: + {{- range $key, $value := . }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} +spec: + {{- with .Values.server.pdb.maxUnavailable }} + maxUnavailable: {{ . }} + {{- else }} + minAvailable: {{ .Values.server.pdb.minAvailable | default 0 }} + {{- end }} + selector: + matchLabels: + {{- include "argo-cd.selectorLabels" (dict "context" . "name" .Values.server.name) | nindent 6 }} +{{- end }} diff --git a/helm/argo-cd/templates/argocd-server/role.yaml b/helm/argo-cd/templates/argocd-server/role.yaml new file mode 100644 index 0000000..16164a9 --- /dev/null +++ b/helm/argo-cd/templates/argocd-server/role.yaml @@ -0,0 +1,52 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ include "argo-cd.server.fullname" . }} + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.server.name "name" .Values.server.name) | nindent 4 }} +rules: +- apiGroups: + - "" + resources: + - secrets + - configmaps + verbs: + - create + - get + - list + - watch + - update + - patch + - delete +- apiGroups: + - argoproj.io + resources: + - applications + - applicationsets + - appprojects + {{- if .Values.server.extensions.enabled }} + - argocdextensions + {{- end }} + verbs: + - create + - get + - list + - watch + - update + - delete + - patch +- apiGroups: + - "" + resources: + - events + verbs: + - create + - list +{{- if eq (toString (index (coalesce .Values.server.config .Values.configs.cm) "exec.enabled")) "true" }} +- apiGroups: + - "" + resources: + - pods/exec + verbs: + - create +{{- end }} diff --git a/helm/argo-cd/templates/argocd-server/rolebinding.yaml b/helm/argo-cd/templates/argocd-server/rolebinding.yaml new file mode 100644 index 0000000..54d4eae --- /dev/null +++ b/helm/argo-cd/templates/argocd-server/rolebinding.yaml @@ -0,0 +1,14 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ template "argo-cd.server.fullname" . }} + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.server.name "name" .Values.server.name) | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "argo-cd.server.fullname" . }} +subjects: +- kind: ServiceAccount + name: {{ template "argo-cd.serverServiceAccountName" . }} + namespace: {{ .Release.Namespace }} \ No newline at end of file diff --git a/helm/argo-cd/templates/argocd-server/service.yaml b/helm/argo-cd/templates/argocd-server/service.yaml new file mode 100644 index 0000000..879bdb3 --- /dev/null +++ b/helm/argo-cd/templates/argocd-server/service.yaml @@ -0,0 +1,52 @@ +apiVersion: v1 +kind: Service +metadata: +{{- if .Values.server.service.annotations }} + annotations: + {{- range $key, $value := .Values.server.service.annotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} +{{- end }} + name: {{ template "argo-cd.server.fullname" . }} + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.server.name "name" .Values.server.name) | nindent 4 }} +{{- if .Values.server.service.labels }} +{{- toYaml .Values.server.service.labels | nindent 4 }} +{{- end }} +spec: + type: {{ .Values.server.service.type }} + ports: + - name: {{ .Values.server.service.servicePortHttpName }} + protocol: TCP + port: {{ .Values.server.service.servicePortHttp }} + targetPort: {{ .Values.server.containerPorts.server }} + {{- if eq .Values.server.service.type "NodePort" }} + nodePort: {{ .Values.server.service.nodePortHttp }} + {{- end }} + - name: {{ .Values.server.service.servicePortHttpsName }} + protocol: TCP + port: {{ .Values.server.service.servicePortHttps }} + targetPort: {{ .Values.server.containerPorts.server }} + {{- if eq .Values.server.service.type "NodePort" }} + nodePort: {{ .Values.server.service.nodePortHttps }} + {{- end }} + selector: + {{- include "argo-cd.selectorLabels" (dict "context" . "name" .Values.server.name) | nindent 4 }} +{{- if eq .Values.server.service.type "LoadBalancer" }} +{{- if .Values.server.service.loadBalancerIP }} + loadBalancerIP: {{ .Values.server.service.loadBalancerIP | quote }} +{{- end }} +{{- if .Values.server.service.externalIPs }} + externalIPs: {{ .Values.server.service.externalIPs }} +{{- end }} +{{- if .Values.server.service.loadBalancerSourceRanges }} + loadBalancerSourceRanges: +{{ toYaml .Values.server.service.loadBalancerSourceRanges | indent 4 }} +{{- end }} +{{- end -}} +{{- with .Values.server.service.externalTrafficPolicy }} + externalTrafficPolicy: {{ . }} +{{- end }} +{{- with .Values.server.service.sessionAffinity }} + sessionAffinity: {{ . }} +{{- end }} diff --git a/helm/argo-cd/templates/argocd-server/serviceaccount.yaml b/helm/argo-cd/templates/argocd-server/serviceaccount.yaml new file mode 100644 index 0000000..a2eb9b1 --- /dev/null +++ b/helm/argo-cd/templates/argocd-server/serviceaccount.yaml @@ -0,0 +1,18 @@ +{{- if .Values.server.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +automountServiceAccountToken: {{ .Values.server.serviceAccount.automountServiceAccountToken }} +metadata: + name: {{ template "argo-cd.serverServiceAccountName" . }} +{{- if .Values.server.serviceAccount.annotations }} + annotations: + {{- range $key, $value := .Values.server.serviceAccount.annotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} +{{- end }} + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.server.name "name" .Values.server.name) | nindent 4 }} + {{- range $key, $value := .Values.server.serviceAccount.labels }} + {{ $key }}: {{ $value | quote }} + {{- end }} +{{- end }} diff --git a/helm/argo-cd/templates/argocd-server/servicemonitor.yaml b/helm/argo-cd/templates/argocd-server/servicemonitor.yaml new file mode 100644 index 0000000..d00e565 --- /dev/null +++ b/helm/argo-cd/templates/argocd-server/servicemonitor.yaml @@ -0,0 +1,49 @@ +{{- if and .Values.server.metrics.enabled .Values.server.metrics.serviceMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "argo-cd.server.fullname" . }} + {{- if .Values.server.metrics.serviceMonitor.namespace }} + namespace: {{ .Values.server.metrics.serviceMonitor.namespace }} + {{- end }} + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.server.name "name" .Values.server.name) | nindent 4 }} + {{- with .Values.server.metrics.serviceMonitor.selector }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.server.metrics.serviceMonitor.additionalLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + {{- range $key, $value := .Values.server.metrics.serviceMonitor.annotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} +spec: + endpoints: + - port: {{ .Values.server.metrics.service.portName }} + {{- with .Values.server.metrics.serviceMonitor.interval }} + interval: {{ . }} + {{- end }} + path: /metrics + {{- with .Values.server.metrics.serviceMonitor.relabelings }} + relabelings: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.server.metrics.serviceMonitor.metricRelabelings }} + metricRelabelings: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.server.metrics.serviceMonitor.scheme }} + scheme: {{ . }} + {{- end }} + {{- with .Values.server.metrics.serviceMonitor.tlsConfig }} + tlsConfig: + {{- toYaml . | nindent 8 }} + {{- end }} + namespaceSelector: + matchNames: + - {{ .Release.Namespace }} + selector: + matchLabels: + {{- include "argo-cd.selectorLabels" (dict "context" . "component" .Values.server.name "name" (printf "%s-metrics" .Values.server.name)) | nindent 6 }} +{{- end }} diff --git a/helm/argo-cd/templates/crds/crd-application.yaml b/helm/argo-cd/templates/crds/crd-application.yaml new file mode 100644 index 0000000..ae0f729 --- /dev/null +++ b/helm/argo-cd/templates/crds/crd-application.yaml @@ -0,0 +1,4021 @@ +{{- if .Values.crds.install }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + {{- if .Values.crds.keep }} + "helm.sh/resource-policy": keep + {{- end }} + {{- with .Values.crds.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + labels: + app.kubernetes.io/name: applications.argoproj.io + app.kubernetes.io/part-of: argocd + name: applications.argoproj.io +spec: + group: argoproj.io + names: + kind: Application + listKind: ApplicationList + plural: applications + shortNames: + - app + - apps + singular: application + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.sync.status + name: Sync Status + type: string + - jsonPath: .status.health.status + name: Health Status + type: string + - jsonPath: .status.sync.revision + name: Revision + priority: 10 + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + description: Application is a definition of Application resource. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + operation: + description: Operation contains information about a requested or running + operation + properties: + info: + description: Info is a list of informational items for this operation + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + initiatedBy: + description: InitiatedBy contains information about who initiated + the operations + properties: + automated: + description: Automated is set to true if operation was initiated + automatically by the application controller. + type: boolean + username: + description: Username contains the name of a user who started + operation + type: string + type: object + retry: + description: Retry controls the strategy to apply if a sync fails + properties: + backoff: + description: Backoff controls how to backoff on subsequent retries + of failed syncs + properties: + duration: + description: Duration is the amount to back off. Default unit + is seconds, but could also be a duration (e.g. "2m", "1h") + type: string + factor: + description: Factor is a factor to multiply the base duration + after each failed retry + format: int64 + type: integer + maxDuration: + description: MaxDuration is the maximum amount of time allowed + for the backoff strategy + type: string + type: object + limit: + description: Limit is the maximum number of attempts for retrying + a failed sync. If set to 0, no retries will be performed. + format: int64 + type: integer + type: object + sync: + description: Sync contains parameters for the operation + properties: + dryRun: + description: DryRun specifies to perform a `kubectl apply --dry-run` + without actually performing the sync + type: boolean + manifests: + description: Manifests is an optional field that overrides sync + source with a local directory for development + items: + type: string + type: array + prune: + description: Prune specifies to delete resources from the cluster + that are no longer tracked in git + type: boolean + resources: + description: Resources describes which resources shall be part + of the sync + items: + description: SyncOperationResource contains resources to sync. + properties: + group: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + type: array + revision: + description: Revision is the revision (Git) or chart version (Helm) + which to sync the application to If omitted, will use the revision + specified in app spec. + type: string + revisions: + description: Revisions is the list of revision (Git) or chart + version (Helm) which to sync each source in sources field for + the application to If omitted, will use the revision specified + in app spec. + items: + type: string + type: array + source: + description: Source overrides the source definition set in the + application. This is typically set in a Rollback operation and + is nil during a Sync operation + properties: + chart: + description: Chart is a Helm chart name, and must be specified + for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific options + properties: + exclude: + description: Exclude contains a glob pattern to match + paths against that should be explicitly excluded from + being used during manifest generation + type: string + include: + description: Include contains a glob pattern to match + paths against that should be explicitly included during + manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External + Variables + items: + description: JsonnetVar represents a variable to + be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level Arguments + items: + description: JsonnetVar represents a variable to + be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a directory + recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + fileParameters: + description: FileParameters are file parameters to the + helm template + items: + description: HelmFileParameter is a file parameter that's + passed to helm template during manifest generation + properties: + name: + description: Name is the name of the Helm parameter + type: string + path: + description: Path is the path to the file containing + the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm template + from failing when valueFiles do not exist locally by + not appending them to helm template --values + type: boolean + parameters: + description: Parameters is a list of Helm parameters which + are passed to the helm template command upon manifest + generation + items: + description: HelmParameter is a parameter that's passed + to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether to tell + Helm to interpret booleans and numbers as strings + type: boolean + name: + description: Name is the name of the Helm parameter + type: string + value: + description: Value is the value for the Helm parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to all domains + (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name to use. + If omitted it will use the application name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value files + to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be passed + to helm template, typically defined as a block + type: string + version: + description: Version is the Helm version to use for templating + ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional labels + to add to rendered manifests + type: object + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether + to force applying common annotations to resources for + Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether to force + applying common labels to resources for Kustomize apps + type: boolean + images: + description: Images is a list of Kustomize image override + specifications + items: + description: KustomizeImage represents a Kustomize image + definition in the format [old_image_name=]: + type: string + type: array + namePrefix: + description: NamePrefix is a prefix appended to resources + for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to resources + for Kustomize apps + type: string + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + path: + description: Path is a directory path within the Git repository, + and is only valid for applications sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable entries + items: + description: EnvEntry represents an entry in the application's + environment + properties: + name: + description: Name is the name of the variable, usually + expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array type + parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type parameter. + type: object + name: + description: Name is the name identifying a parameter. + type: string + string: + description: String_ is the value of a string type + parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within sources + field. This field will not be used if used with a `source` + tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git or + Helm) that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of the source + to sync the application to. In case of Git, this can be + commit, tag, or branch. If omitted, will equal to HEAD. + In case of Helm, this is a semver tag for the Chart's version. + type: string + required: + - repoURL + type: object + sources: + description: Sources overrides the source definition set in the + application. This is typically set in a Rollback operation and + is nil during a Sync operation + items: + description: ApplicationSource contains all required information + about the source of an application + properties: + chart: + description: Chart is a Helm chart name, and must be specified + for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific options + properties: + exclude: + description: Exclude contains a glob pattern to match + paths against that should be explicitly excluded from + being used during manifest generation + type: string + include: + description: Include contains a glob pattern to match + paths against that should be explicitly included during + manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External + Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a directory + recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + fileParameters: + description: FileParameters are file parameters to the + helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest generation + properties: + name: + description: Name is the name of the Helm parameter + type: string + path: + description: Path is the path to the file containing + the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm template + from failing when valueFiles do not exist locally + by not appending them to helm template --values + type: boolean + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command upon + manifest generation + items: + description: HelmParameter is a parameter that's passed + to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether to + tell Helm to interpret booleans and numbers + as strings + type: boolean + name: + description: Name is the name of the Helm parameter + type: string + value: + description: Value is the value for the Helm parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to all + domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name to + use. If omitted it will use the application name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value files + to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be passed + to helm template, typically defined as a block + type: string + version: + description: Version is the Helm version to use for + templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional labels + to add to rendered manifests + type: object + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether + to force applying common annotations to resources + for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether to + force applying common labels to resources for Kustomize + apps + type: boolean + images: + description: Images is a list of Kustomize image override + specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + namePrefix: + description: NamePrefix is a prefix appended to resources + for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to resources + for Kustomize apps + type: string + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + path: + description: Path is a directory path within the Git repository, + and is only valid for applications sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable entries + items: + description: EnvEntry represents an entry in the application's + environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array type + parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type parameter. + type: object + name: + description: Name is the name identifying a parameter. + type: string + string: + description: String_ is the value of a string + type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within sources + field. This field will not be used if used with a `source` + tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git or + Helm) that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of the + source to sync the application to. In case of Git, this + can be commit, tag, or branch. If omitted, will equal + to HEAD. In case of Helm, this is a semver tag for the + Chart's version. + type: string + required: + - repoURL + type: object + type: array + syncOptions: + description: SyncOptions provide per-sync sync-options, e.g. Validate=false + items: + type: string + type: array + syncStrategy: + description: SyncStrategy describes how to perform the sync + properties: + apply: + description: Apply will perform a `kubectl apply` to perform + the sync. + properties: + force: + description: Force indicates whether or not to supply + the --force flag to `kubectl apply`. The --force flag + deletes and re-create the resource, when PATCH encounters + conflict and has retried for 5 times. + type: boolean + type: object + hook: + description: Hook will submit any referenced resources to + perform the sync. This is the default strategy + properties: + force: + description: Force indicates whether or not to supply + the --force flag to `kubectl apply`. The --force flag + deletes and re-create the resource, when PATCH encounters + conflict and has retried for 5 times. + type: boolean + type: object + type: object + type: object + type: object + spec: + description: ApplicationSpec represents desired application state. Contains + link to repository with application definition and additional parameters + link definition revision. + properties: + destination: + description: Destination is a reference to the target Kubernetes server + and namespace + properties: + name: + description: Name is an alternate way of specifying the target + cluster by its symbolic name + type: string + namespace: + description: Namespace specifies the target namespace for the + application's resources. The namespace will only be set for + namespace-scoped resources that have not set a value for .metadata.namespace + type: string + server: + description: Server specifies the URL of the target cluster and + must be set to the Kubernetes control plane API + type: string + type: object + ignoreDifferences: + description: IgnoreDifferences is a list of resources and their fields + which should be ignored during comparison + items: + description: ResourceIgnoreDifferences contains resource filter + and list of json paths which should be ignored during comparison + with live state. + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + description: ManagedFieldsManagers is a list of trusted managers. + Fields mutated by those managers will take precedence over + the desired state defined in the SCM and won't be displayed + in diffs + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + description: Info contains a list of information (URLs, email addresses, + and plain text) that relates to the application + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + description: Project is a reference to the project this application + belongs to. The empty string means that application belongs to the + 'default' project. + type: string + revisionHistoryLimit: + description: RevisionHistoryLimit limits the number of items kept + in the application's revision history, which is used for informational + purposes as well as for rollbacks to previous versions. This should + only be changed in exceptional circumstances. Setting to zero will + store no history. This will reduce storage used. Increasing will + increase the space used to store the history, so we do not recommend + increasing it. Default is 10. + format: int64 + type: integer + source: + description: Source is a reference to the location of the application's + manifests or chart + properties: + chart: + description: Chart is a Helm chart name, and must be specified + for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific options + properties: + exclude: + description: Exclude contains a glob pattern to match paths + against that should be explicitly excluded from being used + during manifest generation + type: string + include: + description: Include contains a glob pattern to match paths + against that should be explicitly included during manifest + generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External Variables + items: + description: JsonnetVar represents a variable to be + passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level Arguments + items: + description: JsonnetVar represents a variable to be + passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a directory + recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + fileParameters: + description: FileParameters are file parameters to the helm + template + items: + description: HelmFileParameter is a file parameter that's + passed to helm template during manifest generation + properties: + name: + description: Name is the name of the Helm parameter + type: string + path: + description: Path is the path to the file containing + the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm template + from failing when valueFiles do not exist locally by not + appending them to helm template --values + type: boolean + parameters: + description: Parameters is a list of Helm parameters which + are passed to the helm template command upon manifest generation + items: + description: HelmParameter is a parameter that's passed + to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether to tell + Helm to interpret booleans and numbers as strings + type: boolean + name: + description: Name is the name of the Helm parameter + type: string + value: + description: Value is the value for the Helm parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to all domains + (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name to use. + If omitted it will use the application name + type: string + skipCrds: + description: SkipCrds skips custom resource definition installation + step (Helm's --skip-crds) + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value files to + use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be passed to + helm template, typically defined as a block + type: string + version: + description: Version is the Helm version to use for templating + ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional annotations + to add to rendered manifests + type: object + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional labels to + add to rendered manifests + type: object + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether to force + applying common annotations to resources for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether to force + applying common labels to resources for Kustomize apps + type: boolean + images: + description: Images is a list of Kustomize image override + specifications + items: + description: KustomizeImage represents a Kustomize image + definition in the format [old_image_name=]: + type: string + type: array + namePrefix: + description: NamePrefix is a prefix appended to resources + for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to resources + for Kustomize apps + type: string + version: + description: Version controls which version of Kustomize to + use for rendering manifests + type: string + type: object + path: + description: Path is a directory path within the Git repository, + and is only valid for applications sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin specific options + properties: + env: + description: Env is a list of environment variable entries + items: + description: EnvEntry represents an entry in the application's + environment + properties: + name: + description: Name is the name of the variable, usually + expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type parameter. + type: object + name: + description: Name is the name identifying a parameter. + type: string + string: + description: String_ is the value of a string type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within sources + field. This field will not be used if used with a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git or Helm) + that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of the source + to sync the application to. In case of Git, this can be commit, + tag, or branch. If omitted, will equal to HEAD. In case of Helm, + this is a semver tag for the Chart's version. + type: string + required: + - repoURL + type: object + sources: + description: Sources is a reference to the location of the application's + manifests or chart + items: + description: ApplicationSource contains all required information + about the source of an application + properties: + chart: + description: Chart is a Helm chart name, and must be specified + for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific options + properties: + exclude: + description: Exclude contains a glob pattern to match paths + against that should be explicitly excluded from being + used during manifest generation + type: string + include: + description: Include contains a glob pattern to match paths + against that should be explicitly included during manifest + generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External Variables + items: + description: JsonnetVar represents a variable to be + passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level Arguments + items: + description: JsonnetVar represents a variable to be + passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a directory + recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + fileParameters: + description: FileParameters are file parameters to the helm + template + items: + description: HelmFileParameter is a file parameter that's + passed to helm template during manifest generation + properties: + name: + description: Name is the name of the Helm parameter + type: string + path: + description: Path is the path to the file containing + the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm template + from failing when valueFiles do not exist locally by not + appending them to helm template --values + type: boolean + parameters: + description: Parameters is a list of Helm parameters which + are passed to the helm template command upon manifest + generation + items: + description: HelmParameter is a parameter that's passed + to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether to tell + Helm to interpret booleans and numbers as strings + type: boolean + name: + description: Name is the name of the Helm parameter + type: string + value: + description: Value is the value for the Helm parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to all domains + (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name to use. + If omitted it will use the application name + type: string + skipCrds: + description: SkipCrds skips custom resource definition installation + step (Helm's --skip-crds) + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value files to + use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be passed to + helm template, typically defined as a block + type: string + version: + description: Version is the Helm version to use for templating + ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional annotations + to add to rendered manifests + type: object + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional labels + to add to rendered manifests + type: object + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether to + force applying common annotations to resources for Kustomize + apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether to force + applying common labels to resources for Kustomize apps + type: boolean + images: + description: Images is a list of Kustomize image override + specifications + items: + description: KustomizeImage represents a Kustomize image + definition in the format [old_image_name=]: + type: string + type: array + namePrefix: + description: NamePrefix is a prefix appended to resources + for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to resources + for Kustomize apps + type: string + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + path: + description: Path is a directory path within the Git repository, + and is only valid for applications sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable entries + items: + description: EnvEntry represents an entry in the application's + environment + properties: + name: + description: Name is the name of the variable, usually + expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type parameter. + type: object + name: + description: Name is the name identifying a parameter. + type: string + string: + description: String_ is the value of a string type + parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within sources + field. This field will not be used if used with a `source` + tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git or Helm) + that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of the source + to sync the application to. In case of Git, this can be commit, + tag, or branch. If omitted, will equal to HEAD. In case of + Helm, this is a semver tag for the Chart's version. + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + description: SyncPolicy controls when and how a sync will be performed + properties: + automated: + description: Automated will keep an application synced to the + target revision + properties: + allowEmpty: + description: 'AllowEmpty allows apps have zero live resources + (default: false)' + type: boolean + prune: + description: 'Prune specifies whether to delete resources + from the cluster that are not found in the sources anymore + as part of automated sync (default: false)' + type: boolean + selfHeal: + description: 'SelfHeal specifes whether to revert resources + back to their desired state upon modification in the cluster + (default: false)' + type: boolean + type: object + managedNamespaceMetadata: + description: ManagedNamespaceMetadata controls metadata in the + given namespace (if CreateNamespace=true) + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + description: Retry controls failed sync retry behavior + properties: + backoff: + description: Backoff controls how to backoff on subsequent + retries of failed syncs + properties: + duration: + description: Duration is the amount to back off. Default + unit is seconds, but could also be a duration (e.g. + "2m", "1h") + type: string + factor: + description: Factor is a factor to multiply the base duration + after each failed retry + format: int64 + type: integer + maxDuration: + description: MaxDuration is the maximum amount of time + allowed for the backoff strategy + type: string + type: object + limit: + description: Limit is the maximum number of attempts for retrying + a failed sync. If set to 0, no retries will be performed. + format: int64 + type: integer + type: object + syncOptions: + description: Options allow you to specify whole app sync-options + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + status: + description: ApplicationStatus contains status information for the application + properties: + conditions: + description: Conditions is a list of currently observed application + conditions + items: + description: ApplicationCondition contains details about an application + condition, which is usally an error or warning + properties: + lastTransitionTime: + description: LastTransitionTime is the time the condition was + last observed + format: date-time + type: string + message: + description: Message contains human-readable message indicating + details about condition + type: string + type: + description: Type is an application condition type + type: string + required: + - message + - type + type: object + type: array + health: + description: Health contains information about the application's current + health status + properties: + message: + description: Message is a human-readable informational message + describing the health status + type: string + status: + description: Status holds the status code of the application or + resource + type: string + type: object + history: + description: History contains information about the application's + sync history + items: + description: RevisionHistory contains history information about + a previous sync + properties: + deployStartedAt: + description: DeployStartedAt holds the time the sync operation + started + format: date-time + type: string + deployedAt: + description: DeployedAt holds the time the sync operation completed + format: date-time + type: string + id: + description: ID is an auto incrementing identifier of the RevisionHistory + format: int64 + type: integer + revision: + description: Revision holds the revision the sync was performed + against + type: string + revisions: + description: Revisions holds the revision of each source in + sources field the sync was performed against + items: + type: string + type: array + source: + description: Source is a reference to the application source + used for the sync operation + properties: + chart: + description: Chart is a Helm chart name, and must be specified + for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific options + properties: + exclude: + description: Exclude contains a glob pattern to match + paths against that should be explicitly excluded from + being used during manifest generation + type: string + include: + description: Include contains a glob pattern to match + paths against that should be explicitly included during + manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External + Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a directory + recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + fileParameters: + description: FileParameters are file parameters to the + helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest generation + properties: + name: + description: Name is the name of the Helm parameter + type: string + path: + description: Path is the path to the file containing + the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm template + from failing when valueFiles do not exist locally + by not appending them to helm template --values + type: boolean + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command upon + manifest generation + items: + description: HelmParameter is a parameter that's passed + to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether to + tell Helm to interpret booleans and numbers + as strings + type: boolean + name: + description: Name is the name of the Helm parameter + type: string + value: + description: Value is the value for the Helm parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to all + domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name to + use. If omitted it will use the application name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value files + to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be passed + to helm template, typically defined as a block + type: string + version: + description: Version is the Helm version to use for + templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional labels + to add to rendered manifests + type: object + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether + to force applying common annotations to resources + for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether to + force applying common labels to resources for Kustomize + apps + type: boolean + images: + description: Images is a list of Kustomize image override + specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + namePrefix: + description: NamePrefix is a prefix appended to resources + for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to resources + for Kustomize apps + type: string + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + path: + description: Path is a directory path within the Git repository, + and is only valid for applications sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable entries + items: + description: EnvEntry represents an entry in the application's + environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array type + parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type parameter. + type: object + name: + description: Name is the name identifying a parameter. + type: string + string: + description: String_ is the value of a string + type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within sources + field. This field will not be used if used with a `source` + tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git or + Helm) that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of the + source to sync the application to. In case of Git, this + can be commit, tag, or branch. If omitted, will equal + to HEAD. In case of Helm, this is a semver tag for the + Chart's version. + type: string + required: + - repoURL + type: object + sources: + description: Sources is a reference to the application sources + used for the sync operation + items: + description: ApplicationSource contains all required information + about the source of an application + properties: + chart: + description: Chart is a Helm chart name, and must be specified + for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific options + properties: + exclude: + description: Exclude contains a glob pattern to match + paths against that should be explicitly excluded + from being used during manifest generation + type: string + include: + description: Include contains a glob pattern to match + paths against that should be explicitly included + during manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External + Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a directory + recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + fileParameters: + description: FileParameters are file parameters to + the helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest + generation + properties: + name: + description: Name is the name of the Helm parameter + type: string + path: + description: Path is the path to the file containing + the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm + template from failing when valueFiles do not exist + locally by not appending them to helm template --values + type: boolean + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command upon + manifest generation + items: + description: HelmParameter is a parameter that's + passed to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether + to tell Helm to interpret booleans and numbers + as strings + type: boolean + name: + description: Name is the name of the Helm parameter + type: string + value: + description: Value is the value for the Helm + parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to all + domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name + to use. If omitted it will use the application name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value files + to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be passed + to helm template, typically defined as a block + type: string + version: + description: Version is the Helm version to use for + templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional + labels to add to rendered manifests + type: object + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether + to force applying common annotations to resources + for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether to + force applying common labels to resources for Kustomize + apps + type: boolean + images: + description: Images is a list of Kustomize image override + specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + namePrefix: + description: NamePrefix is a prefix appended to resources + for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to resources + for Kustomize apps + type: string + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + path: + description: Path is a directory path within the Git repository, + and is only valid for applications sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable + entries + items: + description: EnvEntry represents an entry in the + application's environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array + type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type + parameter. + type: object + name: + description: Name is the name identifying a + parameter. + type: string + string: + description: String_ is the value of a string + type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within + sources field. This field will not be used if used with + a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git + or Helm) that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of the + source to sync the application to. In case of Git, this + can be commit, tag, or branch. If omitted, will equal + to HEAD. In case of Helm, this is a semver tag for the + Chart's version. + type: string + required: + - repoURL + type: object + type: array + required: + - deployedAt + - id + type: object + type: array + observedAt: + description: 'ObservedAt indicates when the application state was + updated without querying latest git state Deprecated: controller + no longer updates ObservedAt field' + format: date-time + type: string + operationState: + description: OperationState contains information about any ongoing + operations, such as a sync + properties: + finishedAt: + description: FinishedAt contains time of operation completion + format: date-time + type: string + message: + description: Message holds any pertinent messages when attempting + to perform operation (typically errors). + type: string + operation: + description: Operation is the original requested operation + properties: + info: + description: Info is a list of informational items for this + operation + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + initiatedBy: + description: InitiatedBy contains information about who initiated + the operations + properties: + automated: + description: Automated is set to true if operation was + initiated automatically by the application controller. + type: boolean + username: + description: Username contains the name of a user who + started operation + type: string + type: object + retry: + description: Retry controls the strategy to apply if a sync + fails + properties: + backoff: + description: Backoff controls how to backoff on subsequent + retries of failed syncs + properties: + duration: + description: Duration is the amount to back off. Default + unit is seconds, but could also be a duration (e.g. + "2m", "1h") + type: string + factor: + description: Factor is a factor to multiply the base + duration after each failed retry + format: int64 + type: integer + maxDuration: + description: MaxDuration is the maximum amount of + time allowed for the backoff strategy + type: string + type: object + limit: + description: Limit is the maximum number of attempts for + retrying a failed sync. If set to 0, no retries will + be performed. + format: int64 + type: integer + type: object + sync: + description: Sync contains parameters for the operation + properties: + dryRun: + description: DryRun specifies to perform a `kubectl apply + --dry-run` without actually performing the sync + type: boolean + manifests: + description: Manifests is an optional field that overrides + sync source with a local directory for development + items: + type: string + type: array + prune: + description: Prune specifies to delete resources from + the cluster that are no longer tracked in git + type: boolean + resources: + description: Resources describes which resources shall + be part of the sync + items: + description: SyncOperationResource contains resources + to sync. + properties: + group: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + type: array + revision: + description: Revision is the revision (Git) or chart version + (Helm) which to sync the application to If omitted, + will use the revision specified in app spec. + type: string + revisions: + description: Revisions is the list of revision (Git) or + chart version (Helm) which to sync each source in sources + field for the application to If omitted, will use the + revision specified in app spec. + items: + type: string + type: array + source: + description: Source overrides the source definition set + in the application. This is typically set in a Rollback + operation and is nil during a Sync operation + properties: + chart: + description: Chart is a Helm chart name, and must + be specified for applications sourced from a Helm + repo. + type: string + directory: + description: Directory holds path/directory specific + options + properties: + exclude: + description: Exclude contains a glob pattern to + match paths against that should be explicitly + excluded from being used during manifest generation + type: string + include: + description: Include contains a glob pattern to + match paths against that should be explicitly + included during manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific to + Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet + External Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan + a directory recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + fileParameters: + description: FileParameters are file parameters + to the helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest + generation + properties: + name: + description: Name is the name of the Helm + parameter + type: string + path: + description: Path is the path to the file + containing the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents + helm template from failing when valueFiles do + not exist locally by not appending them to helm + template --values + type: boolean + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command + upon manifest generation + items: + description: HelmParameter is a parameter that's + passed to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether + to tell Helm to interpret booleans and + numbers as strings + type: boolean + name: + description: Name is the name of the Helm + parameter + type: string + value: + description: Value is the value for the + Helm parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials + to all domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name + to use. If omitted it will use the application + name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value + files to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be + passed to helm template, typically defined as + a block + type: string + version: + description: Version is the Helm version to use + for templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional + labels to add to rendered manifests + type: object + forceCommonAnnotations: + description: ForceCommonAnnotations specifies + whether to force applying common annotations + to resources for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether + to force applying common labels to resources + for Kustomize apps + type: boolean + images: + description: Images is a list of Kustomize image + override specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + namePrefix: + description: NamePrefix is a prefix appended to + resources for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to + resources for Kustomize apps + type: string + version: + description: Version controls which version of + Kustomize to use for rendering manifests + type: string + type: object + path: + description: Path is a directory path within the Git + repository, and is only valid for applications sourced + from Git. + type: string + plugin: + description: Plugin holds config management plugin + specific options + properties: + env: + description: Env is a list of environment variable + entries + items: + description: EnvEntry represents an entry in + the application's environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array + type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type + parameter. + type: object + name: + description: Name is the name identifying + a parameter. + type: string + string: + description: String_ is the value of a string + type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within + sources field. This field will not be used if used + with a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository + (Git or Helm) that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of + the source to sync the application to. In case of + Git, this can be commit, tag, or branch. If omitted, + will equal to HEAD. In case of Helm, this is a semver + tag for the Chart's version. + type: string + required: + - repoURL + type: object + sources: + description: Sources overrides the source definition set + in the application. This is typically set in a Rollback + operation and is nil during a Sync operation + items: + description: ApplicationSource contains all required + information about the source of an application + properties: + chart: + description: Chart is a Helm chart name, and must + be specified for applications sourced from a Helm + repo. + type: string + directory: + description: Directory holds path/directory specific + options + properties: + exclude: + description: Exclude contains a glob pattern + to match paths against that should be explicitly + excluded from being used during manifest generation + type: string + include: + description: Include contains a glob pattern + to match paths against that should be explicitly + included during manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific + to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet + External Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan + a directory recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + fileParameters: + description: FileParameters are file parameters + to the helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest + generation + properties: + name: + description: Name is the name of the Helm + parameter + type: string + path: + description: Path is the path to the file + containing the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents + helm template from failing when valueFiles + do not exist locally by not appending them + to helm template --values + type: boolean + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command + upon manifest generation + items: + description: HelmParameter is a parameter + that's passed to helm template during manifest + generation + properties: + forceString: + description: ForceString determines whether + to tell Helm to interpret booleans and + numbers as strings + type: boolean + name: + description: Name is the name of the Helm + parameter + type: string + value: + description: Value is the value for the + Helm parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials + to all domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release + name to use. If omitted it will use the application + name + type: string + skipCrds: + description: SkipCrds skips custom resource + definition installation step (Helm's --skip-crds) + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value + files to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to + be passed to helm template, typically defined + as a block + type: string + version: + description: Version is the Helm version to + use for templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific + options + properties: + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of + additional annotations to add to rendered + manifests + type: object + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional + labels to add to rendered manifests + type: object + forceCommonAnnotations: + description: ForceCommonAnnotations specifies + whether to force applying common annotations + to resources for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether + to force applying common labels to resources + for Kustomize apps + type: boolean + images: + description: Images is a list of Kustomize image + override specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + namePrefix: + description: NamePrefix is a prefix appended + to resources for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended + to resources for Kustomize apps + type: string + version: + description: Version controls which version + of Kustomize to use for rendering manifests + type: string + type: object + path: + description: Path is a directory path within the + Git repository, and is only valid for applications + sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin + specific options + properties: + env: + description: Env is a list of environment variable + entries + items: + description: EnvEntry represents an entry + in the application's environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the + variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an + array type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map + type parameter. + type: object + name: + description: Name is the name identifying + a parameter. + type: string + string: + description: String_ is the value of a + string type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source + within sources field. This field will not be used + if used with a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository + (Git or Helm) that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision + of the source to sync the application to. In case + of Git, this can be commit, tag, or branch. If + omitted, will equal to HEAD. In case of Helm, + this is a semver tag for the Chart's version. + type: string + required: + - repoURL + type: object + type: array + syncOptions: + description: SyncOptions provide per-sync sync-options, + e.g. Validate=false + items: + type: string + type: array + syncStrategy: + description: SyncStrategy describes how to perform the + sync + properties: + apply: + description: Apply will perform a `kubectl apply` + to perform the sync. + properties: + force: + description: Force indicates whether or not to + supply the --force flag to `kubectl apply`. + The --force flag deletes and re-create the resource, + when PATCH encounters conflict and has retried + for 5 times. + type: boolean + type: object + hook: + description: Hook will submit any referenced resources + to perform the sync. This is the default strategy + properties: + force: + description: Force indicates whether or not to + supply the --force flag to `kubectl apply`. + The --force flag deletes and re-create the resource, + when PATCH encounters conflict and has retried + for 5 times. + type: boolean + type: object + type: object + type: object + type: object + phase: + description: Phase is the current phase of the operation + type: string + retryCount: + description: RetryCount contains time of operation retries + format: int64 + type: integer + startedAt: + description: StartedAt contains time of operation start + format: date-time + type: string + syncResult: + description: SyncResult is the result of a Sync operation + properties: + resources: + description: Resources contains a list of sync result items + for each individual resource in a sync operation + items: + description: ResourceResult holds the operation result details + of a specific resource + properties: + group: + description: Group specifies the API group of the resource + type: string + hookPhase: + description: HookPhase contains the state of any operation + associated with this resource OR hook This can also + contain values for non-hook resources. + type: string + hookType: + description: HookType specifies the type of the hook. + Empty for non-hook resources + type: string + kind: + description: Kind specifies the API kind of the resource + type: string + message: + description: Message contains an informational or error + message for the last sync OR operation + type: string + name: + description: Name specifies the name of the resource + type: string + namespace: + description: Namespace specifies the target namespace + of the resource + type: string + status: + description: Status holds the final result of the sync. + Will be empty if the resources is yet to be applied/pruned + and is always zero-value for hooks + type: string + syncPhase: + description: SyncPhase indicates the particular phase + of the sync that this result was acquired in + type: string + version: + description: Version specifies the API version of the + resource + type: string + required: + - group + - kind + - name + - namespace + - version + type: object + type: array + revision: + description: Revision holds the revision this sync operation + was performed to + type: string + revisions: + description: Revisions holds the revision this sync operation + was performed for respective indexed source in sources field + items: + type: string + type: array + source: + description: Source records the application source information + of the sync, used for comparing auto-sync + properties: + chart: + description: Chart is a Helm chart name, and must be specified + for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific options + properties: + exclude: + description: Exclude contains a glob pattern to match + paths against that should be explicitly excluded + from being used during manifest generation + type: string + include: + description: Include contains a glob pattern to match + paths against that should be explicitly included + during manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External + Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a directory + recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + fileParameters: + description: FileParameters are file parameters to + the helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest + generation + properties: + name: + description: Name is the name of the Helm parameter + type: string + path: + description: Path is the path to the file containing + the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm + template from failing when valueFiles do not exist + locally by not appending them to helm template --values + type: boolean + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command upon + manifest generation + items: + description: HelmParameter is a parameter that's + passed to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether + to tell Helm to interpret booleans and numbers + as strings + type: boolean + name: + description: Name is the name of the Helm parameter + type: string + value: + description: Value is the value for the Helm + parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to all + domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name + to use. If omitted it will use the application name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value files + to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be passed + to helm template, typically defined as a block + type: string + version: + description: Version is the Helm version to use for + templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional + labels to add to rendered manifests + type: object + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether + to force applying common annotations to resources + for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether to + force applying common labels to resources for Kustomize + apps + type: boolean + images: + description: Images is a list of Kustomize image override + specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + namePrefix: + description: NamePrefix is a prefix appended to resources + for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to resources + for Kustomize apps + type: string + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + path: + description: Path is a directory path within the Git repository, + and is only valid for applications sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable + entries + items: + description: EnvEntry represents an entry in the + application's environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array + type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type + parameter. + type: object + name: + description: Name is the name identifying a + parameter. + type: string + string: + description: String_ is the value of a string + type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within + sources field. This field will not be used if used with + a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git + or Helm) that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of the + source to sync the application to. In case of Git, this + can be commit, tag, or branch. If omitted, will equal + to HEAD. In case of Helm, this is a semver tag for the + Chart's version. + type: string + required: + - repoURL + type: object + sources: + description: Source records the application source information + of the sync, used for comparing auto-sync + items: + description: ApplicationSource contains all required information + about the source of an application + properties: + chart: + description: Chart is a Helm chart name, and must be + specified for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific + options + properties: + exclude: + description: Exclude contains a glob pattern to + match paths against that should be explicitly + excluded from being used during manifest generation + type: string + include: + description: Include contains a glob pattern to + match paths against that should be explicitly + included during manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External + Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a + directory recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + fileParameters: + description: FileParameters are file parameters + to the helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest + generation + properties: + name: + description: Name is the name of the Helm + parameter + type: string + path: + description: Path is the path to the file + containing the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm + template from failing when valueFiles do not exist + locally by not appending them to helm template + --values + type: boolean + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command + upon manifest generation + items: + description: HelmParameter is a parameter that's + passed to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether + to tell Helm to interpret booleans and numbers + as strings + type: boolean + name: + description: Name is the name of the Helm + parameter + type: string + value: + description: Value is the value for the Helm + parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to + all domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name + to use. If omitted it will use the application + name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value + files to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be + passed to helm template, typically defined as + a block + type: string + version: + description: Version is the Helm version to use + for templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional + labels to add to rendered manifests + type: object + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether + to force applying common annotations to resources + for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether + to force applying common labels to resources for + Kustomize apps + type: boolean + images: + description: Images is a list of Kustomize image + override specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + namePrefix: + description: NamePrefix is a prefix appended to + resources for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to + resources for Kustomize apps + type: string + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + path: + description: Path is a directory path within the Git + repository, and is only valid for applications sourced + from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable + entries + items: + description: EnvEntry represents an entry in the + application's environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array + type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type + parameter. + type: object + name: + description: Name is the name identifying + a parameter. + type: string + string: + description: String_ is the value of a string + type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within + sources field. This field will not be used if used + with a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git + or Helm) that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of + the source to sync the application to. In case of + Git, this can be commit, tag, or branch. If omitted, + will equal to HEAD. In case of Helm, this is a semver + tag for the Chart's version. + type: string + required: + - repoURL + type: object + type: array + required: + - revision + type: object + required: + - operation + - phase + - startedAt + type: object + reconciledAt: + description: ReconciledAt indicates when the application state was + reconciled using the latest git version + format: date-time + type: string + resourceHealthSource: + description: 'ResourceHealthSource indicates where the resource health + status is stored: inline if not set or appTree' + type: string + resources: + description: Resources is a list of Kubernetes resources managed by + this application + items: + description: 'ResourceStatus holds the current sync and health status + of a resource TODO: describe members of this type' + properties: + group: + type: string + health: + description: HealthStatus contains information about the currently + observed health state of an application or resource + properties: + message: + description: Message is a human-readable informational message + describing the health status + type: string + status: + description: Status holds the status code of the application + or resource + type: string + type: object + hook: + type: boolean + kind: + type: string + name: + type: string + namespace: + type: string + requiresPruning: + type: boolean + status: + description: SyncStatusCode is a type which represents possible + comparison results + type: string + syncWave: + format: int64 + type: integer + version: + type: string + type: object + type: array + sourceType: + description: SourceType specifies the type of this application + type: string + sourceTypes: + description: SourceTypes specifies the type of the sources included + in the application + items: + description: ApplicationSourceType specifies the type of the application's + source + type: string + type: array + summary: + description: Summary contains a list of URLs and container images + used by this application + properties: + externalURLs: + description: ExternalURLs holds all external URLs of application + child resources. + items: + type: string + type: array + images: + description: Images holds all images of application child resources. + items: + type: string + type: array + type: object + sync: + description: Sync contains information about the application's current + sync status + properties: + comparedTo: + description: ComparedTo contains information about what has been + compared + properties: + destination: + description: Destination is a reference to the application's + destination used for comparison + properties: + name: + description: Name is an alternate way of specifying the + target cluster by its symbolic name + type: string + namespace: + description: Namespace specifies the target namespace + for the application's resources. The namespace will + only be set for namespace-scoped resources that have + not set a value for .metadata.namespace + type: string + server: + description: Server specifies the URL of the target cluster + and must be set to the Kubernetes control plane API + type: string + type: object + source: + description: Source is a reference to the application's source + used for comparison + properties: + chart: + description: Chart is a Helm chart name, and must be specified + for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific options + properties: + exclude: + description: Exclude contains a glob pattern to match + paths against that should be explicitly excluded + from being used during manifest generation + type: string + include: + description: Include contains a glob pattern to match + paths against that should be explicitly included + during manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External + Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a directory + recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + fileParameters: + description: FileParameters are file parameters to + the helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest + generation + properties: + name: + description: Name is the name of the Helm parameter + type: string + path: + description: Path is the path to the file containing + the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm + template from failing when valueFiles do not exist + locally by not appending them to helm template --values + type: boolean + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command upon + manifest generation + items: + description: HelmParameter is a parameter that's + passed to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether + to tell Helm to interpret booleans and numbers + as strings + type: boolean + name: + description: Name is the name of the Helm parameter + type: string + value: + description: Value is the value for the Helm + parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to all + domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name + to use. If omitted it will use the application name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value files + to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be passed + to helm template, typically defined as a block + type: string + version: + description: Version is the Helm version to use for + templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional + labels to add to rendered manifests + type: object + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether + to force applying common annotations to resources + for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether to + force applying common labels to resources for Kustomize + apps + type: boolean + images: + description: Images is a list of Kustomize image override + specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + namePrefix: + description: NamePrefix is a prefix appended to resources + for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to resources + for Kustomize apps + type: string + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + path: + description: Path is a directory path within the Git repository, + and is only valid for applications sourced from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable + entries + items: + description: EnvEntry represents an entry in the + application's environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array + type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type + parameter. + type: object + name: + description: Name is the name identifying a + parameter. + type: string + string: + description: String_ is the value of a string + type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within + sources field. This field will not be used if used with + a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git + or Helm) that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of the + source to sync the application to. In case of Git, this + can be commit, tag, or branch. If omitted, will equal + to HEAD. In case of Helm, this is a semver tag for the + Chart's version. + type: string + required: + - repoURL + type: object + sources: + description: Sources is a reference to the application's multiple + sources used for comparison + items: + description: ApplicationSource contains all required information + about the source of an application + properties: + chart: + description: Chart is a Helm chart name, and must be + specified for applications sourced from a Helm repo. + type: string + directory: + description: Directory holds path/directory specific + options + properties: + exclude: + description: Exclude contains a glob pattern to + match paths against that should be explicitly + excluded from being used during manifest generation + type: string + include: + description: Include contains a glob pattern to + match paths against that should be explicitly + included during manifest generation + type: string + jsonnet: + description: Jsonnet holds options specific to Jsonnet + properties: + extVars: + description: ExtVars is a list of Jsonnet External + Variables + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + description: Additional library search dirs + items: + type: string + type: array + tlas: + description: TLAS is a list of Jsonnet Top-level + Arguments + items: + description: JsonnetVar represents a variable + to be passed to jsonnet during manifest + generation + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + description: Recurse specifies whether to scan a + directory recursively for manifests + type: boolean + type: object + helm: + description: Helm holds helm specific options + properties: + fileParameters: + description: FileParameters are file parameters + to the helm template + items: + description: HelmFileParameter is a file parameter + that's passed to helm template during manifest + generation + properties: + name: + description: Name is the name of the Helm + parameter + type: string + path: + description: Path is the path to the file + containing the values for the Helm parameter + type: string + type: object + type: array + ignoreMissingValueFiles: + description: IgnoreMissingValueFiles prevents helm + template from failing when valueFiles do not exist + locally by not appending them to helm template + --values + type: boolean + parameters: + description: Parameters is a list of Helm parameters + which are passed to the helm template command + upon manifest generation + items: + description: HelmParameter is a parameter that's + passed to helm template during manifest generation + properties: + forceString: + description: ForceString determines whether + to tell Helm to interpret booleans and numbers + as strings + type: boolean + name: + description: Name is the name of the Helm + parameter + type: string + value: + description: Value is the value for the Helm + parameter + type: string + type: object + type: array + passCredentials: + description: PassCredentials pass credentials to + all domains (Helm's --pass-credentials) + type: boolean + releaseName: + description: ReleaseName is the Helm release name + to use. If omitted it will use the application + name + type: string + skipCrds: + description: SkipCrds skips custom resource definition + installation step (Helm's --skip-crds) + type: boolean + valueFiles: + description: ValuesFiles is a list of Helm value + files to use when generating a template + items: + type: string + type: array + values: + description: Values specifies Helm values to be + passed to helm template, typically defined as + a block + type: string + version: + description: Version is the Helm version to use + for templating ("3") + type: string + type: object + kustomize: + description: Kustomize holds kustomize specific options + properties: + commonAnnotations: + additionalProperties: + type: string + description: CommonAnnotations is a list of additional + annotations to add to rendered manifests + type: object + commonLabels: + additionalProperties: + type: string + description: CommonLabels is a list of additional + labels to add to rendered manifests + type: object + forceCommonAnnotations: + description: ForceCommonAnnotations specifies whether + to force applying common annotations to resources + for Kustomize apps + type: boolean + forceCommonLabels: + description: ForceCommonLabels specifies whether + to force applying common labels to resources for + Kustomize apps + type: boolean + images: + description: Images is a list of Kustomize image + override specifications + items: + description: KustomizeImage represents a Kustomize + image definition in the format [old_image_name=]: + type: string + type: array + namePrefix: + description: NamePrefix is a prefix appended to + resources for Kustomize apps + type: string + nameSuffix: + description: NameSuffix is a suffix appended to + resources for Kustomize apps + type: string + version: + description: Version controls which version of Kustomize + to use for rendering manifests + type: string + type: object + path: + description: Path is a directory path within the Git + repository, and is only valid for applications sourced + from Git. + type: string + plugin: + description: Plugin holds config management plugin specific + options + properties: + env: + description: Env is a list of environment variable + entries + items: + description: EnvEntry represents an entry in the + application's environment + properties: + name: + description: Name is the name of the variable, + usually expressed in uppercase + type: string + value: + description: Value is the value of the variable + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + description: Array is the value of an array + type parameter. + items: + type: string + type: array + map: + additionalProperties: + type: string + description: Map is the value of a map type + parameter. + type: object + name: + description: Name is the name identifying + a parameter. + type: string + string: + description: String_ is the value of a string + type parameter. + type: string + type: object + type: array + type: object + ref: + description: Ref is reference to another source within + sources field. This field will not be used if used + with a `source` tag. + type: string + repoURL: + description: RepoURL is the URL to the repository (Git + or Helm) that contains the application manifests + type: string + targetRevision: + description: TargetRevision defines the revision of + the source to sync the application to. In case of + Git, this can be commit, tag, or branch. If omitted, + will equal to HEAD. In case of Helm, this is a semver + tag for the Chart's version. + type: string + required: + - repoURL + type: object + type: array + required: + - destination + type: object + revision: + description: Revision contains information about the revision + the comparison has been performed to + type: string + revisions: + description: Revisions contains information about the revisions + of multiple sources the comparison has been performed to + items: + type: string + type: array + status: + description: Status is the sync state of the comparison + type: string + required: + - status + type: object + type: object + required: + - metadata + - spec + type: object + served: true + storage: true + subresources: {} +{{- end }} diff --git a/helm/argo-cd/templates/crds/crd-applicationset.yaml b/helm/argo-cd/templates/crds/crd-applicationset.yaml new file mode 100644 index 0000000..4345224 --- /dev/null +++ b/helm/argo-cd/templates/crds/crd-applicationset.yaml @@ -0,0 +1,10775 @@ +{{- if and .Values.crds.install .Values.applicationSet.enabled }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + {{- if .Values.crds.keep }} + "helm.sh/resource-policy": keep + {{- end }} + {{- with .Values.crds.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + labels: + app.kubernetes.io/name: applicationsets.argoproj.io + app.kubernetes.io/part-of: argocd + name: applicationsets.argoproj.io +spec: + group: argoproj.io + names: + kind: ApplicationSet + listKind: ApplicationSetList + plural: applicationsets + shortNames: + - appset + - appsets + singular: applicationset + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + generators: + items: + properties: + clusterDecisionResource: + properties: + configMapRef: + type: string + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + name: + type: string + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + required: + - configMapRef + type: object + clusters: + properties: + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + type: object + git: + properties: + directories: + items: + properties: + exclude: + type: boolean + path: + type: string + required: + - path + type: object + type: array + files: + items: + properties: + path: + type: string + required: + - path + type: object + type: array + pathParamPrefix: + type: string + repoURL: + type: string + requeueAfterSeconds: + format: int64 + type: integer + revision: + type: string + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + required: + - repoURL + - revision + type: object + list: + properties: + elements: + items: + x-kubernetes-preserve-unknown-fields: true + type: array + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + required: + - elements + type: object + matrix: + properties: + generators: + items: + properties: + clusterDecisionResource: + properties: + configMapRef: + type: string + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + name: + type: string + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + required: + - configMapRef + type: object + clusters: + properties: + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + type: object + git: + properties: + directories: + items: + properties: + exclude: + type: boolean + path: + type: string + required: + - path + type: object + type: array + files: + items: + properties: + path: + type: string + required: + - path + type: object + type: array + pathParamPrefix: + type: string + repoURL: + type: string + requeueAfterSeconds: + format: int64 + type: integer + revision: + type: string + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + required: + - repoURL + - revision + type: object + list: + properties: + elements: + items: + x-kubernetes-preserve-unknown-fields: true + type: array + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + required: + - elements + type: object + matrix: + x-kubernetes-preserve-unknown-fields: true + merge: + x-kubernetes-preserve-unknown-fields: true + pullRequest: + properties: + bitbucketServer: + properties: + api: + type: string + basicAuth: + properties: + passwordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + username: + type: string + required: + - passwordRef + - username + type: object + project: + type: string + repo: + type: string + required: + - api + - project + - repo + type: object + filters: + items: + properties: + branchMatch: + type: string + type: object + type: array + gitea: + properties: + api: + type: string + insecure: + type: boolean + owner: + type: string + repo: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - api + - owner + - repo + type: object + github: + properties: + api: + type: string + appSecretName: + type: string + labels: + items: + type: string + type: array + owner: + type: string + repo: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - owner + - repo + type: object + gitlab: + properties: + api: + type: string + labels: + items: + type: string + type: array + project: + type: string + pullRequestState: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - project + type: object + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + type: object + scmProvider: + properties: + azureDevOps: + properties: + accessTokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + allBranches: + type: boolean + api: + type: string + organization: + type: string + teamProject: + type: string + required: + - accessTokenRef + - organization + - teamProject + type: object + bitbucket: + properties: + allBranches: + type: boolean + appPasswordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + owner: + type: string + user: + type: string + required: + - appPasswordRef + - owner + - user + type: object + bitbucketServer: + properties: + allBranches: + type: boolean + api: + type: string + basicAuth: + properties: + passwordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + username: + type: string + required: + - passwordRef + - username + type: object + project: + type: string + required: + - api + - project + type: object + cloneProtocol: + type: string + filters: + items: + properties: + branchMatch: + type: string + labelMatch: + type: string + pathsDoNotExist: + items: + type: string + type: array + pathsExist: + items: + type: string + type: array + repositoryMatch: + type: string + type: object + type: array + gitea: + properties: + allBranches: + type: boolean + api: + type: string + insecure: + type: boolean + owner: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - api + - owner + type: object + github: + properties: + allBranches: + type: boolean + api: + type: string + appSecretName: + type: string + organization: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - organization + type: object + gitlab: + properties: + allBranches: + type: boolean + api: + type: string + group: + type: string + includeSubgroups: + type: boolean + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - group + type: object + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + type: object + type: array + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + required: + - generators + type: object + merge: + properties: + generators: + items: + properties: + clusterDecisionResource: + properties: + configMapRef: + type: string + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + name: + type: string + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + required: + - configMapRef + type: object + clusters: + properties: + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + values: + additionalProperties: + type: string + type: object + type: object + git: + properties: + directories: + items: + properties: + exclude: + type: boolean + path: + type: string + required: + - path + type: object + type: array + files: + items: + properties: + path: + type: string + required: + - path + type: object + type: array + pathParamPrefix: + type: string + repoURL: + type: string + requeueAfterSeconds: + format: int64 + type: integer + revision: + type: string + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + required: + - repoURL + - revision + type: object + list: + properties: + elements: + items: + x-kubernetes-preserve-unknown-fields: true + type: array + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + required: + - elements + type: object + matrix: + x-kubernetes-preserve-unknown-fields: true + merge: + x-kubernetes-preserve-unknown-fields: true + pullRequest: + properties: + bitbucketServer: + properties: + api: + type: string + basicAuth: + properties: + passwordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + username: + type: string + required: + - passwordRef + - username + type: object + project: + type: string + repo: + type: string + required: + - api + - project + - repo + type: object + filters: + items: + properties: + branchMatch: + type: string + type: object + type: array + gitea: + properties: + api: + type: string + insecure: + type: boolean + owner: + type: string + repo: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - api + - owner + - repo + type: object + github: + properties: + api: + type: string + appSecretName: + type: string + labels: + items: + type: string + type: array + owner: + type: string + repo: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - owner + - repo + type: object + gitlab: + properties: + api: + type: string + labels: + items: + type: string + type: array + project: + type: string + pullRequestState: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - project + type: object + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + type: object + scmProvider: + properties: + azureDevOps: + properties: + accessTokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + allBranches: + type: boolean + api: + type: string + organization: + type: string + teamProject: + type: string + required: + - accessTokenRef + - organization + - teamProject + type: object + bitbucket: + properties: + allBranches: + type: boolean + appPasswordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + owner: + type: string + user: + type: string + required: + - appPasswordRef + - owner + - user + type: object + bitbucketServer: + properties: + allBranches: + type: boolean + api: + type: string + basicAuth: + properties: + passwordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + username: + type: string + required: + - passwordRef + - username + type: object + project: + type: string + required: + - api + - project + type: object + cloneProtocol: + type: string + filters: + items: + properties: + branchMatch: + type: string + labelMatch: + type: string + pathsDoNotExist: + items: + type: string + type: array + pathsExist: + items: + type: string + type: array + repositoryMatch: + type: string + type: object + type: array + gitea: + properties: + allBranches: + type: boolean + api: + type: string + insecure: + type: boolean + owner: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - api + - owner + type: object + github: + properties: + allBranches: + type: boolean + api: + type: string + appSecretName: + type: string + organization: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - organization + type: object + gitlab: + properties: + allBranches: + type: boolean + api: + type: string + group: + type: string + includeSubgroups: + type: boolean + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - group + type: object + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + type: object + type: array + mergeKeys: + items: + type: string + type: array + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + required: + - generators + - mergeKeys + type: object + pullRequest: + properties: + bitbucketServer: + properties: + api: + type: string + basicAuth: + properties: + passwordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + username: + type: string + required: + - passwordRef + - username + type: object + project: + type: string + repo: + type: string + required: + - api + - project + - repo + type: object + filters: + items: + properties: + branchMatch: + type: string + type: object + type: array + gitea: + properties: + api: + type: string + insecure: + type: boolean + owner: + type: string + repo: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - api + - owner + - repo + type: object + github: + properties: + api: + type: string + appSecretName: + type: string + labels: + items: + type: string + type: array + owner: + type: string + repo: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - owner + - repo + type: object + gitlab: + properties: + api: + type: string + labels: + items: + type: string + type: array + project: + type: string + pullRequestState: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - project + type: object + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + type: object + scmProvider: + properties: + azureDevOps: + properties: + accessTokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + allBranches: + type: boolean + api: + type: string + organization: + type: string + teamProject: + type: string + required: + - accessTokenRef + - organization + - teamProject + type: object + bitbucket: + properties: + allBranches: + type: boolean + appPasswordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + owner: + type: string + user: + type: string + required: + - appPasswordRef + - owner + - user + type: object + bitbucketServer: + properties: + allBranches: + type: boolean + api: + type: string + basicAuth: + properties: + passwordRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + username: + type: string + required: + - passwordRef + - username + type: object + project: + type: string + required: + - api + - project + type: object + cloneProtocol: + type: string + filters: + items: + properties: + branchMatch: + type: string + labelMatch: + type: string + pathsDoNotExist: + items: + type: string + type: array + pathsExist: + items: + type: string + type: array + repositoryMatch: + type: string + type: object + type: array + gitea: + properties: + allBranches: + type: boolean + api: + type: string + insecure: + type: boolean + owner: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - api + - owner + type: object + github: + properties: + allBranches: + type: boolean + api: + type: string + appSecretName: + type: string + organization: + type: string + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - organization + type: object + gitlab: + properties: + allBranches: + type: boolean + api: + type: string + group: + type: string + includeSubgroups: + type: boolean + tokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + required: + - group + type: object + requeueAfterSeconds: + format: int64 + type: integer + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + type: object + type: array + goTemplate: + type: boolean + strategy: + properties: + rollingSync: + properties: + steps: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + maxUpdate: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + type: array + type: object + type: + type: string + type: object + syncPolicy: + properties: + preserveResourcesOnDeletion: + type: boolean + type: object + template: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + finalizers: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + name: + type: string + namespace: + type: string + type: object + spec: + properties: + destination: + properties: + name: + type: string + namespace: + type: string + server: + type: string + type: object + ignoreDifferences: + items: + properties: + group: + type: string + jqPathExpressions: + items: + type: string + type: array + jsonPointers: + items: + type: string + type: array + kind: + type: string + managedFieldsManagers: + items: + type: string + type: array + name: + type: string + namespace: + type: string + required: + - kind + type: object + type: array + info: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + project: + type: string + revisionHistoryLimit: + format: int64 + type: integer + source: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + sources: + items: + properties: + chart: + type: string + directory: + properties: + exclude: + type: string + include: + type: string + jsonnet: + properties: + extVars: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + libs: + items: + type: string + type: array + tlas: + items: + properties: + code: + type: boolean + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + type: object + recurse: + type: boolean + type: object + helm: + properties: + fileParameters: + items: + properties: + name: + type: string + path: + type: string + type: object + type: array + ignoreMissingValueFiles: + type: boolean + parameters: + items: + properties: + forceString: + type: boolean + name: + type: string + value: + type: string + type: object + type: array + passCredentials: + type: boolean + releaseName: + type: string + skipCrds: + type: boolean + valueFiles: + items: + type: string + type: array + values: + type: string + version: + type: string + type: object + kustomize: + properties: + commonAnnotations: + additionalProperties: + type: string + type: object + commonLabels: + additionalProperties: + type: string + type: object + forceCommonAnnotations: + type: boolean + forceCommonLabels: + type: boolean + images: + items: + type: string + type: array + namePrefix: + type: string + nameSuffix: + type: string + version: + type: string + type: object + path: + type: string + plugin: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + name: + type: string + parameters: + items: + properties: + array: + items: + type: string + type: array + map: + additionalProperties: + type: string + type: object + name: + type: string + string: + type: string + type: object + type: array + type: object + ref: + type: string + repoURL: + type: string + targetRevision: + type: string + required: + - repoURL + type: object + type: array + syncPolicy: + properties: + automated: + properties: + allowEmpty: + type: boolean + prune: + type: boolean + selfHeal: + type: boolean + type: object + managedNamespaceMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + retry: + properties: + backoff: + properties: + duration: + type: string + factor: + format: int64 + type: integer + maxDuration: + type: string + type: object + limit: + format: int64 + type: integer + type: object + syncOptions: + items: + type: string + type: array + type: object + required: + - destination + - project + type: object + required: + - metadata + - spec + type: object + required: + - generators + - template + type: object + status: + properties: + applicationStatus: + items: + properties: + application: + type: string + lastTransitionTime: + format: date-time + type: string + message: + type: string + status: + type: string + step: + type: string + required: + - application + - message + - status + - step + type: object + type: array + conditions: + items: + properties: + lastTransitionTime: + format: date-time + type: string + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + required: + - message + - reason + - status + - type + type: object + type: array + type: object + required: + - metadata + - spec + type: object + served: true + storage: true + subresources: + status: {} +{{- end }} diff --git a/helm/argo-cd/templates/crds/crd-extension.yaml b/helm/argo-cd/templates/crds/crd-extension.yaml new file mode 100644 index 0000000..802f0e8 --- /dev/null +++ b/helm/argo-cd/templates/crds/crd-extension.yaml @@ -0,0 +1,104 @@ +{{- if and .Values.crds.install .Values.server.extensions.enabled }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + {{- if .Values.crds.keep }} + "helm.sh/resource-policy": keep + {{- end }} + {{- with .Values.crds.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + controller-gen.kubebuilder.io/version: v0.4.1 + labels: + app.kubernetes.io/name: argocdextensions.argoproj.io + app.kubernetes.io/part-of: argocd + name: argocdextensions.argoproj.io +spec: + group: argoproj.io + names: + kind: ArgoCDExtension + listKind: ArgoCDExtensionList + plural: argocdextensions + singular: argocdextension + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: ArgoCDExtension is the Schema for the argocdextensions 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: ArgoCDExtensionSpec defines the desired state of ArgoCDExtension + properties: + sources: + description: Sources specifies where the extension should come from + items: + description: ExtensionSource specifies where the extension should + be sourced from + properties: + git: + description: Git is specified if the extension should be sourced + from a git repository + properties: + revision: + description: Revision specifies the revision of the Repository + to fetch + type: string + url: + description: URL specifies the Git repository URL to fetch + type: string + type: object + web: + description: Web is specified if the extension should be sourced + from a web file + properties: + url: + description: URK specifies the remote file URL + type: string + type: object + type: object + type: array + required: + - sources + type: object + status: + description: ArgoCDExtensionStatus defines the observed state of ArgoCDExtension + properties: + conditions: + items: + properties: + message: + description: Message contains human-readable message indicating + details about condition + type: string + status: + description: Boolean status describing if the condition is currently + true + type: string + type: + description: Type is an ArgoCDExtension condition type + type: string + required: + - message + - status + - type + type: object + type: array + type: object + type: object + served: true + storage: true +{{- end }} diff --git a/helm/argo-cd/templates/crds/crd-project.yaml b/helm/argo-cd/templates/crds/crd-project.yaml new file mode 100644 index 0000000..81e57d8 --- /dev/null +++ b/helm/argo-cd/templates/crds/crd-project.yaml @@ -0,0 +1,331 @@ +{{- if .Values.crds.install }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + {{- if .Values.crds.keep }} + "helm.sh/resource-policy": keep + {{- end }} + {{- with .Values.crds.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + labels: + app.kubernetes.io/name: appprojects.argoproj.io + app.kubernetes.io/part-of: argocd + name: appprojects.argoproj.io +spec: + group: argoproj.io + names: + kind: AppProject + listKind: AppProjectList + plural: appprojects + shortNames: + - appproj + - appprojs + singular: appproject + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: 'AppProject provides a logical grouping of applications, providing + controls for: * where the apps may deploy to (cluster whitelist) * what + may be deployed (repository whitelist, resource whitelist/blacklist) * who + can access these applications (roles, OIDC group claims bindings) * and + what they can do (RBAC policies) * automation access to these roles (JWT + tokens)' + 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: AppProjectSpec is the specification of an AppProject + properties: + clusterResourceBlacklist: + description: ClusterResourceBlacklist contains list of blacklisted + cluster level resources + items: + description: GroupKind specifies a Group and a Kind, but does not + force a version. This is useful for identifying concepts during + lookup stages without having partially valid types + properties: + group: + type: string + kind: + type: string + required: + - group + - kind + type: object + type: array + clusterResourceWhitelist: + description: ClusterResourceWhitelist contains list of whitelisted + cluster level resources + items: + description: GroupKind specifies a Group and a Kind, but does not + force a version. This is useful for identifying concepts during + lookup stages without having partially valid types + properties: + group: + type: string + kind: + type: string + required: + - group + - kind + type: object + type: array + description: + description: Description contains optional project description + type: string + destinations: + description: Destinations contains list of destinations available + for deployment + items: + description: ApplicationDestination holds information about the + application's destination + properties: + name: + description: Name is an alternate way of specifying the target + cluster by its symbolic name + type: string + namespace: + description: Namespace specifies the target namespace for the + application's resources. The namespace will only be set for + namespace-scoped resources that have not set a value for .metadata.namespace + type: string + server: + description: Server specifies the URL of the target cluster + and must be set to the Kubernetes control plane API + type: string + type: object + type: array + namespaceResourceBlacklist: + description: NamespaceResourceBlacklist contains list of blacklisted + namespace level resources + items: + description: GroupKind specifies a Group and a Kind, but does not + force a version. This is useful for identifying concepts during + lookup stages without having partially valid types + properties: + group: + type: string + kind: + type: string + required: + - group + - kind + type: object + type: array + namespaceResourceWhitelist: + description: NamespaceResourceWhitelist contains list of whitelisted + namespace level resources + items: + description: GroupKind specifies a Group and a Kind, but does not + force a version. This is useful for identifying concepts during + lookup stages without having partially valid types + properties: + group: + type: string + kind: + type: string + required: + - group + - kind + type: object + type: array + orphanedResources: + description: OrphanedResources specifies if controller should monitor + orphaned resources of apps in this project + properties: + ignore: + description: Ignore contains a list of resources that are to be + excluded from orphaned resources monitoring + items: + description: OrphanedResourceKey is a reference to a resource + to be ignored from + properties: + group: + type: string + kind: + type: string + name: + type: string + type: object + type: array + warn: + description: Warn indicates if warning condition should be created + for apps which have orphaned resources + type: boolean + type: object + permitOnlyProjectScopedClusters: + description: PermitOnlyProjectScopedClusters determines whether destinations + can only reference clusters which are project-scoped + type: boolean + roles: + description: Roles are user defined RBAC roles associated with this + project + items: + description: ProjectRole represents a role that has access to a + project + properties: + description: + description: Description is a description of the role + type: string + groups: + description: Groups are a list of OIDC group claims bound to + this role + items: + type: string + type: array + jwtTokens: + description: JWTTokens are a list of generated JWT tokens bound + to this role + items: + description: JWTToken holds the issuedAt and expiresAt values + of a token + properties: + exp: + format: int64 + type: integer + iat: + format: int64 + type: integer + id: + type: string + required: + - iat + type: object + type: array + name: + description: Name is a name for this role + type: string + policies: + description: Policies Stores a list of casbin formatted strings + that define access policies for the role in the project + items: + type: string + type: array + required: + - name + type: object + type: array + signatureKeys: + description: SignatureKeys contains a list of PGP key IDs that commits + in Git must be signed with in order to be allowed for sync + items: + description: SignatureKey is the specification of a key required + to verify commit signatures with + properties: + keyID: + description: The ID of the key in hexadecimal notation + type: string + required: + - keyID + type: object + type: array + sourceNamespaces: + description: SourceNamespaces defines the namespaces application resources + are allowed to be created in + items: + type: string + type: array + sourceRepos: + description: SourceRepos contains list of repository URLs which can + be used for deployment + items: + type: string + type: array + syncWindows: + description: SyncWindows controls when syncs can be run for apps in + this project + items: + description: SyncWindow contains the kind, time, duration and attributes + that are used to assign the syncWindows to apps + properties: + applications: + description: Applications contains a list of applications that + the window will apply to + items: + type: string + type: array + clusters: + description: Clusters contains a list of clusters that the window + will apply to + items: + type: string + type: array + duration: + description: Duration is the amount of time the sync window + will be open + type: string + kind: + description: Kind defines if the window allows or blocks syncs + type: string + manualSync: + description: ManualSync enables manual syncs when they would + otherwise be blocked + type: boolean + namespaces: + description: Namespaces contains a list of namespaces that the + window will apply to + items: + type: string + type: array + schedule: + description: Schedule is the time the window will begin, specified + in cron format + type: string + timeZone: + description: TimeZone of the sync that will be applied to the + schedule + type: string + type: object + type: array + type: object + status: + description: AppProjectStatus contains status information for AppProject + CRs + properties: + jwtTokensByRole: + additionalProperties: + description: JWTTokens represents a list of JWT tokens + properties: + items: + items: + description: JWTToken holds the issuedAt and expiresAt values + of a token + properties: + exp: + format: int64 + type: integer + iat: + format: int64 + type: integer + id: + type: string + required: + - iat + type: object + type: array + type: object + description: JWTTokensByRole contains a list of JWT tokens issued + for a given role + type: object + type: object + required: + - metadata + - spec + type: object + served: true + storage: true +{{- end }} diff --git a/helm/argo-cd/templates/dex/deployment.yaml b/helm/argo-cd/templates/dex/deployment.yaml new file mode 100755 index 0000000..fd5e00d --- /dev/null +++ b/helm/argo-cd/templates/dex/deployment.yaml @@ -0,0 +1,196 @@ +{{- if .Values.dex.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + {{- with (mergeOverwrite (deepCopy .Values.global.deploymentAnnotations) .Values.dex.deploymentAnnotations) }} + annotations: + {{- range $key, $value := . }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} + name: {{ template "argo-cd.dex.fullname" . }} + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.dex.name "name" .Values.dex.name) | nindent 4 }} +spec: + replicas: 1 + revisionHistoryLimit: {{ .Values.global.revisionHistoryLimit }} + selector: + matchLabels: + {{- include "argo-cd.selectorLabels" (dict "context" . "name" .Values.dex.name) | nindent 6 }} + template: + metadata: + annotations: + checksum/cmd-params: {{ include (print $.Template.BasePath "/argocd-configs/argocd-cmd-params-cm.yaml") . | sha256sum }} + {{- if .Values.dex.certificateSecret.enabled }} + checksum/dex-server-tls: {{ include (print $.Template.BasePath "/argocd-configs/argocd-dex-server-tls-secret.yaml") . | sha256sum }} + {{- end }} + {{- with (mergeOverwrite (deepCopy .Values.global.podAnnotations) .Values.dex.podAnnotations) }} + {{- range $key, $value := . }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.dex.name "name" .Values.dex.name) | nindent 8 }} + {{- with (mergeOverwrite (deepCopy .Values.global.podLabels) .Values.dex.podLabels) }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- with .Values.dex.imagePullSecrets | default .Values.global.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.global.hostAliases }} + hostAliases: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with.Values.global.securityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.dex.priorityClassName | default .Values.global.priorityClassName }} + priorityClassName: {{ . }} + {{- end }} + serviceAccountName: {{ template "argo-cd.dexServiceAccountName" . }} + containers: + - name: {{ .Values.dex.name }} + image: {{ .Values.dex.image.repository }}:{{ .Values.dex.image.tag }} + imagePullPolicy: {{ default .Values.global.image.imagePullPolicy .Values.dex.image.imagePullPolicy }} + command: + - /shared/argocd-dex + args: + - rundex + {{- with .Values.dex.extraArgs }} + {{- toYaml . | nindent 8 }} + {{- end }} + env: + {{- with .Values.dex.env }} + {{- toYaml . | nindent 10 }} + {{- end }} + - name: ARGOCD_DEX_SERVER_DISABLE_TLS + valueFrom: + configMapKeyRef: + name: argocd-cmd-params-cm + key: dexserver.disable.tls + optional: true + {{- with .Values.dex.envFrom }} + envFrom: + {{- toYaml . | nindent 10 }} + {{- end }} + ports: + - name: http + containerPort: {{ .Values.dex.containerPorts.http }} + protocol: TCP + - name: grpc + containerPort: {{ .Values.dex.containerPorts.grpc }} + protocol: TCP + - name: metrics + containerPort: {{ .Values.dex.containerPorts.metrics }} + protocol: TCP + {{- if .Values.dex.livenessProbe.enabled }} + livenessProbe: + httpGet: + path: /healthz/live + port: metrics + initialDelaySeconds: {{ .Values.dex.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.dex.livenessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.dex.livenessProbe.timeoutSeconds }} + successThreshold: {{ .Values.dex.livenessProbe.successThreshold }} + failureThreshold: {{ .Values.dex.livenessProbe.failureThreshold }} + {{- end }} + {{- if .Values.dex.readinessProbe.enabled }} + readinessProbe: + httpGet: + path: /healthz/ready + port: metrics + initialDelaySeconds: {{ .Values.dex.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.dex.readinessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.dex.readinessProbe.timeoutSeconds }} + successThreshold: {{ .Values.dex.readinessProbe.successThreshold }} + failureThreshold: {{ .Values.dex.readinessProbe.failureThreshold }} + {{- end }} + resources: + {{- toYaml .Values.dex.resources | nindent 10 }} + securityContext: + {{- toYaml .Values.dex.containerSecurityContext | nindent 10 }} + volumeMounts: + {{- with .Values.dex.volumeMounts }} + {{- toYaml . | nindent 8 }} + {{- end }} + - name: static-files + mountPath: /shared + - name: dexconfig + mountPath: /tmp + - name: argocd-dex-server-tls + mountPath: /tls + {{- with .Values.dex.extraContainers }} + {{- tpl (toYaml .) $ | nindent 6 }} + {{- end }} + initContainers: + - name: copyutil + image: {{ default .Values.global.image.repository .Values.dex.initImage.repository }}:{{ default (include "argo-cd.defaultTag" .) .Values.dex.initImage.tag }} + imagePullPolicy: {{ default .Values.global.image.imagePullPolicy .Values.dex.initImage.imagePullPolicy }} + command: + - cp + - -n + - /usr/local/bin/argocd + - /shared/argocd-dex + volumeMounts: + - mountPath: /shared + name: static-files + - mountPath: /tmp + name: dexconfig + resources: + {{- toYaml .Values.dex.resources | nindent 10 }} + securityContext: + {{- toYaml .Values.dex.containerSecurityContext | nindent 10 }} + {{- with .Values.dex.initContainers }} + {{- tpl (toYaml .) $ | nindent 6 }} + {{- end }} + {{- with include "argo-cd.affinity" (dict "context" . "component" .Values.dex) }} + affinity: + {{- trim . | nindent 8 }} + {{- end }} + {{- with .Values.dex.nodeSelector | default .Values.global.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.dex.tolerations | default .Values.global.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.dex.topologySpreadConstraints | default .Values.global.topologySpreadConstraints }} + topologySpreadConstraints: + {{- range $constraint := . }} + - {{ toYaml $constraint | nindent 8 | trim }} + {{- if not $constraint.labelSelector }} + labelSelector: + matchLabels: + {{- include "argo-cd.selectorLabels" (dict "context" $ "name" $.Values.dex.name) | nindent 12 }} + {{- end }} + {{- end }} + {{- end }} + volumes: + - name: static-files + emptyDir: {} + - name: dexconfig + emptyDir: {} + - name: argocd-dex-server-tls + secret: + secretName: argocd-dex-server-tls + optional: true + items: + - key: tls.crt + path: tls.crt + - key: tls.key + path: tls.key + - key: ca.crt + path: ca.crt + {{- with .Values.dex.volumes }} + {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.dex.dnsConfig }} + dnsConfig: + {{- toYaml . | nindent 8 }} + {{- end }} + dnsPolicy: {{ .Values.dex.dnsPolicy }} +{{- end }} diff --git a/helm/argo-cd/templates/dex/networkpolicy.yaml b/helm/argo-cd/templates/dex/networkpolicy.yaml new file mode 100644 index 0000000..e79a2e3 --- /dev/null +++ b/helm/argo-cd/templates/dex/networkpolicy.yaml @@ -0,0 +1,31 @@ +{{- if and .Values.global.networkPolicy.create .Values.dex.enabled }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.dex.name "name" .Values.dex.name) | nindent 4 }} + name: {{ template "argo-cd.dex.fullname" . }} +spec: + ingress: + - from: + - podSelector: + matchLabels: + {{- include "argo-cd.selectorLabels" (dict "context" . "name" .Values.server.name) | nindent 10 }} + ports: + - port: http + protocol: TCP + - port: grpc + protocol: TCP + {{- if .Values.dex.metrics.enabled }} + - from: + - namespaceSelector: {} + ports: + - port: metrics + protocol: TCP + {{- end }} + podSelector: + matchLabels: + {{- include "argo-cd.selectorLabels" (dict "context" . "name" .Values.dex.name) | nindent 6 }} + policyTypes: + - Ingress +{{- end }} diff --git a/helm/argo-cd/templates/dex/pdb.yaml b/helm/argo-cd/templates/dex/pdb.yaml new file mode 100644 index 0000000..45bd005 --- /dev/null +++ b/helm/argo-cd/templates/dex/pdb.yaml @@ -0,0 +1,26 @@ +{{- if and .Values.dex.enabled .Values.dex.pdb.enabled }} +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: {{ include "argo-cd.dex.fullname" . }} + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.dex.name "name" .Values.dex.name) | nindent 4 }} + {{- with .Values.dex.pdb.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.dex.pdb.annotations }} + annotations: + {{- range $key, $value := . }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} +spec: + {{- with .Values.dex.pdb.maxUnavailable }} + maxUnavailable: {{ . }} + {{- else }} + minAvailable: {{ .Values.dex.pdb.minAvailable | default 0 }} + {{- end }} + selector: + matchLabels: + {{- include "argo-cd.selectorLabels" (dict "context" . "name" .Values.dex.name) | nindent 6 }} +{{- end }} diff --git a/helm/argo-cd/templates/dex/role.yaml b/helm/argo-cd/templates/dex/role.yaml new file mode 100644 index 0000000..6b9b3f6 --- /dev/null +++ b/helm/argo-cd/templates/dex/role.yaml @@ -0,0 +1,18 @@ +{{- if .Values.dex.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ template "argo-cd.dex.fullname" . }} + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.dex.name "name" .Values.dex.name) | nindent 4 }} +rules: +- apiGroups: + - "" + resources: + - secrets + - configmaps + verbs: + - get + - list + - watch +{{- end }} \ No newline at end of file diff --git a/helm/argo-cd/templates/dex/rolebinding.yaml b/helm/argo-cd/templates/dex/rolebinding.yaml new file mode 100644 index 0000000..4cc4700 --- /dev/null +++ b/helm/argo-cd/templates/dex/rolebinding.yaml @@ -0,0 +1,16 @@ +{{- if .Values.dex.enabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ template "argo-cd.dex.fullname" . }} + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.dex.name "name" .Values.dex.name) | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "argo-cd.dex.fullname" . }} +subjects: +- kind: ServiceAccount + name: {{ template "argo-cd.dexServiceAccountName" . }} + namespace: {{ .Release.Namespace }} +{{- end }} \ No newline at end of file diff --git a/helm/argo-cd/templates/dex/service.yaml b/helm/argo-cd/templates/dex/service.yaml new file mode 100644 index 0000000..9661c7e --- /dev/null +++ b/helm/argo-cd/templates/dex/service.yaml @@ -0,0 +1,35 @@ +{{- if .Values.dex.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "argo-cd.dex.fullname" . }} +{{- if .Values.dex.metrics.service.annotations }} + annotations: + {{- range $key, $value := .Values.dex.metrics.service.annotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} +{{- end }} + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.dex.name "name" .Values.dex.name) | nindent 4 }} +{{- if .Values.dex.metrics.service.labels }} +{{- toYaml .Values.dex.metrics.service.labels | nindent 4 }} +{{- end }} +spec: + ports: + - name: {{ .Values.dex.servicePortHttpName }} + protocol: TCP + port: {{ .Values.dex.servicePortHttp }} + targetPort: http + - name: {{ .Values.dex.servicePortGrpcName }} + protocol: TCP + port: {{ .Values.dex.servicePortGrpc }} + targetPort: grpc +{{- if .Values.dex.metrics.enabled }} + - name: {{ .Values.dex.metrics.service.portName }} + protocol: TCP + port: {{ .Values.dex.servicePortMetrics }} + targetPort: metrics +{{- end }} + selector: + {{- include "argo-cd.selectorLabels" (dict "context" . "name" .Values.dex.name) | nindent 4 }} +{{- end }} diff --git a/helm/argo-cd/templates/dex/serviceaccount.yaml b/helm/argo-cd/templates/dex/serviceaccount.yaml new file mode 100644 index 0000000..71707f0 --- /dev/null +++ b/helm/argo-cd/templates/dex/serviceaccount.yaml @@ -0,0 +1,15 @@ +{{- if and .Values.dex.enabled .Values.dex.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +automountServiceAccountToken: {{ .Values.dex.serviceAccount.automountServiceAccountToken }} +metadata: + name: {{ template "argo-cd.dexServiceAccountName" . }} +{{- if .Values.dex.serviceAccount.annotations }} + annotations: + {{- range $key, $value := .Values.dex.serviceAccount.annotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} +{{- end }} + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.dex.name "name" .Values.dex.name) | nindent 4 }} +{{- end }} diff --git a/helm/argo-cd/templates/dex/servicemonitor.yaml b/helm/argo-cd/templates/dex/servicemonitor.yaml new file mode 100644 index 0000000..d08d018 --- /dev/null +++ b/helm/argo-cd/templates/dex/servicemonitor.yaml @@ -0,0 +1,49 @@ +{{- if and .Values.dex.metrics.enabled .Values.dex.metrics.serviceMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "argo-cd.dex.fullname" . }} + {{- with .Values.dex.metrics.serviceMonitor.namespace }} + namespace: {{ . }} + {{- end }} + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.dex.name "name" .Values.dex.name) | nindent 4 }} + {{- with .Values.dex.metrics.serviceMonitor.selector }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.dex.metrics.serviceMonitor.additionalLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.dex.metrics.serviceMonitor.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + endpoints: + - port: {{ .Values.dex.metrics.service.portName }} + {{- with .Values.dex.metrics.serviceMonitor.interval }} + interval: {{ . }} + {{- end }} + path: /metrics + {{- with .Values.dex.metrics.serviceMonitor.relabelings }} + relabelings: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.dex.metrics.serviceMonitor.metricRelabelings }} + metricRelabelings: + {{- toYaml . |nindent 8 }} + {{- end }} + {{- with .Values.dex.metrics.serviceMonitor.scheme }} + scheme: {{ . }} + {{- end }} + {{- with .Values.dex.metrics.serviceMonitor.tlsConfig }} + tlsConfig: + {{- toYaml . | nindent 8 }} + {{- end }} + namespaceSelector: + matchNames: + - {{ .Release.Namespace }} + selector: + matchLabels: + {{- include "argo-cd.selectorLabels" (dict "context" . "component" .Values.dex.name "name" .Values.dex.name) | nindent 6 }} +{{- end }} diff --git a/helm/argo-cd/templates/extra-manifests.yaml b/helm/argo-cd/templates/extra-manifests.yaml new file mode 100644 index 0000000..a9bb3b6 --- /dev/null +++ b/helm/argo-cd/templates/extra-manifests.yaml @@ -0,0 +1,4 @@ +{{ range .Values.extraObjects }} +--- +{{ tpl (toYaml .) $ }} +{{ end }} diff --git a/helm/argo-cd/templates/networkpolicy-default-deny.yaml b/helm/argo-cd/templates/networkpolicy-default-deny.yaml new file mode 100644 index 0000000..3d47a39 --- /dev/null +++ b/helm/argo-cd/templates/networkpolicy-default-deny.yaml @@ -0,0 +1,12 @@ +{{- if and .Values.global.networkPolicy.create .Values.global.networkPolicy.defaultDenyIngress }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + labels: + {{- include "argo-cd.labels" (dict "context" .) | nindent 4 }} + name: {{ template "argo-cd.fullname" . }}-default-deny +spec: + podSelector: {} + policyTypes: + - Ingress +{{- end }} diff --git a/helm/argo-cd/templates/redis/deployment.yaml b/helm/argo-cd/templates/redis/deployment.yaml new file mode 100755 index 0000000..3376d73 --- /dev/null +++ b/helm/argo-cd/templates/redis/deployment.yaml @@ -0,0 +1,143 @@ +{{- $redisHa := index .Values "redis-ha" -}} +{{- if and .Values.redis.enabled (not $redisHa.enabled) -}} +apiVersion: apps/v1 +kind: Deployment +metadata: + {{- with (mergeOverwrite (deepCopy .Values.global.deploymentAnnotations) .Values.redis.deploymentAnnotations) }} + annotations: + {{- range $key, $value := . }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} + name: {{ include "argo-cd.redis.fullname" . }} + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.redis.name "name" .Values.redis.name) | nindent 4 }} +spec: + replicas: 1 + revisionHistoryLimit: {{ .Values.global.revisionHistoryLimit }} + selector: + matchLabels: + app.kubernetes.io/name: {{ include "argo-cd.name" . }}-{{ .Values.redis.name }} + template: + metadata: + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.redis.name "name" .Values.redis.name) | nindent 8 }} + {{- with (mergeOverwrite (deepCopy .Values.global.podLabels) .Values.redis.podLabels) }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with (mergeOverwrite (deepCopy .Values.global.podAnnotations) .Values.redis.podAnnotations) }} + annotations: + {{- range $key, $value := . }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} + spec: + {{- with .Values.redis.imagePullSecrets | default .Values.global.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.global.hostAliases }} + hostAliases: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.redis.securityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.redis.priorityClassName | default .Values.global.priorityClassName }} + priorityClassName: {{ . }} + {{- end }} + serviceAccountName: {{ include "argo-cd.redisServiceAccountName" . }} + containers: + - name: {{ .Values.redis.name }} + image: {{ .Values.redis.image.repository }}:{{ .Values.redis.image.tag }} + imagePullPolicy: {{ default .Values.global.image.imagePullPolicy .Values.redis.image.imagePullPolicy }} + args: + - --save + - "" + - --appendonly + - "no" + {{- with .Values.redis.extraArgs }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.redis.env }} + env: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.redis.envFrom }} + envFrom: + {{- toYaml . | nindent 8 }} + {{- end }} + ports: + - name: redis + containerPort: {{ .Values.redis.containerPorts.redis }} + protocol: TCP + resources: + {{- toYaml .Values.redis.resources | nindent 10 }} + securityContext: + {{- toYaml .Values.redis.containerSecurityContext | nindent 10 }} + {{- with .Values.redis.volumeMounts }} + volumeMounts: + {{- toYaml . | nindent 10 }} + {{- end }} + {{- if .Values.redis.exporter.enabled }} + - name: metrics + image: {{ .Values.redis.exporter.image.repository }}:{{ .Values.redis.exporter.image.tag }} + imagePullPolicy: {{ default .Values.global.image.imagePullPolicy .Values.redis.exporter.image.imagePullPolicy }} + env: + - name: REDIS_ADDR + value: {{ printf "redis://localhost:%v" .Values.redis.containerPorts.redis }} + - name: REDIS_EXPORTER_WEB_LISTEN_ADDRESS + value: {{ printf "0.0.0.0:%v" .Values.redis.containerPorts.metrics }} + {{- with .Values.redis.exporter.env }} + {{- toYaml . | nindent 8 }} + {{- end }} + ports: + - name: metrics + containerPort: {{ .Values.redis.containerPorts.metrics }} + protocol: TCP + resources: + {{- toYaml .Values.redis.exporter.resources | nindent 10 }} + securityContext: + {{- toYaml .Values.redis.exporter.containerSecurityContext | nindent 10 }} + {{- end }} + {{- with .Values.redis.extraContainers }} + {{- tpl (toYaml .) $ | nindent 6 }} + {{- end }} + {{- with .Values.redis.initContainers }} + initContainers: + {{- tpl (toYaml .) $ | nindent 6 }} + {{- end }} + {{- with .Values.redis.nodeSelector | default .Values.global.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.redis.tolerations | default .Values.global.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with include "argo-cd.affinity" (dict "context" . "component" .Values.redis) }} + affinity: + {{- trim . | nindent 8 }} + {{- end }} + {{- with .Values.redis.topologySpreadConstraints | default .Values.global.topologySpreadConstraints }} + topologySpreadConstraints: + {{- range $constraint := . }} + - {{ toYaml $constraint | nindent 8 | trim }} + {{- if not $constraint.labelSelector }} + labelSelector: + matchLabels: + app.kubernetes.io/name: {{ include "argo-cd.name" $ }}-{{ $.Values.redis.name }} + {{- end }} + {{- end }} + {{- end }} + {{- with .Values.redis.volumes }} + volumes: + {{- toYaml . | nindent 8}} + {{- end }} + {{- with .Values.redis.dnsConfig }} + dnsConfig: + {{- toYaml . | nindent 8 }} + {{- end }} + dnsPolicy: {{ .Values.redis.dnsPolicy }} +{{- end }} diff --git a/helm/argo-cd/templates/redis/metrics.yaml b/helm/argo-cd/templates/redis/metrics.yaml new file mode 100644 index 0000000..6886a74 --- /dev/null +++ b/helm/argo-cd/templates/redis/metrics.yaml @@ -0,0 +1,30 @@ +{{- $redisHa := (index .Values "redis-ha") -}} +{{- if and .Values.redis.enabled (not $redisHa.enabled) .Values.redis.metrics.enabled -}} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "argo-cd.redis.fullname" . }}-metrics + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.redis.name "name" .Values.redis.name) | nindent 4 }} + {{- with .Values.redis.metrics.service.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.redis.metrics.service.annotations }} + annotations: + {{- range $key, $value := . }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} +spec: + type: {{ .Values.redis.metrics.service.type }} + {{- with .Values.redis.metrics.service.clusterIP }} + clusterIP: {{ . }} + {{- end }} + ports: + - name: {{ .Values.redis.metrics.service.portName }} + protocol: TCP + port: {{ .Values.redis.metrics.service.servicePort }} + targetPort: metrics + selector: + {{- include "argo-cd.selectorLabels" (dict "context" . "component" .Values.redis.name "name" .Values.redis.name) | nindent 4 }} +{{- end }} diff --git a/helm/argo-cd/templates/redis/networkpolicy.yaml b/helm/argo-cd/templates/redis/networkpolicy.yaml new file mode 100644 index 0000000..8b564ad --- /dev/null +++ b/helm/argo-cd/templates/redis/networkpolicy.yaml @@ -0,0 +1,36 @@ +{{- $redisHa := (index .Values "redis-ha") -}} +{{- if and .Values.global.networkPolicy.create .Values.redis.enabled (not $redisHa.enabled) }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.redis.name "name" .Values.redis.name) | nindent 4 }} + name: {{ template "argo-cd.redis.fullname" . }} +spec: + ingress: + - from: + - podSelector: + matchLabels: + {{- include "argo-cd.selectorLabels" (dict "context" . "name" .Values.server.name) | nindent 10 }} + - podSelector: + matchLabels: + {{- include "argo-cd.selectorLabels" (dict "context" . "name" .Values.repoServer.name) | nindent 10 }} + - podSelector: + matchLabels: + {{- include "argo-cd.selectorLabels" (dict "context" . "name" .Values.controller.name) | nindent 10 }} + ports: + - port: redis + protocol: TCP + {{- if .Values.redis.metrics.enabled }} + - from: + - namespaceSelector: {} + ports: + - port: metrics + protocol: TCP + {{- end }} + podSelector: + matchLabels: + {{- include "argo-cd.selectorLabels" (dict "context" . "name" .Values.redis.name) | nindent 6 }} + policyTypes: + - Ingress +{{- end }} diff --git a/helm/argo-cd/templates/redis/pdb.yaml b/helm/argo-cd/templates/redis/pdb.yaml new file mode 100644 index 0000000..223c575 --- /dev/null +++ b/helm/argo-cd/templates/redis/pdb.yaml @@ -0,0 +1,27 @@ +{{- $redisHa := index .Values "redis-ha" -}} +{{- if and .Values.redis.enabled (not $redisHa.enabled) .Values.redis.pdb.enabled }} +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: {{ include "argo-cd.redis.fullname" . }} + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.redis.name "name" .Values.redis.name) | nindent 4 }} + {{- with .Values.redis.pdb.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.redis.pdb.annotations }} + annotations: + {{- range $key, $value := . }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} +spec: + {{- with .Values.redis.pdb.maxUnavailable }} + maxUnavailable: {{ . }} + {{- else }} + minAvailable: {{ .Values.redis.pdb.minAvailable | default 0 }} + {{- end }} + selector: + matchLabels: + app.kubernetes.io/name: {{ include "argo-cd.name" . }}-{{ .Values.redis.name }} +{{- end }} diff --git a/helm/argo-cd/templates/redis/service.yaml b/helm/argo-cd/templates/redis/service.yaml new file mode 100644 index 0000000..6e949fd --- /dev/null +++ b/helm/argo-cd/templates/redis/service.yaml @@ -0,0 +1,25 @@ +{{- $redisHa := (index .Values "redis-ha") -}} +{{- if and .Values.redis.enabled (not $redisHa.enabled) -}} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "argo-cd.redis.fullname" . }} + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.redis.name "name" .Values.redis.name) | nindent 4 }} + {{- with .Values.redis.service.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.redis.service.annotations }} + annotations: + {{- range $key, $value := . }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} +spec: + ports: + - name: redis + port: {{ .Values.redis.servicePort }} + targetPort: redis + selector: + {{- include "argo-cd.selectorLabels" (dict "context" . "name" .Values.redis.name) | nindent 4 }} +{{- end }} diff --git a/helm/argo-cd/templates/redis/serviceaccount.yaml b/helm/argo-cd/templates/redis/serviceaccount.yaml new file mode 100644 index 0000000..ae67d3b --- /dev/null +++ b/helm/argo-cd/templates/redis/serviceaccount.yaml @@ -0,0 +1,15 @@ +{{- if and .Values.redis.enabled .Values.redis.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +automountServiceAccountToken: {{ .Values.redis.serviceAccount.automountServiceAccountToken }} +metadata: + name: {{ template "argo-cd.redisServiceAccountName" . }} +{{- if .Values.redis.serviceAccount.annotations }} + annotations: + {{- range $key, $value := .Values.redis.serviceAccount.annotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} +{{- end }} + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.redis.name "name" .Values.redis.name) | nindent 4 }} +{{- end }} diff --git a/helm/argo-cd/templates/redis/servicemonitor.yaml b/helm/argo-cd/templates/redis/servicemonitor.yaml new file mode 100644 index 0000000..ea91346 --- /dev/null +++ b/helm/argo-cd/templates/redis/servicemonitor.yaml @@ -0,0 +1,50 @@ +{{- $redisHa := (index .Values "redis-ha") -}} +{{- if and .Values.redis.enabled (not $redisHa.enabled) .Values.redis.metrics.enabled .Values.redis.metrics.serviceMonitor.enabled -}} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "argo-cd.redis.fullname" . }} + {{- with .Values.redis.metrics.serviceMonitor.namespace }} + namespace: {{ . }} + {{- end }} + labels: + {{- include "argo-cd.labels" (dict "context" . "component" .Values.redis.name "name" .Values.redis.name) | nindent 4 }} + {{- with .Values.redis.metrics.serviceMonitor.selector }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.redis.metrics.serviceMonitor.additionalLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.redis.metrics.serviceMonitor.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + endpoints: + - port: {{ .Values.redis.metrics.service.portName }} + {{- with .Values.redis.metrics.serviceMonitor.interval }} + interval: {{ . }} + {{- end }} + path: /metrics + {{- with .Values.redis.metrics.serviceMonitor.relabelings }} + relabelings: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.redis.metrics.serviceMonitor.metricRelabelings }} + metricRelabelings: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.redis.metrics.serviceMonitor.scheme }} + scheme: {{ . }} + {{- end }} + {{- with .Values.redis.metrics.serviceMonitor.tlsConfig }} + tlsConfig: + {{- toYaml . | nindent 8 }} + {{- end }} + namespaceSelector: + matchNames: + - {{ .Release.Namespace }} + selector: + matchLabels: + {{- include "argo-cd.selectorLabels" (dict "context" . "component" .Values.redis.name "name" .Values.redis.name) | nindent 6 }} +{{- end }} diff --git a/helm/argo-cd/values.yaml b/helm/argo-cd/values.yaml new file mode 100755 index 0000000..c1a693a --- /dev/null +++ b/helm/argo-cd/values.yaml @@ -0,0 +1,3050 @@ +## Argo CD configuration +## Ref: https://github.com/argoproj/argo-cd +## + +# -- Provide a name in place of `argocd` +nameOverride: argocd +# -- String to fully override `"argo-cd.fullname"` +fullnameOverride: "" +# -- Override the Kubernetes version, which is used to evaluate certain manifests +kubeVersionOverride: "" +# Override APIVersions +# If you want to template helm charts but cannot access k8s API server +# you can set api versions here +apiVersionOverrides: + # -- String to override apiVersion of cert-manager resources rendered by this helm chart + certmanager: "" # cert-manager.io/v1 + # -- String to override apiVersion of GKE resources rendered by this helm chart + cloudgoogle: "" # cloud.google.com/v1 + # -- String to override apiVersion of autoscaling rendered by this helm chart + autoscaling: "" # autoscaling/v2 + +# -- Create aggregated roles that extend existing cluster roles to interact with argo-cd resources +## Ref: https://kubernetes.io/docs/reference/access-authn-authz/rbac/#aggregated-clusterroles +createAggregateRoles: false +# -- Create cluster roles for cluster-wide installation. +## Used when you manage applications in the same cluster where Argo CD runs +createClusterRoles: true + +openshift: + # -- enables using arbitrary uid for argo repo server + enabled: false + +## Custom resource configuration +crds: + # -- Install and upgrade CRDs + install: true + # -- Keep CRDs on chart uninstall + keep: true + # -- Annotations to be added to all CRDs + annotations: {} + +## Globally shared configuration +global: + # -- Common labels for the all resources + additionalLabels: {} + # app: argo-cd + + # -- Number of old deployment ReplicaSets to retain. The rest will be garbage collected. + revisionHistoryLimit: 3 + + # Default image used by all components + image: + # -- If defined, a repository applied to all Argo CD deployments + repository: quay.io/argoproj/argocd + # -- Overrides the global Argo CD image tag whose default is the chart appVersion + tag: "" + # -- If defined, a imagePullPolicy applied to all Argo CD deployments + imagePullPolicy: IfNotPresent + + # -- Secrets with credentials to pull images from a private registry + imagePullSecrets: [] + + # Default logging options used by all components + logging: + # -- Set the global logging format. Either: `text` or `json` + format: text + # -- Set the global logging level. One of: `debug`, `info`, `warn` or `error` + level: info + + # -- Annotations for the all deployed Statefulsets + statefulsetAnnotations: {} + + # -- Annotations for the all deployed Deployments + deploymentAnnotations: {} + + # -- Annotations for the all deployed pods + podAnnotations: {} + + # -- Labels for the all deployed pods + podLabels: {} + + # -- Toggle and define pod-level security context. + # @default -- `{}` (See [values.yaml]) + securityContext: {} + # runAsUser: 999 + # runAsGroup: 999 + # fsGroup: 999 + + # -- Mapping between IP and hostnames that will be injected as entries in the pod's hosts files + hostAliases: [] + # - ip: 10.20.30.40 + # hostnames: + # - git.myhostname + + # Default network policy rules used by all components + networkPolicy: + # -- Create NetworkPolicy objects for all components + create: false + # -- Default deny all ingress traffic + defaultDenyIngress: false + + # -- Default priority class for all components + priorityClassName: "" + + # -- Default node selector for all components + nodeSelector: {} + + # -- Default tolerations for all components + tolerations: {} + + # Default affinity preset for all components + affinity: + # -- Default pod anti-affinity rules. Either: `none`, `soft` or `hard` + podAntiAffinity: soft + # Node affinity rules + nodeAffinity: + # -- Default node affinity rules. Either: `none`, `soft` or `hard` + type: hard + # -- Default match expressions for node affinity + matchExpressions: [] + # - key: topology.kubernetes.io/zone + # operator: In + # values: + # - antarctica-east1 + # - antarctica-west1 + + # -- Default [TopologySpreadConstraints] rules for all components + ## Ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ + ## If labelSelector is left out, it will default to the labelSelector of the component + topologySpreadConstraints: [] + # - maxSkew: 1 + # topologyKey: topology.kubernetes.io/zone + # whenUnsatisfiable: DoNotSchedule + + +## Argo Configs +configs: + # General Argo CD configuration + ## Ref: https://github.com/argoproj/argo-cd/blob/master/docs/operator-manual/argocd-cm.yaml + cm: + # -- Create the argocd-cm configmap for [declarative setup] + create: true + + # -- Annotations to be added to argocd-cm configmap + annotations: {} + + # -- Argo CD's externally facing base URL (optional). Required when configuring SSO + url: "" + + # -- The name of tracking label used by Argo CD for resource pruning + # @default -- Defaults to app.kubernetes.io/instance + application.instanceLabelKey: argocd.argoproj.io/instance + + # -- Enable logs RBAC enforcement + ## Ref: https://argo-cd.readthedocs.io/en/latest/operator-manual/upgrading/2.3-2.4/#enable-logs-rbac-enforcement + server.rbac.log.enforce.enable: false + + # -- Enable exec feature in Argo UI + ## Ref: https://argo-cd.readthedocs.io/en/latest/operator-manual/rbac/#exec-resource + exec.enabled: false + + # -- Enable local admin user + ## Ref: https://argo-cd.readthedocs.io/en/latest/faq/#how-to-disable-admin-user + admin.enabled: true + + # -- Timeout to discover if a new manifests version got published to the repository + timeout.reconciliation: 180s + + # -- Timeout to refresh application data as well as target manifests cache + timeout.hard.reconciliation: 0s + + # Dex configuration + # dex.config: | + # connectors: + # # GitHub example + # - type: github + # id: github + # name: GitHub + # config: + # clientID: aabbccddeeff00112233 + # clientSecret: $dex.github.clientSecret # Alternatively $:dex.github.clientSecret + # orgs: + # - name: your-github-org + + # OIDC configuration as an alternative to dex (optional). + # oidc.config: | + # name: AzureAD + # issuer: https://login.microsoftonline.com/TENANT_ID/v2.0 + # clientID: CLIENT_ID + # clientSecret: $oidc.azuread.clientSecret + # rootCA: | + # -----BEGIN CERTIFICATE----- + # ... encoded certificate data here ... + # -----END CERTIFICATE----- + # requestedIDTokenClaims: + # groups: + # essential: true + # requestedScopes: + # - openid + # - profile + # - email + + # Argo CD configuration parameters + ## Ref: https://github.com/argoproj/argo-cd/blob/master/docs/operator-manual/argocd-cmd-params-cm.yaml + params: + # -- Annotations to be added to the argocd-cmd-params-cm ConfigMap + annotations: {} + + ## Generic parameters + # -- Open-Telemetry collector address: (e.g. "otel-collector:4317") + otlp.address: '' + + ## Controller Properties + # -- Number of application status processors + controller.status.processors: 20 + # -- Number of application operation processors + controller.operation.processors: 10 + # -- Specifies timeout between application self heal attempts + controller.self.heal.timeout.seconds: 5 + # -- Repo server RPC call timeout seconds. + controller.repo.server.timeout.seconds: 60 + + ## Server properties + # -- Run server without TLS + server.insecure: false + # -- Value for base href in index.html. Used if Argo CD is running behind reverse proxy under subpath different from / + server.basehref: / + # -- Used if Argo CD is running behind reverse proxy under subpath different from / + server.rootpath: '' + # -- Directory path that contains additional static assets + server.staticassets: /shared/app + # -- Disable Argo CD RBAC for user authentication + server.disable.auth: false + # -- Enable GZIP compression + server.enable.gzip: false + # -- Set X-Frame-Options header in HTTP responses to value. To disable, set to "". + server.x.frame.options: sameorigin + + ## Repo-server properties + # -- Limit on number of concurrent manifests generate requests. Any value less the 1 means no limit. + reposerver.parallelism.limit: 0 + + ## ApplicationSet Properties + # -- Modify how application is synced between the generator and the cluster. One of: `sync`, `create-only`, `create-update`, `create-delete` + applicationsetcontroller.policy: sync + # -- Enables use of the Progressive Syncs capability + applicationsetcontroller.enable.progressive.syncs: false + + # Argo CD RBAC policy configuration + ## Ref: https://github.com/argoproj/argo-cd/blob/master/docs/operator-manual/rbac.md + rbac: + # -- Create the argocd-rbac-cm configmap with ([Argo CD RBAC policy]) definitions. + # If false, it is expected the configmap will be created by something else. + # Argo CD will not work if there is no configmap created with the name above. + create: true + + # -- Annotations to be added to argocd-rbac-cm configmap + annotations: {} + + # -- The name of the default role which Argo CD will falls back to, when authorizing API requests (optional). + # If omitted or empty, users may be still be able to login, but will see no apps, projects, etc... + policy.default: '' + + # -- File containing user-defined policies and role definitions. + # @default -- `''` (See [values.yaml]) + policy.csv: '' + # Policy rules are in the form: + # p, subject, resource, action, object, effect + # Role definitions and bindings are in the form: + # g, subject, inherited-subject + # policy.csv | + # p, role:org-admin, applications, *, */*, allow + # p, role:org-admin, clusters, get, *, allow + # p, role:org-admin, repositories, *, *, allow + # p, role:org-admin, logs, get, *, allow + # p, role:org-admin, exec, create, */*, allow + # g, your-github-org:your-team, role:org-admin + + # -- OIDC scopes to examine during rbac enforcement (in addition to `sub` scope). + # The scope value can be a string, or a list of strings. + scopes: "[groups]" + + # GnuPG public keys for commit verification + ## Ref: https://argo-cd.readthedocs.io/en/stable/user-guide/gpg-verification/ + gpg: + # -- Annotations to be added to argocd-gpg-keys-cm configmap + annotations: {} + + # -- [GnuPG] public keys to add to the keyring + # @default -- `{}` (See [values.yaml]) + ## Note: Public keys should be exported with `gpg --export --armor ` + keys: {} + # 4AEE18F83AFDEB23: | + # -----BEGIN PGP PUBLIC KEY BLOCK----- + # ... + # -----END PGP PUBLIC KEY BLOCK----- + + # SSH known hosts for Git repositories + ## Ref: https://argo-cd.readthedocs.io/en/stable/operator-manual/declarative-setup/#ssh-known-host-public-keys + ssh: + # -- Annotations to be added to argocd-ssh-known-hosts-cm configmap + annotations: {} + + # -- Known hosts to be added to the known host list by default. + # @default -- See [values.yaml] + knownHosts: | + bitbucket.org ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAubiN81eDcafrgMeLzaFPsw2kNvEcqTKl/VqLat/MaB33pZy0y3rJZtnqwR2qOOvbwKZYKiEO1O6VqNEBxKvJJelCq0dTXWT5pbO2gDXC6h6QDXCaHo6pOHGPUy+YBaGQRGuSusMEASYiWunYN0vCAI8QaXnWMXNMdFP3jHAJH0eDsoiGnLPBlBp4TNm6rYI74nMzgz3B9IikW4WVK+dc8KZJZWYjAuORU3jc1c/NPskD2ASinf8v3xnfXeukU0sJ5N6m5E8VLjObPEO+mN2t/FZTMZLiFqPWc/ALSqnMnnhwrNi2rbfg/rd/IpL8Le3pSBne8+seeFVBoGqzHM9yXw== + github.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEmKSENjQEezOmxkZMy7opKgwFB9nkt5YRrYMjNuG5N87uRgg6CLrbo5wAdT/y6v0mKV0U2w0WZ2YB/++Tpockg= + github.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOMqqnkVzrm0SdG6UOoqKLsabgH5C9okWi0dh2l9GKJl + github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ== + gitlab.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFSMqzJeV9rUzU4kWitGjeR4PWSa29SPqJ1fVkhtj3Hw9xjLVXVYrU9QlYWrOLXBpQ6KWjbjTDTdDkoohFzgbEY= + gitlab.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAfuCHKVTjquxvt6CM6tdG4SLp1Btn/nOeHHE5UOzRdf + gitlab.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCsj2bNKTBSpIYDEGk9KxsGh3mySTRgMtXL583qmBpzeQ+jqCMRgBqB98u3z++J1sKlXHWfM9dyhSevkMwSbhoR8XIq/U0tCNyokEi/ueaBMCvbcTHhO7FcwzY92WK4Yt0aGROY5qX2UKSeOvuP4D6TPqKF1onrSzH9bx9XUf2lEdWT/ia1NEKjunUqu1xOB/StKDHMoX4/OKyIzuS0q/T1zOATthvasJFoPrAjkohTyaDUz2LN5JoH839hViyEG82yB+MjcFV5MU3N1l1QL3cVUCh93xSaua1N85qivl+siMkPGbO5xR/En4iEY6K2XPASUEMaieWVNTRCtJ4S8H+9 + ssh.dev.azure.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7Hr1oTWqNqOlzGJOfGJ4NakVyIzf1rXYd4d7wo6jBlkLvCA4odBlL0mDUyZ0/QUfTTqeu+tm22gOsv+VrVTMk6vwRU75gY/y9ut5Mb3bR5BV58dKXyq9A9UeB5Cakehn5Zgm6x1mKoVyf+FFn26iYqXJRgzIZZcZ5V6hrE0Qg39kZm4az48o0AUbf6Sp4SLdvnuMa2sVNwHBboS7EJkm57XQPVU3/QpyNLHbWDdzwtrlS+ez30S3AdYhLKEOxAG8weOnyrtLJAUen9mTkol8oII1edf7mWWbWVf0nBmly21+nZcmCTISQBtdcyPaEno7fFQMDD26/s0lfKob4Kw8H + vs-ssh.visualstudio.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7Hr1oTWqNqOlzGJOfGJ4NakVyIzf1rXYd4d7wo6jBlkLvCA4odBlL0mDUyZ0/QUfTTqeu+tm22gOsv+VrVTMk6vwRU75gY/y9ut5Mb3bR5BV58dKXyq9A9UeB5Cakehn5Zgm6x1mKoVyf+FFn26iYqXJRgzIZZcZ5V6hrE0Qg39kZm4az48o0AUbf6Sp4SLdvnuMa2sVNwHBboS7EJkm57XQPVU3/QpyNLHbWDdzwtrlS+ez30S3AdYhLKEOxAG8weOnyrtLJAUen9mTkol8oII1edf7mWWbWVf0nBmly21+nZcmCTISQBtdcyPaEno7fFQMDD26/s0lfKob4Kw8H + + # -- Additional known hosts for private repositories + extraHosts: '' + + # Repository TLS certificates + # Ref: https://argo-cd.readthedocs.io/en/stable/operator-manual/declarative-setup/#repositories-using-self-signed-tls-certificates-or-are-signed-by-custom-ca + tls: + # -- Annotations to be added to argocd-tls-certs-cm configmap + annotations: {} + + # -- TLS certificates for Git repositories + # @default -- `{}` (See [values.yaml]) + certificates: {} + # server.example.com: | + # -----BEGIN CERTIFICATE----- + # ... + # -----END CERTIFICATE----- + + # ConfigMap for Config Management Plugins + # Ref: https://argo-cd.readthedocs.io/en/stable/operator-manual/config-management-plugins/ + cmp: + # -- Create the argocd-cmp-cm configmap + create: false + + # -- Annotations to be added to argocd-cmp-cm configmap + annotations: {} + + # -- Plugin yaml files to be added to argocd-cmp-cm + plugins: {} + # --- First plugin + # my-plugin: + # init: + # command: [sh] + # args: [-c, 'echo "Initializing..."'] + # generate: + # command: [sh, -c] + # args: + # - | + # echo "{\"kind\": \"ConfigMap\", \"apiVersion\": \"v1\", \"metadata\": { \"name\": \"$ARGOCD_APP_NAME\", \"namespace\": \"$ARGOCD_APP_NAMESPACE\", \"annotations\": {\"Foo\": \"$ARGOCD_ENV_FOO\", \"KubeVersion\": \"$KUBE_VERSION\", \"KubeApiVersion\": \"$KUBE_API_VERSIONS\",\"Bar\": \"baz\"}}}" + # discover: + # fileName: "./subdir/s*.yaml" + # find: + # glob: "**/Chart.yaml" + # command: [sh, -c, find . -name env.yaml] + + # --- Second plugin + # my-plugin2: + # init: + # command: [sh] + # args: [-c, 'echo "Initializing..."'] + # generate: + # command: [sh, -c] + # args: + # - | + # echo "{\"kind\": \"ConfigMap\", \"apiVersion\": \"v1\", \"metadata\": { \"name\": \"$ARGOCD_APP_NAME\", \"namespace\": \"$ARGOCD_APP_NAMESPACE\", \"annotations\": {\"Foo\": \"$ARGOCD_ENV_FOO\", \"KubeVersion\": \"$KUBE_VERSION\", \"KubeApiVersion\": \"$KUBE_API_VERSIONS\",\"Bar\": \"baz\"}}}" + # discover: + # fileName: "./subdir/s*.yaml" + # find: + # glob: "**/Chart.yaml" + # command: [sh, -c, find . -name env.yaml] + + # -- Provide one or multiple [external cluster credentials] + # @default -- `[]` (See [values.yaml]) + ## Ref: + ## - https://argo-cd.readthedocs.io/en/stable/operator-manual/declarative-setup/#clusters + ## - https://argo-cd.readthedocs.io/en/stable/operator-manual/security/#external-cluster-credentials + clusterCredentials: [] + # - name: mycluster + # server: https://mycluster.com + # labels: {} + # annotations: {} + # config: + # bearerToken: "" + # tlsClientConfig: + # insecure: false + # caData: "" + # - name: mycluster2 + # server: https://mycluster2.com + # labels: {} + # annotations: {} + # namespaces: namespace1,namespace2 + # clusterResources: true + # config: + # bearerToken: "" + # tlsClientConfig: + # insecure: false + # caData: "" + + # DEPRECATED - Moved to configs.ssh.annotations + # knownHostsAnnotations: {} + # DEPRECATED - Moved to configs.ssh.knownHosts + # knownHosts: {} + + # DEPRECATED - Moved to configs.tls.annotations + # tlsCertsAnnotations: {} + # DEPRECATED - Moved to configs.tls.certificates + # tlsCerts: {} + + # -- Repository credentials to be used as Templates for other repos + ## Creates a secret for each key/value specified below to create repository credentials + credentialTemplates: {} + # github-enterprise-creds-1: + # url: https://github.com/argoproj + # githubAppID: 1 + # githubAppInstallationID: 2 + # githubAppEnterpriseBaseUrl: https://ghe.example.com/api/v3 + # githubAppPrivateKey: | + # -----BEGIN OPENSSH PRIVATE KEY----- + # ... + # -----END OPENSSH PRIVATE KEY----- + # https-creds: + # url: https://github.com/argoproj + # password: my-password + # username: my-username + # ssh-creds: + # url: git@github.com:argoproj-labs + # sshPrivateKey: | + # -----BEGIN OPENSSH PRIVATE KEY----- + # ... + # -----END OPENSSH PRIVATE KEY----- + + # -- Annotations to be added to `configs.credentialTemplates` Secret + credentialTemplatesAnnotations: {} + + # -- Repositories list to be used by applications + ## Creates a secret for each key/value specified below to create repositories + ## Note: the last example in the list would use a repository credential template, configured under "configs.repositoryCredentials". + repositories: {} + # istio-helm-repo: + # url: https://storage.googleapis.com/istio-prerelease/daily-build/master-latest-daily/charts + # name: istio.io + # type: helm + # private-helm-repo: + # url: https://my-private-chart-repo.internal + # name: private-repo + # type: helm + # password: my-password + # username: my-username + # private-repo: + # url: https://github.com/argoproj/private-repo + + # -- Annotations to be added to `configs.repositories` Secret + repositoriesAnnotations: {} + + # Argo CD sensitive data + # Ref: https://argo-cd.readthedocs.io/en/stable/operator-manual/user-management/#sensitive-data-and-sso-client-secrets + secret: + # -- Create the argocd-secret + createSecret: true + # -- Labels to be added to argocd-secret + labels: {} + # -- Annotations to be added to argocd-secret + annotations: {} + + # -- Shared secret for authenticating GitHub webhook events + githubSecret: "" + # -- Shared secret for authenticating GitLab webhook events + gitlabSecret: "" + # -- Shared secret for authenticating BitbucketServer webhook events + bitbucketServerSecret: "" + # -- UUID for authenticating Bitbucket webhook events + bitbucketUUID: "" + # -- Shared secret for authenticating Gogs webhook events + gogsSecret: "" + + # -- add additional secrets to be added to argocd-secret + ## Custom secrets. Useful for injecting SSO secrets into environment variables. + ## Ref: https://argo-cd.readthedocs.io/en/stable/operator-manual/user-management/#sensitive-data-and-sso-client-secrets + ## Note that all values must be non-empty. + extra: + {} + # LDAP_PASSWORD: "mypassword" + + # -- Argo TLS Data + # DEPRECATED - Use server.certificate or server.certificateSecret + # argocdServerTlsConfig: + # key: '' + # crt: '' + + # -- Bcrypt hashed admin password + ## Argo expects the password in the secret to be bcrypt hashed. You can create this hash with + ## `htpasswd -nbBC 10 "" $ARGO_PWD | tr -d ':\n' | sed 's/$2y/$2a/'` + argocdServerAdminPassword: "" + # -- Admin password modification time. Eg. `"2006-01-02T15:04:05Z"` + # @default -- `""` (defaults to current time) + argocdServerAdminPasswordMtime: "" + + # -- Define custom [CSS styles] for your argo instance. + # This setting will automatically mount the provided CSS and reference it in the argo configuration. + # @default -- `""` (See [values.yaml]) + ## Ref: https://argo-cd.readthedocs.io/en/stable/operator-manual/custom-styles/ + styles: "" + # styles: | + # .nav-bar { + # background: linear-gradient(to bottom, #999, #777, #333, #222, #111); + # } + +# -- Array of extra K8s manifests to deploy +## Note: Supports use of custom Helm templates +extraObjects: [] + # - apiVersion: secrets-store.csi.x-k8s.io/v1 + # kind: SecretProviderClass + # metadata: + # name: argocd-secrets-store + # spec: + # provider: aws + # parameters: + # objects: | + # - objectName: "argocd" + # objectType: "secretsmanager" + # jmesPath: + # - path: "client_id" + # objectAlias: "client_id" + # - path: "client_secret" + # objectAlias: "client_secret" + # secretObjects: + # - data: + # - key: client_id + # objectName: client_id + # - key: client_secret + # objectName: client_secret + # secretName: argocd-secrets-store + # type: Opaque + # labels: + # app.kubernetes.io/part-of: argocd + +## Application controller +controller: + # -- Application controller name string + name: application-controller + + # -- The number of application controller pods to run. + # Additional replicas will cause sharding of managed clusters across number of replicas. + replicas: 1 + + ## Application controller Pod Disruption Budget + ## Ref: https://kubernetes.io/docs/tasks/run-application/configure-pdb/ + pdb: + # -- Deploy a [PodDisruptionBudget] for the application controller + enabled: false + # -- Labels to be added to application controller pdb + labels: {} + # -- Annotations to be added to application controller pdb + annotations: {} + # -- Number of pods that are available after eviction as number or percentage (eg.: 50%) + # @default -- `""` (defaults to 0 if not specified) + minAvailable: "" + # -- Number of pods that are unavailable after eviction as number or percentage (eg.: 50%). + ## Has higher precedence over `controller.pdb.minAvailable` + maxUnavailable: "" + + ## Application controller image + image: + # -- Repository to use for the application controller + # @default -- `""` (defaults to global.image.repository) + repository: "" + # -- Tag to use for the application controller + # @default -- `""` (defaults to global.image.tag) + tag: "" + # -- Image pull policy for the application controller + # @default -- `""` (defaults to global.image.imagePullPolicy) + imagePullPolicy: "" + + # -- Secrets with credentials to pull images from a private registry + # @default -- `[]` (defaults to global.imagePullSecrets) + imagePullSecrets: [] + + # -- DEPRECATED - Application controller commandline flags + args: {} + # DEPRECATED - Use configs.params to override + # # -- define the application controller `--status-processors` + # statusProcessors: "20" + # # -- define the application controller `--operation-processors` + # operationProcessors: "10" + # # -- define the application controller `--app-hard-resync` + # appHardResyncPeriod: "0" + # # -- define the application controller `--app-resync` + # appResyncPeriod: "180" + # # -- define the application controller `--self-heal-timeout-seconds` + # selfHealTimeout: "5" + # # -- define the application controller `--repo-server-timeout-seconds` + # repoServerTimeoutSeconds: "60" + + # -- Additional command line arguments to pass to application controller + extraArgs: [] + + # -- Environment variables to pass to application controller + env: [] + + # -- envFrom to pass to application controller + # @default -- `[]` (See [values.yaml]) + envFrom: [] + # - configMapRef: + # name: config-map-name + # - secretRef: + # name: secret-name + + # -- Additional containers to be added to the application controller pod + ## Note: Supports use of custom Helm templates + extraContainers: [] + + # -- Init containers to add to the application controller pod + ## If your target Kubernetes cluster(s) require a custom credential (exec) plugin + ## you could use this (and the same in the server pod) to provide such executable + ## Ref: https://kubernetes.io/docs/reference/access-authn-authz/authentication/#client-go-credential-plugins + ## Note: Supports use of custom Helm templates + initContainers: [] + # - name: download-tools + # image: alpine:3 + # command: [sh, -c] + # args: + # - wget -qO kubelogin.zip https://github.com/Azure/kubelogin/releases/download/v0.0.25/kubelogin-linux-amd64.zip && + # unzip kubelogin.zip && mv bin/linux_amd64/kubelogin /custom-tools/ + # volumeMounts: + # - mountPath: /custom-tools + # name: custom-tools + + # -- Additional volumeMounts to the application controller main container + volumeMounts: [] + # - mountPath: /usr/local/bin/kubelogin + # name: custom-tools + # subPath: kubelogin + + # -- Additional volumes to the application controller pod + volumes: [] + # - name: custom-tools + # emptyDir: {} + + # -- Annotations for the application controller StatefulSet + statefulsetAnnotations: {} + + # -- Annotations to be added to application controller pods + podAnnotations: {} + + # -- Labels to be added to application controller pods + podLabels: {} + + # -- Resource limits and requests for the application controller pods + resources: {} + # limits: + # cpu: 500m + # memory: 512Mi + # requests: + # cpu: 250m + # memory: 256Mi + + # Application controller container ports + containerPorts: + # -- Metrics container port + metrics: 8082 + + # -- Host Network for application controller pods + hostNetwork: false + + # -- [DNS configuration] + dnsConfig: {} + # -- Alternative DNS policy for application controller pods + dnsPolicy: "ClusterFirst" + + # -- Application controller container-level security context + # @default -- See [values.yaml] + containerSecurityContext: + runAsNonRoot: true + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + seccompProfile: + type: RuntimeDefault + capabilities: + drop: + - ALL + + # Readiness probe for application controller + ## Ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/ + readinessProbe: + # -- Minimum consecutive failures for the [probe] to be considered failed after having succeeded + failureThreshold: 3 + # -- Number of seconds after the container has started before [probe] is initiated + initialDelaySeconds: 10 + # -- How often (in seconds) to perform the [probe] + periodSeconds: 10 + # -- Minimum consecutive successes for the [probe] to be considered successful after having failed + successThreshold: 1 + # -- Number of seconds after which the [probe] times out + timeoutSeconds: 1 + + # -- Priority class for the application controller pods + # @default -- `""` (defaults to global.priorityClassName) + priorityClassName: "" + + # -- [Node selector] + # @default -- `{}` (defaults to global.nodeSelector) + nodeSelector: {} + + # -- [Tolerations] for use with node taints + # @default -- `[]` (defaults to global.tolerations) + tolerations: [] + + # -- Assign custom [affinity] rules to the deployment + # @default -- `{}` (defaults to global.affinity preset) + affinity: {} + + # -- Assign custom [TopologySpreadConstraints] rules to the application controller + # @default -- `[]` (defaults to global.topologySpreadConstraints) + ## Ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ + ## If labelSelector is left out, it will default to the labelSelector configuration of the deployment + topologySpreadConstraints: [] + # - maxSkew: 1 + # topologyKey: topology.kubernetes.io/zone + # whenUnsatisfiable: DoNotSchedule + + serviceAccount: + # -- Create a service account for the application controller + create: true + # -- Service account name + name: argocd-application-controller + # -- Annotations applied to created service account + annotations: {} + # -- Labels applied to created service account + labels: {} + # -- Automount API credentials for the Service Account + automountServiceAccountToken: true + + ## Application controller metrics configuration + metrics: + # -- Deploy metrics service + enabled: false + applicationLabels: + # -- Enables additional labels in argocd_app_labels metric + enabled: false + # -- Additional labels + labels: [] + service: + # -- Metrics service annotations + annotations: {} + # -- Metrics service labels + labels: {} + # -- Metrics service port + servicePort: 8082 + # -- Metrics service port name + portName: http-metrics + serviceMonitor: + # -- Enable a prometheus ServiceMonitor + enabled: false + # -- Prometheus ServiceMonitor interval + interval: 30s + # -- Prometheus [RelabelConfigs] to apply to samples before scraping + relabelings: [] + # -- Prometheus [MetricRelabelConfigs] to apply to samples before ingestion + metricRelabelings: [] + # -- Prometheus ServiceMonitor selector + selector: {} + # prometheus: kube-prometheus + + # -- Prometheus ServiceMonitor scheme + scheme: "" + # -- Prometheus ServiceMonitor tlsConfig + tlsConfig: {} + # -- Prometheus ServiceMonitor namespace + namespace: "" # "monitoring" + # -- Prometheus ServiceMonitor labels + additionalLabels: {} + # -- Prometheus ServiceMonitor annotations + annotations: {} + rules: + # -- Deploy a PrometheusRule for the application controller + enabled: false + # -- PrometheusRule namespace + namespace: "" # "monitoring" + # -- PrometheusRule selector + selector: {} + # prometheus: kube-prometheus + + # -- PrometheusRule labels + additionalLabels: {} + # -- PrometheusRule annotations + annotations: {} + + # -- PrometheusRule.Spec for the application controller + spec: [] + # - alert: ArgoAppMissing + # expr: | + # absent(argocd_app_info) == 1 + # for: 15m + # labels: + # severity: critical + # annotations: + # summary: "[Argo CD] No reported applications" + # description: > + # Argo CD has not reported any applications data for the past 15 minutes which + # means that it must be down or not functioning properly. This needs to be + # resolved for this cloud to continue to maintain state. + # - alert: ArgoAppNotSynced + # expr: | + # argocd_app_info{sync_status!="Synced"} == 1 + # for: 12h + # labels: + # severity: warning + # annotations: + # summary: "[{{`{{$labels.name}}`}}] Application not synchronized" + # description: > + # The application [{{`{{$labels.name}}`}} has not been synchronized for over + # 12 hours which means that the state of this cloud has drifted away from the + # state inside Git. + + ## Enable this and set the rules: to whatever custom rules you want for the Cluster Role resource. + ## Defaults to off + clusterRoleRules: + # -- Enable custom rules for the application controller's ClusterRole resource + enabled: false + # -- List of custom rules for the application controller's ClusterRole resource + rules: [] + +## Dex +dex: + # -- Enable dex + enabled: true + # -- Dex name + name: dex-server + + # -- Additional command line arguments to pass to the Dex server + extraArgs: [] + + metrics: + # -- Deploy metrics service + enabled: false + service: + # -- Metrics service annotations + annotations: {} + # -- Metrics service labels + labels: {} + # -- Metrics service port name + portName: http-metrics + serviceMonitor: + # -- Enable a prometheus ServiceMonitor + enabled: false + # -- Prometheus ServiceMonitor interval + interval: 30s + # -- Prometheus [RelabelConfigs] to apply to samples before scraping + relabelings: [] + # -- Prometheus [MetricRelabelConfigs] to apply to samples before ingestion + metricRelabelings: [] + # -- Prometheus ServiceMonitor selector + selector: {} + # prometheus: kube-prometheus + + # -- Prometheus ServiceMonitor scheme + scheme: "" + # -- Prometheus ServiceMonitor tlsConfig + tlsConfig: {} + # -- Prometheus ServiceMonitor namespace + namespace: "" # "monitoring" + # -- Prometheus ServiceMonitor labels + additionalLabels: {} + # -- Prometheus ServiceMonitor annotations + annotations: {} + + ## Dex Pod Disruption Budget + ## Ref: https://kubernetes.io/docs/tasks/run-application/configure-pdb/ + pdb: + # -- Deploy a [PodDisruptionBudget] for the Dex server + enabled: false + # -- Labels to be added to Dex server pdb + labels: {} + # -- Annotations to be added to Dex server pdb + annotations: {} + # -- Number of pods that are available after eviction as number or percentage (eg.: 50%) + # @default -- `""` (defaults to 0 if not specified) + minAvailable: "" + # -- Number of pods that are unavailble after eviction as number or percentage (eg.: 50%). + ## Has higher precedence over `dex.pdb.minAvailable` + maxUnavailable: "" + + ## Dex image + image: + # -- Dex image repository + repository: ghcr.io/dexidp/dex + # -- Dex image tag + tag: v2.35.3 + # -- Dex imagePullPolicy + # @default -- `""` (defaults to global.image.imagePullPolicy) + imagePullPolicy: "" + + # -- Secrets with credentials to pull images from a private registry + # @default -- `[]` (defaults to global.imagePullSecrets) + imagePullSecrets: [] + + # Argo CD init image that creates Dex config + initImage: + # -- Argo CD init image repository + # @default -- `""` (defaults to global.image.repository) + repository: "" + # -- Argo CD init image tag + # @default -- `""` (defaults to global.image.tag) + tag: "" + # -- Argo CD init image imagePullPolicy + # @default -- `""` (defaults to global.image.imagePullPolicy) + imagePullPolicy: "" + + # -- Environment variables to pass to the Dex server + env: [] + + # -- envFrom to pass to the Dex server + # @default -- `[]` (See [values.yaml]) + envFrom: [] + # - configMapRef: + # name: config-map-name + # - secretRef: + # name: secret-name + + # -- Additional containers to be added to the dex pod + ## Note: Supports use of custom Helm templates + extraContainers: [] + + # -- Init containers to add to the dex pod + ## Note: Supports use of custom Helm templates + initContainers: [] + + # -- Additional volumeMounts to the dex main container + volumeMounts: [] + + # -- Additional volumes to the dex pod + volumes: [] + + # TLS certificate configuration via Secret + ## Ref: https://argo-cd.readthedocs.io/en/stable/operator-manual/tls/#configuring-tls-to-argocd-dex-server + ## Note: Issuing certificates via cert-manager in not supported right now because it's not possible to restart Dex automatically without extra controllers. + certificateSecret: + # -- Create argocd-dex-server-tls secret + enabled: false + # -- Labels to be added to argocd-dex-server-tls secret + labels: {} + # -- Annotations to be added to argocd-dex-server-tls secret + annotations: {} + # -- Certificate authority. Required for self-signed certificates. + ca: '' + # -- Certificate private key + key: '' + # -- Certificate data. Must contain SANs of Dex service (ie: argocd-dex-server, argocd-dex-server.argo-cd.svc) + crt: '' + + # -- Annotations to be added to the Dex server Deployment + deploymentAnnotations: {} + + # -- Annotations to be added to the Dex server pods + podAnnotations: {} + + # -- Labels to be added to the Dex server pods + podLabels: {} + + # -- Resource limits and requests for dex + resources: {} + # limits: + # cpu: 50m + # memory: 64Mi + # requests: + # cpu: 10m + # memory: 32Mi + + # Dex container ports + # NOTE: These ports are currently hardcoded and cannot be changed + containerPorts: + # -- HTTP container port + http: 5556 + # -- gRPC container port + grpc: 5557 + # -- Metrics container port + metrics: 5558 + + # -- [DNS configuration] + dnsConfig: {} + # -- Alternative DNS policy for Dex server pods + dnsPolicy: "ClusterFirst" + + # -- Dex container-level security context + # @default -- See [values.yaml] + containerSecurityContext: + runAsNonRoot: true + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + seccompProfile: + type: RuntimeDefault + capabilities: + drop: + - ALL + + ## Probes for Dex server + ## Supported from Dex >= 2.28.0 + livenessProbe: + # -- Enable Kubernetes liveness probe for Dex >= 2.28.0 + enabled: false + # -- Minimum consecutive failures for the [probe] to be considered failed after having succeeded + failureThreshold: 3 + # -- Number of seconds after the container has started before [probe] is initiated + initialDelaySeconds: 10 + # -- How often (in seconds) to perform the [probe] + periodSeconds: 10 + # -- Minimum consecutive successes for the [probe] to be considered successful after having failed + successThreshold: 1 + # -- Number of seconds after which the [probe] times out + timeoutSeconds: 1 + + readinessProbe: + # -- Enable Kubernetes readiness probe for Dex >= 2.28.0 + enabled: false + # -- Minimum consecutive failures for the [probe] to be considered failed after having succeeded + failureThreshold: 3 + # -- Number of seconds after the container has started before [probe] is initiated + initialDelaySeconds: 10 + # -- How often (in seconds) to perform the [probe] + periodSeconds: 10 + # -- Minimum consecutive successes for the [probe] to be considered successful after having failed + successThreshold: 1 + # -- Number of seconds after which the [probe] times out + timeoutSeconds: 1 + + serviceAccount: + # -- Create dex service account + create: true + # -- Dex service account name + name: argocd-dex-server + # -- Annotations applied to created service account + annotations: {} + # -- Automount API credentials for the Service Account + automountServiceAccountToken: true + + # -- Service port for HTTP access + servicePortHttp: 5556 + # -- Service port name for HTTP access + servicePortHttpName: http + # -- Service port for gRPC access + servicePortGrpc: 5557 + # -- Service port name for gRPC access + servicePortGrpcName: grpc + # -- Service port for metrics access + servicePortMetrics: 5558 + + # -- Priority class for the dex pods + # @default -- `""` (defaults to global.priorityClassName) + priorityClassName: "" + + # -- [Node selector] + # @default -- `{}` (defaults to global.nodeSelector) + nodeSelector: {} + + # -- [Tolerations] for use with node taints + # @default -- `[]` (defaults to global.tolerations) + tolerations: [] + + # -- Assign custom [affinity] rules to the deployment + # @default -- `{}` (defaults to global.affinity preset) + affinity: {} + + # -- Assign custom [TopologySpreadConstraints] rules to dex + # @default -- `[]` (defaults to global.topologySpreadConstraints) + ## Ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ + ## If labelSelector is left out, it will default to the labelSelector configuration of the deployment + topologySpreadConstraints: [] + # - maxSkew: 1 + # topologyKey: topology.kubernetes.io/zone + # whenUnsatisfiable: DoNotSchedule + +## Redis +redis: + # -- Enable redis + enabled: true + # -- Redis name + name: redis + + ## Redis Pod Disruption Budget + ## Ref: https://kubernetes.io/docs/tasks/run-application/configure-pdb/ + pdb: + # -- Deploy a [PodDisruptionBudget] for the Redis + enabled: false + # -- Labels to be added to Redis pdb + labels: {} + # -- Annotations to be added to Redis pdb + annotations: {} + # -- Number of pods that are available after eviction as number or percentage (eg.: 50%) + # @default -- `""` (defaults to 0 if not specified) + minAvailable: "" + # -- Number of pods that are unavailble after eviction as number or percentage (eg.: 50%). + ## Has higher precedence over `redis.pdb.minAvailable` + maxUnavailable: "" + + ## Redis image + image: + # -- Redis repository + repository: public.ecr.aws/docker/library/redis + # -- Redis tag + tag: 7.0.7-alpine + # -- Redis image pull policy + # @default -- `""` (defaults to global.image.imagePullPolicy) + imagePullPolicy: "" + + ## Prometheus redis-exporter sidecar + exporter: + # -- Enable Prometheus redis-exporter sidecar + enabled: false + # -- Environment variables to pass to the Redis exporter + env: [] + ## Prometheus redis-exporter image + image: + # -- Repository to use for the redis-exporter + repository: public.ecr.aws/bitnami/redis-exporter + # -- Tag to use for the redis-exporter + tag: 1.45.0 + # -- Image pull policy for the redis-exporter + # @default -- `""` (defaults to global.image.imagePullPolicy) + imagePullPolicy: "" + + # -- Redis exporter security context + # @default -- See [values.yaml] + containerSecurityContext: + runAsNonRoot: true + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + seccompProfile: + type: RuntimeDefault + capabilities: + drop: + - ALL + + # -- Resource limits and requests for redis-exporter sidecar + resources: {} + # limits: + # cpu: 50m + # memory: 64Mi + # requests: + # cpu: 10m + # memory: 32Mi + + # -- Secrets with credentials to pull images from a private registry + # @default -- `[]` (defaults to global.imagePullSecrets) + imagePullSecrets: [] + + # -- Additional command line arguments to pass to redis-server + extraArgs: [] + # - --bind + # - "0.0.0.0" + + # -- Environment variables to pass to the Redis server + env: [] + + # -- envFrom to pass to the Redis server + # @default -- `[]` (See [values.yaml]) + envFrom: [] + # - configMapRef: + # name: config-map-name + # - secretRef: + # name: secret-name + + # -- Additional containers to be added to the redis pod + ## Note: Supports use of custom Helm templates + extraContainers: [] + + # -- Init containers to add to the redis pod + ## Note: Supports use of custom Helm templates + initContainers: [] + + # -- Additional volumeMounts to the redis container + volumeMounts: [] + + # -- Additional volumes to the redis pod + volumes: [] + + # -- Annotations to be added to the Redis server Deployment + deploymentAnnotations: {} + + # -- Annotations to be added to the Redis server pods + podAnnotations: {} + + # -- Labels to be added to the Redis server pods + podLabels: {} + + # -- Resource limits and requests for redis + resources: {} + # limits: + # cpu: 200m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 64Mi + + # -- Redis pod-level security context + # @default -- See [values.yaml] + securityContext: + runAsNonRoot: true + runAsUser: 999 + seccompProfile: + type: RuntimeDefault + + # Redis container ports + containerPorts: + # -- Redis container port + redis: 6379 + # -- Metrics container port + metrics: 9121 + + # -- [DNS configuration] + dnsConfig: {} + # -- Alternative DNS policy for Redis server pods + dnsPolicy: "ClusterFirst" + + # -- Redis container-level security context + # @default -- See [values.yaml] + containerSecurityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + + # -- Redis service port + servicePort: 6379 + + # -- Priority class for redis pods + # @default -- `""` (defaults to global.priorityClassName) + priorityClassName: "" + + # -- [Node selector] + # @default -- `{}` (defaults to global.nodeSelector) + nodeSelector: {} + + # -- [Tolerations] for use with node taints + # @default -- `[]` (defaults to global.tolerations) + tolerations: [] + + # -- Assign custom [affinity] rules to the deployment + # @default -- `{}` (defaults to global.affinity preset) + affinity: {} + + # -- Assign custom [TopologySpreadConstraints] rules to redis + # @default -- `[]` (defaults to global.topologySpreadConstraints) + ## Ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ + ## If labelSelector is left out, it will default to the labelSelector configuration of the deployment + topologySpreadConstraints: [] + # - maxSkew: 1 + # topologyKey: topology.kubernetes.io/zone + # whenUnsatisfiable: DoNotSchedule + + serviceAccount: + # -- Create a service account for the redis pod + create: false + # -- Service account name for redis pod + name: "" + # -- Annotations applied to created service account + annotations: {} + # -- Automount API credentials for the Service Account + automountServiceAccountToken: false + + service: + # -- Redis service annotations + annotations: {} + # -- Additional redis service labels + labels: {} + + metrics: + # -- Deploy metrics service + enabled: false + + # Redis metrics service configuration + service: + # -- Metrics service type + type: ClusterIP + # -- Metrics service clusterIP. `None` makes a "headless service" (no virtual IP) + clusterIP: None + # -- Metrics service annotations + annotations: {} + # -- Metrics service labels + labels: {} + # -- Metrics service port + servicePort: 9121 + # -- Metrics service port name + portName: http-metrics + + serviceMonitor: + # -- Enable a prometheus ServiceMonitor + enabled: false + # -- Interval at which metrics should be scraped + interval: 30s + # -- Prometheus [RelabelConfigs] to apply to samples before scraping + relabelings: [] + # -- Prometheus [MetricRelabelConfigs] to apply to samples before ingestion + metricRelabelings: [] + # -- Prometheus ServiceMonitor selector + selector: {} + # prometheus: kube-prometheus + + # -- Prometheus ServiceMonitor scheme + scheme: "" + # -- Prometheus ServiceMonitor tlsConfig + tlsConfig: {} + # -- Prometheus ServiceMonitor namespace + namespace: "" # "monitoring" + # -- Prometheus ServiceMonitor labels + additionalLabels: {} + # -- Prometheus ServiceMonitor annotations + annotations: {} + +# This key configures Redis-HA subchart and when enabled (redis-ha.enabled=true) +# the custom redis deployment is omitted +# Check the redis-ha chart for more properties +redis-ha: + # -- Enables the Redis HA subchart and disables the custom Redis single node deployment + enabled: false + ## Prometheus redis-exporter sidecar + exporter: + # -- Enable Prometheus redis-exporter sidecar + enabled: false + # -- Repository to use for the redis-exporter + image: public.ecr.aws/bitnami/redis-exporter + # -- Tag to use for the redis-exporter + tag: 1.45.0 + persistentVolume: + # -- Configures persistence on Redis nodes + enabled: false + redis: + # -- Redis convention for naming the cluster group: must match `^[\\w-\\.]+$` and can be templated + masterGroupName: argocd + # -- Any valid redis config options in this section will be applied to each server (see `redis-ha` chart) + # @default -- See [values.yaml] + config: + # -- Will save the DB if both the given number of seconds and the given number of write operations against the DB occurred. `""` is disabled + # @default -- `'""'` + save: '""' + haproxy: + # -- Enabled HAProxy LoadBalancing/Proxy + enabled: true + metrics: + # -- HAProxy enable prometheus metric scraping + enabled: true + image: + # -- Redis tag + tag: 7.0.7-alpine + + ## https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ + topologySpreadConstraints: + # -- Enable Redis HA topology spread constraints + enabled: false + # -- Max skew of pods tolerated + # @default -- `""` (defaults to `1`) + maxSkew: "" + # -- Topology key for spread + # @default -- `""` (defaults to `topology.kubernetes.io/zone`) + topologyKey: "" + # -- Enforcement policy, hard or soft + # @default -- `""` (defaults to `ScheduleAnyway`) + whenUnsatisfiable: "" + +# External Redis parameters +externalRedis: + # -- External Redis server host + host: "" + # -- External Redis username + username: "" + # -- External Redis password + password: "" + # -- External Redis server port + port: 6379 + # -- The name of an existing secret with Redis credentials (must contain key `redis-password`). + # When it's set, the `externalRedis.password` parameter is ignored + existingSecret: "" + # -- External Redis Secret annotations + secretAnnotations: {} + +## Server +server: + # -- Argo CD server name + name: server + + # -- The number of server pods to run + replicas: 1 + + ## Argo CD server Horizontal Pod Autoscaler + autoscaling: + # -- Enable Horizontal Pod Autoscaler ([HPA]) for the Argo CD server + enabled: false + # -- Minimum number of replicas for the Argo CD server [HPA] + minReplicas: 1 + # -- Maximum number of replicas for the Argo CD server [HPA] + maxReplicas: 5 + # -- Average CPU utilization percentage for the Argo CD server [HPA] + targetCPUUtilizationPercentage: 50 + # -- Average memory utilization percentage for the Argo CD server [HPA] + targetMemoryUtilizationPercentage: 50 + # -- Configures the scaling behavior of the target in both Up and Down directions. + # This is only available on HPA apiVersion `autoscaling/v2beta2` and newer + behavior: {} + # scaleDown: + # stabilizationWindowSeconds: 300 + # policies: + # - type: Pods + # value: 1 + # periodSeconds: 180 + # scaleUp: + # stabilizationWindowSeconds: 300 + # policies: + # - type: Pods + # value: 2 + # periodSeconds: 60 + + ## Argo CD server Pod Disruption Budget + ## Ref: https://kubernetes.io/docs/tasks/run-application/configure-pdb/ + pdb: + # -- Deploy a [PodDisruptionBudget] for the Argo CD server + enabled: false + # -- Labels to be added to Argo CD server pdb + labels: {} + # -- Annotations to be added to Argo CD server pdb + annotations: {} + # -- Number of pods that are available after eviction as number or percentage (eg.: 50%) + # @default -- `""` (defaults to 0 if not specified) + minAvailable: "" + # -- Number of pods that are unavailable after eviction as number or percentage (eg.: 50%). + ## Has higher precedence over `server.pdb.minAvailable` + maxUnavailable: "" + + ## Argo CD server image + image: + # -- Repository to use for the Argo CD server + # @default -- `""` (defaults to global.image.repository) + repository: "" # defaults to global.image.repository + # -- Tag to use for the Argo CD server + # @default -- `""` (defaults to global.image.tag) + tag: "" # defaults to global.image.tag + # -- Image pull policy for the Argo CD server + # @default -- `""` (defaults to global.image.imagePullPolicy) + imagePullPolicy: "" # IfNotPresent + + # -- Secrets with credentials to pull images from a private registry + # @default -- `[]` (defaults to global.imagePullSecrets) + imagePullSecrets: [] + + # -- Additional command line arguments to pass to Argo CD server + extraArgs: [] + + # -- Environment variables to pass to Argo CD server + env: [] + + # -- envFrom to pass to Argo CD server + # @default -- `[]` (See [values.yaml]) + envFrom: [] + # - configMapRef: + # name: config-map-name + # - secretRef: + # name: secret-name + + # -- Specify postStart and preStop lifecycle hooks for your argo-cd-server container + lifecycle: {} + + ## Argo UI extensions + ## This function in tech preview stage, do expect instability or breaking changes in newer versions. + ## Ref: https://github.com/argoproj-labs/argocd-extensions + extensions: + # -- Enable support for Argo UI extensions + enabled: false + + ## Argo UI extensions image + image: + # -- Repository to use for extensions image + repository: "ghcr.io/argoproj-labs/argocd-extensions" + # -- Tag to use for extensions image + tag: "v0.2.1" + # -- Image pull policy for extensions + # @default -- `""` (defaults to global.image.imagePullPolicy) + imagePullPolicy: "" + + # -- Server UI extensions container-level security context + # @default -- See [values.yaml] + containerSecurityContext: + runAsNonRoot: true + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + seccompProfile: + type: RuntimeDefault + capabilities: + drop: + - ALL + + # -- Resource limits and requests for the argocd-extensions container + resources: {} + # limits: + # cpu: 50m + # memory: 128Mi + # requests: + # cpu: 10m + # memory: 64Mi + + # -- Additional containers to be added to the server pod + ## Note: Supports use of custom Helm templates + extraContainers: [] + # - name: my-sidecar + # image: nginx:latest + # - name: lemonldap-ng-controller + # image: lemonldapng/lemonldap-ng-controller:0.2.0 + # args: + # - /lemonldap-ng-controller + # - --alsologtostderr + # - --configmap=$(POD_NAMESPACE)/lemonldap-ng-configuration + # env: + # - name: POD_NAME + # valueFrom: + # fieldRef: + # fieldPath: metadata.name + # - name: POD_NAMESPACE + # valueFrom: + # fieldRef: + # fieldPath: metadata.namespace + # volumeMounts: + # - name: copy-portal-skins + # mountPath: /srv/var/lib/lemonldap-ng/portal/skins + + # -- Init containers to add to the server pod + ## If your target Kubernetes cluster(s) require a custom credential (exec) plugin + ## you could use this (and the same in the application controller pod) to provide such executable + ## Ref: https://kubernetes.io/docs/reference/access-authn-authz/authentication/#client-go-credential-plugins + initContainers: [] + # - name: download-tools + # image: alpine:3 + # command: [sh, -c] + # args: + # - wget -qO kubelogin.zip https://github.com/Azure/kubelogin/releases/download/v0.0.25/kubelogin-linux-amd64.zip && + # unzip kubelogin.zip && mv bin/linux_amd64/kubelogin /custom-tools/ + # volumeMounts: + # - mountPath: /custom-tools + # name: custom-tools + + # -- Additional volumeMounts to the server main container + volumeMounts: [] + # - mountPath: /usr/local/bin/kubelogin + # name: custom-tools + # subPath: kubelogin + + # -- Additional volumes to the server pod + volumes: [] + # - name: custom-tools + # emptyDir: {} + + # -- Annotations to be added to server Deployment + deploymentAnnotations: {} + + # -- Annotations to be added to server pods + podAnnotations: {} + + # -- Labels to be added to server pods + podLabels: {} + + # -- Resource limits and requests for the Argo CD server + resources: {} + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 50m + # memory: 64Mi + + # Server container ports + containerPorts: + # -- Server container port + server: 8080 + # -- Metrics container port + metrics: 8082 + + # -- Host Network for Server pods + hostNetwork: false + + # -- [DNS configuration] + dnsConfig: {} + # -- Alternative DNS policy for Server pods + dnsPolicy: "ClusterFirst" + + # -- Server container-level security context + # @default -- See [values.yaml] + containerSecurityContext: + runAsNonRoot: true + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + seccompProfile: + type: RuntimeDefault + capabilities: + drop: + - ALL + + ## Readiness and liveness probes for default backend + ## Ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/ + readinessProbe: + # -- Minimum consecutive failures for the [probe] to be considered failed after having succeeded + failureThreshold: 3 + # -- Number of seconds after the container has started before [probe] is initiated + initialDelaySeconds: 10 + # -- How often (in seconds) to perform the [probe] + periodSeconds: 10 + # -- Minimum consecutive successes for the [probe] to be considered successful after having failed + successThreshold: 1 + # -- Number of seconds after which the [probe] times out + timeoutSeconds: 1 + + livenessProbe: + # -- Minimum consecutive failures for the [probe] to be considered failed after having succeeded + failureThreshold: 3 + # -- Number of seconds after the container has started before [probe] is initiated + initialDelaySeconds: 10 + # -- How often (in seconds) to perform the [probe] + periodSeconds: 10 + # -- Minimum consecutive successes for the [probe] to be considered successful after having failed + successThreshold: 1 + # -- Number of seconds after which the [probe] times out + timeoutSeconds: 1 + + # -- Priority class for the Argo CD server pods + # @default -- `""` (defaults to global.priorityClassName) + priorityClassName: "" + + # -- [Node selector] + # @default -- `{}` (defaults to global.nodeSelector) + nodeSelector: {} + + # -- [Tolerations] for use with node taints + # @default -- `[]` (defaults to global.tolerations) + tolerations: [] + + # -- Assign custom [affinity] rules to the deployment + # @default -- `{}` (defaults to global.affinity preset) + affinity: {} + + # -- Assign custom [TopologySpreadConstraints] rules to the Argo CD server + # @default -- `[]` (defaults to global.topologySpreadConstraints) + ## Ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ + ## If labelSelector is left out, it will default to the labelSelector configuration of the deployment + topologySpreadConstraints: [] + # - maxSkew: 1 + # topologyKey: topology.kubernetes.io/zone + # whenUnsatisfiable: DoNotSchedule + + # TLS certificate configuration via cert-manager + ## Ref: https://argo-cd.readthedocs.io/en/stable/operator-manual/tls/#tls-certificates-used-by-argocd-server + certificate: + # -- Deploy a Certificate resource (requires cert-manager) + enabled: false + # -- The name of the Secret that will be automatically created and managed by this Certificate resource + secretName: argocd-server-tls + # -- Certificate primary domain (commonName) + domain: argocd.example.com + # -- Certificate Subject Alternate Names (SANs) + additionalHosts: [] + # -- The requested 'duration' (i.e. lifetime) of the certificate. + # @default -- `""` (defaults to 2160h = 90d if not specified) + ## Ref: https://cert-manager.io/docs/usage/certificate/#renewal + duration: "" + # -- How long before the expiry a certificate should be renewed. + # @default -- `""` (defaults to 360h = 15d if not specified) + ## Ref: https://cert-manager.io/docs/usage/certificate/#renewal + renewBefore: "" + # Certificate issuer + ## Ref: https://cert-manager.io/docs/concepts/issuer + issuer: + # -- Certificate issuer group. Set if using an external issuer. Eg. `cert-manager.io` + group: "" + # -- Certificate issuer kind. Either `Issuer` or `ClusterIssuer` + kind: "" + # -- Certificate issuer name. Eg. `letsencrypt` + name: "" + # Private key of the certificate + privateKey: + # -- Rotation policy of private key when certificate is re-issued. Either: `Never` or `Always` + rotationPolicy: Never + # -- The private key cryptography standards (PKCS) encoding for private key. Either: `PCKS1` or `PKCS8` + encoding: PKCS1 + # -- Algorithm used to generate certificate private key. One of: `RSA`, `Ed25519` or `ECDSA` + algorithm: RSA + # -- Key bit size of the private key. If algorithm is set to `Ed25519`, size is ignored. + size: 2048 + + # TLS certificate configuration via Secret + ## Ref: https://argo-cd.readthedocs.io/en/stable/operator-manual/tls/#tls-certificates-used-by-argocd-server + certificateSecret: + # -- Create argocd-server-tls secret + enabled: false + # -- Annotations to be added to argocd-server-tls secret + annotations: {} + # -- Labels to be added to argocd-server-tls secret + labels: {} + # -- Private Key of the certificate + key: '' + # -- Certificate data + crt: '' + + ## Server service configuration + service: + # -- Server service annotations + annotations: {} + # -- Server service labels + labels: {} + # -- Server service type + type: ClusterIP + # -- Server service http port for NodePort service type (only if `server.service.type` is set to "NodePort") + nodePortHttp: 30080 + # -- Server service https port for NodePort service type (only if `server.service.type` is set to "NodePort") + nodePortHttps: 30443 + # -- Server service http port + servicePortHttp: 80 + # -- Server service https port + servicePortHttps: 443 + # -- Server service http port name, can be used to route traffic via istio + servicePortHttpName: http + # -- Server service https port name, can be used to route traffic via istio + servicePortHttpsName: https + # -- LoadBalancer will get created with the IP specified in this field + loadBalancerIP: "" + # -- Source IP ranges to allow access to service from + loadBalancerSourceRanges: [] + # -- Server service external IPs + externalIPs: [] + # -- Denotes if this Service desires to route external traffic to node-local or cluster-wide endpoints + externalTrafficPolicy: "" + # -- Used to maintain session affinity. Supports `ClientIP` and `None` + sessionAffinity: "" + + ## Server metrics service configuration + metrics: + # -- Deploy metrics service + enabled: false + service: + # -- Metrics service annotations + annotations: {} + # -- Metrics service labels + labels: {} + # -- Metrics service port + servicePort: 8083 + # -- Metrics service port name + portName: http-metrics + serviceMonitor: + # -- Enable a prometheus ServiceMonitor + enabled: false + # -- Prometheus ServiceMonitor interval + interval: 30s + # -- Prometheus [RelabelConfigs] to apply to samples before scraping + relabelings: [] + # -- Prometheus [MetricRelabelConfigs] to apply to samples before ingestion + metricRelabelings: [] + # -- Prometheus ServiceMonitor selector + selector: {} + # prometheus: kube-prometheus + + # -- Prometheus ServiceMonitor scheme + scheme: "" + # -- Prometheus ServiceMonitor tlsConfig + tlsConfig: {} + # -- Prometheus ServiceMonitor namespace + namespace: "" # monitoring + # -- Prometheus ServiceMonitor labels + additionalLabels: {} + # -- Prometheus ServiceMonitor annotations + annotations: {} + + serviceAccount: + # -- Create server service account + create: true + # -- Server service account name + name: argocd-server + # -- Annotations applied to created service account + annotations: {} + # -- Labels applied to created service account + labels: {} + # -- Automount API credentials for the Service Account + automountServiceAccountToken: true + + ingress: + # -- Enable an ingress resource for the Argo CD server + enabled: false + # -- Additional ingress annotations + annotations: {} + # -- Additional ingress labels + labels: {} + # -- Defines which ingress controller will implement the resource + ingressClassName: "" + + # -- List of ingress hosts + ## Argo Ingress. + ## Hostnames must be provided if Ingress is enabled. + ## Secrets must be manually created in the namespace + hosts: [] + # - argocd.example.com + + # -- List of ingress paths + paths: + - / + # -- Ingress path type. One of `Exact`, `Prefix` or `ImplementationSpecific` + pathType: Prefix + # -- Additional ingress paths + extraPaths: [] + # - path: /* + # pathType: Prefix + # backend: + # service: + # name: ssl-redirect + # port: + # name: use-annotation + + # -- Ingress TLS configuration + tls: [] + # - secretName: your-certificate-name + # hosts: + # - argocd.example.com + + # -- Uses `server.service.servicePortHttps` instead `server.service.servicePortHttp` + https: false + + # dedicated ingress for gRPC as documented at + # Ref: https://argo-cd.readthedocs.io/en/stable/operator-manual/ingress/ + ingressGrpc: + # -- Enable an ingress resource for the Argo CD server for dedicated [gRPC-ingress] + enabled: false + # -- Setup up gRPC ingress to work with an AWS ALB + isAWSALB: false + # -- Additional ingress annotations for dedicated [gRPC-ingress] + annotations: {} + # -- Additional ingress labels for dedicated [gRPC-ingress] + labels: {} + # -- Defines which ingress controller will implement the resource [gRPC-ingress] + ingressClassName: "" + + awsALB: + # -- Service type for the AWS ALB gRPC service + ## Service Type if isAWSALB is set to true + ## Can be of type NodePort or ClusterIP depending on which mode you are + ## are running. Instance mode needs type NodePort, IP mode needs type + ## ClusterIP + ## Ref: https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.2/how-it-works/#ingress-traffic + serviceType: NodePort + # -- Backend protocol version for the AWS ALB gRPC service + ## This tells AWS to send traffic from the ALB using HTTP2. Can use gRPC as well if you want to leverage gRPC specific features + backendProtocolVersion: HTTP2 + + # -- List of ingress hosts for dedicated [gRPC-ingress] + ## Argo Ingress. + ## Hostnames must be provided if Ingress is enabled. + ## Secrets must be manually created in the namespace + ## + hosts: [] + # - argocd.example.com + + # -- List of ingress paths for dedicated [gRPC-ingress] + paths: + - / + # -- Ingress path type for dedicated [gRPC-ingress]. One of `Exact`, `Prefix` or `ImplementationSpecific` + pathType: Prefix + # -- Additional ingress paths for dedicated [gRPC-ingress] + extraPaths: [] + # - path: /* + # pathType: Prefix + # backend: + # service: + # name: ssl-redirect + # port: + # name: use-annotation + + # -- Ingress TLS configuration for dedicated [gRPC-ingress] + tls: [] + # - secretName: your-certificate-name + # hosts: + # - argocd.example.com + + # -- Uses `server.service.servicePortHttps` instead `server.service.servicePortHttp` + https: false + + # Create a OpenShift Route with SSL passthrough for UI and CLI + # Consider setting 'hostname' e.g. https://argocd.apps-crc.testing/ using your Default Ingress Controller Domain + # Find your domain with: kubectl describe --namespace=openshift-ingress-operator ingresscontroller/default | grep Domain: + # If 'hostname' is an empty string "" OpenShift will create a hostname for you. + route: + # -- Enable an OpenShift Route for the Argo CD server + enabled: false + # -- Openshift Route annotations + annotations: {} + # -- Hostname of OpenShift Route + hostname: "" + # -- Termination type of Openshift Route + termination_type: passthrough + # -- Termination policy of Openshift Route + termination_policy: None + + GKEbackendConfig: + # -- Enable BackendConfig custom resource for Google Kubernetes Engine + enabled: false + # -- [BackendConfigSpec] + spec: {} + # spec: + # iap: + # enabled: true + # oauthclientCredentials: + # secretName: argocd-secret + + ## Create a Google Managed Certificate for use with the GKE Ingress Controller + ## https://cloud.google.com/kubernetes-engine/docs/how-to/managed-certs + GKEmanagedCertificate: + # -- Enable ManagedCertificate custom resource for Google Kubernetes Engine. + enabled: false + # -- Domains for the Google Managed Certificate + domains: + - argocd.example.com + + ## Create a Google FrontendConfig Custom Resource, for use with the GKE Ingress Controller + ## https://cloud.google.com/kubernetes-engine/docs/how-to/ingress-features#configuring_ingress_features_through_frontendconfig_parameters + GKEfrontendConfig: + # -- Enable FrontConfig custom resource for Google Kubernetes Engine + enabled: false + # -- [FrontendConfigSpec] + spec: {} + # spec: + # redirectToHttps: + # enabled: true + # responseCodeName: RESPONSE_CODE + +## Repo Server +repoServer: + # -- Repo server name + name: repo-server + + # -- The number of repo server pods to run + replicas: 1 + + ## Repo server Horizontal Pod Autoscaler + autoscaling: + # -- Enable Horizontal Pod Autoscaler ([HPA]) for the repo server + enabled: false + # -- Minimum number of replicas for the repo server [HPA] + minReplicas: 1 + # -- Maximum number of replicas for the repo server [HPA] + maxReplicas: 5 + # -- Average CPU utilization percentage for the repo server [HPA] + targetCPUUtilizationPercentage: 50 + # -- Average memory utilization percentage for the repo server [HPA] + targetMemoryUtilizationPercentage: 50 + # -- Configures the scaling behavior of the target in both Up and Down directions. + # This is only available on HPA apiVersion `autoscaling/v2beta2` and newer + behavior: {} + # scaleDown: + # stabilizationWindowSeconds: 300 + # policies: + # - type: Pods + # value: 1 + # periodSeconds: 180 + # scaleUp: + # stabilizationWindowSeconds: 300 + # policies: + # - type: Pods + # value: 2 + # periodSeconds: 60 + + ## Repo server Pod Disruption Budget + ## Ref: https://kubernetes.io/docs/tasks/run-application/configure-pdb/ + pdb: + # -- Deploy a [PodDisruptionBudget] for the repo server + enabled: false + # -- Labels to be added to repo server pdb + labels: {} + # -- Annotations to be added to repo server pdb + annotations: {} + # -- Number of pods that are available after eviction as number or percentage (eg.: 50%) + # @default -- `""` (defaults to 0 if not specified) + minAvailable: "" + # -- Number of pods that are unavailable after eviction as number or percentage (eg.: 50%). + ## Has higher precedence over `repoServer.pdb.minAvailable` + maxUnavailable: "" + + ## Repo server image + image: + # -- Repository to use for the repo server + # @default -- `""` (defaults to global.image.repository) + repository: "" + # -- Tag to use for the repo server + # @default -- `""` (defaults to global.image.tag) + tag: "" + # -- Image pull policy for the repo server + # @default -- `""` (defaults to global.image.imagePullPolicy) + imagePullPolicy: "" + + # -- Secrets with credentials to pull images from a private registry + # @default -- `[]` (defaults to global.imagePullSecrets) + imagePullSecrets: [] + + # -- Additional command line arguments to pass to repo server + extraArgs: [] + + # -- Environment variables to pass to repo server + env: [] + + # -- envFrom to pass to repo server + # @default -- `[]` (See [values.yaml]) + envFrom: [] + # - configMapRef: + # name: config-map-name + # - secretRef: + # name: secret-name + + # -- Additional containers to be added to the repo server pod + ## Ref: https://argo-cd.readthedocs.io/en/stable/user-guide/config-management-plugins/ + ## Note: Supports use of custom Helm templates + extraContainers: [] + # - name: cmp-my-plugin + # command: + # - "/var/run/argocd/argocd-cmp-server" + # image: busybox + # securityContext: + # runAsNonRoot: true + # runAsUser: 999 + # volumeMounts: + # - mountPath: /var/run/argocd + # name: var-files + # - mountPath: /home/argocd/cmp-server/plugins + # name: plugins + # # Remove this volumeMount if you've chosen to bake the config file into the sidecar image. + # - mountPath: /home/argocd/cmp-server/config/plugin.yaml + # subPath: my-plugin.yaml + # name: argocd-cmp-cm + # # Starting with v2.4, do NOT mount the same tmp volume as the repo-server container. The filesystem separation helps + # # mitigate path traversal attacks. + # - mountPath: /tmp + # name: cmp-tmp + # - name: cmp-my-plugin2 + # command: + # - "/var/run/argocd/argocd-cmp-server" + # image: busybox + # securityContext: + # runAsNonRoot: true + # runAsUser: 999 + # volumeMounts: + # - mountPath: /var/run/argocd + # name: var-files + # # Remove this volumeMount if you've chosen to bake the config file into the sidecar image. + # - mountPath: /home/argocd/cmp-server/plugins + # name: plugins + # - mountPath: /home/argocd/cmp-server/config/plugin.yaml + # subPath: my-plugin2.yaml + # name: argocd-cmp-cm + # # Starting with v2.4, do NOT mount the same tmp volume as the repo-server container. The filesystem separation helps + # # mitigate path traversal attacks. + # - mountPath: /tmp + # name: cmp-tmp + + # -- Init containers to add to the repo server pods + initContainers: [] + + # -- Additional volumeMounts to the repo server main container + volumeMounts: [] + + # -- Additional volumes to the repo server pod + volumes: [] + # - name: argocd-cmp-cm + # configMap: + # name: argocd-cmp-cm + # - name: cmp-tmp + # emptyDir: {} + + # -- Annotations to be added to repo server Deployment + deploymentAnnotations: {} + + # -- Annotations to be added to repo server pods + podAnnotations: {} + + # -- Labels to be added to repo server pods + podLabels: {} + + # -- Resource limits and requests for the repo server pods + resources: {} + # limits: + # cpu: 50m + # memory: 128Mi + # requests: + # cpu: 10m + # memory: 64Mi + + # Repo server container ports + containerPorts: + # -- Repo server container port + server: 8081 + # -- Metrics container port + metrics: 8084 + + # -- Host Network for Repo server pods + hostNetwork: false + + # -- [DNS configuration] + dnsConfig: {} + # -- Alternative DNS policy for Repo server pods + dnsPolicy: "ClusterFirst" + + # -- Repo server container-level security context + # @default -- See [values.yaml] + containerSecurityContext: + runAsNonRoot: true + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + seccompProfile: + type: RuntimeDefault + capabilities: + drop: + - ALL + + ## Readiness and liveness probes for default backend + ## Ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/ + readinessProbe: + # -- Minimum consecutive failures for the [probe] to be considered failed after having succeeded + failureThreshold: 3 + # -- Number of seconds after the container has started before [probe] is initiated + initialDelaySeconds: 10 + # -- How often (in seconds) to perform the [probe] + periodSeconds: 10 + # -- Minimum consecutive successes for the [probe] to be considered successful after having failed + successThreshold: 1 + # -- Number of seconds after which the [probe] times out + timeoutSeconds: 1 + + livenessProbe: + # -- Minimum consecutive failures for the [probe] to be considered failed after having succeeded + failureThreshold: 3 + # -- Number of seconds after the container has started before [probe] is initiated + initialDelaySeconds: 10 + # -- How often (in seconds) to perform the [probe] + periodSeconds: 10 + # -- Minimum consecutive successes for the [probe] to be considered successful after having failed + successThreshold: 1 + # -- Number of seconds after which the [probe] times out + timeoutSeconds: 1 + + # -- [Node selector] + # @default -- `{}` (defaults to global.nodeSelector) + nodeSelector: {} + + # -- [Tolerations] for use with node taints + # @default -- `[]` (defaults to global.tolerations) + tolerations: [] + + # -- Assign custom [affinity] rules to the deployment + # @default -- `{}` (defaults to global.affinity preset) + affinity: {} + + # -- Assign custom [TopologySpreadConstraints] rules to the repo server + # @default -- `[]` (defaults to global.topologySpreadConstraints) + ## Ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ + ## If labelSelector is left out, it will default to the labelSelector configuration of the deployment + topologySpreadConstraints: [] + # - maxSkew: 1 + # topologyKey: topology.kubernetes.io/zone + # whenUnsatisfiable: DoNotSchedule + + # -- Priority class for the repo server pods + # @default -- `""` (defaults to global.priorityClassName) + priorityClassName: "" + + # TLS certificate configuration via Secret + ## Ref: https://argo-cd.readthedocs.io/en/stable/operator-manual/tls/#configuring-tls-to-argocd-repo-server + ## Note: Issuing certificates via cert-manager in not supported right now because it's not possible to restart repo server automatically without extra controllers. + certificateSecret: + # -- Create argocd-repo-server-tls secret + enabled: false + # -- Annotations to be added to argocd-repo-server-tls secret + annotations: {} + # -- Labels to be added to argocd-repo-server-tls secret + labels: {} + # -- Certificate authority. Required for self-signed certificates. + ca: '' + # -- Certificate private key + key: '' + # -- Certificate data. Must contain SANs of Repo service (ie: argocd-repo-server, argocd-repo-server.argo-cd.svc) + crt: '' + + ## Repo server service configuration + service: + # -- Repo server service annotations + annotations: {} + # -- Repo server service labels + labels: {} + # -- Repo server service port + port: 8081 + # -- Repo server service port name + portName: https-repo-server + + ## Repo server metrics service configuration + metrics: + # -- Deploy metrics service + enabled: false + service: + # -- Metrics service annotations + annotations: {} + # -- Metrics service labels + labels: {} + # -- Metrics service port + servicePort: 8084 + # -- Metrics service port name + portName: http-metrics + serviceMonitor: + # -- Enable a prometheus ServiceMonitor + enabled: false + # -- Prometheus ServiceMonitor interval + interval: 30s + # -- Prometheus [RelabelConfigs] to apply to samples before scraping + relabelings: [] + # -- Prometheus [MetricRelabelConfigs] to apply to samples before ingestion + metricRelabelings: [] + # -- Prometheus ServiceMonitor selector + selector: {} + # prometheus: kube-prometheus + + # -- Prometheus ServiceMonitor scheme + scheme: "" + # -- Prometheus ServiceMonitor tlsConfig + tlsConfig: {} + # -- Prometheus ServiceMonitor namespace + namespace: "" # "monitoring" + # -- Prometheus ServiceMonitor labels + additionalLabels: {} + # -- Prometheus ServiceMonitor annotations + annotations: {} + + ## Enable Custom Rules for the Repo server's Cluster Role resource + ## Enable this and set the rules: to whatever custom rules you want for the Cluster Role resource. + ## Defaults to off + clusterRoleRules: + # -- Enable custom rules for the Repo server's Cluster Role resource + enabled: false + # -- List of custom rules for the Repo server's Cluster Role resource + rules: [] + + ## Repo server service account + ## If create is set to true, make sure to uncomment the name and update the rbac section below + serviceAccount: + # -- Create repo server service account + create: true + # -- Repo server service account name + name: "" # "argocd-repo-server" + # -- Annotations applied to created service account + annotations: {} + # -- Labels applied to created service account + labels: {} + # -- Automount API credentials for the Service Account + automountServiceAccountToken: true + + # -- Repo server rbac rules + rbac: [] + # - apiGroups: + # - argoproj.io + # resources: + # - applications + # verbs: + # - get + # - list + # - watch + +## ApplicationSet controller +applicationSet: + # -- Enable ApplicationSet controller + enabled: true + + # -- ApplicationSet controller name string + name: applicationset-controller + + # -- The number of ApplicationSet controller pods to run + replicaCount: 1 + + ## ApplicationSet controller Pod Disruption Budget + ## Ref: https://kubernetes.io/docs/tasks/run-application/configure-pdb/ + pdb: + # -- Deploy a [PodDisruptionBudget] for the ApplicationSet controller + enabled: false + # -- Labels to be added to ApplicationSet controller pdb + labels: {} + # -- Annotations to be added to ApplicationSet controller pdb + annotations: {} + # -- Number of pods that are available after eviction as number or percentage (eg.: 50%) + # @default -- `""` (defaults to 0 if not specified) + minAvailable: "" + # -- Number of pods that are unavailable after eviction as number or percentage (eg.: 50%). + ## Has higher precedence over `applicationSet.pdb.minAvailable` + maxUnavailable: "" + + ## ApplicationSet controller image + image: + # -- Repository to use for the ApplicationSet controller + # @default -- `""` (defaults to global.image.repository) + repository: "" + # -- Tag to use for the ApplicationSet controller + # @default -- `""` (defaults to global.image.tag) + tag: "" + # -- Image pull policy for the ApplicationSet controller + # @default -- `""` (defaults to global.image.imagePullPolicy) + imagePullPolicy: "" + + # -- If defined, uses a Secret to pull an image from a private Docker registry or repository. + # @default -- `[]` (defaults to global.imagePullSecrets) + imagePullSecrets: [] + + # -- DEPRECATED - ApplicationSet controller command line flags + args: {} + # DEPRECATED - Use configs.params.applicationsetcontroller.policy to override + # -- How application is synced between the generator and the cluster + # policy: sync + # DEPRECATED - Use configs.params.applicationsetcontroller.dryrun to override + # -- Enable dry run mode + # dryRun: false + + # -- List of extra cli args to add + extraArgs: [] + + # -- Environment variables to pass to the ApplicationSet controller + extraEnv: [] + # - name: "MY_VAR" + # value: "value" + + # -- envFrom to pass to the ApplicationSet controller + # @default -- `[]` (See [values.yaml]) + extraEnvFrom: [] + # - configMapRef: + # name: config-map-name + # - secretRef: + # name: secret-name + + # -- Additional containers to be added to the ApplicationSet controller pod + ## Note: Supports use of custom Helm templates + extraContainers: [] + + # -- Init containers to add to the ApplicationSet controller pod + ## Note: Supports use of custom Helm templates + initContainers: [] + + # -- List of extra mounts to add (normally used with extraVolumes) + extraVolumeMounts: [] + + # -- List of extra volumes to add + extraVolumes: [] + + ## Metrics service configuration + metrics: + # -- Deploy metrics service + enabled: false + service: + # -- Metrics service annotations + annotations: {} + # -- Metrics service labels + labels: {} + # -- Metrics service port + servicePort: 8085 + # -- Metrics service port name + portName: http-metrics + serviceMonitor: + # -- Enable a prometheus ServiceMonitor + enabled: false + # -- Prometheus ServiceMonitor interval + interval: 30s + # -- Prometheus [RelabelConfigs] to apply to samples before scraping + relabelings: [] + # -- Prometheus [MetricRelabelConfigs] to apply to samples before ingestion + metricRelabelings: [] + # -- Prometheus ServiceMonitor selector + selector: {} + # prometheus: kube-prometheus + + # -- Prometheus ServiceMonitor scheme + scheme: "" + # -- Prometheus ServiceMonitor tlsConfig + tlsConfig: {} + # -- Prometheus ServiceMonitor namespace + namespace: "" # monitoring + # -- Prometheus ServiceMonitor labels + additionalLabels: {} + # -- Prometheus ServiceMonitor annotations + annotations: {} + + ## ApplicationSet service configuration + service: + # -- ApplicationSet service annotations + annotations: {} + # -- ApplicationSet service labels + labels: {} + # -- ApplicationSet service port + port: 7000 + # -- ApplicationSet service port name + portName: webhook + + serviceAccount: + # -- Create ApplicationSet controller service account + create: true + # -- ApplicationSet controller service account name + name: argocd-applicationset-controller + # -- Annotations applied to created service account + annotations: {} + # -- Labels applied to created service account + labels: {} + # -- Automount API credentials for the Service Account + automountServiceAccountToken: true + + # -- Annotations to be added to ApplicationSet controller Deployment + deploymentAnnotations: {} + + # -- Annotations for the ApplicationSet controller pods + podAnnotations: {} + + # -- Labels for the ApplicationSet controller pods + podLabels: {} + + # -- Resource limits and requests for the ApplicationSet controller pods. + resources: {} + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + + # ApplicationSet controller container ports + containerPorts: + # -- Metrics container port + metrics: 8080 + # -- Probe container port + probe: 8081 + # -- Webhook container port + webhook: 7000 + + # -- [DNS configuration] + dnsConfig: {} + # -- Alternative DNS policy for ApplicationSet controller pods + dnsPolicy: "ClusterFirst" + + # -- ApplicationSet controller container-level security context + # @default -- See [values.yaml] + containerSecurityContext: + runAsNonRoot: true + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + seccompProfile: + type: RuntimeDefault + capabilities: + drop: + - ALL + + ## Probes for ApplicationSet controller (optional) + ## Ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/ + readinessProbe: + # -- Enable Kubernetes liveness probe for ApplicationSet controller + enabled: false + # -- Number of seconds after the container has started before [probe] is initiated + initialDelaySeconds: 10 + # -- How often (in seconds) to perform the [probe] + periodSeconds: 10 + # -- Number of seconds after which the [probe] times out + timeoutSeconds: 1 + # -- Minimum consecutive successes for the [probe] to be considered successful after having failed + successThreshold: 1 + # -- Minimum consecutive failures for the [probe] to be considered failed after having succeeded + failureThreshold: 3 + + livenessProbe: + # -- Enable Kubernetes liveness probe for ApplicationSet controller + enabled: false + # -- Number of seconds after the container has started before [probe] is initiated + initialDelaySeconds: 10 + # -- How often (in seconds) to perform the [probe] + periodSeconds: 10 + # -- Number of seconds after which the [probe] times out + timeoutSeconds: 1 + # -- Minimum consecutive successes for the [probe] to be considered successful after having failed + successThreshold: 1 + # -- Minimum consecutive failures for the [probe] to be considered failed after having succeeded + failureThreshold: 3 + + # -- [Node selector] + # @default -- `{}` (defaults to global.nodeSelector) + nodeSelector: {} + + # -- [Tolerations] for use with node taints + # @default -- `[]` (defaults to global.tolerations) + tolerations: [] + + # -- Assign custom [affinity] rules + # @default -- `{}` (defaults to global.affinity preset) + affinity: {} + + # -- Assign custom [TopologySpreadConstraints] rules to the ApplicationSet controller + # @default -- `[]` (defaults to global.topologySpreadConstraints) + ## Ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ + ## If labelSelector is left out, it will default to the labelSelector configuration of the deployment + topologySpreadConstraints: [] + # - maxSkew: 1 + # topologyKey: topology.kubernetes.io/zone + # whenUnsatisfiable: DoNotSchedule + + # -- Priority class for the ApplicationSet controller pods + # @default -- `""` (defaults to global.priorityClassName) + priorityClassName: "" + + ## Webhook for the Git Generator + ## Ref: https://argocd-applicationset.readthedocs.io/en/master/Generators-Git/#webhook-configuration) + webhook: + ingress: + # -- Enable an ingress resource for Webhooks + enabled: false + # -- Additional ingress annotations + annotations: {} + # -- Additional ingress labels + labels: {} + # -- Defines which ingress ApplicationSet controller will implement the resource + ingressClassName: "" + + # -- List of ingress hosts + ## Hostnames must be provided if Ingress is enabled. + ## Secrets must be manually created in the namespace + hosts: [] + # - argocd-applicationset.example.com + + # -- List of ingress paths + paths: + - /api/webhook + # -- Ingress path type. One of `Exact`, `Prefix` or `ImplementationSpecific` + pathType: Prefix + # -- Additional ingress paths + extraPaths: [] + # - path: /* + # backend: + # serviceName: ssl-redirect + # servicePort: use-annotation + ## for Kubernetes >=1.19 (when "networking.k8s.io/v1" is used) + # - path: /* + # pathType: Prefix + # backend: + # service: + # name: ssl-redirect + # port: + # name: use-annotation + + # -- Ingress TLS configuration + tls: [] + # - secretName: argocd-applicationset-tls + # hosts: + # - argocd-applicationset.example.com + +## Notifications controller +notifications: + # -- Enable notifications controller + enabled: true + + # -- Notifications controller name string + name: notifications-controller + + # -- Argo CD dashboard url; used in place of {{.context.argocdUrl}} in templates + argocdUrl: + + ## Notifications controller Pod Disruption Budget + ## Ref: https://kubernetes.io/docs/tasks/run-application/configure-pdb/ + pdb: + # -- Deploy a [PodDisruptionBudget] for the notifications controller + enabled: false + # -- Labels to be added to notifications controller pdb + labels: {} + # -- Annotations to be added to notifications controller pdb + annotations: {} + # -- Number of pods that are available after eviction as number or percentage (eg.: 50%) + # @default -- `""` (defaults to 0 if not specified) + minAvailable: "" + # -- Number of pods that are unavailable after eviction as number or percentage (eg.: 50%). + ## Has higher precedence over `notifications.pdb.minAvailable` + maxUnavailable: "" + + ## Notifications controller image + image: + # -- Repository to use for the notifications controller + # @default -- `""` (defaults to global.image.repository) + repository: "" + # -- Tag to use for the notifications controller + # @default -- `""` (defaults to global.image.tag) + tag: "" + # -- Image pull policy for the notifications controller + # @default -- `""` (defaults to global.image.imagePullPolicy) + imagePullPolicy: "" + + # -- Secrets with credentials to pull images from a private registry + # @default -- `[]` (defaults to global.imagePullSecrets) + imagePullSecrets: [] + + # -- Notifications controller log format. Either `text` or `json` + # @default -- `""` (defaults to global.logging.format) + logFormat: "" + # -- Notifications controller log level. One of: `debug`, `info`, `warn`, `error` + # @default -- `""` (defaults to global.logging.level) + logLevel: "" + + # -- Extra arguments to provide to the notifications controller + extraArgs: [] + + # -- Additional container environment variables + extraEnv: [] + + # -- envFrom to pass to the notifications controller + # @default -- `[]` (See [values.yaml]) + extraEnvFrom: [] + # - configMapRef: + # name: config-map-name + # - secretRef: + # name: secret-name + + # -- Additional containers to be added to the notifications controller pod + ## Note: Supports use of custom Helm templates + extraContainers: [] + + # -- Init containers to add to the notifications controller pod + ## Note: Supports use of custom Helm templates + initContainers: [] + + # -- List of extra mounts to add (normally used with extraVolumes) + extraVolumeMounts: [] + + # -- List of extra volumes to add + extraVolumes: [] + + # -- Define user-defined context + ## For more information: https://argocd-notifications.readthedocs.io/en/stable/templates/#defining-user-defined-context + context: {} + # region: east + # environmentName: staging + + secret: + # -- Whether helm chart creates notifications controller secret + create: true + + # -- key:value pairs of annotations to be added to the secret + annotations: {} + + # -- Generic key:value pairs to be inserted into the secret + ## Can be used for templates, notification services etc. Some examples given below. + ## For more information: https://argocd-notifications.readthedocs.io/en/stable/services/overview/ + items: {} + # slack-token: + # # For more information: https://argocd-notifications.readthedocs.io/en/stable/services/slack/ + + # grafana-apiKey: + # # For more information: https://argocd-notifications.readthedocs.io/en/stable/services/grafana/ + + # webhooks-github-token: + + # email-username: + # email-password: + # For more information: https://argocd-notifications.readthedocs.io/en/stable/services/email/ + + metrics: + # -- Enables prometheus metrics server + enabled: false + # -- Metrics port + port: 9001 + service: + # -- Metrics service annotations + annotations: {} + # -- Metrics service labels + labels: {} + # -- Metrics service port name + portName: http-metrics + serviceMonitor: + # -- Enable a prometheus ServiceMonitor + enabled: false + # -- Prometheus ServiceMonitor selector + selector: {} + # prometheus: kube-prometheus + # -- Prometheus ServiceMonitor labels + additionalLabels: {} + # -- Prometheus ServiceMonitor annotations + annotations: {} + # namespace: monitoring + # interval: 30s + # scrapeTimeout: 10s + # -- Prometheus ServiceMonitor scheme + scheme: "" + # -- Prometheus ServiceMonitor tlsConfig + tlsConfig: {} + # -- Prometheus [RelabelConfigs] to apply to samples before scraping + relabelings: [] + # -- Prometheus [MetricRelabelConfigs] to apply to samples before ingestion + metricRelabelings: [] + + # -- Configures notification services such as slack, email or custom webhook + # @default -- See [values.yaml] + ## For more information: https://argocd-notifications.readthedocs.io/en/stable/services/overview/ + notifiers: {} + # service.slack: | + # token: $slack-token + + # -- Annotations to be applied to the notifications controller Deployment + deploymentAnnotations: {} + + # -- Annotations to be applied to the notifications controller Pods + podAnnotations: {} + + # -- Labels to be applied to the notifications controller Pods + podLabels: {} + + # -- Resource limits and requests for the notifications controller + resources: {} + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + + # Notification controller container ports + containerPorts: + # -- Metrics container port + metrics: 9001 + + # -- [DNS configuration] + dnsConfig: {} + # -- Alternative DNS policy for notifications controller Pods + dnsPolicy: "ClusterFirst" + + # -- Notification controller container-level security Context + # @default -- See [values.yaml] + containerSecurityContext: + runAsNonRoot: true + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + seccompProfile: + type: RuntimeDefault + capabilities: + drop: + - ALL + + # -- [Node selector] + # @default -- `{}` (defaults to global.nodeSelector) + nodeSelector: {} + + # -- [Tolerations] for use with node taints + # @default -- `[]` (defaults to global.tolerations) + tolerations: [] + + # -- Assign custom [affinity] rules + # @default -- `{}` (defaults to global.affinity preset) + affinity: {} + + # -- Assign custom [TopologySpreadConstraints] rules to the application controller + # @default -- `[]` (defaults to global.topologySpreadConstraints) + ## Ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ + ## If labelSelector is left out, it will default to the labelSelector configuration of the deployment + topologySpreadConstraints: [] + # - maxSkew: 1 + # topologyKey: topology.kubernetes.io/zone + # whenUnsatisfiable: DoNotSchedule + + # -- Priority class for the notifications controller pods + # @default -- `""` (defaults to global.priorityClassName) + priorityClassName: "" + + serviceAccount: + # -- Create notifications controller service account + create: true + # -- Notification controller service account name + name: argocd-notifications-controller + # -- Annotations applied to created service account + annotations: {} + # -- Labels applied to created service account + labels: {} + # -- Automount API credentials for the Service Account + automountServiceAccountToken: true + + cm: + # -- Whether helm chart creates notifications controller config map + create: true + + # -- Contains centrally managed global application subscriptions + ## For more information: https://argocd-notifications.readthedocs.io/en/stable/subscriptions/ + subscriptions: [] + # # subscription for on-sync-status-unknown trigger notifications + # - recipients: + # - slack:test2 + # - email:test@gmail.com + # triggers: + # - on-sync-status-unknown + # # subscription restricted to applications with matching labels only + # - recipients: + # - slack:test3 + # selector: test=true + # triggers: + # - on-sync-status-unknown + + # -- The notification template is used to generate the notification content + ## For more information: https://argocd-notifications.readthedocs.io/en/stable/templates/ + templates: {} + # template.app-deployed: | + # email: + # subject: New version of an application {{.app.metadata.name}} is up and running. + # message: | + # {{if eq .serviceType "slack"}}:white_check_mark:{{end}} Application {{.app.metadata.name}} is now running new version of deployments manifests. + # slack: + # attachments: | + # [{ + # "title": "{{ .app.metadata.name}}", + # "title_link":"{{.context.argocdUrl}}/applications/{{.app.metadata.name}}", + # "color": "#18be52", + # "fields": [ + # { + # "title": "Sync Status", + # "value": "{{.app.status.sync.status}}", + # "short": true + # }, + # { + # "title": "Repository", + # "value": "{{.app.spec.source.repoURL}}", + # "short": true + # }, + # { + # "title": "Revision", + # "value": "{{.app.status.sync.revision}}", + # "short": true + # } + # {{range $index, $c := .app.status.conditions}} + # {{if not $index}},{{end}} + # {{if $index}},{{end}} + # { + # "title": "{{$c.type}}", + # "value": "{{$c.message}}", + # "short": true + # } + # {{end}} + # ] + # }] + # template.app-health-degraded: | + # email: + # subject: Application {{.app.metadata.name}} has degraded. + # message: | + # {{if eq .serviceType "slack"}}:exclamation:{{end}} Application {{.app.metadata.name}} has degraded. + # Application details: {{.context.argocdUrl}}/applications/{{.app.metadata.name}}. + # slack: + # attachments: |- + # [{ + # "title": "{{ .app.metadata.name}}", + # "title_link": "{{.context.argocdUrl}}/applications/{{.app.metadata.name}}", + # "color": "#f4c030", + # "fields": [ + # { + # "title": "Sync Status", + # "value": "{{.app.status.sync.status}}", + # "short": true + # }, + # { + # "title": "Repository", + # "value": "{{.app.spec.source.repoURL}}", + # "short": true + # } + # {{range $index, $c := .app.status.conditions}} + # {{if not $index}},{{end}} + # {{if $index}},{{end}} + # { + # "title": "{{$c.type}}", + # "value": "{{$c.message}}", + # "short": true + # } + # {{end}} + # ] + # }] + # template.app-sync-failed: | + # email: + # subject: Failed to sync application {{.app.metadata.name}}. + # message: | + # {{if eq .serviceType "slack"}}:exclamation:{{end}} The sync operation of application {{.app.metadata.name}} has failed at {{.app.status.operationState.finishedAt}} with the following error: {{.app.status.operationState.message}} + # Sync operation details are available at: {{.context.argocdUrl}}/applications/{{.app.metadata.name}}?operation=true . + # slack: + # attachments: |- + # [{ + # "title": "{{ .app.metadata.name}}", + # "title_link":"{{.context.argocdUrl}}/applications/{{.app.metadata.name}}", + # "color": "#E96D76", + # "fields": [ + # { + # "title": "Sync Status", + # "value": "{{.app.status.sync.status}}", + # "short": true + # }, + # { + # "title": "Repository", + # "value": "{{.app.spec.source.repoURL}}", + # "short": true + # } + # {{range $index, $c := .app.status.conditions}} + # {{if not $index}},{{end}} + # {{if $index}},{{end}} + # { + # "title": "{{$c.type}}", + # "value": "{{$c.message}}", + # "short": true + # } + # {{end}} + # ] + # }] + # template.app-sync-running: | + # email: + # subject: Start syncing application {{.app.metadata.name}}. + # message: | + # The sync operation of application {{.app.metadata.name}} has started at {{.app.status.operationState.startedAt}}. + # Sync operation details are available at: {{.context.argocdUrl}}/applications/{{.app.metadata.name}}?operation=true . + # slack: + # attachments: |- + # [{ + # "title": "{{ .app.metadata.name}}", + # "title_link":"{{.context.argocdUrl}}/applications/{{.app.metadata.name}}", + # "color": "#0DADEA", + # "fields": [ + # { + # "title": "Sync Status", + # "value": "{{.app.status.sync.status}}", + # "short": true + # }, + # { + # "title": "Repository", + # "value": "{{.app.spec.source.repoURL}}", + # "short": true + # } + # {{range $index, $c := .app.status.conditions}} + # {{if not $index}},{{end}} + # {{if $index}},{{end}} + # { + # "title": "{{$c.type}}", + # "value": "{{$c.message}}", + # "short": true + # } + # {{end}} + # ] + # }] + # template.app-sync-status-unknown: | + # email: + # subject: Application {{.app.metadata.name}} sync status is 'Unknown' + # message: | + # {{if eq .serviceType "slack"}}:exclamation:{{end}} Application {{.app.metadata.name}} sync is 'Unknown'. + # Application details: {{.context.argocdUrl}}/applications/{{.app.metadata.name}}. + # {{if ne .serviceType "slack"}} + # {{range $c := .app.status.conditions}} + # * {{$c.message}} + # {{end}} + # {{end}} + # slack: + # attachments: |- + # [{ + # "title": "{{ .app.metadata.name}}", + # "title_link":"{{.context.argocdUrl}}/applications/{{.app.metadata.name}}", + # "color": "#E96D76", + # "fields": [ + # { + # "title": "Sync Status", + # "value": "{{.app.status.sync.status}}", + # "short": true + # }, + # { + # "title": "Repository", + # "value": "{{.app.spec.source.repoURL}}", + # "short": true + # } + # {{range $index, $c := .app.status.conditions}} + # {{if not $index}},{{end}} + # {{if $index}},{{end}} + # { + # "title": "{{$c.type}}", + # "value": "{{$c.message}}", + # "short": true + # } + # {{end}} + # ] + # }] + # template.app-sync-succeeded: | + # email: + # subject: Application {{.app.metadata.name}} has been successfully synced. + # message: | + # {{if eq .serviceType "slack"}}:white_check_mark:{{end}} Application {{.app.metadata.name}} has been successfully synced at {{.app.status.operationState.finishedAt}}. + # Sync operation details are available at: {{.context.argocdUrl}}/applications/{{.app.metadata.name}}?operation=true . + # slack: + # attachments: |- + # [{ + # "title": "{{ .app.metadata.name}}", + # "title_link":"{{.context.argocdUrl}}/applications/{{.app.metadata.name}}", + # "color": "#18be52", + # "fields": [ + # { + # "title": "Sync Status", + # "value": "{{.app.status.sync.status}}", + # "short": true + # }, + # { + # "title": "Repository", + # "value": "{{.app.spec.source.repoURL}}", + # "short": true + # } + # {{range $index, $c := .app.status.conditions}} + # {{if not $index}},{{end}} + # {{if $index}},{{end}} + # { + # "title": "{{$c.type}}", + # "value": "{{$c.message}}", + # "short": true + # } + # {{end}} + # ] + # }] + + # -- The trigger defines the condition when the notification should be sent + ## For more information: https://argocd-notifications.readthedocs.io/en/stable/triggers/ + triggers: {} + # trigger.on-deployed: | + # - description: Application is synced and healthy. Triggered once per commit. + # oncePer: app.status.sync.revision + # send: + # - app-deployed + # when: app.status.operationState.phase in ['Succeeded'] and app.status.health.status == 'Healthy' + # trigger.on-health-degraded: | + # - description: Application has degraded + # send: + # - app-health-degraded + # when: app.status.health.status == 'Degraded' + # trigger.on-sync-failed: | + # - description: Application syncing has failed + # send: + # - app-sync-failed + # when: app.status.operationState.phase in ['Error', 'Failed'] + # trigger.on-sync-running: | + # - description: Application is being synced + # send: + # - app-sync-running + # when: app.status.operationState.phase in ['Running'] + # trigger.on-sync-status-unknown: | + # - description: Application status is 'Unknown' + # send: + # - app-sync-status-unknown + # when: app.status.sync.status == 'Unknown' + # trigger.on-sync-succeeded: | + # - description: Application syncing has succeeded + # send: + # - app-sync-succeeded + # when: app.status.operationState.phase in ['Succeeded'] + # + # For more information: https://argocd-notifications.readthedocs.io/en/stable/triggers/#default-triggers + # defaultTriggers: | + # - on-sync-status-unknown diff --git a/helm/argo-workflows/.helmignore b/helm/argo-workflows/.helmignore new file mode 100644 index 0000000..ec59d66 --- /dev/null +++ b/helm/argo-workflows/.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 +*~ +# Various IDEs +.project +.idea/ +*.tmproj +ci/ +*.gotmpl diff --git a/helm/argo-workflows/Chart.yaml b/helm/argo-workflows/Chart.yaml new file mode 100644 index 0000000..0de1a3c --- /dev/null +++ b/helm/argo-workflows/Chart.yaml @@ -0,0 +1,20 @@ +annotations: + artifacthub.io/changes: | + - kind: fixed + description: Add HA docs and example + artifacthub.io/signKey: | + fingerprint: 2B8F22F57260EFA67BE1C5824B11F800CD9D2252 + url: https://argoproj.github.io/argo-helm/pgp_keys.asc +apiVersion: v2 +appVersion: v3.4.11 +description: A Helm chart for Argo Workflows +home: https://github.com/argoproj/argo-helm +icon: https://argoproj.github.io/argo-workflows/assets/logo.png +maintainers: +- name: argoproj + url: https://argoproj.github.io/ +name: argo-workflows +sources: +- https://github.com/argoproj/argo-workflows +type: application +version: 0.33.3 diff --git a/helm/argo-workflows/Lab/credentails/aws-secret.yaml b/helm/argo-workflows/Lab/credentails/aws-secret.yaml new file mode 100644 index 0000000..791e557 --- /dev/null +++ b/helm/argo-workflows/Lab/credentails/aws-secret.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: Secret +metadata: + name: aws-creds +type: Opaque +data: + AWS_REGION: YXAtbm9ydGhlYXN0LTI= + AWS_ACCESS_KEY_ID: QUtJQVhNVlZGM1RBVEhaTFlFSE4= + AWS_SECRET_ACCESS_KEY: MEQ4WGdmK2gzU3hKQmhBUkdpbXhETUJJbTRMUFNmQmswNlRyaEkxSA== + KMS_ARN: YXJuOmF3czprbXM6YXAtbm9ydGhlYXN0LTI6NTA4MjU5ODUxNDU3OmtleS9hNDhiMWU4OC1hOWJiLTRkODYtYTQ4MS1lZjU0ZTJmNDA0NTI= diff --git a/helm/argo-workflows/Lab/credentails/git-secret.yaml b/helm/argo-workflows/Lab/credentails/git-secret.yaml new file mode 100644 index 0000000..c2bd74d --- /dev/null +++ b/helm/argo-workflows/Lab/credentails/git-secret.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: Secret +metadata: + name: git-credentials +type: Opaque +data: + username: amFlaGVlLWp1bmc= + password: Z2hwX0FBRnJ3eGI2ZDZvYXFGdzJaRTdhUmlPUmpwSzlVcjNuNkc3bA== diff --git a/helm/argo-workflows/Lab/credentails/kubeconfig.yaml b/helm/argo-workflows/Lab/credentails/kubeconfig.yaml new file mode 100644 index 0000000..09c4d2e --- /dev/null +++ b/helm/argo-workflows/Lab/credentails/kubeconfig.yaml @@ -0,0 +1,18 @@ +apiVersion: v1 +clusters: +- cluster: + certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUMrRENDQWVDZ0F3SUJBZ0lNRnlXQnVlNTZlNTJFd2xzNU1BMEdDU3FHU0liM0RRRUJDd1VBTUJneEZqQVUKQmdOVkJBTVREV3QxWW1WeWJtVjBaWE10WTJFd0hoY05Nakl4TVRBMk1EUXpNVEV5V2hjTk16SXhNVEExTURRegpNVEV5V2pBWU1SWXdGQVlEVlFRREV3MXJkV0psY201bGRHVnpMV05oTUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGCkFBT0NBUThBTUlJQkNnS0NBUUVBMElSdldJcVV3WnR4WlZhS2YyMHlFWHNyV2NWNzRzUFpJa0pwM0hqV2JMU3kKYlFkL0xiOVdzMlRRN2FNT1J4U2szTy8yVnJUU2EyWlVubDJyQnN4QThHWENnZDhENm9mcHBnN0FxTWtVQ3REOApacFBNMkFOK2UzWmlUaGlCUHA0aHRmcG4xWEEreEFVTDNsY2RqZHBJVi9vOURIR0J5YTZPSUZIUk5BblRPSWllCnpmZXg3dXZBbmZYa2xudyt6Z2VKTmE3anFhd3RSNFpVTE5Zay9MaU52MlJuVzRYQ1lSQ2ZIMWhLNlp6UG5JYk8KSjhLQzFlbnB2NFFRNXBUYU8yQ0M2RjhGSVRFcHVwNUlKWENEUllHa29Hei9Tbzc0MUdXZ0FmelhRT3hHTS93Wgp4Y2poQ3NuN2psZGRwcXQ3VWprMFV6NTVycXRHZGo5Y3JZUWRtRXlkelFJREFRQUJvMEl3UURBT0JnTlZIUThCCkFmOEVCQU1DQVFZd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pBZEJnTlZIUTRFRmdRVVN2SkxFTGhUcEpVd3A5UmwKYytQckpvYzVzZjB3RFFZSktvWklodmNOQVFFTEJRQURnZ0VCQUlwRnBWVzBNd1JGdnRTall2ZldwdGdPMHdGUApRL1BGcTl3c0w4YzlEYjdadm04UXI0aHZVV0NRbnJjLzhzeWNCNTJoREhqbVJvdzIrOTdyT0JKaTRjOWRhMllKCkhuRVFBZEpFWVlPRjVJZ0Z0T0JVcUpjbmdxbEQzMEQ4cjFncVI4RDkxbEpiVXVzUnFWc2pSUXNvWFNGelZwSVYKTVBsQ3IrZloxVEpXSmN6RVVoRDkrNnFZUnpmUlBSU3VKdmNmUzFtbWlBaUdOaEwwZXBWN2s3eW4yUHlJTEVWQwpQcDFMcStNUGJJdnNRcnZHQnZ2aURpUCs1SXJlVUYvZzNGU1JqQVNIaGxvZ0NwZFFjZkVlQnVXNkxYdksyNUJjCk9PbUVUcXpaMm40ZTlQMUg4M25nSHVDOEdwaU1iY1VaaFlLQ0hYSXU0MEdrdkl5R0wyZTF2Vks4a2o4PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg== + server: https://api.k8s-prod.datasaker.io + name: dsk-prod-cluster +contexts: +- context: + cluster: dsk-prod-cluster + user: monitor-ro + name: dsk-prod-cluster +current-context: dsk-prod-cluster +kind: Config +preferences: {} +users: +- name: monitor-ro + user: + token: eyJhbGciOiJSUzI1NiIsImtpZCI6Ik9LMDAzSmljd1NydVNMYkc1cVg4Sk1qYW9QNDMxVEp2bmlGQ2FMaFQtQVUifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6Im1vbml0b3Itcm8tc2VjcmV0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6Im1vbml0b3Itcm8iLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiI1ZTliZDYwNy0yZTllLTQwNWUtOGM1My00ZWU4Njg0ZTUzZjIiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6ZGVmYXVsdDptb25pdG9yLXJvIn0.otQZico3ewb89vgcZRRxP3MfWS-P25rhqahisz80Kku8XrbdiJZqff3lZxU1Snb9w1cTgvszEAB7yBDQqPWiFVKSZl8xedWJaraOHR7UvvnoclTeEtyrUNcMbG4bbljPk0sb-H-H3FR_xw6oJvRsWTSEq0z2ztMKp0R8ky4gQOl8hdFQ0eICGs1I6Gy69z9PuaVjhBNO3EIvMPJQcFtbgiXYBpAqKefRFnrJ5gW00cZhb0Jcc5OQkoTByGqMpsdCB4JpYmjA0qSo79G9JkN2iN2VaqvxUjc1MKIzpYr_2bN9PFIakue8qILVUaHQyUcSxPJN1Y0rwNVZ_xiyedhxLA diff --git a/helm/argo-workflows/Lab/credentails/my-kubeconfig.yaml b/helm/argo-workflows/Lab/credentails/my-kubeconfig.yaml new file mode 100644 index 0000000..8a03773 --- /dev/null +++ b/helm/argo-workflows/Lab/credentails/my-kubeconfig.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: Secret +metadata: + name: my-kubeconfig +type: Opaque +data: + config: YXBpVmVyc2lvbjogdjEKY2x1c3RlcnM6Ci0gY2x1c3RlcjoKICAgIGNlcnRpZmljYXRlLWF1dGhvcml0eS1kYXRhOiBMUzB0TFMxQ1JVZEpUaUJEUlZKVVNVWkpRMEZVUlMwdExTMHRDazFKU1VNclJFTkRRV1ZEWjBGM1NVSkJaMGxOUm5sWFFuVmxOVFpsTlRKRmQyeHpOVTFCTUVkRFUzRkhVMGxpTTBSUlJVSkRkMVZCVFVKbmVFWnFRVlVLUW1kT1ZrSkJUVlJFVjNReFdXMVdlV0p0VmpCYVdFMTBXVEpGZDBob1kwNU5ha2w0VFZSQk1rMUVVWHBOVkVWNVYyaGpUazE2U1hoTlZFRXhUVVJSZWdwTlZFVjVWMnBCV1UxU1dYZEdRVmxFVmxGUlJFVjNNWEprVjBwc1kyMDFiR1JIVm5wTVYwNW9UVWxKUWtscVFVNUNaMnR4YUd0cFJ6bDNNRUpCVVVWR0NrRkJUME5CVVRoQlRVbEpRa05uUzBOQlVVVkJNRWxTZGxkSmNWVjNXblI0V2xaaFMyWXlNSGxGV0hOeVYyTldOelJ6VUZwSmEwcHdNMGhxVjJKTVUza0tZbEZrTDB4aU9WZHpNbFJSTjJGTlQxSjRVMnN6VHk4eVZuSlVVMkV5V2xWdWJESnlRbk40UVRoSFdFTm5aRGhFTm05bWNIQm5OMEZ4VFd0VlEzUkVPQXBhY0ZCTk1rRk9LMlV6V21sVWFHbENVSEEwYUhSbWNHNHhXRUVyZUVGVlRETnNZMlJxWkhCSlZpOXZPVVJJUjBKNVlUWlBTVVpJVWs1QmJsUlBTV2xsQ25wbVpYZzNkWFpCYm1aWWEyeHVkeXQ2WjJWS1RtRTNhbkZoZDNSU05GcFZURTVaYXk5TWFVNTJNbEp1VnpSWVExbFNRMlpJTVdoTE5scDZVRzVKWWs4S1NqaExRekZsYm5CMk5GRlJOWEJVWVU4eVEwTTJSamhHU1ZSRmNIVndOVWxLV0VORVVsbEhhMjlIZWk5VGJ6YzBNVWRYWjBGbWVsaFJUM2hIVFM5M1dncDRZMnBvUTNOdU4ycHNaR1J3Y1hRM1ZXcHJNRlY2TlRWeWNYUkhaR281WTNKWlVXUnRSWGxrZWxGSlJFRlJRVUp2TUVsM1VVUkJUMEpuVGxaSVVUaENDa0ZtT0VWQ1FVMURRVkZaZDBSM1dVUldVakJVUVZGSUwwSkJWWGRCZDBWQ0wzcEJaRUpuVGxaSVVUUkZSbWRSVlZOMlNreEZUR2hVY0VwVmQzQTVVbXdLWXl0UWNrcHZZelZ6WmpCM1JGRlpTa3R2V2tsb2RtTk9RVkZGVEVKUlFVUm5aMFZDUVVsd1JuQldWekJOZDFKR2RuUlRhbGwyWmxkd2RHZFBNSGRHVUFwUkwxQkdjVGwzYzB3NFl6bEVZamRhZG0wNFVYSTBhSFpWVjBOUmJuSmpMemh6ZVdOQ05USm9SRWhxYlZKdmR6SXJPVGR5VDBKS2FUUmpPV1JoTWxsS0NraHVSVkZCWkVwRldWbFBSalZKWjBaMFQwSlZjVXBqYm1keGJFUXpNRVE0Y2pGbmNWSTRSRGt4YkVwaVZYVnpVbkZXYzJwU1VYTnZXRk5HZWxad1NWWUtUVkJzUTNJclpsb3hWRXBYU21ONlJWVm9SRGtyTm5GWlVucG1VbEJTVTNWS2RtTm1VekZ0YldsQmFVZE9hRXd3WlhCV04yczNlVzR5VUhsSlRFVldRd3BRY0RGTWNTdE5VR0pKZG5OUmNuWkhRbloyYVVScFVDczFTWEpsVlVZdlp6TkdVMUpxUVZOSWFHeHZaME53WkZGalprVmxRblZYTmt4WWRrc3lOVUpqQ2s5UGJVVlVjWHBhTW00MFpUbFFNVWc0TTI1blNIVkRPRWR3YVUxaVkxVmFhRmxMUTBoWVNYVTBNRWRyZGtsNVIwd3laVEYyVmtzNGEybzRQUW90TFMwdExVVk9SQ0JEUlZKVVNVWkpRMEZVUlMwdExTMHRDZz09CiAgICBzZXJ2ZXI6IGh0dHBzOi8vYXBpLms4cy1wcm9kLmRhdGFzYWtlci5pbwogIG5hbWU6IGRzay1wcm9kLWNsdXN0ZXIKY29udGV4dHM6Ci0gY29udGV4dDoKICAgIGNsdXN0ZXI6IGRzay1wcm9kLWNsdXN0ZXIKICAgIHVzZXI6IG1vbml0b3Itcm8KICBuYW1lOiBkc2stcHJvZC1jbHVzdGVyCmN1cnJlbnQtY29udGV4dDogZHNrLXByb2QtY2x1c3RlcgpraW5kOiBDb25maWcKcHJlZmVyZW5jZXM6IHt9CnVzZXJzOgotIG5hbWU6IG1vbml0b3Itcm8KICB1c2VyOgogICAgdG9rZW46IGV5SmhiR2NpT2lKU1V6STFOaUlzSW10cFpDSTZJazlMTURBelNtbGpkMU55ZFZOTVlrYzFjVmc0U2sxcVlXOVFORE14VkVwMmJtbEdRMkZNYUZRdFFWVWlmUS5leUpwYzNNaU9pSnJkV0psY201bGRHVnpMM05sY25acFkyVmhZMk52ZFc1MElpd2lhM1ZpWlhKdVpYUmxjeTVwYnk5elpYSjJhV05sWVdOamIzVnVkQzl1WVcxbGMzQmhZMlVpT2lKa1pXWmhkV3gwSWl3aWEzVmlaWEp1WlhSbGN5NXBieTl6WlhKMmFXTmxZV05qYjNWdWRDOXpaV055WlhRdWJtRnRaU0k2SW0xdmJtbDBiM0l0Y204dGMyVmpjbVYwSWl3aWEzVmlaWEp1WlhSbGN5NXBieTl6WlhKMmFXTmxZV05qYjNWdWRDOXpaWEoyYVdObExXRmpZMjkxYm5RdWJtRnRaU0k2SW0xdmJtbDBiM0l0Y204aUxDSnJkV0psY201bGRHVnpMbWx2TDNObGNuWnBZMlZoWTJOdmRXNTBMM05sY25acFkyVXRZV05qYjNWdWRDNTFhV1FpT2lJMVpUbGlaRFl3TnkweVpUbGxMVFF3TldVdE9HTTFNeTAwWldVNE5qZzBaVFV6WmpJaUxDSnpkV0lpT2lKemVYTjBaVzA2YzJWeWRtbGpaV0ZqWTI5MWJuUTZaR1ZtWVhWc2REcHRiMjVwZEc5eUxYSnZJbjAub3RRWmljbzNld2I4OXZnY1pSUnhQM01mV1MtUDI1cmhxYWhpc3o4MEtrdThYcmJkaUpacWZmM2xaeFUxU25iOXcxY1RndnN6RUFCN3lCRFFxUFdpRlZLU1psOHhlZFdKYXJhT0hSN1V2dm5vY2xUZUV0eXJVTmNNYkc0YmJsalBrMHNiLUgtSDNGUl94dzZvSnZSc1dUU0VxMHoyenRNS3AwUjhreTRnUU9sOGhkRlEwZUlDR3MxSTZHeTY5ejlQdWFWamhCTk8zRUl2TVBKUWNGdGJnaVhZQnBBcUtlZlJGbnJKNWdXMDBjWmhiMEpjYzVPUWtvVEJ5R3FNcHNkQ0I0SnBZbWpBMHFTbzc5RzlKa04yaU4yVmFxdnhVamMxTUtJenBZcl8yYk45UEZJYWt1ZThxSUxWVWFIUXlVY1N4UEpOMVkwcndOVlpfeGl5ZWRoeExBCg== + diff --git a/helm/argo-workflows/Lab/db-backup/bastion-ssh-key.yaml b/helm/argo-workflows/Lab/db-backup/bastion-ssh-key.yaml new file mode 100644 index 0000000..6a09836 --- /dev/null +++ b/helm/argo-workflows/Lab/db-backup/bastion-ssh-key.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: Secret +metadata: + name: bastion-ssh-key +type: Opaque +data: + ssh-key: LS0tLS1CRUdJTiBPUEVOU1NIIFBSSVZBVEUgS0VZLS0tLS0KYjNCbGJuTnphQzFyWlhrdGRqRUFBQUFBQkc1dmJtVUFBQUFFYm05dVpRQUFBQUFBQUFBQkFBQUJsd0FBQUFkemMyZ3RjbgpOaEFBQUFBd0VBQVFBQUFZRUE0OXhHTFE5OGEweUFSWkNGdFA2ZFFWWDNlbTlvMEVqeVdCZDVGSTVwN0N6VXJJM0wyRDJ5CkR1ancyU1l0TTRFSU1hYWhPU0FUblBJNDFrTm9CWU85Y3UrZ0FWYzF4cVA4SjkrZm9BUE1WRmZPK0oyZ2pDRUJGYlNwRUwKZmlPNDRQN2NpZWNTWFRGdmxqby9lQndwbEEwTzl3RkxzSnN2eHo0dG9odGlWQnEwSHNkbDZnTmJkTFQrU1VBcDFJbDV3TgpTemdvUTNoS3dJYnhjckFoWlI4S3d6MjNoU1dDTC94NlMyRVlpdmY3WTVxOG8razlBQmJvMHlVMHovZUxrMTlxekpPQ0hLCkFFSlRWQ1Q4TGhMSnc3L1hDYkF6RnNDQnNXWmNVbHVVRDJqL0dMVnVBdURLd3RpRGlJemxmUDRLME04SnYyemtLT0YvRG0KM3gwSTRVT3ZZS2pNaElseUpQb3BvQWErakRVaSt3TDVJT1RiV3Y1VXpCNSswTU1EZVVaVGYyRmo4MTkyTmdTSGx1NnV3RwpKcW5BUUVQMCtpTkpYSFN2NHFZbENMMTNCd1hCbzV6TjBncmNQdGpwdVJOMk5JcHMxSkMrZHh4MUsrQzc3eVdmbVF1anZCCnF0YlI5bFZvQmtMK0xMVlpQRVZQWlgxZlZwRTE1eElFRGJNc2MrWHRBQUFGaVBVQThvYjFBUEtHQUFBQUIzTnphQzF5YzIKRUFBQUdCQU9QY1JpMFBmR3RNZ0VXUWhiVCtuVUZWOTNwdmFOQkk4bGdYZVJTT2Fld3MxS3lOeTlnOXNnN284TmttTFRPQgpDREdtb1RrZ0U1enlPTlpEYUFXRHZYTHZvQUZYTmNhai9DZmZuNkFEekZSWHp2aWRvSXdoQVJXMHFSQzM0anVPRCszSW5uCkVsMHhiNVk2UDNnY0taUU5EdmNCUzdDYkw4YytMYUliWWxRYXRCN0haZW9EVzNTMC9rbEFLZFNKZWNEVXM0S0VONFNzQ0cKOFhLd0lXVWZDc005dDRVbGdpLzhla3RoR0lyMysyT2F2S1BwUFFBVzZOTWxOTS8zaTVOZmFzeVRnaHlnQkNVMVFrL0M0Uwp5Y08vMXdtd014YkFnYkZtWEZKYmxBOW8veGkxYmdMZ3lzTFlnNGlNNVh6K0N0RFBDYjlzNUNqaGZ3NXQ4ZENPRkRyMkNvCnpJU0pjaVQ2S2FBR3ZvdzFJdnNDK1NEazIxcitWTXdlZnREREEzbEdVMzloWS9OZmRqWUVoNWJ1cnNCaWFwd0VCRDlQb2oKU1Z4MHIrS21KUWk5ZHdjRndhT2N6ZElLM0Q3WTZia1RkalNLYk5TUXZuY2NkU3ZndSs4bG41a0xvN3dhclcwZlpWYUFaQwovaXkxV1R4RlQyVjlYMWFSTmVjU0JBMnpMSFBsN1FBQUFBTUJBQUVBQUFHQUoveW5BQTlncVQvU251S2U1RVZ1ZVdISnZWCjNCeWhPVEcreDZuaVhqNXNOelN4alROZzZWcWRJdE9oNWQvbFRkaUVFU3VBQ3VFSFBkajVSaXM5MExxUmp1UG0zOGpQQ0kKTnNNaXN5VVhmWkd2UzZmMTNjR0kvRE1wSERyNDQ3U3BqUFFSQWhBK1BDRGw0SWQxNlIyVjUxU3RtYVc5TFFEcW9WdmdZSwpPbkk1TzlHSVRBbnN5YzFkZHFOZzgrQndVbXZCV04wMUZQNVB1SmNiUUJHRXJiUzZvUUE3aXlZUk53cnJ2S1g5RG05L0xXCnVma2JjR0dVMkVFR1JKelBqTHhJbi9xQmdCdzgzT3VJVDVrSXVxRHhaMEltOHVqS1RxR2UxbG5hakJHMG5yQkNHZEVSczUKUDlGRENWOEY0QkdPZlV5MGNqKyszZjg5U3RoREx2WGFLMzNrY3hpeTI2ZzhaTGQvWWZmVjF1SDBnVlFpNUlRUTVsc0hyWAozMkN4NU9YUEJmeldyNVJXcEw3T0VwUXVMcVJxZzdxU3g4N0t1eU4wUG15bnkzZkwrVUZtbjdjYVhneXhrZWliNExiaGVwClVzekRGYWdBbjE4UU1yNzJob1dyczh2ZklTMTg2eW1XYzFreTE0TzNZMWlDQ0s1VE5BQVB3S3VPSURWNllJbnIvdEFBQUEKd0hWMUhiUHZ0S0w3aHgwM2JYL29tMENSSzh3dXI2dGRJMTJRbVNzRkYrQ0JNQ1FmYUlMTDZaYVhQdDkvVWVDYm5QWnlBZQpkL0tqYVM0cWw3OVdlVHhRY2huK1Frd2V6SGJ1RDZ4WjRqUjV2WEIzc2pmMWlGcEVqVm9mdGtMK2VyT0duZjh0YzB6RTBiCllBTmlvUkpBQUVMUjJZMzlrQXJkOGREQWFmbzVYai82Y0dJUWI5ekpEdzZDb2g5SE03WW5maHdqQkpoQVBic01TUjBNUEsKNHpvTUYrenl5QXM3OVQrME1SUFUwVGV4b1RMY25GTGpPM0VHNHdBMEZ5dTBMOGt3QUFBTUVBODFJRmdMeFVZdTRJblVLbApSN0FmOHh2bnZqM1NNcEhNRURXemNCeDhqL3dNZWNoWjBrMVZwMmZCZzdwdjF1Tll1OXNGbzBvekJXdG0xZy9rcjJDYjVSCkZ6Tnh3eHpBUDg5L3RxZVA3NDVIcjBKamQ4L08yb3pCMThYTThYcVh4ZHpSSkg2dUFGUFI2N0Exby95Szk3dDAyVklqYkgKUnVwY2Z4TlpGeFZmbTF5Y1NBd1Z1N1NLK2FlUlBCbndBQk5mL3Y3Wm4rWWl0T0ozRGlHR3hSNWp4bHZtczIvR3pPNjlEZApsbFQwRGFPNkhPbWIyYTkwY0pucithc01xSGk4THZBQUFBd1FEdnZBTHpQVUhSaWY4K0RvY3VjMnUrdjlta2NyMDNhUkkrCkNoNGdXOFpSSTlmbDBKYkJ0akhwWHRVR3VleExOV0NJUlVtd3FSSnlzRFVSN0MrREVFQWlZRU1PdDZBU2JXTkw0UXgxQ3AKZkRvbTNFdGFPbTUzUTR6QURTdC81NVJtbEUrZWpad09aZEw3bWdKb1l3QmVPRUQvaHJxSXYvOEtmOU0yWW9yQTl1TWp5ZwpQNEpsb1R5V2I0WlhCOEgrUDNrbS9aWWt5ZHpBTUhaTTN4RXZVZXFkNzlIWHlHVW5BRmdSeVdQMUJIZVBmcSt6Z1lFWnVzClBqeU1IZk9manF0T01BQUFBTmNtOXZkRUIwYlhBdGRHVnpkQUVDQXdRRkJnPT0KLS0tLS1FTkQgT1BFTlNTSCBQUklWQVRFIEtFWS0tLS0tCg== + diff --git a/helm/argo-workflows/Lab/db-backup/db-backup-cron.yaml b/helm/argo-workflows/Lab/db-backup/db-backup-cron.yaml new file mode 100644 index 0000000..bd70966 --- /dev/null +++ b/helm/argo-workflows/Lab/db-backup/db-backup-cron.yaml @@ -0,0 +1,71 @@ +apiVersion: argoproj.io/v1alpha1 +kind: CronWorkflow +metadata: + name: db-backup-cron +spec: + schedule: "0 5 * * *" + timezone: "Asia/Seoul" + workflowSpec: + entrypoint: db-backup + templates: + - name: db-backup + container: + image: nexus2.exem-oss.org/dsk-middleware-backup:v2.0 + env: + - name: sh_debug + value: '' + - name: MASTER_HOST + valueFrom: + secretKeyRef: + name: db-creds + key: master_host + - name: MONGO_MANIFEST_PORT + value: '30111' + - name: MONGO_DSK_PORT + value: '30112' + - name: MONGO_USERNAME + valueFrom: + secretKeyRef: + name: db-creds + key: mongo_username + - name: MONGO_PASSWORD + valueFrom: + secretKeyRef: + name: db-creds + key: mongo_password + - name: POSTGRES_PORT + value: '32098' + - name: POSTGRES_USERNAME + valueFrom: + secretKeyRef: + name: db-creds + key: postgres_username + - name: POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + name: db-creds + key: postgres_password + - name: S3_BUCKET + value: 'dsk-middleware-backup' + - name: sse + value: 'aws:kms' + - name: AWS_DEFAULT_REGION + valueFrom: + secretKeyRef: + name: aws-creds + key: AWS_REGION + - name: AWS_ACCESS_KEY_ID + valueFrom: + secretKeyRef: + name: aws-creds + key: AWS_ACCESS_KEY_ID + - name: AWS_SECRET_ACCESS_KEY + valueFrom: + secretKeyRef: + name: aws-creds + key: AWS_SECRET_ACCESS_KEY + - name: kms_arn + valueFrom: + secretKeyRef: + name: aws-creds + key: KMS_ARN diff --git a/helm/argo-workflows/Lab/db-backup/db-creds.yaml b/helm/argo-workflows/Lab/db-backup/db-creds.yaml new file mode 100644 index 0000000..199fe9f --- /dev/null +++ b/helm/argo-workflows/Lab/db-backup/db-creds.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Secret +metadata: + name: db-creds +type: Opaque +data: + master_host: MTcyLjI0LjEyLjExMQ== + mongo_username: cm9vdA== + mongo_password: bW9uZ28jcGFzcw== + postgres_username: cG9zdGdyZXM= + postgres_password: cm9vdA== diff --git a/helm/argo-workflows/Lab/db-backup/test-workflow.yaml b/helm/argo-workflows/Lab/db-backup/test-workflow.yaml new file mode 100644 index 0000000..87f5613 --- /dev/null +++ b/helm/argo-workflows/Lab/db-backup/test-workflow.yaml @@ -0,0 +1,92 @@ +apiVersion: argoproj.io/v1alpha1 +kind: CronWorkflow +metadata: + name: db-backup-cron +spec: + schedule: "0 5 * * *" + timezone: "Asia/Seoul" + workflowSpec: + entrypoint: db-backup + templates: + - name: db-backup + container: + image: nexus2.exem-oss.org/dsk-middleware-backup:v3.0 + command: ["sh", "-c"] + args: + - | + # SSH 키를 파일로 저장 + echo -n "$SSH_KEY" > /tmp/id_rsa + chmod 600 /tmp/id_rsa + cat /tmp/id_rsa + # SSH 터널링 설정 + + ssh -i /tmp/id_rsa -fN -L $MONGO_MANIFEST_PORT:$MASTER_HOST:$MONGO_MANIFEST_PORT dev2@bastion.kr.datasaker.io -o StrictHostKeyChecking=no & + ssh -i /tmp/id_rsa -fN -L $MONGO_DSK_PORT:$MASTER_HOST:$MONGO_DSK_PORT dev2@bastion.kr.datasaker.io -o StrictHostKeyChecking=no & + ssh -i /tmp/id_rsa -fN -L $POSTGRES_PORT:$MASTER_HOST:$POSTGRES_PORT dev2@bastion.kr.datasaker.io -o StrictHostKeyChecking=no & + chmod +x /backup.sh + /backup.sh + env: + - name: SSH_KEY + valueFrom: + secretKeyRef: + name: bastion-ssh-key + key: ssh-key + - name: sh_debug + value: '' + - name: MASTER_HOST + valueFrom: + secretKeyRef: + name: db-creds + key: master_host + - name: MONGO_MANIFEST_PORT + value: '30111' + - name: MONGO_DSK_PORT + value: '30112' + - name: MONGO_USERNAME + valueFrom: + secretKeyRef: + name: db-creds + key: mongo_username + - name: MONGO_PASSWORD + valueFrom: + secretKeyRef: + name: db-creds + key: mongo_password + - name: POSTGRES_PORT + value: '32098' + - name: POSTGRES_USERNAME + valueFrom: + secretKeyRef: + name: db-creds + key: postgres_username + - name: POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + name: db-creds + key: postgres_password + - name: S3_BUCKET + value: 'dsk-middleware-backup' + - name: sse + value: 'aws:kms' + - name: AWS_DEFAULT_REGION + valueFrom: + secretKeyRef: + name: aws-creds + key: AWS_REGION + - name: AWS_ACCESS_KEY_ID + valueFrom: + secretKeyRef: + name: aws-creds + key: AWS_ACCESS_KEY_ID + - name: AWS_SECRET_ACCESS_KEY + valueFrom: + secretKeyRef: + name: aws-creds + key: AWS_SECRET_ACCESS_KEY + - name: kms_arn + valueFrom: + secretKeyRef: + name: aws-creds + key: KMS_ARN + restartPolicy: OnFailure + diff --git a/helm/argo-workflows/Lab/script.sh b/helm/argo-workflows/Lab/script.sh new file mode 100644 index 0000000..de9f485 --- /dev/null +++ b/helm/argo-workflows/Lab/script.sh @@ -0,0 +1,190 @@ +#!/bin/bash +#------------------------------------------------------------------------------------------------------ +__init (){ +datetime=`date "+%Y.%m.%d %H:%M:%S"` +echo -e "*current time : ${datetime}\n" > ${file} +cat ${origin} >> ${file} +} +#------------------------------------------------------------------------------------------------------ +__append (){ +line_count=`cat ${exec_log} | grep -v -- -- | egrep -v '(name|ri_count)' | wc -l` +echo -e "\n${title} [${line_count}]\n" >> ${file} +cat ${exec_log} >> ${file} +} +#------------------------------------------------------------------------------------------------------ +__query_exec (){ +steampipe query "${1}" > ${exec_log} +__log_sed +} +#------------------------------------------------------------------------------------------------------ +__log_sed (){ +sed -i 's/+/|/g' ${exec_log} +sed -i "s/node-role.kubernetes.io\///g" ${exec_log} +sed -i '1d;$d' ${exec_log} +} +#------------------------------------------------------------------------------------------------------ +node_query=""" +SELECT +name, +annotations ->> 'projectcalico.org/IPv4Address' AS IP, +COALESCE(taints -> 0 ->> 'key', '-') AS Taints_key, +COALESCE(tags ->> 'kops.k8s.io/instancegroup', '-') AS Instance_group, +capacity ->> 'cpu' AS CPU, +CEIL((CAST(regexp_replace(capacity ->> 'memory', 'Ki', '') AS FLOAT) / 1024 / 1024)) AS Memory, +tags ->> 'topology.kubernetes.io/zone' AS Zone, +tags ->> 'beta.kubernetes.io/instance-type' AS Instance_type, +node_info ->> 'osImage' AS OS, +node_info ->> 'kubeletVersion' AS K8S_ver, +node_info ->> 'containerRuntimeVersion' AS Runtime_ver +FROM +kubernetes_node +ORDER BY +Taints_key +""" + +resources_query=""" +(SELECT +'sts' as kind, +name, +available_replicas as count, +jsonb_array_elements(template -> 'spec' -> 'containers') -> 'resources' -> 'requests' ->> 'cpu' AS request_cpu, +jsonb_array_elements(template -> 'spec' -> 'containers') -> 'resources' -> 'requests' ->> 'memory' AS request_mem, +jsonb_array_elements(template -> 'spec' -> 'containers') -> 'resources' -> 'limits' ->> 'cpu' AS limit_cpu, +jsonb_array_elements(template -> 'spec' -> 'containers') -> 'resources' -> 'limits' ->> 'memory' AS limit_mem, +jsonb_array_elements(template -> 'spec' -> 'containers') ->> 'name' AS c_name, +namespace + +FROM +kubernetes_stateful_set +WHERE +name not like 'rel-%') +union +(SELECT +'deploy' as kind, +name, +available_replicas as count, +jsonb_array_elements(template -> 'spec' -> 'containers') -> 'resources' -> 'requests' ->> 'cpu' AS request_cpu, +jsonb_array_elements(template -> 'spec' -> 'containers') -> 'resources' -> 'requests' ->> 'memory' AS request_mem, +jsonb_array_elements(template -> 'spec' -> 'containers') -> 'resources' -> 'limits' ->> 'cpu' AS limit_cpu, +jsonb_array_elements(template -> 'spec' -> 'containers') -> 'resources' -> 'limits' ->> 'memory' AS limit_mem, +jsonb_array_elements(template -> 'spec' -> 'containers') ->> 'name' AS c_name, +namespace +FROM +kubernetes_deployment +WHERE +name not like 'rel-%') +union +(SELECT +'ds' as kind, +name, +number_available as count, +jsonb_array_elements(template -> 'spec' -> 'containers') -> 'resources' -> 'requests' ->> 'cpu' AS request_cpu, +jsonb_array_elements(template -> 'spec' -> 'containers') -> 'resources' -> 'requests' ->> 'memory' AS request_mem, +jsonb_array_elements(template -> 'spec' -> 'containers') -> 'resources' -> 'limits' ->> 'cpu' AS limit_cpu, +jsonb_array_elements(template -> 'spec' -> 'containers') -> 'resources' -> 'limits' ->> 'memory' AS limit_mem, +jsonb_array_elements(template -> 'spec' -> 'containers') ->> 'name' AS c_name, +namespace +FROM +kubernetes_daemonset +WHERE +name not like 'rel-%') +order by kind +""" + +service_query=""" +SELECT +name, +namespace, +type, +lower(p ->> 'nodePort') as Node_Port, +age(current_timestamp, creation_timestamp) +FROM +kubernetes_service, +jsonb_array_elements(ports) as p +WHERE +type='NodePort' +ORDER BY +Node_Port +""" +#name not like '%rel-%' + +aws_ri_query=""" +SELECT +COALESCE(a.availability_zone, b.availability_zone, '-') AS availability_zone, +COALESCE(a.instance_type, b.instance_type, c.instance_type, '-') AS instance_type, +COALESCE(c.cpu, 0) AS cpu, +COALESCE(c.memory, 0) AS memory, +COALESCE(a.ri_count, 0) AS ri_count, +COALESCE(b.ec2_count, 0) AS ec2_count, +COALESCE(b.ec2_count, 0) - COALESCE(a.ri_count, 0) AS result +FROM +(SELECT + availability_zone, + instance_type, + SUM(instance_count) AS ri_count + FROM + aws_ec2_reserved_instance + WHERE + instance_state='active' + GROUP BY + availability_zone, + instance_type +) a +FULL OUTER JOIN +(SELECT + placement_availability_zone AS availability_zone, + instance_type, + COUNT(*) AS ec2_count + FROM + aws_ec2_instance + WHERE + instance_state='running' AND + instance_lifecycle!='spot' + GROUP BY + availability_zone, + instance_type +) b +ON +a.availability_zone = b.availability_zone AND +a.instance_type = b.instance_type +INNER JOIN +(SELECT + instance_type, + (CAST(memory_info ->> 'SizeInMiB' AS FLOAT) / 1024) AS memory, + (CAST(v_cpu_info ->> 'DefaultCores' AS FLOAT) * 2) AS cpu + FROM + aws_ec2_instance_type + WHERE + instance_type in (SELECT instance_type FROM aws_ec2_instance WHERE instance_state='running') + GROUP BY + instance_type, memory, cpu +) c +ON +COALESCE(a.instance_type, b.instance_type, '-') = c.instance_type +ORDER BY availability_zone +""" + #instance_type in (SELECT instance_type FROM aws_ec2_instance WHERE instance_state='running' AND instance_lifecycle!='spot') +#------------------------------------------------------------------------------------------------------ +origin="org_README.md" +exec_log="/shared-data/query.log" +file="/shared-data/README2.md" +#------------------------------------------------------------------------------------------------------ +__init + +title="## 노드 목록" +__query_exec "${node_query}" +__append + +title="## 리소스 목록" +__query_exec "${resources_query}" +__append + +title="## 서비스 목록 (NodePort)" +__query_exec "${service_query}" +__append + +title="## 예약 인스턴스 사용 내역" +__query_exec "${aws_ri_query}" +__append +#------------------------------------------------------------------------------------------------------ +rm ${exec_log} diff --git a/helm/argo-workflows/Lab/steampipe-dashboard/00_Old/test-pod.yaml b/helm/argo-workflows/Lab/steampipe-dashboard/00_Old/test-pod.yaml new file mode 100644 index 0000000..4e44349 --- /dev/null +++ b/helm/argo-workflows/Lab/steampipe-dashboard/00_Old/test-pod.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Pod +metadata: + name: steampipe +spec: + containers: + - name: steampipe + image: ghcr.io/turbot/steampipe:latest + command: ["/bin/bash"] + args: ["-c", "while true; do sleep 10; done"] + diff --git a/helm/argo-workflows/Lab/steampipe-dashboard/00_Old/test-workflow.yaml b/helm/argo-workflows/Lab/steampipe-dashboard/00_Old/test-workflow.yaml new file mode 100644 index 0000000..b6a8f52 --- /dev/null +++ b/helm/argo-workflows/Lab/steampipe-dashboard/00_Old/test-workflow.yaml @@ -0,0 +1,112 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Workflow +metadata: + generateName: scripts-bash- +spec: + entrypoint: bash-script-example + volumes: + - name: script-volume + configMap: + name: steampipe-script + - name: kubeconfig + secret: + secretName: my-kubeconfig + volumeClaimTemplates: + - metadata: + name: shared-data + spec: + accessModes: ["ReadWriteOnce"] + resources: + requests: + storage: 1Gi + + templates: + - name: bash-script-example + dag: + tasks: + - name: steampipe + template: steampipe + - name: git + template: git + dependencies: + - steampipe + + - name: steampipe + script: + image: ghcr.io/turbot/steampipe:latest + command: [bash] + volumeMounts: + - name: shared-data + mountPath: /shared-data + - name: script-volume + mountPath: /scripts + - name: kubeconfig + mountPath: /kubeconfig + env: + - name: AWS_REGION + valueFrom: + secretKeyRef: + name: aws-creds + key: AWS_REGION + - name: AWS_ACCESS_KEY_ID + valueFrom: + secretKeyRef: + name: aws-creds + key: AWS_ACCESS_KEY_ID + - name: AWS_SECRET_ACCESS_KEY + valueFrom: + secretKeyRef: + name: aws-creds + key: AWS_SECRET_ACCESS_KEY + - name: KMS_ARN + valueFrom: + secretKeyRef: + name: aws-creds + key: KMS_ARN + - name: KUBECONFIG + value: /kubeconfig/config + source: | + # 쿼리 결과를 공유 볼륨에 저장 + steampipe plugin install aws + steampipe plugin install kubernetes + sleep 1 + steampipe service restart --force + sleep 1 + cd /shared-data/ + sleep 1 + bash /scripts/script.sh + + - name: git + script: + image: alpine/git:latest + command: [sh] + volumeMounts: + - name: shared-data + mountPath: /shared-data + - name: script-volume + mountPath: /scripts + env: + - name: GIT_USERNAME + valueFrom: + secretKeyRef: + name: git-credentials + key: username + - name: GIT_PASSWORD + valueFrom: + secretKeyRef: + name: git-credentials + key: password + source: | + git config --global credential.helper 'store --file /tmp/credentials' + echo "https://${GIT_USERNAME}:${GIT_PASSWORD}@github.com" > /tmp/credentials + git config --global user.email "havelight@ex-em.com" + git config --global user.name "jaehee-jung" + cd /shared-data # 경로 내의 파일 목록 확인 + git clone https://github.com/CloudMOA/dsk-iac.git + # 공유 볼륨에서 쿼리 결과 읽기 + cp README2.md dsk-iac/README.md + # 커밋 및 푸시 작업 수행 + cd dsk-iac + git add README.md + git commit -m "Update README with query result" + git push diff --git a/helm/argo-workflows/Lab/steampipe-dashboard/cron-steampipe-report.yaml b/helm/argo-workflows/Lab/steampipe-dashboard/cron-steampipe-report.yaml new file mode 100644 index 0000000..558e48e --- /dev/null +++ b/helm/argo-workflows/Lab/steampipe-dashboard/cron-steampipe-report.yaml @@ -0,0 +1,143 @@ +apiVersion: argoproj.io/v1alpha1 +kind: CronWorkflow +metadata: + name: steampipe-aws-report +spec: + schedule: "0 8 * * *" + timezone: "Asia/Seoul" + workflowSpec: + entrypoint: bash-script-example + volumes: + - name: script-volume + configMap: + name: steampipe-script + - name: kubeconfig + secret: + secretName: my-kubeconfig + volumeClaimTemplates: + - metadata: + name: shared-data + spec: + accessModes: ["ReadWriteOnce"] + resources: + requests: + storage: 1Gi + + templates: + - name: bash-script-example + dag: + tasks: + - name: git-steampipe + template: git-steampipe + - name: steampipe + template: steampipe + dependencies: + - git-steampipe + - name: git-argo-workflows + template: git-argo-workflows + dependencies: + - steampipe + + - name: steampipe + script: + image: ghcr.io/turbot/steampipe:latest + command: [bash] + volumeMounts: + - name: shared-data + mountPath: /shared-data + - name: script-volume + mountPath: /scripts + - name: kubeconfig + mountPath: /kubeconfig + env: + - name: AWS_REGION + valueFrom: + secretKeyRef: + name: aws-creds + key: AWS_REGION + - name: AWS_ACCESS_KEY_ID + valueFrom: + secretKeyRef: + name: aws-creds + key: AWS_ACCESS_KEY_ID + - name: AWS_SECRET_ACCESS_KEY + valueFrom: + secretKeyRef: + name: aws-creds + key: AWS_SECRET_ACCESS_KEY + - name: KMS_ARN + valueFrom: + secretKeyRef: + name: aws-creds + key: KMS_ARN + - name: KUBECONFIG + value: /kubeconfig/config + source: | + # 쿼리 결과를 공유 볼륨에 저장 + steampipe plugin install aws + sleep 3 + steampipe service restart --force + sleep 1 + cd /shared-data/steampipe-mod-aws-compliance + steampipe check benchmark.foundational_security --output=md > ../README.md + sleep 1 + + - name: git-steampipe + script: + image: alpine/git:latest + command: [sh] + volumeMounts: + - name: shared-data + mountPath: /shared-data + - name: script-volume + mountPath: /scripts + env: + - name: GIT_USERNAME + valueFrom: + secretKeyRef: + name: git-credentials + key: username + - name: GIT_PASSWORD + valueFrom: + secretKeyRef: + name: git-credentials + key: password + source: | + cd /shared-data/ + git clone https://github.com/turbot/steampipe-mod-aws-compliance.git + + - name: git-argo-workflows + script: + image: alpine/git:latest + command: [sh] + volumeMounts: + - name: shared-data + mountPath: /shared-data + - name: script-volume + mountPath: /scripts + env: + - name: GIT_USERNAME + valueFrom: + secretKeyRef: + name: git-credentials + key: username + - name: GIT_PASSWORD + valueFrom: + secretKeyRef: + name: git-credentials + key: password + source: | + cd /shared-data/ + git config --global credential.helper 'store --file /tmp/credentials' + echo "https://${GIT_USERNAME}:${GIT_PASSWORD}@github.com" > /tmp/credentials + git config --global user.email "havelight@ex-em.com" + git config --global user.name "jaehee-jung" + + git clone https://github.com/CloudMOA/argo-workflows.git + # 공유 볼륨에서 쿼리 결과 읽기 + cp README.md argo-workflows/README.md + # 커밋 및 푸시 작업 수행 + cd argo-workflows + git add README.md + git commit -m "Update README with query result" + git push diff --git a/helm/argo-workflows/Lab/steampipe-dashboard/steampipe_configmap.yaml b/helm/argo-workflows/Lab/steampipe-dashboard/steampipe_configmap.yaml new file mode 100644 index 0000000..644717e --- /dev/null +++ b/helm/argo-workflows/Lab/steampipe-dashboard/steampipe_configmap.yaml @@ -0,0 +1,200 @@ +kind: ConfigMap +metadata: + annotations: + name: steampipe-script + namespace: argo-workflows +apiVersion: v1 +data: + script.sh: | + #!/bin/bash + #------------------------------------------------------------------------------------------------------ + __init (){ + touch ${origin} + touch ${exec_log} + datetime=`TZ='Asia/Seoul' date "+%Y.%m.%d %H:%M:%S"` + echo -e "*update time : ${datetime}\n" > ${file} + cat ${origin} >> ${file} + } + #------------------------------------------------------------------------------------------------------ + __append (){ + line_count=`cat ${exec_log} | grep -v -- -- | egrep -v '(name|ri_count)' | wc -l` + echo -e "\n${title} [${line_count}]\n" >> ${file} + cat ${exec_log} >> ${file} + } + #------------------------------------------------------------------------------------------------------ + __query_exec (){ + steampipe query "${1}" > ${exec_log} + __log_sed + } + #------------------------------------------------------------------------------------------------------ + __log_sed (){ + sed -i 's/+/|/g' ${exec_log} + sed -i "s/node-role.kubernetes.io\///g" ${exec_log} + sed -i '1d;$d' ${exec_log} + } + #------------------------------------------------------------------------------------------------------ + node_query=""" + SELECT + name, + annotations ->> 'projectcalico.org/IPv4Address' AS IP, + COALESCE(taints -> 0 ->> 'key', '-') AS Taints_key, + COALESCE(tags ->> 'kops.k8s.io/instancegroup', '-') AS Instance_group, + capacity ->> 'cpu' AS CPU, + CEIL((CAST(regexp_replace(capacity ->> 'memory', 'Ki', '') AS FLOAT) / 1024 / 1024)) AS Memory, + tags ->> 'topology.kubernetes.io/zone' AS Zone, + tags ->> 'beta.kubernetes.io/instance-type' AS Instance_type, + node_info ->> 'osImage' AS OS, + node_info ->> 'kubeletVersion' AS K8S_ver, + node_info ->> 'containerRuntimeVersion' AS Runtime_ver + FROM + kubernetes_node + ORDER BY + Taints_key + """ + + resources_query=""" + (SELECT + 'sts' as kind, + name, + available_replicas as count, + jsonb_array_elements(template -> 'spec' -> 'containers') -> 'resources' -> 'requests' ->> 'cpu' AS request_cpu, + jsonb_array_elements(template -> 'spec' -> 'containers') -> 'resources' -> 'requests' ->> 'memory' AS request_mem, + jsonb_array_elements(template -> 'spec' -> 'containers') -> 'resources' -> 'limits' ->> 'cpu' AS limit_cpu, + jsonb_array_elements(template -> 'spec' -> 'containers') -> 'resources' -> 'limits' ->> 'memory' AS limit_mem, + jsonb_array_elements(template -> 'spec' -> 'containers') ->> 'name' AS c_name, + namespace + + FROM + kubernetes_stateful_set + WHERE + name not like 'rel-%') + union + (SELECT + 'deploy' as kind, + name, + available_replicas as count, + jsonb_array_elements(template -> 'spec' -> 'containers') -> 'resources' -> 'requests' ->> 'cpu' AS request_cpu, + jsonb_array_elements(template -> 'spec' -> 'containers') -> 'resources' -> 'requests' ->> 'memory' AS request_mem, + jsonb_array_elements(template -> 'spec' -> 'containers') -> 'resources' -> 'limits' ->> 'cpu' AS limit_cpu, + jsonb_array_elements(template -> 'spec' -> 'containers') -> 'resources' -> 'limits' ->> 'memory' AS limit_mem, + jsonb_array_elements(template -> 'spec' -> 'containers') ->> 'name' AS c_name, + namespace + FROM + kubernetes_deployment + WHERE + name not like 'rel-%') + union + (SELECT + 'ds' as kind, + name, + number_available as count, + jsonb_array_elements(template -> 'spec' -> 'containers') -> 'resources' -> 'requests' ->> 'cpu' AS request_cpu, + jsonb_array_elements(template -> 'spec' -> 'containers') -> 'resources' -> 'requests' ->> 'memory' AS request_mem, + jsonb_array_elements(template -> 'spec' -> 'containers') -> 'resources' -> 'limits' ->> 'cpu' AS limit_cpu, + jsonb_array_elements(template -> 'spec' -> 'containers') -> 'resources' -> 'limits' ->> 'memory' AS limit_mem, + jsonb_array_elements(template -> 'spec' -> 'containers') ->> 'name' AS c_name, + namespace + FROM + kubernetes_daemonset + WHERE + name not like 'rel-%') + order by kind + """ + + service_query=""" + SELECT + name, + namespace, + type, + lower(p ->> 'nodePort') as Node_Port, + age(current_timestamp, creation_timestamp) + FROM + kubernetes_service, + jsonb_array_elements(ports) as p + WHERE + type='NodePort' + ORDER BY + Node_Port + """ + #name not like '%rel-%' + + aws_ri_query=""" + SELECT + COALESCE(a.availability_zone, b.availability_zone, '-') AS availability_zone, + COALESCE(a.instance_type, b.instance_type, c.instance_type, '-') AS instance_type, + COALESCE(c.cpu, 0) AS cpu, + COALESCE(c.memory, 0) AS memory, + COALESCE(a.ri_count, 0) AS ri_count, + COALESCE(b.ec2_count, 0) AS ec2_count, + COALESCE(b.ec2_count, 0) - COALESCE(a.ri_count, 0) AS result + FROM + (SELECT + availability_zone, + instance_type, + SUM(instance_count) AS ri_count + FROM + aws_ec2_reserved_instance + WHERE + instance_state='active' + GROUP BY + availability_zone, + instance_type + ) a + FULL OUTER JOIN + (SELECT + placement_availability_zone AS availability_zone, + instance_type, + COUNT(*) AS ec2_count + FROM + aws_ec2_instance + WHERE + instance_state='running' AND + instance_lifecycle!='spot' + GROUP BY + availability_zone, + instance_type + ) b + ON + a.availability_zone = b.availability_zone AND + a.instance_type = b.instance_type + INNER JOIN + (SELECT + instance_type, + (CAST(memory_info ->> 'SizeInMiB' AS FLOAT) / 1024) AS memory, + (CAST(v_cpu_info ->> 'DefaultCores' AS FLOAT) * 2) AS cpu + FROM + aws_ec2_instance_type + WHERE + instance_type in (SELECT instance_type FROM aws_ec2_instance WHERE instance_state='running') + GROUP BY + instance_type, memory, cpu + ) c + ON + COALESCE(a.instance_type, b.instance_type, '-') = c.instance_type + ORDER BY availability_zone + """ + #instance_type in (SELECT instance_type FROM aws_ec2_instance WHERE instance_state='running' AND instance_lifecycle!='spot') + #------------------------------------------------------------------------------------------------------ + origin="/shared-data/org_README.md" + exec_log="/shared-data/query.log" + file="/shared-data/README2.md" + #------------------------------------------------------------------------------------------------------ + __init + + title="## 노드 목록" + __query_exec "${node_query}" + __append + + title="## 리소스 목록" + __query_exec "${resources_query}" + __append + + title="## 서비스 목록 (NodePort)" + __query_exec "${service_query}" + __append + + title="## 예약 인스턴스 사용 내역" + __query_exec "${aws_ri_query}" + __append + #------------------------------------------------------------------------------------------------------ + rm ${exec_log} diff --git a/helm/argo-workflows/Lab/steampipe-dsk-iac/00_Old/test-pod.yaml b/helm/argo-workflows/Lab/steampipe-dsk-iac/00_Old/test-pod.yaml new file mode 100644 index 0000000..4e44349 --- /dev/null +++ b/helm/argo-workflows/Lab/steampipe-dsk-iac/00_Old/test-pod.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Pod +metadata: + name: steampipe +spec: + containers: + - name: steampipe + image: ghcr.io/turbot/steampipe:latest + command: ["/bin/bash"] + args: ["-c", "while true; do sleep 10; done"] + diff --git a/helm/argo-workflows/Lab/steampipe-dsk-iac/00_Old/test-workflow.yaml b/helm/argo-workflows/Lab/steampipe-dsk-iac/00_Old/test-workflow.yaml new file mode 100644 index 0000000..b6a8f52 --- /dev/null +++ b/helm/argo-workflows/Lab/steampipe-dsk-iac/00_Old/test-workflow.yaml @@ -0,0 +1,112 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Workflow +metadata: + generateName: scripts-bash- +spec: + entrypoint: bash-script-example + volumes: + - name: script-volume + configMap: + name: steampipe-script + - name: kubeconfig + secret: + secretName: my-kubeconfig + volumeClaimTemplates: + - metadata: + name: shared-data + spec: + accessModes: ["ReadWriteOnce"] + resources: + requests: + storage: 1Gi + + templates: + - name: bash-script-example + dag: + tasks: + - name: steampipe + template: steampipe + - name: git + template: git + dependencies: + - steampipe + + - name: steampipe + script: + image: ghcr.io/turbot/steampipe:latest + command: [bash] + volumeMounts: + - name: shared-data + mountPath: /shared-data + - name: script-volume + mountPath: /scripts + - name: kubeconfig + mountPath: /kubeconfig + env: + - name: AWS_REGION + valueFrom: + secretKeyRef: + name: aws-creds + key: AWS_REGION + - name: AWS_ACCESS_KEY_ID + valueFrom: + secretKeyRef: + name: aws-creds + key: AWS_ACCESS_KEY_ID + - name: AWS_SECRET_ACCESS_KEY + valueFrom: + secretKeyRef: + name: aws-creds + key: AWS_SECRET_ACCESS_KEY + - name: KMS_ARN + valueFrom: + secretKeyRef: + name: aws-creds + key: KMS_ARN + - name: KUBECONFIG + value: /kubeconfig/config + source: | + # 쿼리 결과를 공유 볼륨에 저장 + steampipe plugin install aws + steampipe plugin install kubernetes + sleep 1 + steampipe service restart --force + sleep 1 + cd /shared-data/ + sleep 1 + bash /scripts/script.sh + + - name: git + script: + image: alpine/git:latest + command: [sh] + volumeMounts: + - name: shared-data + mountPath: /shared-data + - name: script-volume + mountPath: /scripts + env: + - name: GIT_USERNAME + valueFrom: + secretKeyRef: + name: git-credentials + key: username + - name: GIT_PASSWORD + valueFrom: + secretKeyRef: + name: git-credentials + key: password + source: | + git config --global credential.helper 'store --file /tmp/credentials' + echo "https://${GIT_USERNAME}:${GIT_PASSWORD}@github.com" > /tmp/credentials + git config --global user.email "havelight@ex-em.com" + git config --global user.name "jaehee-jung" + cd /shared-data # 경로 내의 파일 목록 확인 + git clone https://github.com/CloudMOA/dsk-iac.git + # 공유 볼륨에서 쿼리 결과 읽기 + cp README2.md dsk-iac/README.md + # 커밋 및 푸시 작업 수행 + cd dsk-iac + git add README.md + git commit -m "Update README with query result" + git push diff --git a/helm/argo-workflows/Lab/steampipe-dsk-iac/cron-steampipe.yaml b/helm/argo-workflows/Lab/steampipe-dsk-iac/cron-steampipe.yaml new file mode 100644 index 0000000..503a011 --- /dev/null +++ b/helm/argo-workflows/Lab/steampipe-dsk-iac/cron-steampipe.yaml @@ -0,0 +1,115 @@ +apiVersion: argoproj.io/v1alpha1 +kind: CronWorkflow +metadata: + name: steampipe-iac-cron +spec: + schedule: "0 8 * * *" + timezone: "Asia/Seoul" + workflowSpec: + entrypoint: bash-script-example + volumes: + - name: script-volume + configMap: + name: steampipe-script + - name: kubeconfig + secret: + secretName: my-kubeconfig + volumeClaimTemplates: + - metadata: + name: shared-data + spec: + accessModes: ["ReadWriteOnce"] + resources: + requests: + storage: 1Gi + + templates: + - name: bash-script-example + dag: + tasks: + - name: steampipe + template: steampipe + - name: git + template: git + dependencies: + - steampipe + + - name: steampipe + script: + image: ghcr.io/turbot/steampipe:latest + command: [bash] + volumeMounts: + - name: shared-data + mountPath: /shared-data + - name: script-volume + mountPath: /scripts + - name: kubeconfig + mountPath: /kubeconfig + env: + - name: AWS_REGION + valueFrom: + secretKeyRef: + name: aws-creds + key: AWS_REGION + - name: AWS_ACCESS_KEY_ID + valueFrom: + secretKeyRef: + name: aws-creds + key: AWS_ACCESS_KEY_ID + - name: AWS_SECRET_ACCESS_KEY + valueFrom: + secretKeyRef: + name: aws-creds + key: AWS_SECRET_ACCESS_KEY + - name: KMS_ARN + valueFrom: + secretKeyRef: + name: aws-creds + key: KMS_ARN + - name: KUBECONFIG + value: /kubeconfig/config + source: | + # 쿼리 결과를 공유 볼륨에 저장 + steampipe plugin install aws + steampipe plugin install kubernetes + sleep 3 + steampipe service restart --force + sleep 1 + cd /shared-data/ + sleep 1 + bash /scripts/script.sh + + - name: git + script: + image: alpine/git:latest + command: [sh] + volumeMounts: + - name: shared-data + mountPath: /shared-data + - name: script-volume + mountPath: /scripts + env: + - name: GIT_USERNAME + valueFrom: + secretKeyRef: + name: git-credentials + key: username + - name: GIT_PASSWORD + valueFrom: + secretKeyRef: + name: git-credentials + key: password + source: | + git config --global credential.helper 'store --file /tmp/credentials' + echo "https://${GIT_USERNAME}:${GIT_PASSWORD}@github.com" > /tmp/credentials + git config --global user.email "havelight@ex-em.com" + git config --global user.name "jaehee-jung" + cd /shared-data # 경로 내의 파일 목록 확인 + git clone https://github.com/CloudMOA/dsk-iac.git + # 공유 볼륨에서 쿼리 결과 읽기 + cp README2.md dsk-iac/README.md + # 커밋 및 푸시 작업 수행 + cd dsk-iac + git add README.md + git commit -m "Update README with query result" + git push diff --git a/helm/argo-workflows/Lab/steampipe-dsk-iac/steampipe_configmap.yaml b/helm/argo-workflows/Lab/steampipe-dsk-iac/steampipe_configmap.yaml new file mode 100644 index 0000000..644717e --- /dev/null +++ b/helm/argo-workflows/Lab/steampipe-dsk-iac/steampipe_configmap.yaml @@ -0,0 +1,200 @@ +kind: ConfigMap +metadata: + annotations: + name: steampipe-script + namespace: argo-workflows +apiVersion: v1 +data: + script.sh: | + #!/bin/bash + #------------------------------------------------------------------------------------------------------ + __init (){ + touch ${origin} + touch ${exec_log} + datetime=`TZ='Asia/Seoul' date "+%Y.%m.%d %H:%M:%S"` + echo -e "*update time : ${datetime}\n" > ${file} + cat ${origin} >> ${file} + } + #------------------------------------------------------------------------------------------------------ + __append (){ + line_count=`cat ${exec_log} | grep -v -- -- | egrep -v '(name|ri_count)' | wc -l` + echo -e "\n${title} [${line_count}]\n" >> ${file} + cat ${exec_log} >> ${file} + } + #------------------------------------------------------------------------------------------------------ + __query_exec (){ + steampipe query "${1}" > ${exec_log} + __log_sed + } + #------------------------------------------------------------------------------------------------------ + __log_sed (){ + sed -i 's/+/|/g' ${exec_log} + sed -i "s/node-role.kubernetes.io\///g" ${exec_log} + sed -i '1d;$d' ${exec_log} + } + #------------------------------------------------------------------------------------------------------ + node_query=""" + SELECT + name, + annotations ->> 'projectcalico.org/IPv4Address' AS IP, + COALESCE(taints -> 0 ->> 'key', '-') AS Taints_key, + COALESCE(tags ->> 'kops.k8s.io/instancegroup', '-') AS Instance_group, + capacity ->> 'cpu' AS CPU, + CEIL((CAST(regexp_replace(capacity ->> 'memory', 'Ki', '') AS FLOAT) / 1024 / 1024)) AS Memory, + tags ->> 'topology.kubernetes.io/zone' AS Zone, + tags ->> 'beta.kubernetes.io/instance-type' AS Instance_type, + node_info ->> 'osImage' AS OS, + node_info ->> 'kubeletVersion' AS K8S_ver, + node_info ->> 'containerRuntimeVersion' AS Runtime_ver + FROM + kubernetes_node + ORDER BY + Taints_key + """ + + resources_query=""" + (SELECT + 'sts' as kind, + name, + available_replicas as count, + jsonb_array_elements(template -> 'spec' -> 'containers') -> 'resources' -> 'requests' ->> 'cpu' AS request_cpu, + jsonb_array_elements(template -> 'spec' -> 'containers') -> 'resources' -> 'requests' ->> 'memory' AS request_mem, + jsonb_array_elements(template -> 'spec' -> 'containers') -> 'resources' -> 'limits' ->> 'cpu' AS limit_cpu, + jsonb_array_elements(template -> 'spec' -> 'containers') -> 'resources' -> 'limits' ->> 'memory' AS limit_mem, + jsonb_array_elements(template -> 'spec' -> 'containers') ->> 'name' AS c_name, + namespace + + FROM + kubernetes_stateful_set + WHERE + name not like 'rel-%') + union + (SELECT + 'deploy' as kind, + name, + available_replicas as count, + jsonb_array_elements(template -> 'spec' -> 'containers') -> 'resources' -> 'requests' ->> 'cpu' AS request_cpu, + jsonb_array_elements(template -> 'spec' -> 'containers') -> 'resources' -> 'requests' ->> 'memory' AS request_mem, + jsonb_array_elements(template -> 'spec' -> 'containers') -> 'resources' -> 'limits' ->> 'cpu' AS limit_cpu, + jsonb_array_elements(template -> 'spec' -> 'containers') -> 'resources' -> 'limits' ->> 'memory' AS limit_mem, + jsonb_array_elements(template -> 'spec' -> 'containers') ->> 'name' AS c_name, + namespace + FROM + kubernetes_deployment + WHERE + name not like 'rel-%') + union + (SELECT + 'ds' as kind, + name, + number_available as count, + jsonb_array_elements(template -> 'spec' -> 'containers') -> 'resources' -> 'requests' ->> 'cpu' AS request_cpu, + jsonb_array_elements(template -> 'spec' -> 'containers') -> 'resources' -> 'requests' ->> 'memory' AS request_mem, + jsonb_array_elements(template -> 'spec' -> 'containers') -> 'resources' -> 'limits' ->> 'cpu' AS limit_cpu, + jsonb_array_elements(template -> 'spec' -> 'containers') -> 'resources' -> 'limits' ->> 'memory' AS limit_mem, + jsonb_array_elements(template -> 'spec' -> 'containers') ->> 'name' AS c_name, + namespace + FROM + kubernetes_daemonset + WHERE + name not like 'rel-%') + order by kind + """ + + service_query=""" + SELECT + name, + namespace, + type, + lower(p ->> 'nodePort') as Node_Port, + age(current_timestamp, creation_timestamp) + FROM + kubernetes_service, + jsonb_array_elements(ports) as p + WHERE + type='NodePort' + ORDER BY + Node_Port + """ + #name not like '%rel-%' + + aws_ri_query=""" + SELECT + COALESCE(a.availability_zone, b.availability_zone, '-') AS availability_zone, + COALESCE(a.instance_type, b.instance_type, c.instance_type, '-') AS instance_type, + COALESCE(c.cpu, 0) AS cpu, + COALESCE(c.memory, 0) AS memory, + COALESCE(a.ri_count, 0) AS ri_count, + COALESCE(b.ec2_count, 0) AS ec2_count, + COALESCE(b.ec2_count, 0) - COALESCE(a.ri_count, 0) AS result + FROM + (SELECT + availability_zone, + instance_type, + SUM(instance_count) AS ri_count + FROM + aws_ec2_reserved_instance + WHERE + instance_state='active' + GROUP BY + availability_zone, + instance_type + ) a + FULL OUTER JOIN + (SELECT + placement_availability_zone AS availability_zone, + instance_type, + COUNT(*) AS ec2_count + FROM + aws_ec2_instance + WHERE + instance_state='running' AND + instance_lifecycle!='spot' + GROUP BY + availability_zone, + instance_type + ) b + ON + a.availability_zone = b.availability_zone AND + a.instance_type = b.instance_type + INNER JOIN + (SELECT + instance_type, + (CAST(memory_info ->> 'SizeInMiB' AS FLOAT) / 1024) AS memory, + (CAST(v_cpu_info ->> 'DefaultCores' AS FLOAT) * 2) AS cpu + FROM + aws_ec2_instance_type + WHERE + instance_type in (SELECT instance_type FROM aws_ec2_instance WHERE instance_state='running') + GROUP BY + instance_type, memory, cpu + ) c + ON + COALESCE(a.instance_type, b.instance_type, '-') = c.instance_type + ORDER BY availability_zone + """ + #instance_type in (SELECT instance_type FROM aws_ec2_instance WHERE instance_state='running' AND instance_lifecycle!='spot') + #------------------------------------------------------------------------------------------------------ + origin="/shared-data/org_README.md" + exec_log="/shared-data/query.log" + file="/shared-data/README2.md" + #------------------------------------------------------------------------------------------------------ + __init + + title="## 노드 목록" + __query_exec "${node_query}" + __append + + title="## 리소스 목록" + __query_exec "${resources_query}" + __append + + title="## 서비스 목록 (NodePort)" + __query_exec "${service_query}" + __append + + title="## 예약 인스턴스 사용 내역" + __query_exec "${aws_ri_query}" + __append + #------------------------------------------------------------------------------------------------------ + rm ${exec_log} diff --git a/helm/argo-workflows/Lab/steampipe.yaml b/helm/argo-workflows/Lab/steampipe.yaml new file mode 100644 index 0000000..67722df --- /dev/null +++ b/helm/argo-workflows/Lab/steampipe.yaml @@ -0,0 +1,34 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Workflow +metadata: + generateName: scripts-bash- +spec: + entrypoint: bash-script-example + templates: + - name: bash-script-example + steps: + - - name: generate + template: steampipe + - - name: print + template: print-message + arguments: + parameters: + - name: message + value: "{{steps.generate.outputs.result}}" + + - name: steampipe + script: + image: ghcr.io/turbot/steampipe:latest + command: [bash] + source: | + steampipe + + - name: print-message + inputs: + parameters: + - name: message + container: + image: alpine:latest + command: [sh, -c] + args: ["echo result was: {{inputs.parameters.message}}"] + diff --git a/helm/argo-workflows/Lab/test.sh b/helm/argo-workflows/Lab/test.sh new file mode 100644 index 0000000..c6d4a58 --- /dev/null +++ b/helm/argo-workflows/Lab/test.sh @@ -0,0 +1,6 @@ + +GIT_USERNAME="jaehee-jung" +GIT_PASSWORD="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" +git config --global credential.helper 'store --file /etc/git/credentials' +echo "https://${GIT_USERNAME}:${GIT_PASSWORD}@github.com" > /etc/git/credentials + diff --git a/helm/argo-workflows/Lab/ui-monitoring/cron_ui_monitoring.yaml b/helm/argo-workflows/Lab/ui-monitoring/cron_ui_monitoring.yaml new file mode 100644 index 0000000..c8b2bc4 --- /dev/null +++ b/helm/argo-workflows/Lab/ui-monitoring/cron_ui_monitoring.yaml @@ -0,0 +1,49 @@ +apiVersion: argoproj.io/v1alpha1 +kind: CronWorkflow +metadata: + name: ui-monitoring-cron +spec: + schedule: "0 * * * *" + timezone: "Asia/Seoul" + workflowSpec: + entrypoint: python-example + volumes: + - name: config-volume + configMap: + name: ui-monitoring + volumeClaimTemplates: + - metadata: + name: shared-data + spec: + accessModes: ["ReadWriteOnce"] + resources: + requests: + storage: 1Gi + templates: + - name: python-example + dag: + tasks: + - name: ui-monitoring + template: ui-monitoring + + - name: ui-monitoring + container: + image: nexus2.exem-oss.org/ui_monitoring:v0.6 + command: ["sh", "-c"] + args: + - | + echo "======================================" + python /tmp/dsk_playwright.py + echo "======================================" + echo -n "$SSH_KEY" > /tmp/id_rsa + chmod 600 /tmp/id_rsa + scp -i /tmp/id_rsa -o StrictHostKeyChecking=no -rp /shared-data/*_screenshot* root@10.10.43.98:/tmp/ + env: + - name: SSH_KEY + valueFrom: + secretKeyRef: + name: bastion-ssh-key + key: ssh-key + volumeMounts: + - name: shared-data + mountPath: /shared-data diff --git a/helm/argo-workflows/Lab/ui-monitoring/cron_ui_monitoring.yaml_bak b/helm/argo-workflows/Lab/ui-monitoring/cron_ui_monitoring.yaml_bak new file mode 100644 index 0000000..2e3a005 --- /dev/null +++ b/helm/argo-workflows/Lab/ui-monitoring/cron_ui_monitoring.yaml_bak @@ -0,0 +1,37 @@ +apiVersion: argoproj.io/v1alpha1 +kind: CronWorkflow +metadata: + name: ui-monitoring-cron +spec: + schedule: "0 * * * *" + timezone: "Asia/Seoul" + workflowSpec: + entrypoint: python-example + volumes: + - name: config-volume + configMap: + name: ui-monitoring + volumeClaimTemplates: + - metadata: + name: shared-data + spec: + accessModes: ["ReadWriteOnce"] + resources: + requests: + storage: 1Gi + templates: + - name: python-example + dag: + tasks: + - name: ui-monitoring + template: ui-monitoring + + - name: ui-monitoring + script: + image: nexus2.exem-oss.org/ui_monitoring:v0.2 + volumeMounts: + - name: shared-data + mountPath: /shared-data + - name: config-volume + mountPath: /tmp/config.json + subPath: config.json diff --git a/helm/argo-workflows/Lab/ui-monitoring/test/cron_ui_monitoring.yaml b/helm/argo-workflows/Lab/ui-monitoring/test/cron_ui_monitoring.yaml new file mode 100644 index 0000000..f14928f --- /dev/null +++ b/helm/argo-workflows/Lab/ui-monitoring/test/cron_ui_monitoring.yaml @@ -0,0 +1,62 @@ +apiVersion: argoproj.io/v1alpha1 +kind: CronWorkflow +metadata: + name: ui-monitoring-cron-test +spec: + schedule: "0 * * * *" + timezone: "Asia/Seoul" + workflowSpec: + entrypoint: python-example + volumes: + - name: config-volume + configMap: + name: ui-monitoring + volumeClaimTemplates: + - metadata: + name: shared-data-{{workflow.name}} + spec: + accessModes: ["ReadWriteOnce"] + resources: + requests: + storage: 1Gi + templates: + - name: python-example + dag: + tasks: + - name: ui-monitoring + template: ui-monitoring + - name: move-capture + template: scp + dependencies: + - ui-monitoring + + - name: ui-monitoring + script: + image: nexus2.exem-oss.org/ui_monitoring:v0.3 + volumeMounts: + - name: shared-data-{{workflow.name}} + mountPath: /shared-data + - name: config-volume + mountPath: /tmp/config.json + subPath: config.json + + - name: scp + container: + image: nexus2.exem-oss.org/dsk-openssh-client:v1.0 + command: ["sh", "-c"] + args: + - | + echo -n "$SSH_KEY" > /tmp/id_rsa + chmod 600 /tmp/id_rsa + while true; do sleep 1; done + scp -i /tmp/id_rsa -o StrictHostKeyChecking=no -rp /shared-data/*_screenshot* root@10.10.43.98:/tmp/ + scp -i /tmp/id_rsa -o StrictHostKeyChecking=no -rp /shared-data/*_error* root@10.10.43.98:/tmp/ + env: + - name: SSH_KEY + valueFrom: + secretKeyRef: + name: bastion-ssh-key + key: ssh-key + volumeMounts: + - name: shared-data-{{workflow.name}} + mountPath: /shared-data diff --git a/helm/argo-workflows/Lab/ui-monitoring/ui_monitoring_configmap.yaml b/helm/argo-workflows/Lab/ui-monitoring/ui_monitoring_configmap.yaml new file mode 100644 index 0000000..147abac --- /dev/null +++ b/helm/argo-workflows/Lab/ui-monitoring/ui_monitoring_configmap.yaml @@ -0,0 +1,16 @@ +kind: ConfigMap +metadata: + annotations: + name: ui-monitoring + namespace: argo-workflows +apiVersion: v1 +data: + config.json: | + { + "dsk_url": "https://app.kr.datasaker.io", + "dsk_username": "support@ex-em.com", + "dsk_password": "saasadmin12#$", + "slack_webhook_url" : "https://hooks.slack.com/services/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", + "timeout": 10000 + } + diff --git a/helm/argo-workflows/README.md b/helm/argo-workflows/README.md new file mode 100644 index 0000000..732baec --- /dev/null +++ b/helm/argo-workflows/README.md @@ -0,0 +1,376 @@ +# Argo Workflows Chart + +This is a **community maintained** chart. It is used to set up argo and its needed dependencies through one command. This is used in conjunction with [helm](https://github.com/kubernetes/helm). + +If you want your deployment of this helm chart to most closely match the [argo CLI](https://github.com/argoproj/argo-workflows), you should deploy it in the `kube-system` namespace. + +## Pre-Requisites + +### Custom resource definitions + +Some users would prefer to install the CRDs _outside_ of the chart. You can disable the CRD installation of this chart by using `--set crds.install=false` when installing the chart. + +Helm cannot upgrade custom resource definitions in the `/crds` folder [by design](https://helm.sh/docs/chart_best_practices/custom_resource_definitions/#some-caveats-and-explanations). Starting with 3.4.0 (chart version 0.19.0), the CRDs have been moved to `/templates` to address this design decision. + +If you are using Argo Workflows chart version prior to 3.4.0 (chart version 0.19.0) or have elected to manage the Argo Workflows CRDs outside of the chart, please use `kubectl` to upgrade CRDs manually from [templates/crds](templates/crds/) folder or via the manifests from the upstream project repo: + +```bash +kubectl apply -k "https://github.com/argoproj/argo-workflows/manifests/base/crds/full?ref=" + +# Eg. version v3.3.9 +kubectl apply -k "https://github.com/argoproj/argo-workflows/manifests/base/crds/full?ref=v3.3.9" +``` + +### ServiceAccount for Workflow Spec +In order for each Workflow run, you create ServiceAccount via `values.yaml` like below. + +```yaml +workflow: + serviceAccount: + create: true + name: "argo-workflow" + rbac: + create: true +controller: + workflowNamespaces: + - default + - foo + - bar +``` + +Set ServiceAccount on Workflow. + +```yaml +apiVersion: argoproj.io/v1alpha1 +kind: Workflow +metadata: + generateName: hello-world- +spec: + entrypoint: whalesay + serviceAccountName: argo-workflow # Set ServiceAccount + templates: + - name: whalesay + container: + image: docker/whalesay + command: [ cowsay ] + args: [ "hello world" ] +``` + +## Installing the Chart + +To install the chart with the release name `my-release`: + +```console +$ helm repo add argo https://argoproj.github.io/argo-helm +"argo" has been added to your repositories + +$ helm install my-release argo/argo-workflows +NAME: my-release +... +``` + +## Changelog + +For full list of changes, please check ArtifactHub [changelog]. + +## Usage Notes + +### High Availability + +This chart installs the non-HA version of Argo Workflows by default. If you want to run in HA mode, you can use [these example values](ci/ha-values.yaml) as a starting point. +Please see the upstream [Operator Manual's High Availability page](https://argoproj.github.io/argo-workflows/high-availability/) to understand how to scale Argo Workflows in depth. + +### Workflow controller + +This chart defaults to setting the `controller.instanceID.enabled` to `false` now, which means the deployed controller will act upon any workflow deployed to the cluster. If you would like to limit the behavior and deploy multiple workflow controllers, please use the `controller.instanceID.enabled` attribute along with one of its configuration options to set the `instanceID` of the workflow controller to be properly scoped for your needs. + +### Workflow server authentication + +By default, the chart requires some kind of authentication mechanism. This adopts the [default behaviour from the Argo project](https://github.com/argoproj/argo-workflows/pull/5211) itself. However, for local development purposes, or cases where your gateway authentication is covered by some other means, you can set the authentication mode for the Argo server by setting the `server.extraArgs: [--auth-mode=server]`. There are a few additional comments in the values.yaml file itself, including commented-out settings to disable authentication on the server UI itself using the same `--auth-mode=server` setting. + +## Values + +The `values.yaml` contains items used to tweak a deployment of this chart. +Fields to note: + +- `controller.instanceID.enabled`: If set to true, the Argo Controller will **ONLY** monitor Workflow submissions with a `--instanceid` attribute +- `controller.instanceID.useReleaseName`: If set to true then chart set controller instance id to release name +- `controller.instanceID.explicitID`: Allows customization of an instance id for the workflow controller to monitor +- `singleNamespace`: When true, restricts the workflow controller to operate + in just the single namespace (that one of the Helm release). +- `controller.workflowNamespaces`: This is a list of namespaces where the + workflow controller will manage workflows. Only valid when `singleNamespace` + is false. + +### General parameters + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| apiVersionOverrides.autoscaling | string | `""` | String to override apiVersion of autoscaling rendered by this helm chart | +| apiVersionOverrides.cloudgoogle | string | `""` | String to override apiVersion of GKE resources rendered by this helm chart | +| crds.annotations | object | `{}` | Annotations to be added to all CRDs | +| crds.install | bool | `true` | Install and upgrade CRDs | +| crds.keep | bool | `true` | Keep CRDs on chart uninstall | +| createAggregateRoles | bool | `true` | Create clusterroles that extend existing clusterroles to interact with argo-cd crds | +| emissary.images | list | `[]` | The command/args for each image on workflow, needed when the command is not specified and the emissary executor is used. | +| extraObjects | list | `[]` | Array of extra K8s manifests to deploy | +| fullnameOverride | string | `nil` | String to fully override "argo-workflows.fullname" template | +| images.pullPolicy | string | `"Always"` | imagePullPolicy to apply to all containers | +| images.pullSecrets | list | `[]` | Secrets with credentials to pull images from a private registry | +| images.tag | string | `""` | Common tag for Argo Workflows images. Defaults to `.Chart.AppVersion`. | +| kubeVersionOverride | string | `""` | Override the Kubernetes version, which is used to evaluate certain manifests | +| nameOverride | string | `nil` | String to partially override "argo-workflows.fullname" template | +| singleNamespace | bool | `false` | Restrict Argo to operate only in a single namespace (the namespace of the Helm release) by apply Roles and RoleBindings instead of the Cluster equivalents, and start workflow-controller with the --namespaced flag. Use it in clusters with strict access policy. | + +### Workflow + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| workflow.namespace | string | `nil` | Deprecated; use controller.workflowNamespaces instead. | +| workflow.rbac.create | bool | `true` | Adds Role and RoleBinding for the above specified service account to be able to run workflows. A Role and Rolebinding pair is also created for each namespace in controller.workflowNamespaces (see below) | +| workflow.serviceAccount.annotations | object | `{}` | Annotations applied to created service account | +| workflow.serviceAccount.create | bool | `false` | Specifies whether a service account should be created | +| workflow.serviceAccount.labels | object | `{}` | Labels applied to created service account | +| workflow.serviceAccount.name | string | `"argo-workflow"` | Service account which is used to run workflows | +| workflow.serviceAccount.pullSecrets | list | `[]` | Secrets with credentials to pull images from a private registry. Same format as `.Values.images.pullSecrets` | + +### Workflow Controller + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| controller.affinity | object | `{}` | Assign custom [affinity] rules | +| controller.clusterWorkflowTemplates.enabled | bool | `true` | Create a ClusterRole and CRB for the controller to access ClusterWorkflowTemplates. | +| controller.columns | list | `[]` | Configure Argo Server to show custom [columns] | +| controller.deploymentAnnotations | object | `{}` | deploymentAnnotations is an optional map of annotations to be applied to the controller Deployment | +| controller.extraArgs | list | `[]` | Extra arguments to be added to the controller | +| controller.extraContainers | list | `[]` | Extra containers to be added to the controller deployment | +| controller.extraEnv | list | `[]` | Extra environment variables to provide to the controller container | +| controller.extraInitContainers | list | `[]` | Enables init containers to be added to the controller deployment | +| controller.image.registry | string | `"quay.io"` | Registry to use for the controller | +| controller.image.repository | string | `"argoproj/workflow-controller"` | Registry to use for the controller | +| controller.image.tag | string | `""` | Image tag for the workflow controller. Defaults to `.Values.images.tag`. | +| controller.initialDelay | string | `nil` | Resolves ongoing, uncommon AWS EKS bug: https://github.com/argoproj/argo-workflows/pull/4224 | +| controller.instanceID.enabled | bool | `false` | Configures the controller to filter workflow submissions to only those which have a matching instanceID attribute. | +| controller.instanceID.explicitID | string | `""` | Use a custom instanceID | +| controller.instanceID.useReleaseName | bool | `false` | Use ReleaseName as instanceID | +| controller.kubeConfig | object | `{}` (See [values.yaml]) | Configure when workflow controller runs in a different k8s cluster with the workflow workloads, or needs to communicate with the k8s apiserver using an out-of-cluster kubeconfig secret. | +| controller.links | list | `[]` | Configure Argo Server to show custom [links] | +| controller.livenessProbe | object | See [values.yaml] | Configure liveness [probe] for the controller | +| controller.loadBalancerSourceRanges | list | `[]` | Source ranges to allow access to service from. Only applies to service type `LoadBalancer` | +| controller.logging.format | string | `"text"` | Set the logging format (one of: `text`, `json`) | +| controller.logging.globallevel | string | `"0"` | Set the glog logging level | +| controller.logging.level | string | `"info"` | Set the logging level (one of: `debug`, `info`, `warn`, `error`) | +| controller.metricsConfig.enabled | bool | `false` | Enables prometheus metrics server | +| controller.metricsConfig.ignoreErrors | bool | `false` | Flag that instructs prometheus to ignore metric emission errors. | +| controller.metricsConfig.metricRelabelings | list | `[]` | ServiceMonitor metric relabel configs to apply to samples before ingestion | +| controller.metricsConfig.metricsTTL | string | `""` | How often custom metrics are cleared from memory | +| controller.metricsConfig.path | string | `"/metrics"` | Path is the path where metrics are emitted. Must start with a "/". | +| controller.metricsConfig.port | int | `9090` | Port is the port where metrics are emitted | +| controller.metricsConfig.portName | string | `"metrics"` | Container metrics port name | +| controller.metricsConfig.relabelings | list | `[]` | ServiceMonitor relabel configs to apply to samples before scraping | +| controller.metricsConfig.secure | bool | `false` | Flag that use a self-signed cert for TLS | +| controller.metricsConfig.servicePort | int | `8080` | Service metrics port | +| controller.metricsConfig.servicePortName | string | `"metrics"` | Service metrics port name | +| controller.metricsConfig.targetLabels | list | `[]` | ServiceMonitor will add labels from the service to the Prometheus metric | +| controller.name | string | `"workflow-controller"` | Workflow controller name string | +| controller.namespaceParallelism | string | `nil` | Limits the maximum number of incomplete workflows in a namespace | +| controller.navColor | string | `""` | Set ui navigation bar background color | +| controller.nodeEvents.enabled | bool | `true` | Enable to emit events on node completion. | +| controller.nodeSelector | object | `{"kubernetes.io/os":"linux"}` | [Node selector] | +| controller.parallelism | string | `nil` | parallelism dictates how many workflows can be running at the same time | +| controller.pdb.enabled | bool | `false` | Configure [Pod Disruption Budget] for the controller pods | +| controller.persistence | object | `{}` | enable persistence using postgres | +| controller.podAnnotations | object | `{}` | podAnnotations is an optional map of annotations to be applied to the controller Pods | +| controller.podGCDeleteDelayDuration | string | `5s` (Argo Workflows default) | The duration in seconds before the pods in the GC queue get deleted. A zero value indicates that the pods will be deleted immediately. | +| controller.podGCGracePeriodSeconds | string | `30` seconds (Kubernetes default) | Specifies the duration in seconds before a terminating pod is forcefully killed. A zero value indicates that the pod will be forcefully terminated immediately. | +| controller.podLabels | object | `{}` | Optional labels to add to the controller pods | +| controller.podSecurityContext | object | `{}` | SecurityContext to set on the controller pods | +| controller.priorityClassName | string | `""` | Leverage a PriorityClass to ensure your pods survive resource shortages. | +| controller.rbac.accessAllSecrets | bool | `false` | Allows controller to get, list and watch all k8s secrets. Can only be used if secretWhitelist is empty. | +| controller.rbac.create | bool | `true` | Adds Role and RoleBinding for the controller. | +| controller.rbac.secretWhitelist | list | `[]` | Allows controller to get, list, and watch certain k8s secrets | +| controller.rbac.writeConfigMaps | bool | `false` | Allows controller to create and update ConfigMaps. Enables memoization feature | +| controller.replicas | int | `1` | The number of controller pods to run | +| controller.resourceRateLimit | object | `{}` | Globally limits the rate at which pods are created. This is intended to mitigate flooding of the Kubernetes API server by workflows with a large amount of parallel nodes. | +| controller.resources | object | `{}` | Resource limits and requests for the controller | +| controller.retentionPolicy | object | `{}` | Workflow retention by number of workflows | +| controller.securityContext | object | `{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]},"readOnlyRootFilesystem":true,"runAsNonRoot":true}` | the controller container's securityContext | +| controller.serviceAccount.annotations | object | `{}` | Annotations applied to created service account | +| controller.serviceAccount.create | bool | `true` | Create a service account for the controller | +| controller.serviceAccount.labels | object | `{}` | Labels applied to created service account | +| controller.serviceAccount.name | string | `""` | Service account name | +| controller.serviceAnnotations | object | `{}` | Annotations to be applied to the controller Service | +| controller.serviceLabels | object | `{}` | Optional labels to add to the controller Service | +| controller.serviceMonitor.additionalLabels | object | `{}` | Prometheus ServiceMonitor labels | +| controller.serviceMonitor.enabled | bool | `false` | Enable a prometheus ServiceMonitor | +| controller.serviceMonitor.namespace | string | `""` | Prometheus ServiceMonitor namespace | +| controller.serviceType | string | `"ClusterIP"` | Service type of the controller Service | +| controller.telemetryConfig.enabled | bool | `false` | Enables prometheus telemetry server | +| controller.telemetryConfig.ignoreErrors | bool | `false` | Flag that instructs prometheus to ignore metric emission errors. | +| controller.telemetryConfig.metricsTTL | string | `""` | How often custom metrics are cleared from memory | +| controller.telemetryConfig.path | string | `"/telemetry"` | telemetry path | +| controller.telemetryConfig.port | int | `8081` | telemetry container port | +| controller.telemetryConfig.secure | bool | `false` | Flag that use a self-signed cert for TLS | +| controller.telemetryConfig.servicePort | int | `8081` | telemetry service port | +| controller.telemetryConfig.servicePortName | string | `"telemetry"` | telemetry service port name | +| controller.tolerations | list | `[]` | [Tolerations] for use with node taints | +| controller.topologySpreadConstraints | list | `[]` | Assign custom [TopologySpreadConstraints] rules to the workflow controller | +| controller.volumeMounts | list | `[]` | Additional volume mounts to the controller main container | +| controller.volumes | list | `[]` | Additional volumes to the controller pod | +| controller.workflowDefaults | object | `{}` | Default values that will apply to all Workflows from this controller, unless overridden on the Workflow-level. Only valid for 2.7+ | +| controller.workflowNamespaces | list | `["default"]` | Specify all namespaces where this workflow controller instance will manage workflows. This controls where the service account and RBAC resources will be created. Only valid when singleNamespace is false. | +| controller.workflowRestrictions | object | `{}` | Restricts the Workflows that the controller will process. Only valid for 2.9+ | +| controller.workflowWorkers | string | `nil` | Number of workflow workers | + +### Workflow Main Container + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| mainContainer.env | list | `[]` | Adds environment variables for the Workflow main container | +| mainContainer.envFrom | list | `[]` | Adds reference environment variables for the Workflow main container | +| mainContainer.imagePullPolicy | string | `""` | imagePullPolicy to apply to Workflow main container. Defaults to `.Values.images.pullPolicy`. | +| mainContainer.resources | object | `{}` | Resource limits and requests for the Workflow main container | +| mainContainer.securityContext | object | `{}` | sets security context for the Workflow main container | + +### Workflow Executor + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| executor.args | list | `[]` | Passes arguments to the executor processes | +| executor.env | list | `[]` | Adds environment variables for the executor. | +| executor.image.pullPolicy | string | `""` | Image PullPolicy to use for the Workflow Executors. Defaults to `.Values.images.pullPolicy`. | +| executor.image.registry | string | `"quay.io"` | Registry to use for the Workflow Executors | +| executor.image.repository | string | `"argoproj/argoexec"` | Repository to use for the Workflow Executors | +| executor.image.tag | string | `""` | Image tag for the workflow executor. Defaults to `.Values.images.tag`. | +| executor.resources | object | `{}` | Resource limits and requests for the Workflow Executors | +| executor.securityContext | object | `{}` | sets security context for the executor container | + +### Workflow Server + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| server.GKEbackendConfig.enabled | bool | `false` | Enable BackendConfig custom resource for Google Kubernetes Engine | +| server.GKEbackendConfig.spec | object | `{}` | [BackendConfigSpec] | +| server.GKEfrontendConfig.enabled | bool | `false` | Enable FrontConfig custom resource for Google Kubernetes Engine | +| server.GKEfrontendConfig.spec | object | `{}` | [FrontendConfigSpec] | +| server.GKEmanagedCertificate.domains | list | `["argoworkflows.example.com"]` | Domains for the Google Managed Certificate | +| server.GKEmanagedCertificate.enabled | bool | `false` | Enable ManagedCertificate custom resource for Google Kubernetes Engine. | +| server.affinity | object | `{}` | Assign custom [affinity] rules | +| server.autoscaling.behavior | object | `{}` | Configures the scaling behavior of the target in both Up and Down directions. This is only available on HPA apiVersion `autoscaling/v2beta2` and newer | +| server.autoscaling.enabled | bool | `false` | Enable Horizontal Pod Autoscaler ([HPA]) for the Argo Server | +| server.autoscaling.maxReplicas | int | `5` | Maximum number of replicas for the Argo Server [HPA] | +| server.autoscaling.minReplicas | int | `1` | Minimum number of replicas for the Argo Server [HPA] | +| server.autoscaling.targetCPUUtilizationPercentage | int | `50` | Average CPU utilization percentage for the Argo Server [HPA] | +| server.autoscaling.targetMemoryUtilizationPercentage | int | `50` | Average memory utilization percentage for the Argo Server [HPA] | +| server.baseHref | string | `"/"` | Value for base href in index.html. Used if the server is running behind reverse proxy under subpath different from /. | +| server.clusterWorkflowTemplates.enableEditing | bool | `true` | Give the server permissions to edit ClusterWorkflowTemplates. | +| server.clusterWorkflowTemplates.enabled | bool | `true` | Create a ClusterRole and CRB for the server to access ClusterWorkflowTemplates. | +| server.deploymentAnnotations | object | `{}` | optional map of annotations to be applied to the ui Deployment | +| server.enabled | bool | `true` | Deploy the Argo Server | +| server.extraArgs | list | `[]` | Extra arguments to provide to the Argo server binary, such as for disabling authentication. | +| server.extraContainers | list | `[]` | Extra containers to be added to the server deployment | +| server.extraEnv | list | `[]` | Extra environment variables to provide to the argo-server container | +| server.extraInitContainers | list | `[]` | Enables init containers to be added to the server deployment | +| server.image.registry | string | `"quay.io"` | Registry to use for the server | +| server.image.repository | string | `"argoproj/argocli"` | Repository to use for the server | +| server.image.tag | string | `""` | Image tag for the Argo Workflows server. Defaults to `.Values.images.tag`. | +| server.ingress.annotations | object | `{}` | Additional ingress annotations | +| server.ingress.enabled | bool | `false` | Enable an ingress resource | +| server.ingress.extraPaths | list | `[]` | Additional ingress paths | +| server.ingress.hosts | list | `[]` | List of ingress hosts | +| server.ingress.ingressClassName | string | `""` | Defines which ingress controller will implement the resource | +| server.ingress.labels | object | `{}` | Additional ingress labels | +| server.ingress.pathType | string | `"Prefix"` | Ingress path type. One of `Exact`, `Prefix` or `ImplementationSpecific` | +| server.ingress.paths | list | `["/"]` | List of ingress paths | +| server.ingress.tls | list | `[]` | Ingress TLS configuration | +| server.loadBalancerIP | string | `""` | Static IP address to assign to loadBalancer service type `LoadBalancer` | +| server.loadBalancerSourceRanges | list | `[]` | Source ranges to allow access to service from. Only applies to service type `LoadBalancer` | +| server.logging.format | string | `"text"` | Set the logging format (one of: `text`, `json`) | +| server.logging.globallevel | string | `"0"` | Set the glog logging level | +| server.logging.level | string | `"info"` | Set the logging level (one of: `debug`, `info`, `warn`, `error`) | +| server.name | string | `"server"` | Server name string | +| server.nodeSelector | object | `{"kubernetes.io/os":"linux"}` | [Node selector] | +| server.pdb.enabled | bool | `false` | Configure [Pod Disruption Budget] for the server pods | +| server.podAnnotations | object | `{}` | optional map of annotations to be applied to the ui Pods | +| server.podLabels | object | `{}` | Optional labels to add to the UI pods | +| server.podSecurityContext | object | `{}` | SecurityContext to set on the server pods | +| server.priorityClassName | string | `""` | Leverage a PriorityClass to ensure your pods survive resource shortages | +| server.rbac.create | bool | `true` | Adds Role and RoleBinding for the server. | +| server.replicas | int | `1` | The number of server pods to run | +| server.resources | object | `{}` | Resource limits and requests for the server | +| server.secure | bool | `false` | Run the argo server in "secure" mode. Configure this value instead of `--secure` in extraArgs. | +| server.securityContext | object | `{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]},"readOnlyRootFilesystem":false,"runAsNonRoot":true}` | Servers container-level security context | +| server.serviceAccount.annotations | object | `{}` | Annotations applied to created service account | +| server.serviceAccount.create | bool | `true` | Create a service account for the server | +| server.serviceAccount.labels | object | `{}` | Labels applied to created service account | +| server.serviceAccount.name | string | `""` | Service account name | +| server.serviceAnnotations | object | `{}` | Annotations to be applied to the UI Service | +| server.serviceLabels | object | `{}` | Optional labels to add to the UI Service | +| server.serviceNodePort | string | `nil` | Service node port | +| server.servicePort | int | `2746` | Service port for server | +| server.servicePortName | string | `""` | Service port name | +| server.serviceType | string | `"ClusterIP"` | Service type for server pods | +| server.sso.clientId.key | string | `"client-id"` | Key of secret to retrieve the app OIDC client ID | +| server.sso.clientId.name | string | `"argo-server-sso"` | Name of secret to retrieve the app OIDC client ID | +| server.sso.clientSecret.key | string | `"client-secret"` | Key of a secret to retrieve the app OIDC client secret | +| server.sso.clientSecret.name | string | `"argo-server-sso"` | Name of a secret to retrieve the app OIDC client secret | +| server.sso.customGroupClaimName | string | `""` | Override claim name for OIDC groups | +| server.sso.enabled | bool | `false` | Create SSO configuration | +| server.sso.insecureSkipVerify | bool | `false` | Skip TLS verification for the HTTP client | +| server.sso.issuer | string | `"https://accounts.google.com"` | The root URL of the OIDC identity provider | +| server.sso.issuerAlias | string | `""` | Alternate root URLs that can be included for some OIDC providers | +| server.sso.rbac.enabled | bool | `true` | Adds ServiceAccount Policy to server (Cluster)Role. | +| server.sso.rbac.secretWhitelist | list | `[]` | Whitelist to allow server to fetch Secrets | +| server.sso.redirectUrl | string | `"https://argo/oauth2/callback"` | | +| server.sso.scopes | list | `[]` | Scopes requested from the SSO ID provider | +| server.sso.sessionExpiry | string | `""` | Define how long your login is valid for (in hours) | +| server.sso.userInfoPath | string | `""` | Specify the user info endpoint that contains the groups claim | +| server.tolerations | list | `[]` | [Tolerations] for use with node taints | +| server.topologySpreadConstraints | list | `[]` | Assign custom [TopologySpreadConstraints] rules to the argo server | +| server.volumeMounts | list | `[]` | Additional volume mounts to the server main container. | +| server.volumes | list | `[]` | Additional volumes to the server pod. | + +### Artifact Repository + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| artifactRepository.archiveLogs | bool | `false` | Archive the main container logs as an artifact | +| artifactRepository.azure | object | `{}` (See [values.yaml]) | Store artifact in Azure Blob Storage | +| artifactRepository.gcs | object | `{}` (See [values.yaml]) | Store artifact in a GCS object store | +| artifactRepository.s3 | object | See [values.yaml] | Store artifact in a S3-compliant object store | +| artifactRepositoryRef | object | `{}` (See [values.yaml]) | The section of [artifact repository ref](https://argoproj.github.io/argo-workflows/artifact-repository-ref/). Each map key is the name of configmap | +| customArtifactRepository | object | `{}` | The section of custom artifact repository. Utilize a custom artifact repository that is not one of the current base ones (s3, gcs, azure) | +| useStaticCredentials | bool | `true` | Use static credentials for S3 (eg. when not using AWS IRSA) | + +## Breaking changes from the deprecated `argo` chart + +1. the `installCRD` value has been removed. CRDs are now only installed from the conventional crds/ directory +1. the CRDs were updated to `apiextensions.k8s.io/v1` +1. the container image registry/project/tag format was changed to be more in line with the more common + + ```yaml + image: + registry: quay.io + repository: argoproj/argocli + tag: v3.0.1 + ``` + + this also makes it easier for automatic update tooling (eg. renovate bot) to detect and update images. + +1. switched to quay.io as the default registry for all images +1. removed any included usage of Minio +1. aligned the configuration of serviceAccounts with the argo-cd chart, ie: what used to be `server.createServiceAccount` is now `server.serviceAccount.create` +1. moved the field previously known as `telemetryServicePort` inside the `telemetryConfig` as `telemetryConfig.servicePort` - same for `metricsConfig` + +[affinity]: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ +[BackendConfigSpec]: https://cloud.google.com/kubernetes-engine/docs/concepts/backendconfig#backendconfigspec_v1beta1_cloudgooglecom +[FrontendConfigSpec]: https://cloud.google.com/kubernetes-engine/docs/how-to/ingress-features#configuring_ingress_features_through_frontendconfig_parameters +[links]: https://argoproj.github.io/argo-workflows/links/ +[columns]: https://github.com/argoproj/argo-workflows/pull/10693 +[Node selector]: https://kubernetes.io/docs/user-guide/node-selection/ +[Pod Disruption Budget]: https://kubernetes.io/docs/tasks/run-application/configure-pdb/ +[probe]: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#container-probes +[Tolerations]: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ +[TopologySpreadConstraints]: https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ +[values.yaml]: values.yaml +[changelog]: https://artifacthub.io/packages/helm/argo/argo-workflows?modal=changelog diff --git a/helm/argo-workflows/override_values.yaml b/helm/argo-workflows/override_values.yaml new file mode 100644 index 0000000..53f092b --- /dev/null +++ b/helm/argo-workflows/override_values.yaml @@ -0,0 +1,38 @@ +singleNamespace: true +# -- String to partially override "argo-workflowss.fullname" template +nameOverride: argo-workflows + +# -- String to fully override "argo-workflowss.fullname" template +fullnameOverride: argo-workflows + + +workflow: + serviceAccount: + create: true + name: "argo-workflows" + rbac: + create: true + +controller: + metricsConfig: + enabled: true + + logging: + level: debug + + rbac: + accessAllSecrets: true + writeConfigMaps: true + + serviceType: NodePort + + extraEnv: + - name: ARGO_EXECUTOR_PLUGINS + value: "true" + +server: + serviceType: NodePort + serviceNodePort: 30800 + secure: true + extraArgs: + - --auth-mode=server diff --git a/helm/argo-workflows/templates/NOTES.txt b/helm/argo-workflows/templates/NOTES.txt new file mode 100644 index 0000000..b4933a7 --- /dev/null +++ b/helm/argo-workflows/templates/NOTES.txt @@ -0,0 +1,7 @@ +1. Get Argo Server external IP/domain by running: + +kubectl --namespace {{ .Release.Namespace }} get services -o wide | grep {{ template "argo-workflows.server.fullname" . }} + +2. Submit the hello-world workflow by running: + +argo submit https://raw.githubusercontent.com/argoproj/argo-workflows/master/examples/hello-world.yaml --watch diff --git a/helm/argo-workflows/templates/_helpers.tpl b/helm/argo-workflows/templates/_helpers.tpl new file mode 100644 index 0000000..f81e6fc --- /dev/null +++ b/helm/argo-workflows/templates/_helpers.tpl @@ -0,0 +1,181 @@ +{{/* vim: set filetype=mustache: */}} + +{{/* +Create argo workflows server name and version as used by the chart label. +*/}} +{{- define "argo-workflows.server.fullname" -}} +{{- printf "%s-%s" (include "argo-workflows.fullname" .) .Values.server.name | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create controller name and version as used by the chart label. +*/}} +{{- define "argo-workflows.controller.fullname" -}} +{{- printf "%s-%s" (include "argo-workflows.fullname" .) .Values.controller.name | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Expand the name of the chart. +*/}} +{{- define "argo-workflows.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +*/}} +{{- define "argo-workflows.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 "argo-workflows.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create kubernetes friendly chart version label for the controller. +Examples: +image.tag = v3.4.4 +output = v3.4.4 + +image.tag = v3.4.4@sha256:d06860f1394a94ac3ff8401126ef32ba28915aa6c3c982c7e607ea0b4dadb696 +output = v3.4.4 +*/}} +{{- define "argo-workflows.controller_chart_version_label" -}} +{{- regexReplaceAll "[^a-zA-Z0-9-_.]+" (regexReplaceAll "@sha256:[a-f0-9]+" (default (include "argo-workflows.defaultTag" .) .Values.controller.image.tag) "") "" | trunc 63 | quote -}} +{{- end -}} + +{{/* +Create kubernetes friendly chart version label for the server. +Examples: +image.tag = v3.4.4 +output = v3.4.4 + +image.tag = v3.4.4@sha256:d06860f1394a94ac3ff8401126ef32ba28915aa6c3c982c7e607ea0b4dadb696 +output = v3.4.4 +*/}} +{{- define "argo-workflows.server_chart_version_label" -}} +{{- regexReplaceAll "[^a-zA-Z0-9-_.]+" (regexReplaceAll "@sha256:[a-f0-9]+" (default (include "argo-workflows.defaultTag" .) .Values.server.image.tag) "") "" | trunc 63 | quote -}} +{{- end -}} + +{{/* +Common labels +*/}} +{{- define "argo-workflows.labels" -}} +helm.sh/chart: {{ include "argo-workflows.chart" .context }} +{{ include "argo-workflows.selectorLabels" (dict "context" .context "component" .component "name" .name) }} +app.kubernetes.io/managed-by: {{ .context.Release.Service }} +app.kubernetes.io/part-of: argo-workflows +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "argo-workflows.selectorLabels" -}} +{{- if .name -}} +app.kubernetes.io/name: {{ include "argo-workflows.name" .context }}-{{ .name }} +{{ end -}} +app.kubernetes.io/instance: {{ .context.Release.Name }} +{{- if .component }} +app.kubernetes.io/component: {{ .component }} +{{- end }} +{{- end }} + +{{/* +Create the name of the server service account to use +*/}} +{{- define "argo-workflows.serverServiceAccountName" -}} +{{- if .Values.server.serviceAccount.create -}} + {{ default (include "argo-workflows.server.fullname" .) .Values.server.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.server.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +Create the name of the controller service account to use +*/}} +{{- define "argo-workflows.controllerServiceAccountName" -}} +{{- if .Values.controller.serviceAccount.create -}} + {{ default (include "argo-workflows.controller.fullname" .) .Values.controller.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.controller.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for ingress +*/}} +{{- define "argo-workflows.ingress.apiVersion" -}} +{{- if semverCompare "<1.14-0" (include "argo-workflows.kubeVersion" $) -}} +{{- print "extensions/v1beta1" -}} +{{- else if semverCompare "<1.19-0" (include "argo-workflows.kubeVersion" $) -}} +{{- print "networking.k8s.io/v1beta1" -}} +{{- else -}} +{{- print "networking.k8s.io/v1" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the target Kubernetes version +*/}} +{{- define "argo-workflows.kubeVersion" -}} + {{- default .Capabilities.KubeVersion.Version .Values.kubeVersionOverride }} +{{- end -}} + +{{/* +Return the default Argo Workflows app version +*/}} +{{- define "argo-workflows.defaultTag" -}} + {{- default .Chart.AppVersion .Values.images.tag }} +{{- end -}} + +{{/* +Return full image name including or excluding registry based on existence +*/}} +{{- define "argo-workflows.image" -}} +{{- if and .image.registry .image.repository -}} + {{ .image.registry }}/{{ .image.repository }} +{{- else -}} + {{ .image.repository }} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for autoscaling +*/}} +{{- define "argo-workflows.apiVersion.autoscaling" -}} +{{- if .Values.apiVersionOverrides.autoscaling -}} +{{- print .Values.apiVersionOverrides.autoscaling -}} +{{- else if semverCompare "<1.23-0" (include "argo-workflows.kubeVersion" .) -}} +{{- print "autoscaling/v2beta1" -}} +{{- else -}} +{{- print "autoscaling/v2" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for GKE resources +*/}} +{{- define "argo-workflows.apiVersions.cloudgoogle" -}} +{{- if .Values.apiVersionOverrides.cloudgoogle -}} +{{- print .Values.apiVersionOverrides.cloudgoogle -}} +{{- else if .Capabilities.APIVersions.Has "cloud.google.com/v1" -}} +{{- print "cloud.google.com/v1" -}} +{{- else -}} +{{- print "cloud.google.com/v1beta1" -}} +{{- end -}} +{{- end -}} diff --git a/helm/argo-workflows/templates/controller/artifact-repository-ref-cm.yaml b/helm/argo-workflows/templates/controller/artifact-repository-ref-cm.yaml new file mode 100644 index 0000000..ce7cd55 --- /dev/null +++ b/helm/argo-workflows/templates/controller/artifact-repository-ref-cm.yaml @@ -0,0 +1,19 @@ +{{- range $cm_name, $cm_val := .Values.artifactRepositoryRef }} +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ $cm_name }} + namespace: {{ $.Release.Namespace | quote }} + labels: + {{- include "argo-workflows.labels" (dict "context" $ "component" $.Values.controller.name "name" $cm_name) | nindent 4 }} + {{- with $cm_val.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +data: + {{- range $data_key, $data_val := (omit $cm_val "annotations") }} + {{- $data_key | nindent 2 }}: | + {{- toYaml $data_val | nindent 4 }} + {{- end }} +{{- end }} diff --git a/helm/argo-workflows/templates/controller/workflow-aggregate-roles.yaml b/helm/argo-workflows/templates/controller/workflow-aggregate-roles.yaml new file mode 100644 index 0000000..977bb86 --- /dev/null +++ b/helm/argo-workflows/templates/controller/workflow-aggregate-roles.yaml @@ -0,0 +1,91 @@ +{{- if .Values.createAggregateRoles }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "argo-workflows.fullname" . }}-view + labels: + {{- include "argo-workflows.labels" (dict "context" . "component" .Values.controller.name "name" .Values.controller.name) | nindent 4 }} + rbac.authorization.k8s.io/aggregate-to-view: "true" +rules: +- apiGroups: + - argoproj.io + resources: + - workflows + - workflows/finalizers + - workfloweventbindings + - workfloweventbindings/finalizers + - workflowtemplates + - workflowtemplates/finalizers + - cronworkflows + - cronworkflows/finalizers + - clusterworkflowtemplates + - clusterworkflowtemplates/finalizers + verbs: + - get + - list + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "argo-workflows.fullname" . }}-edit + labels: + {{- include "argo-workflows.labels" (dict "context" . "component" .Values.server.name "name" .Values.server.name) | nindent 4 }} + rbac.authorization.k8s.io/aggregate-to-edit: "true" +rules: +- apiGroups: + - argoproj.io + resources: + - workflows + - workflows/finalizers + - workfloweventbindings + - workfloweventbindings/finalizers + - workflowtemplates + - workflowtemplates/finalizers + - cronworkflows + - cronworkflows/finalizers + - clusterworkflowtemplates + - clusterworkflowtemplates/finalizers + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "argo-workflows.fullname" . }}-admin + labels: + {{- include "argo-workflows.labels" (dict "context" . "component" .Values.server.name "name" .Values.server.name) | nindent 4 }} + rbac.authorization.k8s.io/aggregate-to-admin: "true" +rules: +- apiGroups: + - argoproj.io + resources: + - workflows + - workflows/finalizers + - workfloweventbindings + - workfloweventbindings/finalizers + - workflowtasksets + - workflowtasksets/finalizers + - workflowtemplates + - workflowtemplates/finalizers + - cronworkflows + - cronworkflows/finalizers + - clusterworkflowtemplates + - clusterworkflowtemplates/finalizers + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch +{{- end }} diff --git a/helm/argo-workflows/templates/controller/workflow-controller-cluster-roles.yaml b/helm/argo-workflows/templates/controller/workflow-controller-cluster-roles.yaml new file mode 100644 index 0000000..c2d2a77 --- /dev/null +++ b/helm/argo-workflows/templates/controller/workflow-controller-cluster-roles.yaml @@ -0,0 +1,220 @@ +{{- if .Values.controller.rbac.create }} +apiVersion: rbac.authorization.k8s.io/v1 +{{- if .Values.singleNamespace }} +kind: Role +{{- else }} +kind: ClusterRole +{{- end }} +metadata: + name: {{ template "argo-workflows.controller.fullname" . }} + {{- if .Values.singleNamespace }} + namespace: {{ .Release.Namespace | quote }} + {{- end }} + labels: + {{- include "argo-workflows.labels" (dict "context" . "component" .Values.controller.name "name" .Values.controller.name) | nindent 4 }} +rules: +- apiGroups: + - "" + resources: + - pods + verbs: + - create + - get + - list + - watch + - update + - patch + - delete +- apiGroups: + - "" + resources: + - pods/exec + verbs: + - create +- apiGroups: + - "" + resources: + - configmaps + verbs: + - get + - watch + - list + {{- if .Values.controller.rbac.writeConfigMaps }} + - create + - update + {{- end}} +- apiGroups: + - "" + resources: + - persistentvolumeclaims + - persistentvolumeclaims/finalizers + verbs: + - create + - update + - delete + - get +- apiGroups: + - argoproj.io + resources: + - workflows + - workflows/finalizers + - workflowtasksets + - workflowtasksets/finalizers + - workflowartifactgctasks + verbs: + - get + - list + - watch + - update + - patch + - delete + - create +- apiGroups: + - argoproj.io + resources: + - workflowtemplates + - workflowtemplates/finalizers + verbs: + - get + - list + - watch +- apiGroups: + - argoproj.io + resources: + - workflowtaskresults + - workflowtaskresults/finalizers + verbs: + - list + - watch + - deletecollection +- apiGroups: + - argoproj.io + resources: + - cronworkflows + - cronworkflows/finalizers + verbs: + - get + - list + - watch + - update + - patch + - delete +- apiGroups: + - "" + resources: + - events + verbs: + - create + - patch +- apiGroups: + - "" + resources: + - serviceaccounts + verbs: + - get + - list +- apiGroups: + - "policy" + resources: + - poddisruptionbudgets + verbs: + - create + - get + - delete +{{- if .Values.controller.persistence }} +- apiGroups: + - "" + resources: + - secrets + resourceNames: + {{- if .Values.controller.persistence.postgresql }} + - {{ .Values.controller.persistence.postgresql.userNameSecret.name }} + - {{ .Values.controller.persistence.postgresql.passwordSecret.name }} + {{- end}} + {{- if .Values.controller.persistence.mysql }} + - {{ .Values.controller.persistence.mysql.userNameSecret.name }} + - {{ .Values.controller.persistence.mysql.passwordSecret.name }} + {{- end}} + verbs: + - get +{{- end}} +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - create +- apiGroups: + - coordination.k8s.io + resources: + - leases + resourceNames: + {{- if .Values.controller.instanceID.enabled }} + {{- if .Values.controller.instanceID.useReleaseName }} + - workflow-controller-{{ .Release.Name }} + - workflow-controller-lease-{{ .Release.Name }} + {{- else }} + - workflow-controller-{{ .Values.controller.instanceID.explicitID }} + - workflow-controller-lease-{{ .Values.controller.instanceID.explicitID }} + {{- end }} + {{- else }} + - workflow-controller + - workflow-controller-lease + {{- end }} + verbs: + - get + - watch + - update + - patch + - delete +- apiGroups: + - "" + resources: + - secrets + verbs: + - get + resourceNames: + {{/* for HTTP templates */}} + - argo-workflows-agent-ca-certificates +{{- with .Values.controller.rbac.secretWhitelist }} +- apiGroups: + - "" + resources: + - secrets + verbs: + - get + - list + - watch + resourceNames: {{- toYaml . | nindent 4 }} +{{- end }} +{{- if and (not .Values.controller.rbac.secretWhitelist) (.Values.controller.rbac.accessAllSecrets) }} +- apiGroups: + - "" + resources: + - secrets + verbs: + - get + - list + - watch +{{- end }} + +{{- if .Values.controller.clusterWorkflowTemplates.enabled }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "argo-workflows.controller.fullname" . }}-cluster-template + labels: + {{- include "argo-workflows.labels" (dict "context" . "component" .Values.controller.name "name" .Values.controller.name) | nindent 4 }} +rules: +- apiGroups: + - argoproj.io + resources: + - clusterworkflowtemplates + - clusterworkflowtemplates/finalizers + verbs: + - get + - list + - watch +{{- end }} +{{- end }} diff --git a/helm/argo-workflows/templates/controller/workflow-controller-config-map.yaml b/helm/argo-workflows/templates/controller/workflow-controller-config-map.yaml new file mode 100644 index 0000000..d4728a3 --- /dev/null +++ b/helm/argo-workflows/templates/controller/workflow-controller-config-map.yaml @@ -0,0 +1,193 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "argo-workflows.controller.fullname" . }}-configmap + namespace: {{ .Release.Namespace | quote }} + labels: + {{- include "argo-workflows.labels" (dict "context" . "component" .Values.controller.name "name" "cm") | nindent 4 }} +data: + config: | + {{- if .Values.controller.instanceID.enabled }} + {{- if .Values.controller.instanceID.useReleaseName }} + instanceID: {{ .Release.Name }} + {{- else }} + instanceID: {{ .Values.controller.instanceID.explicitID }} + {{- end }} + {{- end }} + {{- if .Values.controller.parallelism }} + parallelism: {{ .Values.controller.parallelism }} + {{- end }} + {{- if .Values.controller.resourceRateLimit }} + resourceRateLimit: {{ toYaml .Values.controller.resourceRateLimit | nindent 6 }} + {{- end }} + {{- with .Values.controller.namespaceParallelism }} + namespaceParallelism: {{ . }} + {{- end }} + {{- with .Values.controller.initialDelay }} + initialDelay: {{ . }} + {{- end }} + {{- if or .Values.mainContainer.resources .Values.mainContainer.env .Values.mainContainer.envFrom .Values.mainContainer.securityContext}} + mainContainer: + imagePullPolicy: {{ default (.Values.images.pullPolicy) .Values.mainContainer.imagePullPolicy }} + {{- with .Values.mainContainer.resources }} + resources: {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.mainContainer.env }} + env: {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.mainContainer.envFrom }} + envFrom: {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.mainContainer.securityContext }} + securityContext: {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + {{- if or .Values.executor.resources .Values.executor.env .Values.executor.args .Values.executor.securityContext}} + executor: + imagePullPolicy: {{ default (.Values.images.pullPolicy) .Values.executor.image.pullPolicy }} + {{- with .Values.executor.resources }} + resources: {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.executor.args }} + args: {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.executor.env }} + env: {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.executor.securityContext }} + securityContext: {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + {{- if or .Values.artifactRepository.s3 .Values.artifactRepository.gcs .Values.artifactRepository.azure .Values.customArtifactRepository }} + artifactRepository: + {{- if .Values.artifactRepository.archiveLogs }} + archiveLogs: {{ .Values.artifactRepository.archiveLogs }} + {{- end }} + {{- with .Values.artifactRepository.gcs }} + gcs: {{- tpl (toYaml .) $ | nindent 8 }} + {{- end }} + {{- with .Values.artifactRepository.azure }} + azure: {{- tpl (toYaml .) $ | nindent 8 }} + {{- end }} + {{- if .Values.artifactRepository.s3 }} + s3: + {{- if .Values.useStaticCredentials }} + accessKeySecret: + key: {{ tpl .Values.artifactRepository.s3.accessKeySecret.key . }} + name: {{ tpl .Values.artifactRepository.s3.accessKeySecret.name . }} + secretKeySecret: + key: {{ tpl .Values.artifactRepository.s3.secretKeySecret.key . }} + name: {{ tpl .Values.artifactRepository.s3.secretKeySecret.name . }} + {{- end }} + bucket: {{ tpl (.Values.artifactRepository.s3.bucket | default "") . }} + endpoint: {{ tpl (.Values.artifactRepository.s3.endpoint | default "") . }} + insecure: {{ .Values.artifactRepository.s3.insecure }} + {{- if .Values.artifactRepository.s3.keyFormat }} + keyFormat: {{ .Values.artifactRepository.s3.keyFormat | quote }} + {{- end }} + {{- if .Values.artifactRepository.s3.region }} + region: {{ tpl .Values.artifactRepository.s3.region $ }} + {{- end }} + {{- if .Values.artifactRepository.s3.roleARN }} + roleARN: {{ .Values.artifactRepository.s3.roleARN }} + {{- end }} + {{- if .Values.artifactRepository.s3.useSDKCreds }} + useSDKCreds: {{ .Values.artifactRepository.s3.useSDKCreds }} + {{- end }} + {{- with .Values.artifactRepository.s3.encryptionOptions }} + encryptionOptions: + {{- toYaml . | nindent 10 }} + {{- end }} + {{- end }} + {{- if .Values.customArtifactRepository }} + {{- toYaml .Values.customArtifactRepository | nindent 6 }} + {{- end }} + {{- end }} + {{- if .Values.controller.metricsConfig.enabled }} + metricsConfig: + enabled: {{ .Values.controller.metricsConfig.enabled }} + path: {{ .Values.controller.metricsConfig.path }} + port: {{ .Values.controller.metricsConfig.port }} + {{- if .Values.controller.metricsConfig.metricsTTL }} + metricsTTL: {{ .Values.controller.metricsConfig.metricsTTL }} + {{- end }} + ignoreErrors: {{ .Values.controller.metricsConfig.ignoreErrors }} + secure: {{ .Values.controller.metricsConfig.secure }} + {{- end }} + {{- if .Values.controller.telemetryConfig.enabled }} + telemetryConfig: + enabled: {{ .Values.controller.telemetryConfig.enabled }} + path: {{ .Values.controller.telemetryConfig.path }} + port: {{ .Values.controller.telemetryConfig.port }} + {{- if .Values.controller.telemetryConfig.metricsTTL }} + metricsTTL: {{ .Values.controller.telemetryConfig.metricsTTL }} + {{- end }} + ignoreErrors: {{ .Values.controller.telemetryConfig.ignoreErrors }} + secure: {{ .Values.controller.telemetryConfig.secure }} + {{- end }} + {{- if .Values.controller.persistence }} + persistence: +{{ toYaml .Values.controller.persistence | indent 6 }}{{- end }} + {{- if .Values.controller.workflowDefaults }} + workflowDefaults: +{{ toYaml .Values.controller.workflowDefaults | indent 6 }}{{- end }} + {{- if .Values.server.sso.enabled }} + sso: + issuer: {{ .Values.server.sso.issuer }} + clientId: + name: {{ .Values.server.sso.clientId.name }} + key: {{ .Values.server.sso.clientId.key }} + clientSecret: + name: {{ .Values.server.sso.clientSecret.name }} + key: {{ .Values.server.sso.clientSecret.key }} + redirectUrl: {{ .Values.server.sso.redirectUrl }} + rbac: + enabled: {{ .Values.server.sso.rbac.enabled }} + {{- with .Values.server.sso.scopes }} + scopes: {{ toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.server.sso.issuerAlias }} + issuerAlias: {{ toYaml . }} + {{- end }} + {{- with .Values.server.sso.sessionExpiry }} + sessionExpiry: {{ toYaml . }} + {{- end }} + {{- with .Values.server.sso.customGroupClaimName }} + customGroupClaimName: {{ toYaml . }} + {{- end }} + {{- with .Values.server.sso.userInfoPath }} + userInfoPath: {{ toYaml . }} + {{- end }} + {{- with .Values.server.sso.insecureSkipVerify }} + insecureSkipVerify: {{ toYaml . }} + {{- end }} + {{- end }} + {{- with .Values.controller.workflowRestrictions }} + workflowRestrictions: {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.controller.links }} + links: {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.controller.columns }} + columns: {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.controller.navColor }} + navColor: {{ . }} + {{- end }} + {{- with .Values.controller.retentionPolicy }} + retentionPolicy: {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.emissary.images }} + images: {{- toYaml . | nindent 6 }} + {{- end }} + nodeEvents: + enabled: {{ .Values.controller.nodeEvents.enabled }} + {{- with .Values.controller.kubeConfig }} + kubeConfig: {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.controller.podGCGracePeriodSeconds }} + podGCGracePeriodSeconds: {{ . }} + {{- end }} + {{- with .Values.controller.podGCDeleteDelayDuration }} + podGCDeleteDelayDuration: {{ . }} + {{- end }} diff --git a/helm/argo-workflows/templates/controller/workflow-controller-crb.yaml b/helm/argo-workflows/templates/controller/workflow-controller-crb.yaml new file mode 100644 index 0000000..9fa7a7f --- /dev/null +++ b/helm/argo-workflows/templates/controller/workflow-controller-crb.yaml @@ -0,0 +1,45 @@ +{{- if .Values.controller.rbac.create }} +apiVersion: rbac.authorization.k8s.io/v1 +{{- if .Values.singleNamespace }} +kind: RoleBinding +{{ else }} +kind: ClusterRoleBinding +{{- end }} +metadata: + name: {{ template "argo-workflows.controller.fullname" . }} + {{- if .Values.singleNamespace }} + namespace: {{ .Release.Namespace | quote }} + {{- end }} + labels: + {{- include "argo-workflows.labels" (dict "context" . "component" .Values.controller.name "name" .Values.controller.name) | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + {{- if .Values.singleNamespace }} + kind: Role + {{ else }} + kind: ClusterRole + {{- end }} + name: {{ template "argo-workflows.controller.fullname" . }} +subjects: + - kind: ServiceAccount + name: {{ template "argo-workflows.controllerServiceAccountName" . }} + namespace: {{ .Release.Namespace | quote }} + +{{- if .Values.controller.clusterWorkflowTemplates.enabled }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "argo-workflows.controller.fullname" . }}-cluster-template + labels: + {{- include "argo-workflows.labels" (dict "context" . "component" .Values.controller.name "name" .Values.controller.name) | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "argo-workflows.controller.fullname" . }}-cluster-template +subjects: + - kind: ServiceAccount + name: {{ template "argo-workflows.controllerServiceAccountName" . }} + namespace: {{ .Release.Namespace | quote }} +{{- end }} +{{- end }} diff --git a/helm/argo-workflows/templates/controller/workflow-controller-deployment-pdb.yaml b/helm/argo-workflows/templates/controller/workflow-controller-deployment-pdb.yaml new file mode 100644 index 0000000..ee38445 --- /dev/null +++ b/helm/argo-workflows/templates/controller/workflow-controller-deployment-pdb.yaml @@ -0,0 +1,20 @@ +{{- if .Values.controller.pdb.enabled }} +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: {{ template "argo-workflows.controller.fullname" . }} + namespace: {{ .Release.Namespace | quote }} + labels: + {{- include "argo-workflows.labels" (dict "context" . "component" .Values.controller.name "name" .Values.controller.name) | nindent 4 }} +spec: + {{- if .Values.controller.pdb.minAvailable }} + minAvailable: {{ .Values.controller.pdb.minAvailable }} + {{- else if .Values.controller.pdb.maxUnavailable }} + maxUnavailable: {{ .Values.controller.pdb.maxUnavailable }} + {{- else }} + minAvailable: 0 + {{- end }} + selector: + matchLabels: + {{- include "argo-workflows.selectorLabels" (dict "context" . "name" .Values.controller.name) | nindent 6 }} +{{- end }} diff --git a/helm/argo-workflows/templates/controller/workflow-controller-deployment.yaml b/helm/argo-workflows/templates/controller/workflow-controller-deployment.yaml new file mode 100644 index 0000000..c391bee --- /dev/null +++ b/helm/argo-workflows/templates/controller/workflow-controller-deployment.yaml @@ -0,0 +1,129 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "argo-workflows.controller.fullname" . }} + namespace: {{ .Release.Namespace | quote }} + labels: + {{- include "argo-workflows.labels" (dict "context" . "component" .Values.controller.name "name" .Values.controller.name) | nindent 4 }} + app.kubernetes.io/version: {{ include "argo-workflows.controller_chart_version_label" . }} + {{- with .Values.controller.deploymentAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + replicas: {{ .Values.controller.replicas }} + selector: + matchLabels: + {{- include "argo-workflows.selectorLabels" (dict "context" . "name" .Values.controller.name) | nindent 6 }} + template: + metadata: + labels: + {{- include "argo-workflows.labels" (dict "context" . "component" .Values.controller.name "name" .Values.controller.name) | nindent 8 }} + app.kubernetes.io/version: {{ include "argo-workflows.controller_chart_version_label" . }} + {{- with.Values.controller.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.controller.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + serviceAccountName: {{ template "argo-workflows.controllerServiceAccountName" . }} + {{- with .Values.controller.podSecurityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.controller.extraInitContainers }} + initContainers: + {{- tpl (toYaml .) $ | nindent 8 }} + {{- end }} + containers: + - name: controller + image: "{{- include "argo-workflows.image" (dict "context" . "image" .Values.controller.image) }}:{{ default (include "argo-workflows.defaultTag" .) .Values.controller.image.tag }}" + imagePullPolicy: {{ .Values.images.pullPolicy }} + command: [ "workflow-controller" ] + args: + - "--configmap" + - "{{ template "argo-workflows.controller.fullname" . }}-configmap" + - "--executor-image" + - "{{- include "argo-workflows.image" (dict "context" . "image" .Values.executor.image) }}:{{ default (include "argo-workflows.defaultTag" .) .Values.executor.image.tag }}" + - "--loglevel" + - "{{ .Values.controller.logging.level }}" + - "--gloglevel" + - "{{ .Values.controller.logging.globallevel }}" + - "--log-format" + - "{{ .Values.controller.logging.format }}" + {{- if .Values.singleNamespace }} + - "--namespaced" + {{- end }} + {{- with .Values.controller.workflowWorkers }} + - "--workflow-workers" + - {{ . | quote }} + {{- end }} + {{- with .Values.controller.extraArgs }} + {{- toYaml . | nindent 10 }} + {{- end }} + securityContext: + {{- toYaml .Values.controller.securityContext | nindent 12 }} + env: + - name: ARGO_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: LEADER_ELECTION_IDENTITY + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + {{- with .Values.controller.extraEnv }} + {{- toYaml . | nindent 12 }} + {{- end }} + resources: + {{- toYaml .Values.controller.resources | nindent 12 }} + {{- with .Values.controller.volumeMounts }} + volumeMounts: + {{- toYaml . | nindent 10 }} + {{- end }} + ports: + - name: {{ .Values.controller.metricsConfig.portName }} + containerPort: {{ .Values.controller.metricsConfig.port }} + - containerPort: 6060 + livenessProbe: {{ .Values.controller.livenessProbe | toYaml | nindent 12 }} + {{- with .Values.controller.extraContainers }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.images.pullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.controller.volumes }} + volumes: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.controller.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.controller.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.controller.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.controller.topologySpreadConstraints }} + topologySpreadConstraints: + {{- range $constraint := . }} + - {{ toYaml $constraint | nindent 8 | trim }} + {{- if not $constraint.labelSelector }} + labelSelector: + matchLabels: + {{- include "argo-workflows.selectorLabels" (dict "context" $ "name" $.Values.controller.name) | nindent 12 }} + {{- end }} + {{- end }} + {{- end }} + {{- with .Values.controller.priorityClassName }} + priorityClassName: {{ . }} + {{- end }} diff --git a/helm/argo-workflows/templates/controller/workflow-controller-sa.yaml b/helm/argo-workflows/templates/controller/workflow-controller-sa.yaml new file mode 100644 index 0000000..c6a8bf6 --- /dev/null +++ b/helm/argo-workflows/templates/controller/workflow-controller-sa.yaml @@ -0,0 +1,16 @@ +{{- if .Values.controller.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "argo-workflows.controllerServiceAccountName" . }} + namespace: {{ .Release.Namespace | quote }} + labels: + {{- include "argo-workflows.labels" (dict "context" . "component" .Values.controller.name "name" .Values.controller.name) | nindent 4 }} + {{- with .Values.controller.serviceAccount.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{ with .Values.controller.serviceAccount.annotations }} + annotations: + {{- toYaml .| nindent 4 }} + {{- end }} +{{- end }} diff --git a/helm/argo-workflows/templates/controller/workflow-controller-service.yaml b/helm/argo-workflows/templates/controller/workflow-controller-service.yaml new file mode 100644 index 0000000..5ade3d4 --- /dev/null +++ b/helm/argo-workflows/templates/controller/workflow-controller-service.yaml @@ -0,0 +1,39 @@ +{{- if or .Values.controller.metricsConfig.enabled .Values.controller.telemetryConfig.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "argo-workflows.controller.fullname" . }} + namespace: {{ .Release.Namespace | quote }} + labels: + {{- include "argo-workflows.labels" (dict "context" . "component" .Values.controller.name "name" .Values.controller.name) | nindent 4 }} + app.kubernetes.io/version: {{ default (include "argo-workflows.defaultTag" .) .Values.controller.image.tag | trunc 63 | quote }} + {{- with .Values.controller.serviceLabels }} + {{ toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.controller.serviceAnnotations }} + annotations: + {{- toYaml . | nindent 4}} + {{- end }} +spec: + ports: + {{- if .Values.controller.metricsConfig.enabled }} + - name: {{ .Values.controller.metricsConfig.servicePortName }} + port: {{ .Values.controller.metricsConfig.servicePort }} + protocol: TCP + targetPort: {{ .Values.controller.metricsConfig.port }} + {{- end }} + {{- if .Values.controller.telemetryConfig.enabled }} + - name: {{ .Values.controller.telemetryConfig.servicePortName }} + port: {{ .Values.controller.telemetryConfig.servicePort }} + protocol: TCP + targetPort: {{ .Values.controller.telemetryConfig.port }} + {{- end }} + selector: + {{- include "argo-workflows.selectorLabels" (dict "context" . "name" .Values.controller.name) | nindent 4 }} + sessionAffinity: None + type: {{ .Values.controller.serviceType }} + {{- if and (eq .Values.controller.serviceType "LoadBalancer") .Values.controller.loadBalancerSourceRanges }} + loadBalancerSourceRanges: + {{- toYaml .Values.controller.loadBalancerSourceRanges | nindent 4 }} + {{- end }} +{{- end -}} diff --git a/helm/argo-workflows/templates/controller/workflow-controller-servicemonitor.yaml b/helm/argo-workflows/templates/controller/workflow-controller-servicemonitor.yaml new file mode 100644 index 0000000..6643d63 --- /dev/null +++ b/helm/argo-workflows/templates/controller/workflow-controller-servicemonitor.yaml @@ -0,0 +1,50 @@ +{{- if and (or .Values.controller.metricsConfig.enabled .Values.controller.telemetryConfig.enabled) .Values.controller.serviceMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "argo-workflows.controller.fullname" . }} + namespace: {{ default .Release.Namespace .Values.controller.serviceMonitor.namespace | quote }} + labels: + {{- include "argo-workflows.labels" (dict "context" . "component" .Values.controller.name "name" .Values.controller.name) | nindent 4 }} + {{- with .Values.controller.serviceMonitor.additionalLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + endpoints: + {{- if .Values.controller.metricsConfig.enabled }} + - port: {{ .Values.controller.metricsConfig.servicePortName }} + path: {{ .Values.controller.metricsConfig.path }} + interval: 30s + {{- with .Values.controller.metricsConfig.relabelings }} + relabelings: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.controller.metricsConfig.metricRelabelings }} + metricRelabelings: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + {{- if .Values.controller.telemetryConfig.enabled }} + - port: telemetry + path: {{ .Values.controller.telemetryConfig.path }} + interval: 30s + {{- with .Values.controller.metricsConfig.relabelings }} + relabelings: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.controller.metricsConfig.metricRelabelings }} + metricRelabelings: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + {{- with .Values.controller.metricsConfig.targetLabels }} + targetLabels: + {{- toYaml . | nindent 8 }} + {{- end }} + namespaceSelector: + matchNames: + - {{ .Release.Namespace | quote }} + selector: + matchLabels: + {{- include "argo-workflows.selectorLabels" (dict "context" . "name" .Values.controller.name) | nindent 6 }} +{{- end }} diff --git a/helm/argo-workflows/templates/controller/workflow-rb.yaml b/helm/argo-workflows/templates/controller/workflow-rb.yaml new file mode 100644 index 0000000..6f9ba23 --- /dev/null +++ b/helm/argo-workflows/templates/controller/workflow-rb.yaml @@ -0,0 +1,24 @@ +{{- if .Values.workflow.rbac.create -}} + {{- range $namespace := or .Values.singleNamespace false | ternary (list "") (append .Values.controller.workflowNamespaces (coalesce .Values.workflow.namespace .Release.Namespace) | uniq) }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ template "argo-workflows.fullname" $ }}-workflow + labels: + {{- include "argo-workflows.labels" (dict "context" $ "component" $.Values.controller.name "name" $.Values.controller.name) | nindent 4 }} + {{- with $namespace }} + namespace: {{ . }} + {{- end }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "argo-workflows.fullname" $ }}-workflow +subjects: + - kind: ServiceAccount + name: {{ $.Values.workflow.serviceAccount.name }} + {{- with $namespace }} + namespace: {{ . }} + {{- end }} + {{- end }} +{{- end }} diff --git a/helm/argo-workflows/templates/controller/workflow-role.yaml b/helm/argo-workflows/templates/controller/workflow-role.yaml new file mode 100644 index 0000000..51050d0 --- /dev/null +++ b/helm/argo-workflows/templates/controller/workflow-role.yaml @@ -0,0 +1,58 @@ +{{- if .Values.workflow.rbac.create -}} + {{- range $namespace := or .Values.singleNamespace false | ternary (list "") (append .Values.controller.workflowNamespaces (coalesce .Values.workflow.namespace .Release.Namespace) | uniq) }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ template "argo-workflows.fullname" $ }}-workflow + labels: + {{- include "argo-workflows.labels" (dict "context" $ "component" $.Values.controller.name "name" $.Values.controller.name) | nindent 4 }} + {{- with $namespace }} + namespace: {{ . }} + {{- end }} +rules: + - apiGroups: + - "" + resources: + - pods + verbs: + - get + - watch + - patch + - apiGroups: + - "" + resources: + - pods/log + verbs: + - get + - watch + - apiGroups: + - "" + resources: + - pods/exec + verbs: + - create + - apiGroups: + - argoproj.io + resources: + - workflowtaskresults + verbs: + - create + - apiGroups: + - argoproj.io + resources: + - workflowtasksets + - workflowartifactgctasks + verbs: + - list + - watch + - apiGroups: + - argoproj.io + resources: + - workflowtasksets/status + - workflowartifactgctasks/status + verbs: + - patch + {{- end }} + +{{- end }} diff --git a/helm/argo-workflows/templates/controller/workflow-sa.yaml b/helm/argo-workflows/templates/controller/workflow-sa.yaml new file mode 100644 index 0000000..273487c --- /dev/null +++ b/helm/argo-workflows/templates/controller/workflow-sa.yaml @@ -0,0 +1,25 @@ +{{- if .Values.workflow.serviceAccount.create -}} + {{- range $namespace := or .Values.singleNamespace false | ternary (list "") (append .Values.controller.workflowNamespaces (coalesce .Values.workflow.namespace .Release.Namespace) | uniq) }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ $.Values.workflow.serviceAccount.name }} + labels: + {{- include "argo-workflows.labels" (dict "context" $ "component" $.Values.controller.name "name" $.Values.controller.name) | nindent 4 }} + {{- with $.Values.workflow.serviceAccount.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with $namespace }} + namespace: {{ . }} + {{- end }} + {{- with $.Values.workflow.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with $.Values.workflow.serviceAccount.pullSecrets }} +imagePullSecrets: + {{- toYaml . | nindent 2 }} + {{- end }} + {{- end }} +{{- end }} diff --git a/helm/argo-workflows/templates/crds/argoproj.io_clusterworkflowtemplates.yaml b/helm/argo-workflows/templates/crds/argoproj.io_clusterworkflowtemplates.yaml new file mode 100644 index 0000000..9264eab --- /dev/null +++ b/helm/argo-workflows/templates/crds/argoproj.io_clusterworkflowtemplates.yaml @@ -0,0 +1,47 @@ +{{- if .Values.crds.install }} +{{- if or (.Values.server.clusterWorkflowTemplates.enabled) (.Values.controller.clusterWorkflowTemplates.enabled) }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: clusterworkflowtemplates.argoproj.io + annotations: + {{- if .Values.crds.keep }} + "helm.sh/resource-policy": keep + {{- end }} + {{- with .Values.crds.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + group: argoproj.io + names: + kind: ClusterWorkflowTemplate + listKind: ClusterWorkflowTemplateList + plural: clusterworkflowtemplates + shortNames: + - clusterwftmpl + - cwft + singular: clusterworkflowtemplate + scope: Cluster + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + type: object + x-kubernetes-map-type: atomic + x-kubernetes-preserve-unknown-fields: true + required: + - metadata + - spec + type: object + served: true + storage: true +{{- end }} +{{- end }} diff --git a/helm/argo-workflows/templates/crds/argoproj.io_cronworkflows.yaml b/helm/argo-workflows/templates/crds/argoproj.io_cronworkflows.yaml new file mode 100644 index 0000000..7b932d8 --- /dev/null +++ b/helm/argo-workflows/templates/crds/argoproj.io_cronworkflows.yaml @@ -0,0 +1,49 @@ +{{- if .Values.crds.install }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: cronworkflows.argoproj.io + annotations: + {{- if .Values.crds.keep }} + "helm.sh/resource-policy": keep + {{- end }} + {{- with .Values.crds.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + group: argoproj.io + names: + kind: CronWorkflow + listKind: CronWorkflowList + plural: cronworkflows + shortNames: + - cwf + - cronwf + singular: cronworkflow + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + type: object + x-kubernetes-map-type: atomic + x-kubernetes-preserve-unknown-fields: true + status: + type: object + x-kubernetes-map-type: atomic + x-kubernetes-preserve-unknown-fields: true + required: + - metadata + - spec + type: object + served: true + storage: true +{{- end }} diff --git a/helm/argo-workflows/templates/crds/argoproj.io_workflowartifactgctasks.yaml b/helm/argo-workflows/templates/crds/argoproj.io_workflowartifactgctasks.yaml new file mode 100644 index 0000000..dcebddb --- /dev/null +++ b/helm/argo-workflows/templates/crds/argoproj.io_workflowartifactgctasks.yaml @@ -0,0 +1,50 @@ +{{- if .Values.crds.install }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: workflowartifactgctasks.argoproj.io + annotations: + {{- if .Values.crds.keep }} + "helm.sh/resource-policy": keep + {{- end }} + {{- with .Values.crds.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + group: argoproj.io + names: + kind: WorkflowArtifactGCTask + listKind: WorkflowArtifactGCTaskList + plural: workflowartifactgctasks + shortNames: + - wfat + singular: workflowartifactgctask + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + type: object + x-kubernetes-map-type: atomic + x-kubernetes-preserve-unknown-fields: true + status: + type: object + x-kubernetes-map-type: atomic + x-kubernetes-preserve-unknown-fields: true + required: + - metadata + - spec + type: object + served: true + storage: true + subresources: + status: {} +{{- end }} diff --git a/helm/argo-workflows/templates/crds/argoproj.io_workfloweventbindings.yaml b/helm/argo-workflows/templates/crds/argoproj.io_workfloweventbindings.yaml new file mode 100644 index 0000000..097fa5c --- /dev/null +++ b/helm/argo-workflows/templates/crds/argoproj.io_workfloweventbindings.yaml @@ -0,0 +1,44 @@ +{{- if .Values.crds.install }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: workfloweventbindings.argoproj.io + annotations: + {{- if .Values.crds.keep }} + "helm.sh/resource-policy": keep + {{- end }} + {{- with .Values.crds.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + group: argoproj.io + names: + kind: WorkflowEventBinding + listKind: WorkflowEventBindingList + plural: workfloweventbindings + shortNames: + - wfeb + singular: workfloweventbinding + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + type: object + x-kubernetes-map-type: atomic + x-kubernetes-preserve-unknown-fields: true + required: + - metadata + - spec + type: object + served: true + storage: true +{{- end }} diff --git a/helm/argo-workflows/templates/crds/argoproj.io_workflows.yaml b/helm/argo-workflows/templates/crds/argoproj.io_workflows.yaml new file mode 100644 index 0000000..85b71f9 --- /dev/null +++ b/helm/argo-workflows/templates/crds/argoproj.io_workflows.yaml @@ -0,0 +1,64 @@ +{{- if .Values.crds.install }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: workflows.argoproj.io + annotations: + {{- if .Values.crds.keep }} + "helm.sh/resource-policy": keep + {{- end }} + {{- with .Values.crds.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + group: argoproj.io + names: + kind: Workflow + listKind: WorkflowList + plural: workflows + shortNames: + - wf + singular: workflow + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Status of the workflow + jsonPath: .status.phase + name: Status + type: string + - description: When the workflow was started + format: date-time + jsonPath: .status.startedAt + name: Age + type: date + - description: Human readable message indicating details about why the workflow + is in this condition. + jsonPath: .status.message + name: Message + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + type: object + x-kubernetes-map-type: atomic + x-kubernetes-preserve-unknown-fields: true + status: + type: object + x-kubernetes-map-type: atomic + x-kubernetes-preserve-unknown-fields: true + required: + - metadata + - spec + type: object + served: true + storage: true + subresources: {} +{{- end }} diff --git a/helm/argo-workflows/templates/crds/argoproj.io_workflowtaskresults.yaml b/helm/argo-workflows/templates/crds/argoproj.io_workflowtaskresults.yaml new file mode 100644 index 0000000..e9bb93f --- /dev/null +++ b/helm/argo-workflows/templates/crds/argoproj.io_workflowtaskresults.yaml @@ -0,0 +1,593 @@ +{{- if .Values.crds.install }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: workflowtaskresults.argoproj.io + annotations: + {{- if .Values.crds.keep }} + "helm.sh/resource-policy": keep + {{- end }} + {{- with .Values.crds.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + group: argoproj.io + names: + kind: WorkflowTaskResult + listKind: WorkflowTaskResultList + plural: workflowtaskresults + singular: workflowtaskresult + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + message: + type: string + metadata: + type: object + outputs: + properties: + artifacts: + items: + properties: + archive: + properties: + none: + type: object + tar: + properties: + compressionLevel: + format: int32 + type: integer + type: object + zip: + type: object + type: object + archiveLogs: + type: boolean + artifactGC: + properties: + podMetadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + serviceAccountName: + type: string + strategy: + enum: + - "" + - OnWorkflowCompletion + - OnWorkflowDeletion + - Never + type: string + type: object + artifactory: + properties: + passwordSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + url: + type: string + usernameSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + required: + - url + type: object + azure: + properties: + accountKeySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + blob: + type: string + container: + type: string + endpoint: + type: string + useSDKCreds: + type: boolean + required: + - blob + - container + - endpoint + type: object + deleted: + type: boolean + from: + type: string + fromExpression: + type: string + gcs: + properties: + bucket: + type: string + key: + type: string + serviceAccountKeySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + required: + - key + type: object + git: + properties: + branch: + type: string + depth: + format: int64 + type: integer + disableSubmodules: + type: boolean + fetch: + items: + type: string + type: array + insecureIgnoreHostKey: + type: boolean + passwordSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + repo: + type: string + revision: + type: string + singleBranch: + type: boolean + sshPrivateKeySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + usernameSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + required: + - repo + type: object + globalName: + type: string + hdfs: + properties: + addresses: + items: + type: string + type: array + force: + type: boolean + hdfsUser: + type: string + krbCCacheSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + krbConfigConfigMap: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + krbKeytabSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + krbRealm: + type: string + krbServicePrincipalName: + type: string + krbUsername: + type: string + path: + type: string + required: + - path + type: object + http: + properties: + auth: + properties: + basicAuth: + properties: + passwordSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + usernameSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + clientCert: + properties: + clientCertSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + clientKeySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + oauth2: + properties: + clientIDSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + clientSecretSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + endpointParams: + items: + properties: + key: + type: string + value: + type: string + required: + - key + type: object + type: array + scopes: + items: + type: string + type: array + tokenURLSecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + type: object + headers: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + url: + type: string + required: + - url + type: object + mode: + format: int32 + type: integer + name: + type: string + optional: + type: boolean + oss: + properties: + accessKeySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + bucket: + type: string + createBucketIfNotPresent: + type: boolean + endpoint: + type: string + key: + type: string + lifecycleRule: + properties: + markDeletionAfterDays: + format: int32 + type: integer + markInfrequentAccessAfterDays: + format: int32 + type: integer + type: object + secretKeySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + securityToken: + type: string + required: + - key + type: object + path: + type: string + raw: + properties: + data: + type: string + required: + - data + type: object + recurseMode: + type: boolean + s3: + properties: + accessKeySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + bucket: + type: string + createBucketIfNotPresent: + properties: + objectLocking: + type: boolean + type: object + encryptionOptions: + properties: + enableEncryption: + type: boolean + kmsEncryptionContext: + type: string + kmsKeyId: + type: string + serverSideCustomerKeySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + endpoint: + type: string + insecure: + type: boolean + key: + type: string + region: + type: string + roleARN: + type: string + secretKeySecret: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + useSDKCreds: + type: boolean + type: object + subPath: + type: string + required: + - name + type: object + type: array + exitCode: + type: string + parameters: + items: + properties: + default: + type: string + description: + type: string + enum: + items: + type: string + type: array + globalName: + type: string + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + default: + type: string + event: + type: string + expression: + type: string + jqFilter: + type: string + jsonPath: + type: string + parameter: + type: string + path: + type: string + supplied: + type: object + type: object + required: + - name + type: object + type: array + result: + type: string + type: object + phase: + type: string + progress: + type: string + required: + - metadata + type: object + served: true + storage: true +{{- end }} diff --git a/helm/argo-workflows/templates/crds/argoproj.io_workflowtasksets.yaml b/helm/argo-workflows/templates/crds/argoproj.io_workflowtasksets.yaml new file mode 100644 index 0000000..7469294 --- /dev/null +++ b/helm/argo-workflows/templates/crds/argoproj.io_workflowtasksets.yaml @@ -0,0 +1,50 @@ +{{- if .Values.crds.install }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: workflowtasksets.argoproj.io + annotations: + {{- if .Values.crds.keep }} + "helm.sh/resource-policy": keep + {{- end }} + {{- with .Values.crds.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + group: argoproj.io + names: + kind: WorkflowTaskSet + listKind: WorkflowTaskSetList + plural: workflowtasksets + shortNames: + - wfts + singular: workflowtaskset + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + type: object + x-kubernetes-map-type: atomic + x-kubernetes-preserve-unknown-fields: true + status: + type: object + x-kubernetes-map-type: atomic + x-kubernetes-preserve-unknown-fields: true + required: + - metadata + - spec + type: object + served: true + storage: true + subresources: + status: {} +{{- end }} diff --git a/helm/argo-workflows/templates/crds/argoproj.io_workflowtemplates.yaml b/helm/argo-workflows/templates/crds/argoproj.io_workflowtemplates.yaml new file mode 100644 index 0000000..810e6f5 --- /dev/null +++ b/helm/argo-workflows/templates/crds/argoproj.io_workflowtemplates.yaml @@ -0,0 +1,44 @@ +{{- if .Values.crds.install }} +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: workflowtemplates.argoproj.io + annotations: + {{- if .Values.crds.keep }} + "helm.sh/resource-policy": keep + {{- end }} + {{- with .Values.crds.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + group: argoproj.io + names: + kind: WorkflowTemplate + listKind: WorkflowTemplateList + plural: workflowtemplates + shortNames: + - wftmpl + singular: workflowtemplate + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + type: object + x-kubernetes-map-type: atomic + x-kubernetes-preserve-unknown-fields: true + required: + - metadata + - spec + type: object + served: true + storage: true +{{- end }} diff --git a/helm/argo-workflows/templates/extra-manifests.yaml b/helm/argo-workflows/templates/extra-manifests.yaml new file mode 100644 index 0000000..f17b1a9 --- /dev/null +++ b/helm/argo-workflows/templates/extra-manifests.yaml @@ -0,0 +1,8 @@ +{{ range .Values.extraObjects }} +--- +{{- if typeIs "string" . }} + {{- tpl . $ }} +{{- else }} + {{- tpl (toYaml .) $ }} +{{- end }} +{{ end }} diff --git a/helm/argo-workflows/templates/server/gke/backendconfig.yaml b/helm/argo-workflows/templates/server/gke/backendconfig.yaml new file mode 100644 index 0000000..4597db3 --- /dev/null +++ b/helm/argo-workflows/templates/server/gke/backendconfig.yaml @@ -0,0 +1,11 @@ +{{- if .Values.server.GKEbackendConfig.enabled }} +apiVersion: {{ include "argo-workflows.apiVersions.cloudgoogle" . }} +kind: BackendConfig +metadata: + name: {{ template "argo-workflows.server.fullname" . }} + namespace: {{ .Release.Namespace | quote }} + labels: + {{- include "argo-workflows.labels" (dict "context" . "component" .Values.server.name "name" .Values.server.name) | nindent 4 }} +spec: + {{- toYaml .Values.server.GKEbackendConfig.spec | nindent 2 }} +{{- end }} diff --git a/helm/argo-workflows/templates/server/gke/frontendconfig.yaml b/helm/argo-workflows/templates/server/gke/frontendconfig.yaml new file mode 100644 index 0000000..6b81c92 --- /dev/null +++ b/helm/argo-workflows/templates/server/gke/frontendconfig.yaml @@ -0,0 +1,11 @@ +{{- if .Values.server.GKEfrontendConfig.enabled }} +apiVersion: networking.gke.io/v1beta1 +kind: FrontendConfig +metadata: + name: {{ template "argo-workflows.server.fullname" . }} + namespace: {{ .Release.Namespace | quote }} + labels: + {{- include "argo-workflows.labels" (dict "context" . "component" .Values.server.name "name" .Values.server.name) | nindent 4 }} +spec: + {{- toYaml .Values.server.GKEfrontendConfig.spec | nindent 2 }} +{{- end }} diff --git a/helm/argo-workflows/templates/server/gke/managedcertificate.yaml b/helm/argo-workflows/templates/server/gke/managedcertificate.yaml new file mode 100644 index 0000000..b77c313 --- /dev/null +++ b/helm/argo-workflows/templates/server/gke/managedcertificate.yaml @@ -0,0 +1,12 @@ +{{- if .Values.server.GKEmanagedCertificate.enabled }} +apiVersion: networking.gke.io/v1 +kind: ManagedCertificate +metadata: + name: {{ template "argo-workflows.server.fullname" . }} + namespace: {{ .Release.Namespace | quote }} +spec: + domains: + {{- with .Values.server.GKEmanagedCertificate.domains }} + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/helm/argo-workflows/templates/server/server-cluster-roles.yaml b/helm/argo-workflows/templates/server/server-cluster-roles.yaml new file mode 100644 index 0000000..56d4dca --- /dev/null +++ b/helm/argo-workflows/templates/server/server-cluster-roles.yaml @@ -0,0 +1,145 @@ +{{- if and .Values.server.enabled .Values.server.rbac.create}} +apiVersion: rbac.authorization.k8s.io/v1 + {{- if .Values.singleNamespace }} +kind: Role + {{- else }} +kind: ClusterRole + {{- end }} +metadata: + name: {{ template "argo-workflows.server.fullname" . }} + {{- if .Values.singleNamespace }} + namespace: {{ .Release.Namespace | quote }} + {{- end }} + labels: + {{- include "argo-workflows.labels" (dict "context" . "component" .Values.server.name "name" .Values.server.name) | nindent 4 }} +rules: +- apiGroups: + - "" + resources: + - configmaps + - events + verbs: + - get + - watch + - list +- apiGroups: + - "" + resources: + - pods + verbs: + - get + - list + - watch + - delete +- apiGroups: + - "" + resources: + - pods/log + verbs: + - get + - list +{{- if .Values.server.sso.enabled }} +- apiGroups: + - "" + resources: + - secrets + resourceNames: + - sso + verbs: + - get +- apiGroups: + - "" + resources: + - secrets + verbs: + - create + {{- if .Values.server.sso.rbac.enabled }} +- apiGroups: + - "" + resources: + - serviceaccounts + verbs: + - get + - list + - watch + {{- end }} +{{- end }} +- apiGroups: + - "" + resources: + - secrets + verbs: + - get +{{- if and .Values.server.sso.enabled .Values.server.sso.rbac.enabled }} + {{- with .Values.server.sso.rbac.secretWhitelist }} + resourceNames: {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} +- apiGroups: + - "" + resources: + - events + verbs: + - watch + - create + - patch +{{- if .Values.controller.persistence }} +- apiGroups: + - "" + resources: + - secrets + resourceNames: + {{- with .Values.controller.persistence.postgresql }} + - {{ .userNameSecret.name }} + - {{ .passwordSecret.name }} + {{- end}} + {{- with .Values.controller.persistence.mysql }} + - {{ .userNameSecret.name }} + - {{ .passwordSecret.name }} + {{- end}} + verbs: + - get +{{- end}} +- apiGroups: + - argoproj.io + resources: + - eventsources + - sensors + - workflows + - workfloweventbindings + - workflowtemplates + - cronworkflows + verbs: + - create + - get + - list + - watch + - update + - patch + - delete + +{{- if .Values.server.clusterWorkflowTemplates.enabled }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "argo-workflows.server.fullname" . }}-cluster-template + labels: + {{- include "argo-workflows.labels" (dict "context" . "component" .Values.server.name "name" .Values.server.name) | nindent 4 }} +rules: +- apiGroups: + - argoproj.io + resources: + - clusterworkflowtemplates + verbs: + - get + - list + - watch + {{- if .Values.server.clusterWorkflowTemplates.enableEditing }} + - create + - update + - patch + - delete + {{- end }} +{{- end }} +{{- end }} diff --git a/helm/argo-workflows/templates/server/server-crb.yaml b/helm/argo-workflows/templates/server/server-crb.yaml new file mode 100644 index 0000000..e8d6511 --- /dev/null +++ b/helm/argo-workflows/templates/server/server-crb.yaml @@ -0,0 +1,45 @@ +{{- if and .Values.server.enabled .Values.server.rbac.create -}} +apiVersion: rbac.authorization.k8s.io/v1 +{{- if .Values.singleNamespace }} +kind: RoleBinding +{{ else }} +kind: ClusterRoleBinding +{{- end }} +metadata: + name: {{ template "argo-workflows.server.fullname" . }} + {{- if .Values.singleNamespace }} + namespace: {{ .Release.Namespace | quote }} + {{- end }} + labels: + {{- include "argo-workflows.labels" (dict "context" . "component" .Values.server.name "name" .Values.server.name) | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + {{- if .Values.singleNamespace }} + kind: Role + {{ else }} + kind: ClusterRole + {{- end }} + name: {{ template "argo-workflows.server.fullname" . }} +subjects: +- kind: ServiceAccount + name: {{ template "argo-workflows.serverServiceAccountName" . }} + namespace: {{ .Release.Namespace | quote }} + +{{- if .Values.server.clusterWorkflowTemplates.enabled }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "argo-workflows.server.fullname" . }}-cluster-template + labels: + {{- include "argo-workflows.labels" (dict "context" . "component" .Values.server.name "name" .Values.server.name) | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "argo-workflows.server.fullname" . }}-cluster-template +subjects: +- kind: ServiceAccount + name: {{ template "argo-workflows.serverServiceAccountName" . }} + namespace: {{ .Release.Namespace | quote }} +{{- end -}} +{{- end -}} diff --git a/helm/argo-workflows/templates/server/server-deployment-hpa.yaml b/helm/argo-workflows/templates/server/server-deployment-hpa.yaml new file mode 100644 index 0000000..9194bbd --- /dev/null +++ b/helm/argo-workflows/templates/server/server-deployment-hpa.yaml @@ -0,0 +1,45 @@ +{{- if and .Values.server.enabled .Values.server.autoscaling.enabled }} +apiVersion: {{ include "argo-workflows.apiVersion.autoscaling" . }} +kind: HorizontalPodAutoscaler +metadata: + name: {{ template "argo-workflows.server.fullname" . }} + namespace: {{ .Release.Namespace | quote }} + labels: + {{- include "argo-workflows.labels" (dict "context" . "component" .Values.server.name "name" .Values.server.name) | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ template "argo-workflows.server.fullname" . }} + minReplicas: {{ .Values.server.autoscaling.minReplicas }} + maxReplicas: {{ .Values.server.autoscaling.maxReplicas }} + metrics: + {{- with .Values.server.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + {{- if eq (include "argo-workflows.apiVersion.autoscaling" $) "autoscaling/v2beta1" }} + targetAverageUtilization: {{ . }} + {{- else }} + target: + averageUtilization: {{ . }} + type: Utilization + {{- end }} + {{- end }} + {{- with .Values.server.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + {{- if eq (include "argo-workflows.apiVersion.autoscaling" $) "autoscaling/v2beta1" }} + targetAverageUtilization: {{ . }} + {{- else }} + target: + averageUtilization: {{ . }} + type: Utilization + {{- end }} + {{- end }} + {{- with .Values.server.autoscaling.behavior }} + behavior: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/helm/argo-workflows/templates/server/server-deployment-pdb.yaml b/helm/argo-workflows/templates/server/server-deployment-pdb.yaml new file mode 100644 index 0000000..7ea6d46 --- /dev/null +++ b/helm/argo-workflows/templates/server/server-deployment-pdb.yaml @@ -0,0 +1,20 @@ +{{- if and .Values.server.enabled .Values.server.pdb.enabled -}} +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: {{ template "argo-workflows.server.fullname" . }} + namespace: {{ .Release.Namespace | quote }} + labels: + {{- include "argo-workflows.labels" (dict "context" . "component" .Values.server.name "name" .Values.server.name) | nindent 4 }} +spec: + {{- if .Values.server.pdb.minAvailable }} + minAvailable: {{ .Values.server.pdb.minAvailable }} + {{- else if .Values.server.pdb.maxUnavailable }} + maxUnavailable: {{ .Values.server.pdb.maxUnavailable }} + {{- else }} + minAvailable: 0 + {{- end }} + selector: + matchLabels: + {{- include "argo-workflows.selectorLabels" (dict "context" . "name" .Values.server.name) | nindent 6 }} +{{- end -}} diff --git a/helm/argo-workflows/templates/server/server-deployment.yaml b/helm/argo-workflows/templates/server/server-deployment.yaml new file mode 100644 index 0000000..b2e5096 --- /dev/null +++ b/helm/argo-workflows/templates/server/server-deployment.yaml @@ -0,0 +1,139 @@ +{{- if .Values.server.enabled -}} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "argo-workflows.server.fullname" . }} + namespace: {{ .Release.Namespace | quote }} + labels: + {{- include "argo-workflows.labels" (dict "context" . "component" .Values.server.name "name" .Values.server.name) | nindent 4 }} + app.kubernetes.io/version: {{ include "argo-workflows.server_chart_version_label" . }} + {{- with .Values.server.deploymentAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if not .Values.server.autoscaling.enabled }} + replicas: {{ .Values.server.replicas }} + {{- end }} + selector: + matchLabels: + {{- include "argo-workflows.selectorLabels" (dict "context" . "name" .Values.server.name) | nindent 6 }} + template: + metadata: + labels: + {{- include "argo-workflows.labels" (dict "context" . "component" .Values.server.name "name" .Values.server.name) | nindent 8 }} + app.kubernetes.io/version: {{ include "argo-workflows.server_chart_version_label" . }} + {{- with .Values.server.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.server.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + serviceAccountName: {{ template "argo-workflows.serverServiceAccountName" . }} + {{- with .Values.server.podSecurityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.server.extraInitContainers }} + initContainers: + {{- tpl (toYaml .) $ | nindent 8 }} + {{- end }} + containers: + - name: argo-server + image: "{{- include "argo-workflows.image" (dict "context" . "image" .Values.server.image) }}:{{ default (include "argo-workflows.defaultTag" .) .Values.server.image.tag }}" + imagePullPolicy: {{ .Values.images.pullPolicy }} + securityContext: + {{- toYaml .Values.server.securityContext | nindent 12 }} + args: + - server + - --configmap={{ template "argo-workflows.controller.fullname" . }}-configmap + {{- with .Values.server.extraArgs }} + {{- toYaml . | nindent 10 }} + {{- end }} + - "--secure={{ .Values.server.secure }}" + {{- if .Values.singleNamespace }} + - "--namespaced" + {{- end }} + - "--loglevel" + - "{{ .Values.server.logging.level }}" + - "--gloglevel" + - "{{ .Values.server.logging.globallevel }}" + - "--log-format" + - "{{ .Values.server.logging.format }}" + ports: + - name: web + containerPort: 2746 + readinessProbe: + httpGet: + path: / + port: 2746 + {{- if .Values.server.secure }} + scheme: HTTPS + {{- else }} + scheme: HTTP + {{- end }} + initialDelaySeconds: 10 + periodSeconds: 20 + env: + - name: IN_CLUSTER + value: "true" + - name: ARGO_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: BASE_HREF + value: {{ .Values.server.baseHref | quote }} + {{- with .Values.server.extraEnv }} + {{- toYaml . | nindent 12 }} + {{- end }} + resources: + {{- toYaml .Values.server.resources | nindent 12 }} + volumeMounts: + - name: tmp + mountPath: /tmp + {{- with .Values.server.volumeMounts }} + {{- toYaml . | nindent 10}} + {{- end }} + {{- with .Values.server.extraContainers }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.images.pullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: tmp + emptyDir: {} + {{- with .Values.server.volumes }} + {{- toYaml . | nindent 6}} + {{- end }} + {{- with .Values.server.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.server.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.server.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.server.topologySpreadConstraints }} + topologySpreadConstraints: + {{- range $constraint := . }} + - {{ toYaml $constraint | nindent 8 | trim }} + {{- if not $constraint.labelSelector }} + labelSelector: + matchLabels: + {{- include "argo-workflows.selectorLabels" (dict "context" $ "name" $.Values.server.name) | nindent 12 }} + {{- end }} + {{- end }} + {{- end }} + {{- with .Values.server.priorityClassName }} + priorityClassName: {{ . }} + {{- end }} +{{- end -}} diff --git a/helm/argo-workflows/templates/server/server-ingress.yaml b/helm/argo-workflows/templates/server/server-ingress.yaml new file mode 100644 index 0000000..36209f5 --- /dev/null +++ b/helm/argo-workflows/templates/server/server-ingress.yaml @@ -0,0 +1,90 @@ +{{- if .Values.server.ingress.enabled -}} +{{- $serviceName := include "argo-workflows.server.fullname" . -}} +{{- $servicePort := .Values.server.servicePort -}} +{{- $paths := .Values.server.ingress.paths -}} +{{- $extraPaths := .Values.server.ingress.extraPaths -}} +{{- $pathType := .Values.server.ingress.pathType -}} +apiVersion: {{ include "argo-workflows.ingress.apiVersion" . }} +kind: Ingress +metadata: +{{- if .Values.server.ingress.annotations }} + annotations: + {{- range $key, $value := .Values.server.ingress.annotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} +{{- end }} + name: {{ template "argo-workflows.server.fullname" . }} + namespace: {{ .Release.Namespace | quote }} + labels: + {{- include "argo-workflows.labels" (dict "context" . "component" .Values.server.name "name" .Values.server.name) | nindent 4 }} + {{- if .Values.server.ingress.labels }} + {{- toYaml .Values.server.ingress.labels | nindent 4 }} + {{- end }} +spec: + {{- if eq (include "argo-workflows.ingress.apiVersion" $) "networking.k8s.io/v1" }} + {{- with .Values.server.ingress.ingressClassName }} + ingressClassName: {{ . }} + {{- end }} + {{- end }} + rules: + {{- if .Values.server.ingress.hosts }} + {{- range $host := .Values.server.ingress.hosts }} + - host: {{ $host }} + http: + paths: + {{- if $extraPaths }} + {{- toYaml $extraPaths | nindent 10 }} + {{- end }} + {{- range $p := $paths }} + - path: {{ $p }} + {{- if eq (include "argo-workflows.ingress.apiVersion" $) "networking.k8s.io/v1" }} + pathType: {{ $pathType }} + {{- end }} + backend: + {{- if eq (include "argo-workflows.ingress.apiVersion" $) "networking.k8s.io/v1" }} + service: + name: {{ $serviceName }} + port: + {{- if kindIs "float64" $servicePort }} + number: {{ $servicePort }} + {{- else }} + name: {{ $servicePort }} + {{- end }} + {{- else }} + serviceName: {{ $serviceName }} + servicePort: {{ $servicePort }} + {{- end }} + {{- end -}} + {{- end -}} + {{- else }} + - http: + paths: + {{- if $extraPaths }} + {{- toYaml $extraPaths | nindent 10 }} + {{- end }} + {{- range $p := $paths }} + - path: {{ $p }} + {{- if eq (include "argo-workflows.ingress.apiVersion" $) "networking.k8s.io/v1" }} + pathType: {{ $pathType }} + {{- end }} + backend: + {{- if eq (include "argo-workflows.ingress.apiVersion" $) "networking.k8s.io/v1" }} + service: + name: {{ $serviceName }} + port: + {{- if kindIs "float64" $servicePort }} + number: {{ $servicePort }} + {{- else }} + name: {{ $servicePort }} + {{- end }} + {{- else }} + serviceName: {{ $serviceName }} + servicePort: {{ $servicePort }} + {{- end }} + {{- end -}} + {{- end -}} + {{- if .Values.server.ingress.tls }} + tls: + {{- toYaml .Values.server.ingress.tls | nindent 4 }} + {{- end -}} +{{- end -}} diff --git a/helm/argo-workflows/templates/server/server-sa.yaml b/helm/argo-workflows/templates/server/server-sa.yaml new file mode 100644 index 0000000..382d565 --- /dev/null +++ b/helm/argo-workflows/templates/server/server-sa.yaml @@ -0,0 +1,16 @@ +{{- if and .Values.server.enabled .Values.server.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "argo-workflows.serverServiceAccountName" . }} + namespace: {{ .Release.Namespace | quote }} + labels: + {{- include "argo-workflows.labels" (dict "context" . "component" .Values.server.name "name" .Values.server.name) | nindent 4 }} + {{- with .Values.server.serviceAccount.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.server.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end -}} diff --git a/helm/argo-workflows/templates/server/server-service.yaml b/helm/argo-workflows/templates/server/server-service.yaml new file mode 100644 index 0000000..f7096a8 --- /dev/null +++ b/helm/argo-workflows/templates/server/server-service.yaml @@ -0,0 +1,35 @@ +{{- if .Values.server.enabled -}} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "argo-workflows.server.fullname" . }} + namespace: {{ .Release.Namespace | quote }} + labels: + {{- include "argo-workflows.labels" (dict "context" . "component" .Values.server.name "name" .Values.server.name) | nindent 4 }} + app.kubernetes.io/version: {{ include "argo-workflows.server_chart_version_label" . }} + {{- with .Values.server.serviceAnnotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + ports: + - port: {{ .Values.server.servicePort }} + {{- with .Values.server.servicePortName }} + name: {{ . }} + {{- end }} + targetPort: 2746 + {{- if and (eq .Values.server.serviceType "NodePort") .Values.server.serviceNodePort }} + nodePort: {{ .Values.server.serviceNodePort }} + {{- end }} + selector: + {{- include "argo-workflows.selectorLabels" (dict "context" . "name" .Values.server.name) | nindent 4 }} + sessionAffinity: None + type: {{ .Values.server.serviceType }} + {{- if and (eq .Values.server.serviceType "LoadBalancer") .Values.server.loadBalancerIP }} + loadBalancerIP: {{ .Values.server.loadBalancerIP | quote }} + {{- end }} + {{- if and (eq .Values.server.serviceType "LoadBalancer") .Values.server.loadBalancerSourceRanges }} + loadBalancerSourceRanges: + {{- toYaml .Values.server.loadBalancerSourceRanges | nindent 4 }} + {{- end }} +{{- end -}} diff --git a/helm/argo-workflows/values.yaml b/helm/argo-workflows/values.yaml new file mode 100644 index 0000000..d6d2246 --- /dev/null +++ b/helm/argo-workflows/values.yaml @@ -0,0 +1,841 @@ +images: + # -- Common tag for Argo Workflows images. Defaults to `.Chart.AppVersion`. + tag: "" + # -- imagePullPolicy to apply to all containers + pullPolicy: Always + # -- Secrets with credentials to pull images from a private registry + pullSecrets: [] + # - name: argo-pull-secret + +## Custom resource configuration +crds: + # -- Install and upgrade CRDs + install: true + # -- Keep CRDs on chart uninstall + keep: true + # -- Annotations to be added to all CRDs + annotations: {} + +# -- Create clusterroles that extend existing clusterroles to interact with argo-cd crds +## Ref: https://kubernetes.io/docs/reference/access-authn-authz/rbac/#aggregated-clusterroles +createAggregateRoles: true + +# -- String to partially override "argo-workflows.fullname" template +nameOverride: + +# -- String to fully override "argo-workflows.fullname" template +fullnameOverride: + +# -- Override the Kubernetes version, which is used to evaluate certain manifests +kubeVersionOverride: "" + +# Override APIVersions +apiVersionOverrides: + # -- String to override apiVersion of autoscaling rendered by this helm chart + autoscaling: "" # autoscaling/v2 + # -- String to override apiVersion of GKE resources rendered by this helm chart + cloudgoogle: "" # cloud.google.com/v1 + +# -- Restrict Argo to operate only in a single namespace (the namespace of the +# Helm release) by apply Roles and RoleBindings instead of the Cluster +# equivalents, and start workflow-controller with the --namespaced flag. Use it +# in clusters with strict access policy. +singleNamespace: false + +workflow: + # -- Deprecated; use controller.workflowNamespaces instead. + namespace: + serviceAccount: + # -- Specifies whether a service account should be created + create: false + # -- Labels applied to created service account + labels: {} + # -- Annotations applied to created service account + annotations: {} + # -- Service account which is used to run workflows + name: "argo-workflow" + # -- Secrets with credentials to pull images from a private registry. Same format as `.Values.images.pullSecrets` + pullSecrets: [] + rbac: + # -- Adds Role and RoleBinding for the above specified service account to be able to run workflows. + # A Role and Rolebinding pair is also created for each namespace in controller.workflowNamespaces (see below) + create: true + +controller: + image: + # -- Registry to use for the controller + registry: quay.io + # -- Registry to use for the controller + repository: argoproj/workflow-controller + # -- Image tag for the workflow controller. Defaults to `.Values.images.tag`. + tag: "" + # -- parallelism dictates how many workflows can be running at the same time + parallelism: + # -- Globally limits the rate at which pods are created. + # This is intended to mitigate flooding of the Kubernetes API server by workflows with a large amount of + # parallel nodes. + resourceRateLimit: {} + # limit: 10 + # burst: 1 + + rbac: + # -- Adds Role and RoleBinding for the controller. + create: true + # -- Allows controller to get, list, and watch certain k8s secrets + secretWhitelist: [] + # -- Allows controller to get, list and watch all k8s secrets. Can only be used if secretWhitelist is empty. + accessAllSecrets: false + # -- Allows controller to create and update ConfigMaps. Enables memoization feature + writeConfigMaps: false + + # -- Limits the maximum number of incomplete workflows in a namespace + namespaceParallelism: + # -- Resolves ongoing, uncommon AWS EKS bug: https://github.com/argoproj/argo-workflows/pull/4224 + initialDelay: + # -- deploymentAnnotations is an optional map of annotations to be applied to the controller Deployment + deploymentAnnotations: {} + # -- podAnnotations is an optional map of annotations to be applied to the controller Pods + podAnnotations: {} + # -- Optional labels to add to the controller pods + podLabels: {} + # -- SecurityContext to set on the controller pods + podSecurityContext: {} + # podPortName: http + metricsConfig: + # -- Enables prometheus metrics server + enabled: false + # -- Path is the path where metrics are emitted. Must start with a "/". + path: /metrics + # -- Port is the port where metrics are emitted + port: 9090 + # -- How often custom metrics are cleared from memory + metricsTTL: "" + # -- Flag that instructs prometheus to ignore metric emission errors. + ignoreErrors: false + # -- Flag that use a self-signed cert for TLS + secure: false + # -- Container metrics port name + portName: metrics + # -- Service metrics port + servicePort: 8080 + # -- Service metrics port name + servicePortName: metrics + # -- ServiceMonitor relabel configs to apply to samples before scraping + ## Ref: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#relabelconfig + relabelings: [] + # -- ServiceMonitor metric relabel configs to apply to samples before ingestion + ## Ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#endpoint + metricRelabelings: [] + # -- ServiceMonitor will add labels from the service to the Prometheus metric + ## Ref: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/api.md#servicemonitorspec + targetLabels: [] + # -- the controller container's securityContext + securityContext: + readOnlyRootFilesystem: true + runAsNonRoot: true + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + # -- enable persistence using postgres + persistence: {} + # connectionPool: + # maxIdleConns: 100 + # maxOpenConns: 0 + # # save the entire workflow into etcd and DB + # nodeStatusOffLoad: false + # # enable archiving of old workflows + # archive: false + # postgresql: + # host: localhost + # port: 5432 + # database: postgres + # tableName: argo_workflows + # # the database secrets must be in the same namespace of the controller + # userNameSecret: + # name: argo-postgres-config + # key: username + # passwordSecret: + # name: argo-postgres-config + # key: password + + # -- Default values that will apply to all Workflows from this controller, unless overridden on the Workflow-level. + # Only valid for 2.7+ + ## See more: https://argoproj.github.io/argo-workflows/default-workflow-specs/ + workflowDefaults: {} + # spec: + # ttlStrategy: + # secondsAfterCompletion: 84600 + # # Ref: https://argoproj.github.io/argo-workflows/artifact-repository-ref/ + # artifactRepositoryRef: + # configMap: my-artifact-repository # default is "artifact-repositories" + # key: v2-s3-artifact-repository # default can be set by the `workflows.argoproj.io/default-artifact-repository` annotation in config map. + + # -- Number of workflow workers + workflowWorkers: # 32 + # -- Restricts the Workflows that the controller will process. + # Only valid for 2.9+ + workflowRestrictions: {} + # templateReferencing: Strict|Secure + + # telemetryConfig controls the path and port for prometheus telemetry. Telemetry is enabled and emitted in the same endpoint + # as metrics by default, but can be overridden using this config. + telemetryConfig: + # -- Enables prometheus telemetry server + enabled: false + # -- telemetry path + path: /telemetry + # -- telemetry container port + port: 8081 + # -- How often custom metrics are cleared from memory + metricsTTL: "" + # -- Flag that instructs prometheus to ignore metric emission errors. + ignoreErrors: false + # -- Flag that use a self-signed cert for TLS + secure: false + # -- telemetry service port + servicePort: 8081 + # -- telemetry service port name + servicePortName: telemetry + serviceMonitor: + # -- Enable a prometheus ServiceMonitor + enabled: false + # -- Prometheus ServiceMonitor labels + additionalLabels: {} + # -- Prometheus ServiceMonitor namespace + namespace: "" # "monitoring" + serviceAccount: + # -- Create a service account for the controller + create: true + # -- Service account name + name: "" + # -- Labels applied to created service account + labels: {} + # -- Annotations applied to created service account + annotations: {} + + # -- Workflow controller name string + name: workflow-controller + + # -- Specify all namespaces where this workflow controller instance will manage + # workflows. This controls where the service account and RBAC resources will + # be created. Only valid when singleNamespace is false. + workflowNamespaces: + - default + + instanceID: + # -- Configures the controller to filter workflow submissions + # to only those which have a matching instanceID attribute. + ## NOTE: If `instanceID.enabled` is set to `true` then either `instanceID.userReleaseName` + ## or `instanceID.explicitID` must be defined. + enabled: false + # -- Use ReleaseName as instanceID + useReleaseName: false + # useReleaseName: true + + # -- Use a custom instanceID + explicitID: "" + # explicitID: unique-argo-controller-identifier + + logging: + # -- Set the logging level (one of: `debug`, `info`, `warn`, `error`) + level: info + # -- Set the glog logging level + globallevel: "0" + # -- Set the logging format (one of: `text`, `json`) + format: "text" + + # -- Service type of the controller Service + serviceType: ClusterIP + # -- Annotations to be applied to the controller Service + serviceAnnotations: {} + # -- Optional labels to add to the controller Service + serviceLabels: {} + # -- Source ranges to allow access to service from. Only applies to service type `LoadBalancer` + loadBalancerSourceRanges: [] + + # -- Resource limits and requests for the controller + resources: {} + + # -- Configure liveness [probe] for the controller + # @default -- See [values.yaml] + livenessProbe: + httpGet: + port: 6060 + path: /healthz + failureThreshold: 3 + initialDelaySeconds: 90 + periodSeconds: 60 + timeoutSeconds: 30 + + # -- Extra environment variables to provide to the controller container + extraEnv: [] + # - name: FOO + # value: "bar" + + # -- Extra arguments to be added to the controller + extraArgs: [] + # -- Additional volume mounts to the controller main container + volumeMounts: [] + # -- Additional volumes to the controller pod + volumes: [] + # -- The number of controller pods to run + replicas: 1 + + pdb: + # -- Configure [Pod Disruption Budget] for the controller pods + enabled: false + # minAvailable: 1 + # maxUnavailable: 1 + + # -- [Node selector] + nodeSelector: + kubernetes.io/os: linux + # -- [Tolerations] for use with node taints + tolerations: [] + # -- Assign custom [affinity] rules + affinity: {} + + # -- Assign custom [TopologySpreadConstraints] rules to the workflow controller + ## Ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ + ## If labelSelector is left out, it will default to the labelSelector configuration of the deployment + topologySpreadConstraints: [] + # - maxSkew: 1 + # topologyKey: topology.kubernetes.io/zone + # whenUnsatisfiable: DoNotSchedule + + # -- Leverage a PriorityClass to ensure your pods survive resource shortages. + ## ref: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/ + priorityClassName: "" + + # -- Configure Argo Server to show custom [links] + ## Ref: https://argoproj.github.io/argo-workflows/links/ + links: [] + # -- Configure Argo Server to show custom [columns] + ## Ref: https://github.com/argoproj/argo-workflows/pull/10693 + columns: [] + # -- Set ui navigation bar background color + navColor: "" + clusterWorkflowTemplates: + # -- Create a ClusterRole and CRB for the controller to access ClusterWorkflowTemplates. + enabled: true + # -- Extra containers to be added to the controller deployment + extraContainers: [] + + # -- Enables init containers to be added to the controller deployment + extraInitContainers: [] + + # -- Workflow retention by number of workflows + retentionPolicy: {} + # completed: 10 + # failed: 3 + # errored: 3 + + nodeEvents: + # -- Enable to emit events on node completion. + ## This can take up a lot of space in k8s (typically etcd) resulting in errors when trying to create new events: + ## "Unable to create audit event: etcdserver: mvcc: database space exceeded" + enabled: true + + # -- Configure when workflow controller runs in a different k8s cluster with the workflow workloads, + # or needs to communicate with the k8s apiserver using an out-of-cluster kubeconfig secret. + # @default -- `{}` (See [values.yaml]) + kubeConfig: {} + # # name of the kubeconfig secret, may not be empty when kubeConfig specified + # secretName: kubeconfig-secret + # # key of the kubeconfig secret, may not be empty when kubeConfig specified + # secretKey: kubeconfig + # # mounting path of the kubeconfig secret, default to /kube/config + # mountPath: /kubeconfig/mount/path + # # volume name when mounting the secret, default to kubeconfig + # volumeName: kube-config-volume + + # -- Specifies the duration in seconds before a terminating pod is forcefully killed. A zero value indicates that the pod will be forcefully terminated immediately. + # @default -- `30` seconds (Kubernetes default) + podGCGracePeriodSeconds: + + # -- The duration in seconds before the pods in the GC queue get deleted. A zero value indicates that the pods will be deleted immediately. + # @default -- `5s` (Argo Workflows default) + podGCDeleteDelayDuration: "" + +# mainContainer adds default config for main container that could be overriden in workflows template +mainContainer: + # -- imagePullPolicy to apply to Workflow main container. Defaults to `.Values.images.pullPolicy`. + imagePullPolicy: "" + # -- Resource limits and requests for the Workflow main container + resources: {} + # -- Adds environment variables for the Workflow main container + env: [] + # -- Adds reference environment variables for the Workflow main container + envFrom: [] + # -- sets security context for the Workflow main container + securityContext: {} + +# executor controls how the init and wait container should be customized +executor: + image: + # -- Registry to use for the Workflow Executors + registry: quay.io + # -- Repository to use for the Workflow Executors + repository: argoproj/argoexec + # -- Image tag for the workflow executor. Defaults to `.Values.images.tag`. + tag: "" + # -- Image PullPolicy to use for the Workflow Executors. Defaults to `.Values.images.pullPolicy`. + pullPolicy: "" + # -- Resource limits and requests for the Workflow Executors + resources: {} + # -- Passes arguments to the executor processes + args: [] + # -- Adds environment variables for the executor. + env: [] + # -- sets security context for the executor container + securityContext: {} + +server: + # -- Deploy the Argo Server + enabled: true + # -- Value for base href in index.html. Used if the server is running behind reverse proxy under subpath different from /. + ## only updates base url of resources on client side, + ## it's expected that a proxy server rewrites the request URL and gets rid of this prefix + ## https://github.com/argoproj/argo-workflows/issues/716#issuecomment-433213190 + baseHref: / + image: + # -- Registry to use for the server + registry: quay.io + # -- Repository to use for the server + repository: argoproj/argocli + # -- Image tag for the Argo Workflows server. Defaults to `.Values.images.tag`. + tag: "" + # -- optional map of annotations to be applied to the ui Deployment + deploymentAnnotations: {} + # -- optional map of annotations to be applied to the ui Pods + podAnnotations: {} + # -- Optional labels to add to the UI pods + podLabels: {} + # -- SecurityContext to set on the server pods + podSecurityContext: {} + rbac: + # -- Adds Role and RoleBinding for the server. + create: true + # -- Servers container-level security context + securityContext: + readOnlyRootFilesystem: false + runAsNonRoot: true + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + # -- Server name string + name: server + # -- Service type for server pods + serviceType: ClusterIP + # -- Service port for server + servicePort: 2746 + # -- Service node port + serviceNodePort: # 32746 + # -- Service port name + servicePortName: "" # http + + serviceAccount: + # -- Create a service account for the server + create: true + # -- Service account name + name: "" + # -- Labels applied to created service account + labels: {} + # -- Annotations applied to created service account + annotations: {} + + # -- Annotations to be applied to the UI Service + serviceAnnotations: {} + # -- Optional labels to add to the UI Service + serviceLabels: {} + # -- Static IP address to assign to loadBalancer service type `LoadBalancer` + loadBalancerIP: "" + # -- Source ranges to allow access to service from. Only applies to service type `LoadBalancer` + loadBalancerSourceRanges: [] + # -- Resource limits and requests for the server + resources: {} + # -- The number of server pods to run + replicas: 1 + ## Argo Server Horizontal Pod Autoscaler + autoscaling: + # -- Enable Horizontal Pod Autoscaler ([HPA]) for the Argo Server + enabled: false + # -- Minimum number of replicas for the Argo Server [HPA] + minReplicas: 1 + # -- Maximum number of replicas for the Argo Server [HPA] + maxReplicas: 5 + # -- Average CPU utilization percentage for the Argo Server [HPA] + targetCPUUtilizationPercentage: 50 + # -- Average memory utilization percentage for the Argo Server [HPA] + targetMemoryUtilizationPercentage: 50 + # -- Configures the scaling behavior of the target in both Up and Down directions. + # This is only available on HPA apiVersion `autoscaling/v2beta2` and newer + behavior: {} + # scaleDown: + # stabilizationWindowSeconds: 300 + # policies: + # - type: Pods + # value: 1 + # periodSeconds: 180 + # scaleUp: + # stabilizationWindowSeconds: 300 + # policies: + # - type: Pods + # value: 2 + pdb: + # -- Configure [Pod Disruption Budget] for the server pods + enabled: false + # minAvailable: 1 + # maxUnavailable: 1 + + # -- [Node selector] + nodeSelector: + kubernetes.io/os: linux + + # -- [Tolerations] for use with node taints + tolerations: [] + + # -- Assign custom [affinity] rules + affinity: {} + + # -- Assign custom [TopologySpreadConstraints] rules to the argo server + ## Ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ + ## If labelSelector is left out, it will default to the labelSelector configuration of the deployment + topologySpreadConstraints: [] + # - maxSkew: 1 + # topologyKey: topology.kubernetes.io/zone + # whenUnsatisfiable: DoNotSchedule + + # -- Leverage a PriorityClass to ensure your pods survive resource shortages + ## ref: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/ + priorityClassName: "" + + # -- Run the argo server in "secure" mode. Configure this value instead of `--secure` in extraArgs. + ## See the following documentation for more details on secure mode: + ## https://argoproj.github.io/argo-workflows/tls/ + secure: false + + # -- Extra environment variables to provide to the argo-server container + extraEnv: [] + # - name: FOO + # value: "bar" + + # -- Extra arguments to provide to the Argo server binary, such as for disabling authentication. + extraArgs: [] + # If you want to disable authentication for purposes such as: + # - local dev-mode without authentication + # - gateway authentication through some other service such as KeyCloak + # uncomment the lines below and comment out the default empty list `extraArgs: []` above: + # extraArgs: + # - --auth-mode=server + + logging: + # -- Set the logging level (one of: `debug`, `info`, `warn`, `error`) + level: info + # -- Set the glog logging level + globallevel: "0" + # -- Set the logging format (one of: `text`, `json`) + format: "text" + + # -- Additional volume mounts to the server main container. + volumeMounts: [] + # -- Additional volumes to the server pod. + volumes: [] + + ## Ingress configuration. + # ref: https://kubernetes.io/docs/user-guide/ingress/ + ingress: + # -- Enable an ingress resource + enabled: false + # -- Additional ingress annotations + annotations: {} + # -- Additional ingress labels + labels: {} + # -- Defines which ingress controller will implement the resource + ingressClassName: "" + + # -- List of ingress hosts + ## Hostnames must be provided if Ingress is enabled. + ## Secrets must be manually created in the namespace + hosts: [] + # - argoworkflows.example.com + + # -- List of ingress paths + paths: + - / + + # -- Ingress path type. One of `Exact`, `Prefix` or `ImplementationSpecific` + pathType: Prefix + # -- Additional ingress paths + extraPaths: [] + # - path: /* + # backend: + # serviceName: ssl-redirect + # servicePort: use-annotation + ## for Kubernetes >=1.19 (when "networking.k8s.io/v1" is used) + # - path: /* + # pathType: Prefix + # backend: + # service + # name: ssl-redirect + # port: + # name: use-annotation + + # -- Ingress TLS configuration + tls: [] + # - secretName: argoworkflows-example-tls + # hosts: + # - argoworkflows.example.com + + ## Create a Google Backendconfig for use with the GKE Ingress Controller + ## https://cloud.google.com/kubernetes-engine/docs/how-to/ingress-configuration#configuring_ingress_features_through_backendconfig_parameters + GKEbackendConfig: + # -- Enable BackendConfig custom resource for Google Kubernetes Engine + enabled: false + # -- [BackendConfigSpec] + spec: {} + # spec: + # iap: + # enabled: true + # oauthclientCredentials: + # secretName: argoworkflows-secret + + ## Create a Google Managed Certificate for use with the GKE Ingress Controller + ## https://cloud.google.com/kubernetes-engine/docs/how-to/managed-certs + GKEmanagedCertificate: + # -- Enable ManagedCertificate custom resource for Google Kubernetes Engine. + enabled: false + # -- Domains for the Google Managed Certificate + domains: + - argoworkflows.example.com + + ## Create a Google FrontendConfig Custom Resource, for use with the GKE Ingress Controller + ## https://cloud.google.com/kubernetes-engine/docs/how-to/ingress-features#configuring_ingress_features_through_frontendconfig_parameters + GKEfrontendConfig: + # -- Enable FrontConfig custom resource for Google Kubernetes Engine + enabled: false + # -- [FrontendConfigSpec] + spec: {} + # spec: + # redirectToHttps: + # enabled: true + # responseCodeName: RESPONSE_CODE + + clusterWorkflowTemplates: + # -- Create a ClusterRole and CRB for the server to access ClusterWorkflowTemplates. + enabled: true + # -- Give the server permissions to edit ClusterWorkflowTemplates. + enableEditing: true + + # SSO configuration when SSO is specified as a server auth mode. + sso: + # -- Create SSO configuration + ## SSO is activated by adding --auth-mode=sso to the server command line. + enabled: false + # -- The root URL of the OIDC identity provider + issuer: https://accounts.google.com + clientId: + # -- Name of secret to retrieve the app OIDC client ID + name: argo-server-sso + # -- Key of secret to retrieve the app OIDC client ID + key: client-id + clientSecret: + # -- Name of a secret to retrieve the app OIDC client secret + name: argo-server-sso + # -- Key of a secret to retrieve the app OIDC client secret + key: client-secret + # - The OIDC redirect URL. Should be in the form /oauth2/callback. + redirectUrl: https://argo/oauth2/callback + rbac: + # -- Adds ServiceAccount Policy to server (Cluster)Role. + enabled: true + # -- Whitelist to allow server to fetch Secrets + ## When present, restricts secrets the server can read to a given list. + ## You can use it to restrict the server to only be able to access the + ## service account token secrets that are associated with service accounts + ## used for authorization. + secretWhitelist: [] + # -- Scopes requested from the SSO ID provider + ## The 'groups' scope requests group membership information, which is usually used for authorization decisions. + scopes: [] + # - groups + # -- Define how long your login is valid for (in hours) + ## If omitted, defaults to 10h. + sessionExpiry: "" + # -- Alternate root URLs that can be included for some OIDC providers + issuerAlias: "" + # -- Override claim name for OIDC groups + customGroupClaimName: "" + # -- Specify the user info endpoint that contains the groups claim + ## Configure this if your OIDC provider provides groups information only using the user-info endpoint (e.g. Okta) + userInfoPath: "" + # -- Skip TLS verification for the HTTP client + insecureSkipVerify: false + + # -- Extra containers to be added to the server deployment + extraContainers: [] + + # -- Enables init containers to be added to the server deployment + extraInitContainers: [] + +# -- Array of extra K8s manifests to deploy +extraObjects: [] + # - apiVersion: secrets-store.csi.x-k8s.io/v1 + # kind: SecretProviderClass + # metadata: + # name: argo-server-sso + # spec: + # provider: aws + # parameters: + # objects: | + # - objectName: "argo/server/sso" + # objectType: "secretsmanager" + # jmesPath: + # - path: "client_id" + # objectAlias: "client_id" + # - path: "client_secret" + # objectAlias: "client_secret" + # secretObjects: + # - data: + # - key: client_id + # objectName: client_id + # - key: client_secret + # objectName: client_secret + # secretName: argo-server-sso-secrets-store + # type: Opaque + +# -- Use static credentials for S3 (eg. when not using AWS IRSA) +useStaticCredentials: true +artifactRepository: + # -- Archive the main container logs as an artifact + archiveLogs: false + # -- Store artifact in a S3-compliant object store + # @default -- See [values.yaml] + s3: {} + # # Note the `key` attribute is not the actual secret, it's the PATH to + # # the contents in the associated secret, as defined by the `name` attribute. + # accessKeySecret: + # name: "{{ .Release.Name }}-minio" + # key: accesskey + # secretKeySecret: + # name: "{{ .Release.Name }}-minio" + # key: secretkey + # # insecure will disable TLS. Primarily used for minio installs not configured with TLS + # insecure: false + # bucket: + # endpoint: + # region: + # roleARN: + # useSDKCreds: true + # encryptionOptions: + # enableEncryption: true + # -- Store artifact in a GCS object store + # @default -- `{}` (See [values.yaml]) + gcs: {} + # bucket: -argo + # keyFormat: "{{ \"{{workflow.namespace}}/{{workflow.name}}/{{pod.name}}\" }}" + # serviceAccountKeySecret is a secret selector. + # It references the k8s secret named 'my-gcs-credentials'. + # This secret is expected to have have the key 'serviceAccountKey', + # containing the base64 encoded credentials + # to the bucket. + # + # If it's running on GKE and Workload Identity is used, + # serviceAccountKeySecret is not needed. + # serviceAccountKeySecret: + # name: my-gcs-credentials + # key: serviceAccountKey + # -- Store artifact in Azure Blob Storage + # @default -- `{}` (See [values.yaml]) + azure: {} + # endpoint: https://mystorageaccountname.blob.core.windows.net + # container: my-container-name + # blobNameFormat: path/in/container + ## accountKeySecret is a secret selector. + ## It references the k8s secret named 'my-azure-storage-credentials'. + ## This secret is expected to have have the key 'account-access-key', + ## containing the base64 encoded credentials to the storage account. + ## If a managed identity has been assigned to the machines running the + ## workflow (e.g., https://docs.microsoft.com/en-us/azure/aks/use-managed-identity) + ## then accountKeySecret is not needed, and useSDKCreds should be + ## set to true instead: + # useSDKCreds: true + # accountKeySecret: + # name: my-azure-storage-credentials + # key: account-access-key + +# -- The section of custom artifact repository. +# Utilize a custom artifact repository that is not one of the current base ones (s3, gcs, azure) +customArtifactRepository: {} +# artifactory: +# repoUrl: https://artifactory.example.com/raw +# usernameSecret: +# name: artifactory-creds +# key: username +# passwordSecret: +# name: artifactory-creds +# key: password + +# -- The section of [artifact repository ref](https://argoproj.github.io/argo-workflows/artifact-repository-ref/). +# Each map key is the name of configmap +# @default -- `{}` (See [values.yaml]) +artifactRepositoryRef: {} + # # -- 1st ConfigMap + # # If you want to use this config map by default, name it "artifact-repositories". + # # Otherwise, you can provide a reference to a + # # different config map in `artifactRepositoryRef.configMap`. + # artifact-repositories: + # # -- v3.0 and after - if you want to use a specific key, put that key into this annotation. + # annotations: + # workflows.argoproj.io/default-artifact-repository: default-v1-s3-artifact-repository + # # 1st data of configmap. See above artifactRepository or customArtifactRepository. + # default-v1-s3-artifact-repository: + # archiveLogs: false + # s3: + # bucket: my-bucket + # endpoint: minio:9000 + # insecure: true + # accessKeySecret: + # name: my-minio-cred + # key: accesskey + # secretKeySecret: + # name: my-minio-cred + # key: secretkey + # # 2nd data + # oss-artifact-repository: + # archiveLogs: false + # oss: + # endpoint: http://oss-cn-zhangjiakou-internal.aliyuncs.com + # bucket: $mybucket + # # accessKeySecret and secretKeySecret are secret selectors. + # # It references the k8s secret named 'bucket-workflow-artifect-credentials'. + # # This secret is expected to have have the keys 'accessKey' + # # and 'secretKey', containing the base64 encoded credentials + # # to the bucket. + # accessKeySecret: + # name: $mybucket-credentials + # key: accessKey + # secretKeySecret: + # name: $mybucket-credentials + # key: secretKey + # # 2nd ConfigMap + # another-artifact-repositories: + # annotations: + # workflows.argoproj.io/default-artifact-repository: gcs + # gcs: + # bucket: my-bucket + # keyFormat: prefix/in/bucket/{{workflow.name}}/{{pod.name}} + # serviceAccountKeySecret: + # name: my-gcs-credentials + # key: serviceAccountKey + +emissary: + # -- The command/args for each image on workflow, needed when the command is not specified and the emissary executor is used. + ## See more: https://argoproj.github.io/argo-workflows/workflow-executors/#emissary-emissary + images: [] + # argoproj/argosay:v2: + # cmd: [/argosay] + # docker/whalesay:latest: + # cmd: [/bin/bash] diff --git a/helm/awx-operator/.helmignore b/helm/awx-operator/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/helm/awx-operator/.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/helm/awx-operator/Chart.yaml b/helm/awx-operator/Chart.yaml new file mode 100644 index 0000000..a49ce61 --- /dev/null +++ b/helm/awx-operator/Chart.yaml @@ -0,0 +1,6 @@ +apiVersion: v2 +appVersion: 2.3.0 +description: A Helm chart for the AWX Operator +name: awx-operator +type: application +version: 2.3.0 diff --git a/helm/awx-operator/README.md b/helm/awx-operator/README.md new file mode 100644 index 0000000..5630291 --- /dev/null +++ b/helm/awx-operator/README.md @@ -0,0 +1,67 @@ +# AWX Operator Helm Chart + +This chart installs the AWX Operator resources configured in [this](https://github.com/ansible/awx-operator) repository. + +## Getting Started +To configure your AWX resource using this chart, create your own `yaml` values file. The name is up to personal preference since it will explicitly be passed into the helm chart. Helm will merge whatever values you specify in your file with the default `values.yaml`, overriding any settings you've changed while allowing you to fall back on defaults. Because of this functionality, `values.yaml` should not be edited directly. + +In your values config, enable `AWX.enabled` and add `AWX.spec` values based on the awx operator's [documentation](https://github.com/ansible/awx-operator/blob/devel/README.md). Consult the docs below for additional functionality. + +### Installing +The operator's [helm install](https://github.com/ansible/awx-operator/blob/devel/README.md#helm-install-on-existing-cluster) guide provides key installation instructions. + +Example: +``` +helm install my-awx-operator awx-operator/awx-operator -n awx --create-namespace -f myvalues.yaml +``` + +Argument breakdown: +* `-f` passes in the file with your custom values +* `-n` sets the namespace to be installed in + * This value is accessed by `{{ $.Release.Namespace }}` in the templates + * Acts as the default namespace for all unspecified resources +* `--create-namespace` specifies that helm should create the namespace before installing + +To update an existing installation, use `helm upgrade` instead of `install`. The rest of the syntax remains the same. + +## Configuration +The goal of adding helm configurations is to abstract out and simplify the creation of multi-resource configs. The `AWX.spec` field maps directly to the spec configs of the `AWX` resource that the operator provides, which are detailed in the [main README](https://github.com/ansible/awx-operator/blob/devel/README.md). Other sub-config can be added with the goal of simplifying more involved setups that require additional resources to be specified. + +These sub-headers aim to be a more intuitive entrypoint into customizing your deployment, and are easier to manage in the long-term. By design, the helm templates will defer to the manually defined specs to avoid configuration conflicts. For example, if `AWX.spec.postgres_configuration_secret` is being used, the `AWX.postgres` settings will not be applied, even if enabled. + +### External Postgres +The `AWX.postgres` section simplifies the creation of the external postgres secret. If enabled, the configs provided will automatically be placed in a `postgres-config` secret and linked to the `AWX` resource. For proper secret management, the `AWX.postgres.password` value, and any other sensitive values, can be passed in at the command line rather than specified in code. Use the `--set` argument with `helm install`. Supplying the password this way is not recommended for production use, but may be helpful for initial PoC. + + +## Values Summary + +### AWX +| Value | Description | Default | +|---|---|---| +| `AWX.enabled` | Enable this AWX resource configuration | `false` | +| `AWX.name` | The name of the AWX resource and default prefix for other resources | `"awx"` | +| `AWX.spec` | specs to directly configure the AWX resource | `{}` | +| `AWX.postgres` | configurations for the external postgres secret | - | + + +# Contributing + +## Adding abstracted sections +Where possible, defer to `AWX.spec` configs before applying the abstracted configs to avoid collision. This can be facilitated by the `(hasKey .spec what_i_will_abstract)` check. + +## Building and Testing +This chart is built using the Makefile in the [awx-operator repo](https://github.com/ansible/awx-operator). Clone the repo and run `make helm-chart`. This will create the awx-operator chart in the `charts/awx-operator` directory. In this process, the contents of the `.helm/starter` directory will be added to the chart. + +## Future Goals +All values under the `AWX` header are focused on configurations that use the operator. Configurations that relate to the Operator itself could be placed under an `Operator` heading, but that may add a layer of complication over current development. + + +# Chart Publishing + +The chart is currently hosted on the gh-pages branch of the repo. During the release pipeline, the `index.yaml` stored in that branch is generated with helm chart entries from all valid tags. We are currently unable to use the `chart-releaser` pipeline due to the fact that the complete helm chart is not committed to the repo and is instead built during the release process. Therefore, the cr action is unable to compare against previous versions. + +Instead of CR, we use `helm repo index` to generate an index from all locally pulled chart versions. Since we build from scratch every time, the timestamps of all entries will be updated. This could be improved by using yq or something similar to detect which tags are already in the index.yaml file, and only merge in tags that are not present. + +Not using CR could be addressed in the future by keeping the chart built as a part of releases, as long as CR compares the chart to previous release packages rather than previous commits. If the latter is the case, then we would not have the necessary history for comparison. + + diff --git a/helm/awx-operator/crds/customresourcedefinition-awxbackups.awx.ansible.com.yaml b/helm/awx-operator/crds/customresourcedefinition-awxbackups.awx.ansible.com.yaml new file mode 100644 index 0000000..1a8f97e --- /dev/null +++ b/helm/awx-operator/crds/customresourcedefinition-awxbackups.awx.ansible.com.yaml @@ -0,0 +1,127 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + labels: + helm.sh/chart: awx-operator + name: awxbackups.awx.ansible.com +spec: + group: awx.ansible.com + names: + kind: AWXBackup + listKind: AWXBackupList + plural: awxbackups + singular: awxbackup + scope: Namespaced + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + description: Schema validation for the AWXBackup CRD + 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: + additional_labels: + description: Additional labels defined on the resource, which should be propagated to child resources + items: + type: string + type: array + backup_pvc: + description: Name of the backup PVC + type: string + backup_pvc_namespace: + description: (Deprecated) Namespace the PVC is in + type: string + backup_resource_requirements: + description: Resource requirements for the management pod used to create a backup + properties: + limits: + properties: + cpu: + type: string + memory: + type: string + type: object + requests: + properties: + cpu: + type: string + memory: + type: string + type: object + type: object + backup_storage_class: + description: Storage class to use when creating PVC for backup + type: string + backup_storage_requirements: + description: Storage requirements for backup PVC (may be similar to existing postgres PVC backing up from) + type: string + clean_backup_on_delete: + description: Flag to indicate if backup should be deleted on PVC if AWXBackup object is deleted + type: boolean + db_management_pod_node_selector: + description: nodeSelector for the Postgres pods to backup + type: string + deployment_name: + description: Name of the deployment to be backed up + type: string + no_log: + default: true + description: Configure no_log for no_log tasks + type: boolean + pg_dump_suffix: + description: Additional parameters for the pg_dump command + type: string + postgres_image: + description: Registry path to the PostgreSQL container to use + type: string + postgres_image_version: + description: PostgreSQL container image version to use + type: string + postgres_label_selector: + description: Label selector used to identify postgres pod for backing up data + type: string + set_self_labels: + default: true + description: Maintain some of the recommended `app.kubernetes.io/*` labels on the resource (self) + type: boolean + required: + - deployment_name + type: object + x-kubernetes-preserve-unknown-fields: true + status: + properties: + backupClaim: + description: Backup persistent volume claim + type: string + backupDirectory: + description: Backup directory name on the specified pvc + type: string + conditions: + description: The resulting conditions when a Service Telemetry is instantiated + items: + properties: + lastTransitionTime: + type: string + reason: + type: string + status: + type: string + type: + type: string + type: object + type: array + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + served: true + storage: true + subresources: + status: {} diff --git a/helm/awx-operator/crds/customresourcedefinition-awxrestores.awx.ansible.com.yaml b/helm/awx-operator/crds/customresourcedefinition-awxrestores.awx.ansible.com.yaml new file mode 100644 index 0000000..6fbb048 --- /dev/null +++ b/helm/awx-operator/crds/customresourcedefinition-awxrestores.awx.ansible.com.yaml @@ -0,0 +1,127 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + labels: + helm.sh/chart: awx-operator + name: awxrestores.awx.ansible.com +spec: + group: awx.ansible.com + names: + kind: AWXRestore + listKind: AWXRestoreList + plural: awxrestores + singular: awxrestore + scope: Namespaced + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + description: Schema validation for the AWXRestore CRD + 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: + additional_labels: + description: Additional labels defined on the resource, which should be propagated to child resources + items: + type: string + type: array + backup_dir: + description: Backup directory name, set as a status found on the awxbackup object (backupDirectory) + type: string + backup_name: + description: AWXBackup object name + type: string + backup_pvc: + description: Name of the PVC to be restored from, set as a status found on the awxbackup object (backupClaim) + type: string + backup_pvc_namespace: + description: (Deprecated) Namespace the PVC is in + type: string + backup_source: + description: Backup source + enum: + - Backup CR + - PVC + type: string + cluster_name: + description: Cluster name + type: string + db_management_pod_node_selector: + description: nodeSelector for the Postgres pods to backup + type: string + deployment_name: + description: Name of the restored deployment. This should be different from the original deployment name if the original deployment still exists. + type: string + no_log: + default: true + description: Configure no_log for no_log tasks + type: boolean + postgres_image: + description: Registry path to the PostgreSQL container to use + type: string + postgres_image_version: + description: PostgreSQL container image version to use + type: string + postgres_label_selector: + description: Label selector used to identify postgres pod for backing up data + type: string + restore_resource_requirements: + description: Resource requirements for the management pod that restores AWX from a backup + properties: + limits: + properties: + cpu: + type: string + memory: + type: string + type: object + requests: + properties: + cpu: + type: string + memory: + type: string + type: object + type: object + set_self_labels: + default: true + description: Maintain some of the recommended `app.kubernetes.io/*` labels on the resource (self) + type: boolean + required: + - deployment_name + type: object + x-kubernetes-preserve-unknown-fields: true + status: + properties: + conditions: + description: The resulting conditions when a Service Telemetry is instantiated + items: + properties: + lastTransitionTime: + type: string + reason: + type: string + status: + type: string + type: + type: string + type: object + type: array + restoreComplete: + description: Restore process complete + type: boolean + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + served: true + storage: true + subresources: + status: {} diff --git a/helm/awx-operator/crds/customresourcedefinition-awxs.awx.ansible.com.yaml b/helm/awx-operator/crds/customresourcedefinition-awxs.awx.ansible.com.yaml new file mode 100644 index 0000000..029789d --- /dev/null +++ b/helm/awx-operator/crds/customresourcedefinition-awxs.awx.ansible.com.yaml @@ -0,0 +1,1797 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + labels: + helm.sh/chart: awx-operator + name: awxs.awx.ansible.com +spec: + group: awx.ansible.com + names: + kind: AWX + listKind: AWXList + plural: awxs + singular: awx + scope: Namespaced + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + description: Schema validation for the AWX CRD + 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: + additional_labels: + description: Additional labels defined on the resource, which should be propagated to child resources + items: + type: string + type: array + admin_email: + description: The admin user email + type: string + admin_password_secret: + description: Secret where the admin password can be found + type: string + admin_user: + default: admin + description: Username to use for the admin account + type: string + affinity: + description: If specified, the pod's scheduling constraints + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + type: array + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + annotations: + description: Common annotations for both Web and Task deployments. + type: string + api_version: + description: apiVersion of the deployment type + type: string + auto_upgrade: + default: true + description: Should AWX instances be automatically upgraded when operator gets upgraded + type: boolean + broadcast_websocket_secret: + description: Secret where the broadcast websocket secret can be found + type: string + bundle_cacert_secret: + description: Secret where can be found the trusted Certificate Authority Bundle + type: string + ca_trust_bundle: + description: Path where the trusted CA bundle is available + type: string + control_plane_ee_image: + description: Registry path to the Execution Environment container image to use on control plane pods + type: string + control_plane_priority_class: + description: Assign a preexisting priority class to the control plane pods + type: string + create_preload_data: + default: true + description: Whether or not to preload data upon instance creation + type: boolean + csrf_cookie_secure: + description: Set csrf cookie secure mode for web + type: string + deployment_type: + description: Name of the deployment type + type: string + development_mode: + description: If the deployment should be done in development mode + type: boolean + ee_extra_env: + type: string + ee_extra_volume_mounts: + description: Specify volume mounts to be added to Execution container + type: string + ee_images: + description: Registry path to the Execution Environment container to use + items: + properties: + image: + type: string + name: + type: string + type: object + type: array + ee_pull_credentials_secret: + description: Secret where pull credentials for registered ees can be found + type: string + ee_resource_requirements: + description: Resource requirements for the ee container + properties: + limits: + properties: + cpu: + type: string + memory: + type: string + storage: + type: string + type: object + requests: + properties: + cpu: + type: string + memory: + type: string + storage: + type: string + type: object + type: object + extra_settings: + description: Extra settings to specify for the API + items: + properties: + setting: + type: string + value: + x-kubernetes-preserve-unknown-fields: true + type: object + type: array + extra_volumes: + description: Specify extra volumes to add to the application pod + type: string + garbage_collect_secrets: + default: false + description: Whether or not to remove secrets upon instance removal + type: boolean + host_aliases: + description: HostAliases for app containers + items: + properties: + hostnames: + items: + type: string + type: array + ip: + type: string + type: object + type: array + hostname: + description: The hostname of the instance + type: string + image: + description: Registry path to the application container to use + type: string + image_pull_policy: + default: IfNotPresent + description: The image pull policy + enum: + - Always + - always + - Never + - never + - IfNotPresent + - ifnotpresent + type: string + image_pull_secret: + description: (Deprecated) Image pull secret for app and database containers + type: string + image_pull_secrets: + description: Image pull secrets for app and database containers + items: + type: string + type: array + image_version: + description: Application container image version to use + type: string + ingress_annotations: + description: Annotations to add to the Ingress Controller + type: string + ingress_api_version: + description: The Ingress API version to use + type: string + ingress_class_name: + description: The name of ingress class to use instead of the cluster default. + type: string + ingress_controller: + description: Special configuration for specific Ingress Controllers + type: string + ingress_path: + description: The ingress path used to reach the deployed service + type: string + ingress_path_type: + description: The ingress path type for the deployed service + type: string + ingress_tls_secret: + description: Secret where the Ingress TLS secret can be found + type: string + ingress_type: + description: The ingress type to use to reach the deployed instance + enum: + - none + - Ingress + - ingress + - Route + - route + type: string + init_container_extra_commands: + description: Extra commands for the init container + type: string + init_container_extra_volume_mounts: + description: Specify volume mounts to be added to the init container + type: string + init_container_image: + description: Registry path to the init container to use + type: string + init_container_image_version: + description: Init container image version to use + type: string + init_container_resource_requirements: + description: Resource requirements for the init container + properties: + limits: + properties: + cpu: + type: string + memory: + type: string + storage: + type: string + type: object + requests: + properties: + cpu: + type: string + memory: + type: string + storage: + type: string + type: object + type: object + init_projects_container_image: + description: Registry path to the init projects container to use + type: string + ipv6_disabled: + default: false + description: Disable web container's nginx ipv6 listener + type: boolean + kind: + description: Kind of the deployment type + type: string + ldap_cacert_secret: + description: Secret where can be found the LDAP trusted Certificate Authority Bundle + type: string + ldap_password_secret: + description: Secret where can be found the LDAP bind password + type: string + loadbalancer_ip: + default: "" + description: Assign LoadBalancer IP address + type: string + loadbalancer_port: + default: 80 + description: Port to use for the loadbalancer + type: integer + loadbalancer_protocol: + default: http + description: Protocol to use for the loadbalancer + enum: + - http + - https + type: string + no_log: + default: true + description: Configure no_log for no_log tasks + type: boolean + node_selector: + description: nodeSelector for the pods + type: string + nodeport_port: + description: Port to use for the nodeport + type: integer + old_postgres_configuration_secret: + description: Secret where the old database configuration can be found for data migration + type: string + postgres_configuration_secret: + description: Secret where the database configuration can be found + type: string + postgres_data_path: + description: Path where the PostgreSQL data are located + type: string + postgres_extra_args: + items: + type: string + type: array + postgres_image: + description: Registry path to the PostgreSQL container to use + type: string + postgres_image_version: + description: PostgreSQL container image version to use + type: string + postgres_init_container_resource_requirements: + description: Resource requirements for the postgres init container + properties: + limits: + properties: + cpu: + type: string + memory: + type: string + storage: + type: string + type: object + requests: + properties: + cpu: + type: string + memory: + type: string + storage: + type: string + type: object + type: object + postgres_keep_pvc_after_upgrade: + description: Specify whether or not to keep the old PVC after PostgreSQL upgrades + type: boolean + postgres_keepalives: + default: true + description: Controls whether client-side TCP keepalives are used for Postgres connections. + type: boolean + postgres_keepalives_count: + default: 5 + description: Controls the number of TCP keepalives that can be lost before the client's connection to the server is considered dead. + format: int32 + type: integer + postgres_keepalives_idle: + default: 5 + description: Controls the number of seconds of inactivity after which TCP should send a keepalive message to the server. + format: int32 + type: integer + postgres_keepalives_interval: + default: 5 + description: Controls the number of seconds after which a TCP keepalive message that is not acknowledged by the server should be retransmitted. + format: int32 + type: integer + postgres_label_selector: + description: Label selector used to identify postgres pod for data migration + type: string + postgres_priority_class: + description: Assign a preexisting priority class to the postgres pod + type: string + postgres_resource_requirements: + description: Resource requirements for the PostgreSQL container + properties: + limits: + properties: + cpu: + type: string + memory: + type: string + type: object + requests: + properties: + cpu: + type: string + memory: + type: string + type: object + type: object + postgres_selector: + description: nodeSelector for the Postgres pods + type: string + postgres_storage_class: + description: Storage class to use for the PostgreSQL PVC + type: string + postgres_storage_requirements: + description: Storage requirements for the PostgreSQL container + properties: + limits: + properties: + storage: + type: string + type: object + requests: + properties: + storage: + type: string + type: object + type: object + postgres_tolerations: + description: node tolerations for the Postgres pods + type: string + projects_existing_claim: + description: PersistentVolumeClaim to mount /var/lib/projects directory + type: string + projects_persistence: + default: false + description: Whether or not the /var/lib/projects directory will be persistent + type: boolean + projects_storage_access_mode: + default: ReadWriteMany + description: AccessMode for the /var/lib/projects PersistentVolumeClaim + type: string + projects_storage_class: + description: Storage class for the /var/lib/projects PersistentVolumeClaim + type: string + projects_storage_size: + default: 8Gi + description: Size for the /var/lib/projects PersistentVolumeClaim + type: string + projects_use_existing_claim: + description: Using existing PersistentVolumeClaim + enum: + - _Yes_ + - _No_ + type: string + redis_capabilities: + description: Redis container capabilities + items: + type: string + type: array + redis_image: + description: Registry path to the redis container to use + type: string + redis_image_version: + description: Redis container image version to use + type: string + redis_resource_requirements: + description: Resource requirements for the redis container + properties: + limits: + properties: + cpu: + type: string + memory: + type: string + storage: + type: string + type: object + requests: + properties: + cpu: + type: string + memory: + type: string + storage: + type: string + type: object + type: object + replicas: + default: 1 + description: Number of instance replicas + format: int32 + type: integer + route_api_version: + description: The route API version to use + type: string + route_host: + description: The DNS to use to points to the instance + type: string + route_tls_secret: + description: Secret where the TLS related credentials are stored + type: string + route_tls_termination_mechanism: + default: Edge + description: The secure TLS termination mechanism to use + enum: + - Edge + - edge + - Passthrough + - passthrough + type: string + rsyslog_resource_requirements: + description: Resource requirements for the rsyslog container + properties: + limits: + properties: + cpu: + type: string + memory: + type: string + storage: + type: string + type: object + requests: + properties: + cpu: + type: string + memory: + type: string + storage: + type: string + type: object + type: object + secret_key_secret: + description: Secret where the secret key can be found + type: string + security_context_settings: + description: Key/values that will be set under the pod-level securityContext field + type: object + x-kubernetes-preserve-unknown-fields: true + service_account_annotations: + description: ServiceAccount annotations + type: string + service_annotations: + description: Annotations to add to the service + type: string + service_labels: + description: Additional labels to apply to the service + type: string + service_type: + description: The service type to be used on the deployed instance + enum: + - LoadBalancer + - loadbalancer + - ClusterIP + - clusterip + - NodePort + - nodeport + type: string + session_cookie_secure: + description: Set session cookie secure mode for web + type: string + set_self_labels: + default: true + description: Maintain some of the recommended `app.kubernetes.io/*` labels on the resource (self) + type: boolean + task_affinity: + description: If specified, the pod's scheduling constraints + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + type: array + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + task_annotations: + description: Task deployment annotations. This will override the general annotations parameter for the Task deployment. + type: string + task_args: + items: + type: string + type: array + task_command: + items: + type: string + type: array + task_extra_env: + type: string + task_extra_volume_mounts: + description: Specify volume mounts to be added to Task container + type: string + task_node_selector: + description: nodeSelector for the task pods + type: string + task_privileged: + default: false + description: If a privileged security context should be enabled + type: boolean + task_replicas: + description: Number of task instance replicas + format: int32 + type: integer + task_resource_requirements: + description: Resource requirements for the task container + properties: + limits: + properties: + cpu: + type: string + memory: + type: string + storage: + type: string + type: object + requests: + properties: + cpu: + type: string + memory: + type: string + storage: + type: string + type: object + type: object + task_tolerations: + description: node tolerations for the task pods + type: string + task_topology_spread_constraints: + description: topology rule(s) for the task pods + type: string + termination_grace_period_seconds: + description: Optional duration in seconds pods needs to terminate gracefully + format: int32 + type: integer + tolerations: + description: node tolerations for the pods + type: string + topology_spread_constraints: + description: topology rule(s) for the pods + type: string + web_affinity: + description: If specified, the pod's scheduling constraints + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + type: array + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + web_annotations: + description: Web deployment annotations. This will override the general annotations parameter for the Web deployment. + type: string + web_args: + items: + type: string + type: array + web_command: + items: + type: string + type: array + web_extra_env: + type: string + web_extra_volume_mounts: + description: Specify volume mounts to be added to the Web container + type: string + web_node_selector: + description: nodeSelector for the web pods + type: string + web_replicas: + description: Number of web instance replicas + format: int32 + type: integer + web_resource_requirements: + description: Resource requirements for the web container + properties: + limits: + properties: + cpu: + type: string + memory: + type: string + storage: + type: string + type: object + requests: + properties: + cpu: + type: string + memory: + type: string + storage: + type: string + type: object + type: object + web_tolerations: + description: node tolerations for the web pods + type: string + web_topology_spread_constraints: + description: topology rule(s) for the web pods + type: string + type: object + status: + properties: + URL: + description: URL to access the deployed instance + type: string + adminPasswordSecret: + description: Admin password secret name of the deployed instance + type: string + adminUser: + description: Admin user of the deployed instance + type: string + broadcastWebsocketSecret: + description: Broadcast websocket secret name of the deployed instance + type: string + conditions: + description: The resulting conditions when a Service Telemetry is instantiated + items: + properties: + lastTransitionTime: + type: string + reason: + type: string + status: + type: string + type: + type: string + type: object + type: array + image: + description: URL of the image used for the deployed instance + type: string + migratedFromSecret: + description: The secret used for migrating an old instance + type: string + postgresConfigurationSecret: + description: Postgres Configuration secret name of the deployed instance + type: string + secretKeySecret: + description: Secret key secret name of the deployed instance + type: string + upgradedPostgresVersion: + description: Status to indicate that the database has been upgraded to the version in the status + type: string + version: + description: Version of the deployed instance + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/helm/awx-operator/templates/NOTES.txt b/helm/awx-operator/templates/NOTES.txt new file mode 100644 index 0000000..f99143d --- /dev/null +++ b/helm/awx-operator/templates/NOTES.txt @@ -0,0 +1 @@ +AWX Operator installed with Helm Chart version 2.3.0 diff --git a/helm/awx-operator/templates/_helpers.tpl b/helm/awx-operator/templates/_helpers.tpl new file mode 100644 index 0000000..5deab29 --- /dev/null +++ b/helm/awx-operator/templates/_helpers.tpl @@ -0,0 +1,6 @@ +{{/* +Generate the name of the postgres secret, expects AWX context passed in +*/}} +{{- define "postgres.secretName" -}} +{{ default (printf "%s-postgres-configuration" .Values.AWX.name) .Values.AWX.postgres.secretName }} +{{- end }} diff --git a/helm/awx-operator/templates/awx-deploy.yaml b/helm/awx-operator/templates/awx-deploy.yaml new file mode 100644 index 0000000..cf90e68 --- /dev/null +++ b/helm/awx-operator/templates/awx-deploy.yaml @@ -0,0 +1,24 @@ +{{- if $.Values.AWX.enabled }} +{{- with .Values.AWX }} +apiVersion: awx.ansible.com/v1beta1 +kind: AWX +metadata: + name: {{ .name }} + namespace: {{ $.Release.Namespace }} +spec: +{{- /* Include raw map from the values file spec */}} +{{ .spec | toYaml | indent 2 }} +{{- /* Provide security context defaults */}} + {{- if not (hasKey .spec "security_context_settings") }} + security_context_settings: + runAsGroup: 0 + runAsUser: 0 + fsGroup: 0 + fsGroupChangePolicy: OnRootMismatch + {{- end }} +{{- /* Postgres configs if enabled and not already present */}} + {{- if and .postgres.enabled (not (hasKey .spec "postgres_configuration_secret")) }} + postgres_configuration_secret: {{ include "postgres.secretName" $ }} + {{- end }} +{{- end }} +{{- end }} diff --git a/helm/awx-operator/templates/clusterrole-awx-operator-metrics-reader.yaml b/helm/awx-operator/templates/clusterrole-awx-operator-metrics-reader.yaml new file mode 100644 index 0000000..8e5a2fc --- /dev/null +++ b/helm/awx-operator/templates/clusterrole-awx-operator-metrics-reader.yaml @@ -0,0 +1,11 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + helm.sh/chart: awx-operator + name: awx-operator-metrics-reader +rules: + - nonResourceURLs: + - /metrics + verbs: + - get diff --git a/helm/awx-operator/templates/clusterrole-awx-operator-proxy-role.yaml b/helm/awx-operator/templates/clusterrole-awx-operator-proxy-role.yaml new file mode 100644 index 0000000..8344846 --- /dev/null +++ b/helm/awx-operator/templates/clusterrole-awx-operator-proxy-role.yaml @@ -0,0 +1,19 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + helm.sh/chart: awx-operator + name: awx-operator-proxy-role +rules: + - apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create + - apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create diff --git a/helm/awx-operator/templates/clusterrolebinding-awx-operator-proxy-rolebinding.yaml b/helm/awx-operator/templates/clusterrolebinding-awx-operator-proxy-rolebinding.yaml new file mode 100644 index 0000000..276a58f --- /dev/null +++ b/helm/awx-operator/templates/clusterrolebinding-awx-operator-proxy-rolebinding.yaml @@ -0,0 +1,14 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + helm.sh/chart: awx-operator + name: awx-operator-proxy-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: awx-operator-proxy-role +subjects: + - kind: ServiceAccount + name: awx-operator-controller-manager + namespace: '{{ .Release.Namespace }}' diff --git a/helm/awx-operator/templates/configmap-awx-operator-awx-manager-config.yaml b/helm/awx-operator/templates/configmap-awx-operator-awx-manager-config.yaml new file mode 100644 index 0000000..a262c4a --- /dev/null +++ b/helm/awx-operator/templates/configmap-awx-operator-awx-manager-config.yaml @@ -0,0 +1,28 @@ +apiVersion: v1 +data: + controller_manager_config.yaml: | + apiVersion: controller-runtime.sigs.k8s.io/v1alpha1 + kind: ControllerManagerConfig + health: + healthProbeBindAddress: :6789 + metrics: + bindAddress: 127.0.0.1:8080 + + leaderElection: + leaderElect: true + resourceName: 811c9dc5.ansible.com + # leaderElectionReleaseOnCancel defines if the leader should step down volume + # when the Manager ends. This requires the binary to immediately end when the + # Manager is stopped, otherwise, this setting is unsafe. Setting this significantly + # speeds up voluntary leader transitions as the new leader don't have to wait + # LeaseDuration time first. + # In the default scaffold provided, the program ends immediately after + # the manager stops, so would be fine to enable this option. However, + # if you are doing or is intended to do any operation such as perform cleanups + # after the manager stops then its usage might be unsafe. + # leaderElectionReleaseOnCancel: true +kind: ConfigMap +metadata: + labels: + helm.sh/chart: awx-operator + name: awx-operator-awx-manager-config diff --git a/helm/awx-operator/templates/deployment-awx-operator-controller-manager.yaml b/helm/awx-operator/templates/deployment-awx-operator-controller-manager.yaml new file mode 100644 index 0000000..0e2560e --- /dev/null +++ b/helm/awx-operator/templates/deployment-awx-operator-controller-manager.yaml @@ -0,0 +1,91 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + control-plane: controller-manager + helm.sh/chart: awx-operator + name: awx-operator-controller-manager +spec: + replicas: 1 + selector: + matchLabels: + control-plane: controller-manager + helm.sh/chart: awx-operator + template: + metadata: + annotations: + kubectl.kubernetes.io/default-container: awx-manager + labels: + control-plane: controller-manager + helm.sh/chart: awx-operator + spec: + containers: + - args: + - --secure-listen-address=0.0.0.0:8443 + - --upstream=http://127.0.0.1:8080/ + - --logtostderr=true + - --v=0 + image: gcr.io/kubebuilder/kube-rbac-proxy:v0.14.1 + name: kube-rbac-proxy + ports: + - containerPort: 8443 + name: https + protocol: TCP + resources: + limits: + cpu: 500m + memory: 128Mi + requests: + cpu: 5m + memory: 64Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + - args: + - --health-probe-bind-address=:6789 + - --metrics-bind-address=127.0.0.1:8080 + - --leader-elect + - --leader-election-id=awx-operator + env: + - name: ANSIBLE_GATHERING + value: explicit + - name: ANSIBLE_DEBUG_LOGS + value: "false" + - name: WATCH_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + image: quay.io/ansible/awx-operator:latest + livenessProbe: + httpGet: + path: /healthz + port: 6789 + initialDelaySeconds: 15 + periodSeconds: 20 + name: awx-manager + readinessProbe: + httpGet: + path: /readyz + port: 6789 + initialDelaySeconds: 5 + periodSeconds: 10 + resources: + limits: + cpu: 2000m + memory: 4096Mi + requests: + cpu: 50m + memory: 32Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + imagePullSecrets: + - name: redhat-operators-pull-secret + securityContext: + runAsNonRoot: true + serviceAccountName: awx-operator-controller-manager + terminationGracePeriodSeconds: 10 diff --git a/helm/awx-operator/templates/postgres-config.yaml b/helm/awx-operator/templates/postgres-config.yaml new file mode 100644 index 0000000..4a1d9ec --- /dev/null +++ b/helm/awx-operator/templates/postgres-config.yaml @@ -0,0 +1,18 @@ +{{- if and $.Values.AWX.enabled $.Values.AWX.postgres.enabled }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "postgres.secretName" . }} + namespace: {{ $.Release.Namespace }} +{{- with $.Values.AWX.postgres }} +stringData: + host: {{ .host }} + port: {{ .port | quote }} + database: {{ .dbName }} + username: {{ .username }} + password: {{ .password }} + sslmode: {{ .sslmode }} + type: {{ .type }} +type: Opaque +{{- end }} +{{- end }} diff --git a/helm/awx-operator/templates/role-awx-operator-awx-manager-role.yaml b/helm/awx-operator/templates/role-awx-operator-awx-manager-role.yaml new file mode 100644 index 0000000..bd1b123 --- /dev/null +++ b/helm/awx-operator/templates/role-awx-operator-awx-manager-role.yaml @@ -0,0 +1,127 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + creationTimestamp: null + labels: + helm.sh/chart: awx-operator + name: awx-operator-awx-manager-role +rules: + - apiGroups: + - route.openshift.io + resources: + - routes + - routes/custom-host + verbs: + - get + - list + - create + - delete + - patch + - update + - watch + - apiGroups: + - "" + resources: + - pods + - services + - services/finalizers + - serviceaccounts + - endpoints + - persistentvolumeclaims + - events + - configmaps + - secrets + verbs: + - get + - list + - create + - delete + - patch + - update + - watch + - apiGroups: + - rbac.authorization.k8s.io + resources: + - roles + - rolebindings + verbs: + - get + - list + - create + - delete + - patch + - update + - watch + - apiGroups: + - apps + resources: + - deployments + - daemonsets + - replicasets + - statefulsets + verbs: + - get + - list + - create + - delete + - patch + - update + - watch + - apiGroups: + - networking.k8s.io + resources: + - ingresses + verbs: + - get + - list + - create + - delete + - patch + - update + - watch + - apiGroups: + - monitoring.coreos.com + resources: + - servicemonitors + verbs: + - get + - create + - apiGroups: + - apps + resourceNames: + - awx-operator + resources: + - deployments/finalizers + verbs: + - update + - apiGroups: + - apps + resources: + - deployments/scale + - statefulsets/scale + verbs: + - patch + - apiGroups: + - "" + resources: + - pods/exec + - pods/attach + - pods/log + verbs: + - create + - get + - apiGroups: + - apps + resources: + - replicasets + verbs: + - get + - create + - apiGroups: + - awx.ansible.com + resources: + - '*' + - awxbackups + - awxrestores + verbs: + - '*' diff --git a/helm/awx-operator/templates/role-awx-operator-leader-election-role.yaml b/helm/awx-operator/templates/role-awx-operator-leader-election-role.yaml new file mode 100644 index 0000000..f52a177 --- /dev/null +++ b/helm/awx-operator/templates/role-awx-operator-leader-election-role.yaml @@ -0,0 +1,38 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + helm.sh/chart: awx-operator + name: awx-operator-leader-election-role +rules: + - apiGroups: + - "" + resources: + - configmaps + verbs: + - get + - list + - watch + - create + - update + - patch + - delete + - apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - get + - list + - watch + - create + - update + - patch + - delete + - apiGroups: + - "" + resources: + - events + verbs: + - create + - patch diff --git a/helm/awx-operator/templates/rolebinding-awx-operator-awx-manager-rolebinding.yaml b/helm/awx-operator/templates/rolebinding-awx-operator-awx-manager-rolebinding.yaml new file mode 100644 index 0000000..400bcac --- /dev/null +++ b/helm/awx-operator/templates/rolebinding-awx-operator-awx-manager-rolebinding.yaml @@ -0,0 +1,14 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + helm.sh/chart: awx-operator + name: awx-operator-awx-manager-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: awx-operator-awx-manager-role +subjects: + - kind: ServiceAccount + name: awx-operator-controller-manager + namespace: '{{ .Release.Namespace }}' diff --git a/helm/awx-operator/templates/rolebinding-awx-operator-leader-election-rolebinding.yaml b/helm/awx-operator/templates/rolebinding-awx-operator-leader-election-rolebinding.yaml new file mode 100644 index 0000000..200ba58 --- /dev/null +++ b/helm/awx-operator/templates/rolebinding-awx-operator-leader-election-rolebinding.yaml @@ -0,0 +1,14 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + helm.sh/chart: awx-operator + name: awx-operator-leader-election-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: awx-operator-leader-election-role +subjects: + - kind: ServiceAccount + name: awx-operator-controller-manager + namespace: '{{ .Release.Namespace }}' diff --git a/helm/awx-operator/templates/service-awx-operator-controller-manager-metrics-service.yaml b/helm/awx-operator/templates/service-awx-operator-controller-manager-metrics-service.yaml new file mode 100644 index 0000000..a53356d --- /dev/null +++ b/helm/awx-operator/templates/service-awx-operator-controller-manager-metrics-service.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + control-plane: controller-manager + helm.sh/chart: awx-operator + name: awx-operator-controller-manager-metrics-service +spec: + ports: + - name: https + port: 8443 + protocol: TCP + targetPort: https + selector: + control-plane: controller-manager + helm.sh/chart: awx-operator diff --git a/helm/awx-operator/templates/serviceaccount-awx-operator-controller-manager.yaml b/helm/awx-operator/templates/serviceaccount-awx-operator-controller-manager.yaml new file mode 100644 index 0000000..128bcb1 --- /dev/null +++ b/helm/awx-operator/templates/serviceaccount-awx-operator-controller-manager.yaml @@ -0,0 +1,6 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + helm.sh/chart: awx-operator + name: awx-operator-controller-manager diff --git a/helm/awx-operator/values.yaml b/helm/awx-operator/values.yaml new file mode 100644 index 0000000..b6612ed --- /dev/null +++ b/helm/awx-operator/values.yaml @@ -0,0 +1,26 @@ +AWX: + # enable use of awx-deploy template + enabled: True + name: awx + csrf_cookie_secure: False + spec: + admin_user: admin + service_type: nodeport + nodeport_port: 30801 + #service_type: LoadBalancer + #loadbalancer_ip: '10.10.43.98' + loadbalancer_protocol: https + #loadbalancer_port: 80 + + # configurations for external postgres instance + postgres: + enabled: True + host: awx-postgres-13 + port: 5432 + dbName: infra + username: infra + # for secret management, pass in the password independently of this file + # at the command line, use --set AWX.postgres.password + password: infraadmin1234 + sslmode: prefer + type: managed diff --git a/helm/ghost/.helmignore b/helm/ghost/.helmignore new file mode 100644 index 0000000..f0c1319 --- /dev/null +++ b/helm/ghost/.helmignore @@ -0,0 +1,21 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*~ +# Various IDEs +.project +.idea/ +*.tmproj diff --git a/helm/ghost/Chart.lock b/helm/ghost/Chart.lock new file mode 100644 index 0000000..36322ed --- /dev/null +++ b/helm/ghost/Chart.lock @@ -0,0 +1,9 @@ +dependencies: +- name: mysql + repository: oci://registry-1.docker.io/bitnamicharts + version: 9.10.6 +- name: common + repository: oci://registry-1.docker.io/bitnamicharts + version: 2.6.0 +digest: sha256:d71d0eea3774c2113f8754249fe106d924184a57f84ea45603b9d30866927c1a +generated: "2023-07-17T22:16:18.795087193Z" diff --git a/helm/ghost/Chart.yaml b/helm/ghost/Chart.yaml new file mode 100644 index 0000000..54df497 --- /dev/null +++ b/helm/ghost/Chart.yaml @@ -0,0 +1,37 @@ +annotations: + category: CMS + licenses: Apache-2.0 +apiVersion: v2 +appVersion: 5.54.3 +dependencies: +- condition: mysql.enabled + name: mysql + repository: oci://registry-1.docker.io/bitnamicharts + tags: + - ghost-database + version: 9.x.x +- name: common + repository: oci://registry-1.docker.io/bitnamicharts + tags: + - bitnami-common + version: 2.x.x +description: Ghost is an open source publishing platform designed to create blogs, + magazines, and news sites. It includes a simple markdown editor with preview, theming, + and SEO built-in to simplify editing. +home: https://bitnami.com +icon: https://bitnami.com/assets/stacks/ghost/img/ghost-stack-220x234.png +keywords: +- ghost +- blog +- http +- web +- application +- nodejs +- javascript +maintainers: +- name: VMware, Inc. + url: https://github.com/bitnami/charts +name: ghost +sources: +- https://github.com/bitnami/charts/tree/main/bitnami/ghost +version: 19.3.25 diff --git a/helm/ghost/README.md b/helm/ghost/README.md new file mode 100644 index 0000000..772bc05 --- /dev/null +++ b/helm/ghost/README.md @@ -0,0 +1,537 @@ + + +# Ghost packaged by Bitnami + +Ghost is an open source publishing platform designed to create blogs, magazines, and news sites. It includes a simple markdown editor with preview, theming, and SEO built-in to simplify editing. + +[Overview of Ghost](https://ghost.org/) + +Trademarks: This software listing is packaged by Bitnami. The respective trademarks mentioned in the offering are owned by the respective companies, and use of them does not imply any affiliation or endorsement. + +## TL;DR + +```console +helm install my-release oci://registry-1.docker.io/bitnamicharts/ghost +``` + +## Introduction + +This chart bootstraps a [Ghost](https://github.com/bitnami/containers/tree/main/bitnami/ghost) deployment on a [Kubernetes](https://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. + +It also packages the [Bitnami MySQL chart](https://github.com/bitnami/charts/tree/main/bitnami/mysql) which is required for bootstrapping a MySQL deployment for the database requirements of the Ghost application. + +Bitnami charts can be used with [Kubeapps](https://kubeapps.dev/) for deployment and management of Helm Charts in clusters. + +Looking to use Ghost in production? Try [VMware Application Catalog](https://bitnami.com/enterprise), the enterprise edition of Bitnami Application Catalog. + +## Prerequisites + +- Kubernetes 1.19+ +- Helm 3.2.0+ +- PV provisioner support in the underlying infrastructure +- ReadWriteMany volumes for deployment scaling + +## Installing the Chart + +To install the chart with the release name `my-release`: + +```console +helm install my-release oci://registry-1.docker.io/bitnamicharts/ghost +``` + +The command deploys Ghost on the Kubernetes cluster in the default configuration. The [Parameters](#parameters) section lists the parameters that can be configured during installation. + +> **Tip**: List all releases using `helm list` + +## Uninstalling the Chart + +To uninstall/delete the `my-release` deployment: + +```console +helm delete my-release +``` + +The command removes all the Kubernetes components associated with the chart and deletes the release. + +## Parameters + +### Global parameters + +| Name | Description | Value | +| ------------------------- | ----------------------------------------------- | ----- | +| `global.imageRegistry` | Global Docker image registry | `""` | +| `global.imagePullSecrets` | Global Docker registry secret names as an array | `[]` | +| `global.storageClass` | Global StorageClass for Persistent Volume(s) | `""` | + +### Common parameters + +| Name | Description | Value | +| ------------------- | -------------------------------------------------- | --------------- | +| `kubeVersion` | Override Kubernetes version | `""` | +| `nameOverride` | String to partially override common.names.fullname | `""` | +| `fullnameOverride` | String to fully override common.names.fullname | `""` | +| `commonLabels` | Labels to add to all deployed objects | `{}` | +| `commonAnnotations` | Annotations to add to all deployed objects | `{}` | +| `clusterDomain` | Kubernetes cluster domain name | `cluster.local` | +| `extraDeploy` | Array of extra objects to deploy with the release | `[]` | + +### Ghost Image parameters + +| Name | Description | Value | +| ------------------- | ----------------------------------------------------------------------------------------------------- | --------------------- | +| `image.registry` | Ghost image registry | `docker.io` | +| `image.repository` | Ghost image repository | `bitnami/ghost` | +| `image.tag` | Ghost image tag (immutable tags are recommended) | `5.54.3-debian-11-r0` | +| `image.digest` | Ghost image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag | `""` | +| `image.pullPolicy` | Ghost image pull policy | `IfNotPresent` | +| `image.pullSecrets` | Ghost image pull secrets | `[]` | +| `image.debug` | Enable image debug mode | `false` | + +### Ghost Configuration parameters + +| Name | Description | Value | +| -------------------- | -------------------------------------------------------------------- | ------------------ | +| `ghostUsername` | Ghost user name | `user` | +| `ghostPassword` | Ghost user password | `""` | +| `existingSecret` | Name of existing secret containing Ghost credentials | `""` | +| `ghostEmail` | Ghost user email | `user@example.com` | +| `ghostBlogTitle` | Ghost Blog title | `User's Blog` | +| `ghostHost` | Ghost host to create application URLs | `""` | +| `ghostPath` | URL sub path where to server the Ghost application | `/` | +| `ghostEnableHttps` | Configure Ghost to build application URLs using https | `false` | +| `smtpHost` | SMTP server host | `""` | +| `smtpPort` | SMTP server port | `""` | +| `smtpUser` | SMTP username | `""` | +| `smtpPassword` | SMTP user password | `""` | +| `smtpService` | SMTP service | `""` | +| `smtpProtocol` | SMTP protocol (ssl or tls) | `""` | +| `smtpExistingSecret` | The name of an existing secret with SMTP credentials | `""` | +| `allowEmptyPassword` | Allow the container to be started with blank passwords | `true` | +| `ghostSkipInstall` | Skip performing the initial bootstrapping for Ghost | `false` | +| `command` | Override default container command (useful when using custom images) | `[]` | +| `args` | Override default container args (useful when using custom images) | `[]` | +| `extraEnvVars` | Array with extra environment variables to add to the Ghost container | `[]` | +| `extraEnvVarsCM` | Name of existing ConfigMap containing extra env vars | `""` | +| `extraEnvVarsSecret` | Name of existing Secret containing extra env vars | `""` | + +### Ghost deployment parameters + +| Name | Description | Value | +| --------------------------------------- | ----------------------------------------------------------------------------------------- | --------------- | +| `replicaCount` | Number of Ghost replicas to deploy | `1` | +| `updateStrategy.type` | Ghost deployment strategy type | `RollingUpdate` | +| `priorityClassName` | Ghost pod priority class name | `""` | +| `schedulerName` | Name of the k8s scheduler (other than default) | `""` | +| `topologySpreadConstraints` | Topology Spread Constraints for pod assignment | `[]` | +| `hostAliases` | Ghost pod host aliases | `[]` | +| `extraVolumes` | Optionally specify extra list of additional volumes for Ghost pods | `[]` | +| `extraVolumeMounts` | Optionally specify extra list of additional volumeMounts for Ghost container(s) | `[]` | +| `sidecars` | Add additional sidecar containers to the Ghost pod | `[]` | +| `initContainers` | Add additional init containers to the Ghost pods | `[]` | +| `lifecycleHooks` | Add lifecycle hooks to the Ghost deployment | `{}` | +| `podLabels` | Extra labels for Ghost pods | `{}` | +| `podAnnotations` | Annotations for Ghost pods | `{}` | +| `podAffinityPreset` | Pod affinity preset. Ignored if `affinity` is set. Allowed values: `soft` or `hard` | `""` | +| `podAntiAffinityPreset` | Pod anti-affinity preset. Ignored if `affinity` is set. Allowed values: `soft` or `hard` | `soft` | +| `nodeAffinityPreset.type` | Node affinity preset type. Ignored if `affinity` is set. Allowed values: `soft` or `hard` | `""` | +| `nodeAffinityPreset.key` | Node label key to match. Ignored if `affinity` is set | `""` | +| `nodeAffinityPreset.values` | Node label values to match. Ignored if `affinity` is set | `[]` | +| `affinity` | Affinity for pod assignment | `{}` | +| `nodeSelector` | Node labels for pod assignment | `{}` | +| `tolerations` | Tolerations for pod assignment | `[]` | +| `resources.limits` | The resources limits for the Ghost container | `{}` | +| `resources.requests` | The requested resources for the Ghost container | `{}` | +| `containerPorts.http` | Ghost HTTP container port | `2368` | +| `containerPorts.https` | Ghost HTTPS container port | `2368` | +| `podSecurityContext.enabled` | Enabled Ghost pods' Security Context | `true` | +| `podSecurityContext.fsGroup` | Set Ghost pod's Security Context fsGroup | `1001` | +| `containerSecurityContext.enabled` | Enabled Ghost containers' Security Context | `true` | +| `containerSecurityContext.runAsUser` | Set Ghost container's Security Context runAsUser | `1001` | +| `containerSecurityContext.runAsNonRoot` | Set Ghost container's Security Context runAsNonRoot | `true` | +| `startupProbe.enabled` | Enable startupProbe | `false` | +| `startupProbe.initialDelaySeconds` | Initial delay seconds for startupProbe | `120` | +| `startupProbe.periodSeconds` | Period seconds for startupProbe | `10` | +| `startupProbe.timeoutSeconds` | Timeout seconds for startupProbe | `5` | +| `startupProbe.failureThreshold` | Failure threshold for startupProbe | `6` | +| `startupProbe.successThreshold` | Success threshold for startupProbe | `1` | +| `livenessProbe.enabled` | Enable livenessProbe | `true` | +| `livenessProbe.initialDelaySeconds` | Initial delay seconds for livenessProbe | `120` | +| `livenessProbe.periodSeconds` | Period seconds for livenessProbe | `10` | +| `livenessProbe.timeoutSeconds` | Timeout seconds for livenessProbe | `5` | +| `livenessProbe.failureThreshold` | Failure threshold for livenessProbe | `6` | +| `livenessProbe.successThreshold` | Success threshold for livenessProbe | `1` | +| `readinessProbe.enabled` | Enable readinessProbe | `true` | +| `readinessProbe.initialDelaySeconds` | Initial delay seconds for readinessProbe | `30` | +| `readinessProbe.periodSeconds` | Period seconds for readinessProbe | `5` | +| `readinessProbe.timeoutSeconds` | Timeout seconds for readinessProbe | `3` | +| `readinessProbe.failureThreshold` | Failure threshold for readinessProbe | `6` | +| `readinessProbe.successThreshold` | Success threshold for readinessProbe | `1` | +| `customLivenessProbe` | Custom livenessProbe that overrides the default one | `{}` | +| `customReadinessProbe` | Custom readinessProbe that overrides the default one | `{}` | + +### Traffic Exposure Parameters + +| Name | Description | Value | +| ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | ------------------------ | +| `service.type` | Ghost service type | `LoadBalancer` | +| `service.ports.http` | Ghost service HTTP port | `80` | +| `service.ports.https` | Ghost service HTTPS port | `443` | +| `service.nodePorts.http` | Node port for HTTP | `""` | +| `service.nodePorts.https` | Node port for HTTPS | `""` | +| `service.clusterIP` | Ghost service Cluster IP | `""` | +| `service.loadBalancerIP` | Ghost service Load Balancer IP | `""` | +| `service.loadBalancerSourceRanges` | Ghost service Load Balancer sources | `[]` | +| `service.externalTrafficPolicy` | Ghost service external traffic policy | `Cluster` | +| `service.annotations` | Additional custom annotations for Ghost service | `{}` | +| `service.extraPorts` | Extra port to expose on Ghost service | `[]` | +| `service.sessionAffinity` | Session Affinity for Kubernetes service, can be "None" or "ClientIP" | `None` | +| `service.sessionAffinityConfig` | Additional settings for the sessionAffinity | `{}` | +| `ingress.enabled` | Enable ingress record generation for Ghost | `false` | +| `ingress.pathType` | Ingress path type | `ImplementationSpecific` | +| `ingress.apiVersion` | Force Ingress API version (automatically detected if not set) | `""` | +| `ingress.hostname` | Default host for the ingress record | `ghost.local` | +| `ingress.path` | Default path for the ingress record | `/` | +| `ingress.annotations` | Additional annotations for the Ingress resource. To enable certificate autogeneration, place here your cert-manager annotations. | `{}` | +| `ingress.tls` | Enable TLS configuration for the host defined at `ingress.hostname` parameter | `false` | +| `ingress.selfSigned` | Create a TLS secret for this ingress record using self-signed certificates generated by Helm | `false` | +| `ingress.extraHosts` | An array with additional hostname(s) to be covered with the ingress record | `[]` | +| `ingress.extraPaths` | An array with additional arbitrary paths that may need to be added to the ingress under the main host | `[]` | +| `ingress.extraTls` | TLS configuration for additional hostname(s) to be covered with this ingress record | `[]` | +| `ingress.secrets` | Custom TLS certificates as secrets | `[]` | +| `ingress.ingressClassName` | IngressClass that will be be used to implement the Ingress (Kubernetes 1.18+) | `""` | +| `ingress.extraRules` | Additional rules to be covered with this ingress record | `[]` | + +### Persistence Parameters + +| Name | Description | Value | +| --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ | ------------------ | +| `persistence.enabled` | Enable persistence using Persistent Volume Claims | `true` | +| `persistence.storageClass` | Persistent Volume storage class | `""` | +| `persistence.annotations` | Additional custom annotations for the PVC | `{}` | +| `persistence.accessModes` | Persistent Volume access modes | `[]` | +| `persistence.size` | Persistent Volume size | `8Gi` | +| `persistence.existingClaim` | The name of an existing PVC to use for persistence | `""` | +| `persistence.subPath` | The name of a volume's sub path to mount for persistence | `""` | +| `volumePermissions.enabled` | Enable init container that changes the owner/group of the PV mount point to `runAsUser:fsGroup` | `false` | +| `volumePermissions.image.registry` | OS Shell + Utility image registry | `docker.io` | +| `volumePermissions.image.repository` | OS Shell + Utility image repository | `bitnami/os-shell` | +| `volumePermissions.image.tag` | OS Shell + Utility image tag (immutable tags are recommended) | `11-debian-11-r11` | +| `volumePermissions.image.digest` | OS Shell + Utility image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag | `""` | +| `volumePermissions.image.pullPolicy` | OS Shell + Utility image pull policy | `IfNotPresent` | +| `volumePermissions.image.pullSecrets` | OS Shell + Utility image pull secrets | `[]` | +| `volumePermissions.resources.limits` | The resources limits for the init container | `{}` | +| `volumePermissions.resources.requests` | The requested resources for the init container | `{}` | +| `volumePermissions.securityContext.runAsUser` | Set init container's Security Context runAsUser | `0` | + +### Database Parameters + +| Name | Description | Value | +| ---------------------------------------- | ----------------------------------------------------------------------- | --------------- | +| `mysql.enabled` | Deploy a MySQL server to satisfy the applications database requirements | `true` | +| `mysql.architecture` | MySQL architecture. Allowed values: `standalone` or `replication` | `standalone` | +| `mysql.auth.rootPassword` | MySQL root password | `""` | +| `mysql.auth.database` | MySQL custom database | `bitnami_ghost` | +| `mysql.auth.username` | MySQL custom user name | `bn_ghost` | +| `mysql.auth.password` | MySQL custom user password | `""` | +| `mysql.auth.existingSecret` | Existing secret with MySQL credentials | `""` | +| `mysql.primary.persistence.enabled` | Enable persistence on MySQL using PVC(s) | `true` | +| `mysql.primary.persistence.storageClass` | Persistent Volume storage class | `""` | +| `mysql.primary.persistence.accessModes` | Persistent Volume access modes | `[]` | +| `mysql.primary.persistence.size` | Persistent Volume size | `8Gi` | +| `externalDatabase.host` | External Database server host | `localhost` | +| `externalDatabase.port` | External Database server port | `3306` | +| `externalDatabase.user` | External Database username | `bn_ghost` | +| `externalDatabase.password` | External Database user password | `""` | +| `externalDatabase.database` | External Database database name | `bitnami_ghost` | +| `externalDatabase.existingSecret` | The name of an existing secret with database credentials | `""` | +| `externalDatabase.ssl` | External Database ssl | `false` | +| `externalDatabase.sslCaFile` | External Database ssl CA filepath | `""` | + +### NetworkPolicy parameters + +| Name | Description | Value | +| ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- | ------- | +| `networkPolicy.enabled` | Enable network policies | `false` | +| `networkPolicy.ingress.enabled` | Enable network policy for Ingress Proxies | `false` | +| `networkPolicy.ingress.namespaceSelector` | Ingress Proxy namespace selector labels. These labels will be used to identify the Ingress Proxy's namespace. | `{}` | +| `networkPolicy.ingress.podSelector` | Ingress Proxy pods selector labels. These labels will be used to identify the Ingress Proxy pods. | `{}` | +| `networkPolicy.ingressRules.backendOnlyAccessibleByFrontend` | Enable ingress rule that makes the backend (mysql) only accessible by Ghost's pods. | `false` | +| `networkPolicy.ingressRules.customBackendSelector` | Backend selector labels. These labels will be used to identify the backend pods. | `{}` | +| `networkPolicy.ingressRules.accessOnlyFrom.enabled` | Enable ingress rule that makes Ghost only accessible from a particular origin | `false` | +| `networkPolicy.ingressRules.accessOnlyFrom.namespaceSelector` | Namespace selector label that is allowed to access Ghost. This label will be used to identified the allowed namespace(s). | `{}` | +| `networkPolicy.ingressRules.accessOnlyFrom.podSelector` | Pods selector label that is allowed to access Ghost. This label will be used to identified the allowed pod(s). | `{}` | +| `networkPolicy.ingressRules.customRules` | Custom network policy ingress rule | `{}` | +| `networkPolicy.egressRules.denyConnectionsToExternal` | Enable egress rule that denies outgoing traffic outside the cluster, except for DNS (port 53). | `false` | +| `networkPolicy.egressRules.customRules` | Custom network policy rule | `{}` | +| `serviceAccount.create` | Specifies whether a ServiceAccount should be created | `true` | +| `serviceAccount.name` | Name of the service account to use. If not set and create is true, a name is generated using the fullname template. | `""` | +| `serviceAccount.automountServiceAccountToken` | Automount service account token for the server service account | `true` | +| `serviceAccount.annotations` | Annotations for service account. Evaluated as a template. Only used if `create` is `true`. | `{}` | + +The above parameters map to the env variables defined in [bitnami/ghost](https://github.com/bitnami/containers/tree/main/bitnami/ghost). For more information please refer to the [bitnami/ghost](https://github.com/bitnami/containers/tree/main/bitnami/ghost) image documentation. + +> **Note**: +> +> For the Ghost application function correctly, you should specify the `ghostHost` parameter to specify the FQDN (recommended) or the public IP address of the Ghost service. +> +> Optionally, you can specify the `ghostLoadBalancerIP` parameter to assign a reserved IP address to the Ghost service of the chart. However please note that this feature is only available on a few cloud providers (f.e. GKE). +> +> To reserve a public IP address on GKE: +> +> ```console +> $ gcloud compute addresses create ghost-public-ip +> ``` +> +> The reserved IP address can be assigned to the Ghost service by specifying it as the value of the `service.loadBalancerIP` parameter while installing the chart. + +Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example, + +```console +helm install my-release \ + --set ghostUsername=admin,ghostPassword=password,mysql.auth.rootPassword=secretpassword \ + oci://registry-1.docker.io/bitnamicharts/ghost +``` + +The above command sets the Ghost administrator account username and password to `admin` and `password` respectively. Additionally, it sets the MySQL `root` user password to `secretpassword`. + +> NOTE: Once this chart is deployed, it is not possible to change the application's access credentials, such as usernames or passwords, using Helm. To change these application credentials after deployment, delete any persistent volumes (PVs) used by the chart and re-deploy it, or use the application's built-in administrative tools if available. + +Alternatively, a YAML file that specifies the values for the above parameters can be provided while installing the chart. For example, + +```console +helm install my-release -f values.yaml oci://registry-1.docker.io/bitnamicharts/ghost +``` + +> **Tip**: You can use the default [values.yaml](values.yaml) + +## Configuration and installation details + +### [Rolling VS Immutable tags](https://docs.bitnami.com/containers/how-to/understand-rolling-tags-containers/) + +It is strongly recommended to use immutable tags in a production environment. This ensures your deployment does not change automatically if the same tag is updated with a different image. + +Bitnami will release a new chart updating its containers if a new version of the main container, significant changes, or critical vulnerabilities exist. + +### External database support + +You may want to have Ghost connect to an external database rather than installing one inside your cluster. Typical reasons for this are to use a managed database service, or to share a common database server for all your applications. To achieve this, the chart allows you to specify credentials for an external database with the [`externalDatabase` parameter](#database-parameters). You should also disable the MySQL installation with the `mysql.enabled` option. Here is an example: + +```console +mysql.enabled=false +externalDatabase.host=myexternalhost +externalDatabase.user=myuser +externalDatabase.password=mypassword +externalDatabase.database=mydatabase +externalDatabase.port=3306 +``` + +Refer to the [documentation on using an external database with Ghost](https://docs.bitnami.com/kubernetes/apps/ghost/configuration/use-external-database/) for more information. + +### Configure Ingress + +This chart provides support for Ingress resources. If you have an ingress controller installed on your cluster, such as [nginx-ingress-controller](https://github.com/bitnami/charts/tree/main/bitnami/nginx-ingress-controller) or [contour](https://github.com/bitnami/charts/tree/main/bitnami/contour) you can utilize the ingress controller to serve your application. + +To enable Ingress integration, set `ingress.enabled` to `true`. The `ingress.hostname` property can be used to set the host name. The `ingress.tls` parameter can be used to add the TLS configuration for this host. It is also possible to have more than one host, with a separate TLS configuration for each host. [Learn more about configuring and using Ingress](https://docs.bitnami.com/kubernetes/apps/ghost/configuration/configure-ingress/). + +### Configure TLS Secrets for use with Ingress + +The chart also facilitates the creation of TLS secrets for use with the Ingress controller, with different options for certificate management. [Learn more about TLS secrets](https://docs.bitnami.com/kubernetes/apps/ghost/administration/enable-tls-ingress/). + +### Configure extra environment variables + +To add extra environment variables (useful for advanced operations like custom init scripts), use the `extraEnvVars` property. + +```yaml +extraEnvVars: + - name: LOG_LEVEL + value: DEBUG +``` + +Alternatively, use a ConfigMap or a Secret with the environment variables. To do so, use the `extraEnvVarsCM` or the `extraEnvVarsSecret` values. + +### Configure Sidecars and Init Containers + +If additional containers are needed in the same pod as Ghost (such as additional metrics or logging exporters), they can be defined using the `sidecars` parameter. Similarly, you can add extra init containers using the `initContainers` parameter. + +[Learn more about configuring and using sidecar and init containers](https://docs.bitnami.com/kubernetes/apps/ghost/configuration/configure-sidecar-init-containers/). + +### Deploy extra resources + +There are cases where you may want to deploy extra objects, such a ConfigMap containing your app's configuration or some extra deployment with a micro service used by your app. For covering this case, the chart allows adding the full specification of other objects using the `extraDeploy` parameter. + +### Set Pod affinity + +This chart allows you to set custom Pod affinity using the `affinity` parameter(s). Find more information about Pod affinity in the [Kubernetes documentation](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity). + +As an alternative, you can use the preset configurations for pod affinity, pod anti-affinity, and node affinity available at the [bitnami/common](https://github.com/bitnami/charts/tree/main/bitnami/common#affinities) chart. To do so, set the `podAffinityPreset`, `podAntiAffinityPreset`, or `nodeAffinityPreset` parameters. + +## Persistence + +The [Bitnami Ghost](https://github.com/bitnami/containers/tree/main/bitnami/ghost) image stores the Ghost data and configurations at the `/bitnami/ghost` and `/bitnami/apache` paths of the container. + +Persistent Volume Claims are used to keep the data across deployments. This is known to work in GCE, AWS, and minikube. +See the [Parameters](#parameters) section to configure the PVC or to disable persistence. + +## Troubleshooting + +Find more information about how to deal with common errors related to Bitnami's Helm charts in [this troubleshooting guide](https://docs.bitnami.com/general/how-to/troubleshoot-helm-chart-issues). + +## Upgrading + +### To 19.0.0 + +This major release changes database management system from MariaDB to MySQL. Since a new DB will be used, you need to create a back up beforehand and restore it in order to keep your data. See [the official migration docs](https://ghost.org/docs/migration/ghost/). + +### To 17.0.0 + +This major release bumps the MariaDB version to 10.6. Follow the [upstream instructions](https://mariadb.com/kb/en/upgrading-from-mariadb-105-to-mariadb-106/) for upgrading from MariaDB 10.5 to 10.6. No major issues are expected during the upgrade. + +### To 16.0.0 + +This major release updates the MariaDB subchart to its newest major, 10.0.0. Check [MariaDB Upgrading Notes](https://github.com/bitnami/charts/tree/main/bitnami/mariadb#to-1000) for more information. + +### To 15.0.0 + +This major release renames several values in this chart and adds missing features, in order to be inline with the rest of assets in the Bitnami charts repository. + +Affected values: + +- `service.port` was deprecated, we recommend using `service.ports.http` instead. +- `service.httpsPort` was deprecated, we recommend using `service.ports.https` instead. + +### To 14.0.0 + +Due to recent changes in the container image (see [Notable changes](https://github.com/bitnami/containers/tree/main/bitnami/ghost#notable-changes)), the major version of the chart has been bumped preemptively. + +Compatibility is not guaranteed due to the amount of involved changes, however no breaking changes are expected. + +### To 12.0.0 + +This version standardizes the way of defining Ingress rules. When configuring a single hostname for the Ingress rule, set the `ingress.hostname` value. When defining more than one, set the `ingress.extraHosts` array. Apart from this case, no issues are expected to appear when upgrading. + +### To 11.0.0 + +In this major there were two main changes introduced: + +1. Adaptation to Helm v2 EOL +2. Updated MariaDB dependency version + +Please read the update notes carefully. + +#### 1. Adaptation to Helm v2 EOL + +[On November 13, 2020, Helm v2 support was formally finished](https://github.com/helm/charts#status-of-the-project), this major version is the result of the required changes applied to the Helm Chart to be able to incorporate the different features added in Helm v3 and to be consistent with the Helm project itself regarding the Helm v2 EOL. + +##### What changes were introduced in this major version? + +- Previous versions of this Helm Chart use `apiVersion: v1` (installable by both Helm 2 and 3), this Helm Chart was updated to `apiVersion: v2` (installable by Helm 3 only). [Here](https://helm.sh/docs/topics/charts/#the-apiversion-field) you can find more information about the `apiVersion` field. +- Move dependency information from the *requirements.yaml* to the *Chart.yaml* +- After running `helm dependency update`, a *Chart.lock* file is generated containing the same structure used in the previous *requirements.lock* +- The different fields present in the *Chart.yaml* file has been ordered alphabetically in a homogeneous way for all the Bitnami Helm Charts + +##### Considerations when upgrading to this version + +- If you want to upgrade to this version from a previous one installed with Helm v3, you shouldn't face any issues +- If you want to upgrade to this version using Helm v2, this scenario is not supported as this version doesn't support Helm v2 anymore +- If you installed the previous version with Helm v2 and wants to upgrade to this version with Helm v3, please refer to the [official Helm documentation](https://helm.sh/docs/topics/v2_v3_migration/#migration-use-cases) about migrating from Helm v2 to v3 + +##### Useful links + +- +- +- + +#### 2. Updated MariaDB dependency version** + +In this major the MariaDB dependency version was also bumped to a new major version that introduces several incompatilibites. Therefore, backwards compatibility is not guaranteed unless an external database is used. Check [MariaDB Upgrading Notes](https://github.com/bitnami/charts/tree/main/bitnami/mariadb#to-800) for more information. + +To upgrade to `11.0.0`, it should be done reusing the PVCs used to hold both the MariaDB and Ghost data on your previous release. To do so, follow the instructions below (the following example assumes that the release name is `ghost`): + +> NOTE: Please, create a backup of your database before running any of those actions. The steps below would be only valid if your application (e.g. any plugins or custom code) is compatible with MariaDB 10.5.x + +Obtain the credentials and the name of the PVC used to hold the MariaDB data on your current release: + +```console +export GHOST_HOST=$(kubectl get svc --namespace default ghost --template "{{ range (index .status.loadBalancer.ingress 0) }}{{ . }}{{ end }}") +export GHOST_PASSWORD=$(kubectl get secret --namespace default ghost -o jsonpath="{.data.ghost-password}" | base64 -d) +export MARIADB_ROOT_PASSWORD=$(kubectl get secret --namespace default ghost-mariadb -o jsonpath="{.data.mariadb-root-password}" | base64 -d) +export MARIADB_PASSWORD=$(kubectl get secret --namespace default ghost-mariadb -o jsonpath="{.data.mariadb-password}" | base64 -d) +export MARIADB_PVC=$(kubectl get pvc -l app=mariadb,component=master,release=ghost -o jsonpath="{.items[0].metadata.name}") +``` + +Delete the Ghost deployment and delete the MariaDB statefulset. Notice the option `--cascade=false` in the latter. + + ```console + kubectl delete deployments.apps ghost + + kubectl delete statefulsets.apps ghost-mariadb --cascade=false + ``` + +Upgrade you release to 11.0.0 reusing the existing PVC, and enabling back MariaDB: + +```console +helm upgrade ghost oci://registry-1.docker.io/bitnamicharts/ghost --set mariadb.primary.persistence.existingClaim=$MARIADB_PVC --set mariadb.auth.rootPassword=$MARIADB_ROOT_PASSWORD --set mariadb.auth.password=$MARIADB_PASSWORD --set ghostPassword=$GHOST_PASSWORD --set ghostHost=$GHOST_HOST +``` + +You will need to kill the existing MariaDB pod now as the new statefulset is going to create a new one: + +```console +kubectl delete pod ghost-mariadb-0 +``` + +You should see the lines below in MariaDB container logs: + +```console +$ kubectl logs $(kubectl get pods -l app.kubernetes.io/instance=ghost,app.kubernetes.io/name=mariadb,app.kubernetes.io/component=primary -o jsonpath="{.items[0].metadata.name}") +... +mariadb 12:13:24.98 INFO ==> Using persisted data +mariadb 12:13:25.01 INFO ==> Running mysql_upgrade +... +``` + +### To 10.0.0 + +This version introduces `bitnami/common`, a [library chart](https://helm.sh/docs/topics/library_charts/#helm) as a dependency. More documentation about this new utility could be found [here](https://github.com/bitnami/charts/tree/main/bitnami/common#bitnami-common-library-chart). Please, make sure that you have updated the chart dependencies before executing any upgrade. + +Also, `allowEmptyPassword` has changed its value type from string to boolean, if you were using it please make sure that you are passing the proper value. + +```console +# before +--set allowEmptyPassword="no" +# after +--set allowEmptyPassword=false +``` + +### To 9.0.0 + +Helm performs a lookup for the object based on its group (apps), version (v1), and kind (Deployment). Also known as its GroupVersionKind, or GVK. Changing the GVK is considered a compatibility breaker from Kubernetes' point of view, so you cannot "upgrade" those objects to the new GVK in-place. Earlier versions of Helm 3 did not perform the lookup correctly which has since been fixed to match the spec. + +In the `apiVersion` of the deployment resources was updated to `apps/v1` in tune with the api's deprecated, resulting in compatibility breakage. + +This major version signifies this change. + +### To 5.0.0 + +Backwards compatibility is not guaranteed unless you modify the labels used on the chart's deployments. +Use the workaround below to upgrade from versions previous to 5.0.0. The following example assumes that the release name is ghost: + +```console +kubectl patch deployment ghost-ghost --type=json -p='[{"op": "remove", "path": "/spec/selector/matchLabels/chart"}]' +kubectl delete statefulset ghost-mariadb --cascade=false +``` + +## License + +Copyright © 2023 VMware, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. \ No newline at end of file diff --git a/helm/ghost/charts/common/.helmignore b/helm/ghost/charts/common/.helmignore new file mode 100644 index 0000000..50af031 --- /dev/null +++ b/helm/ghost/charts/common/.helmignore @@ -0,0 +1,22 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/helm/ghost/charts/common/Chart.yaml b/helm/ghost/charts/common/Chart.yaml new file mode 100644 index 0000000..191699d --- /dev/null +++ b/helm/ghost/charts/common/Chart.yaml @@ -0,0 +1,23 @@ +annotations: + category: Infrastructure + licenses: Apache-2.0 +apiVersion: v2 +appVersion: 2.6.0 +description: A Library Helm Chart for grouping common logic between bitnami charts. + This chart is not deployable by itself. +home: https://bitnami.com +icon: https://bitnami.com/downloads/logos/bitnami-mark.png +keywords: +- common +- helper +- template +- function +- bitnami +maintainers: +- name: VMware, Inc. + url: https://github.com/bitnami/charts +name: common +sources: +- https://github.com/bitnami/charts +type: library +version: 2.6.0 diff --git a/helm/ghost/charts/common/README.md b/helm/ghost/charts/common/README.md new file mode 100644 index 0000000..b48bb7a --- /dev/null +++ b/helm/ghost/charts/common/README.md @@ -0,0 +1,235 @@ +# Bitnami Common Library Chart + +A [Helm Library Chart](https://helm.sh/docs/topics/library_charts/#helm) for grouping common logic between Bitnami charts. + +## TL;DR + +```yaml +dependencies: + - name: common + version: 1.x.x + repository: oci://registry-1.docker.io/bitnamicharts +``` + +```console +helm dependency update +``` + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "common.names.fullname" . }} +data: + myvalue: "Hello World" +``` + +## Introduction + +This chart provides a common template helpers which can be used to develop new charts using [Helm](https://helm.sh) package manager. + +Bitnami charts can be used with [Kubeapps](https://kubeapps.dev/) for deployment and management of Helm Charts in clusters. + +Looking to use our applications in production? Try [VMware Application Catalog](https://bitnami.com/enterprise), the enterprise edition of Bitnami Application Catalog. + +## Prerequisites + +- Kubernetes 1.19+ +- Helm 3.2.0+ + +## Parameters + +## Special input schemas + +### ImageRoot + +```yaml +registry: + type: string + description: Docker registry where the image is located + example: docker.io + +repository: + type: string + description: Repository and image name + example: bitnami/nginx + +tag: + type: string + description: image tag + example: 1.16.1-debian-10-r63 + +pullPolicy: + type: string + description: Specify a imagePullPolicy. Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' + +pullSecrets: + type: array + items: + type: string + description: Optionally specify an array of imagePullSecrets (evaluated as templates). + +debug: + type: boolean + description: Set to true if you would like to see extra information on logs + example: false + +## An instance would be: +# registry: docker.io +# repository: bitnami/nginx +# tag: 1.16.1-debian-10-r63 +# pullPolicy: IfNotPresent +# debug: false +``` + +### Persistence + +```yaml +enabled: + type: boolean + description: Whether enable persistence. + example: true + +storageClass: + type: string + description: Ghost data Persistent Volume Storage Class, If set to "-", storageClassName: "" which disables dynamic provisioning. + example: "-" + +accessMode: + type: string + description: Access mode for the Persistent Volume Storage. + example: ReadWriteOnce + +size: + type: string + description: Size the Persistent Volume Storage. + example: 8Gi + +path: + type: string + description: Path to be persisted. + example: /bitnami + +## An instance would be: +# enabled: true +# storageClass: "-" +# accessMode: ReadWriteOnce +# size: 8Gi +# path: /bitnami +``` + +### ExistingSecret + +```yaml +name: + type: string + description: Name of the existing secret. + example: mySecret +keyMapping: + description: Mapping between the expected key name and the name of the key in the existing secret. + type: object + +## An instance would be: +# name: mySecret +# keyMapping: +# password: myPasswordKey +``` + +#### Example of use + +When we store sensitive data for a deployment in a secret, some times we want to give to users the possibility of using theirs existing secrets. + +```yaml +# templates/secret.yaml +--- +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "common.names.fullname" . }} + labels: + app: {{ include "common.names.fullname" . }} +type: Opaque +data: + password: {{ .Values.password | b64enc | quote }} + +# templates/dpl.yaml +--- +... + env: + - name: PASSWORD + valueFrom: + secretKeyRef: + name: {{ include "common.secrets.name" (dict "existingSecret" .Values.existingSecret "context" $) }} + key: {{ include "common.secrets.key" (dict "existingSecret" .Values.existingSecret "key" "password") }} +... + +# values.yaml +--- +name: mySecret +keyMapping: + password: myPasswordKey +``` + +### ValidateValue + +#### NOTES.txt + +```console +{{- $validateValueConf00 := (dict "valueKey" "path.to.value00" "secret" "secretName" "field" "password-00") -}} +{{- $validateValueConf01 := (dict "valueKey" "path.to.value01" "secret" "secretName" "field" "password-01") -}} + +{{ include "common.validations.values.multiple.empty" (dict "required" (list $validateValueConf00 $validateValueConf01) "context" $) }} +``` + +If we force those values to be empty we will see some alerts + +```console +helm install test mychart --set path.to.value00="",path.to.value01="" + 'path.to.value00' must not be empty, please add '--set path.to.value00=$PASSWORD_00' to the command. To get the current value: + + export PASSWORD_00=$(kubectl get secret --namespace default secretName -o jsonpath="{.data.password-00}" | base64 -d) + + 'path.to.value01' must not be empty, please add '--set path.to.value01=$PASSWORD_01' to the command. To get the current value: + + export PASSWORD_01=$(kubectl get secret --namespace default secretName -o jsonpath="{.data.password-01}" | base64 -d) +``` + +## Upgrading + +### To 1.0.0 + +[On November 13, 2020, Helm v2 support was formally finished](https://github.com/helm/charts#status-of-the-project), this major version is the result of the required changes applied to the Helm Chart to be able to incorporate the different features added in Helm v3 and to be consistent with the Helm project itself regarding the Helm v2 EOL. + +#### What changes were introduced in this major version? + +- Previous versions of this Helm Chart use `apiVersion: v1` (installable by both Helm 2 and 3), this Helm Chart was updated to `apiVersion: v2` (installable by Helm 3 only). [Here](https://helm.sh/docs/topics/charts/#the-apiversion-field) you can find more information about the `apiVersion` field. +- Use `type: library`. [Here](https://v3.helm.sh/docs/faq/#library-chart-support) you can find more information. +- The different fields present in the *Chart.yaml* file has been ordered alphabetically in a homogeneous way for all the Bitnami Helm Charts + +#### Considerations when upgrading to this version + +- If you want to upgrade to this version from a previous one installed with Helm v3, you shouldn't face any issues +- If you want to upgrade to this version using Helm v2, this scenario is not supported as this version doesn't support Helm v2 anymore +- If you installed the previous version with Helm v2 and wants to upgrade to this version with Helm v3, please refer to the [official Helm documentation](https://helm.sh/docs/topics/v2_v3_migration/#migration-use-cases) about migrating from Helm v2 to v3 + +#### Useful links + +- +- +- + +## License + +Copyright © 2023 VMware, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/helm/ghost/charts/common/templates/_affinities.tpl b/helm/ghost/charts/common/templates/_affinities.tpl new file mode 100644 index 0000000..0e57102 --- /dev/null +++ b/helm/ghost/charts/common/templates/_affinities.tpl @@ -0,0 +1,111 @@ +{{/* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} + +{{/* +Return a soft nodeAffinity definition +{{ include "common.affinities.nodes.soft" (dict "key" "FOO" "values" (list "BAR" "BAZ")) -}} +*/}} +{{- define "common.affinities.nodes.soft" -}} +preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: {{ .key }} + operator: In + values: + {{- range .values }} + - {{ . | quote }} + {{- end }} + weight: 1 +{{- end -}} + +{{/* +Return a hard nodeAffinity definition +{{ include "common.affinities.nodes.hard" (dict "key" "FOO" "values" (list "BAR" "BAZ")) -}} +*/}} +{{- define "common.affinities.nodes.hard" -}} +requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: {{ .key }} + operator: In + values: + {{- range .values }} + - {{ . | quote }} + {{- end }} +{{- end -}} + +{{/* +Return a nodeAffinity definition +{{ include "common.affinities.nodes" (dict "type" "soft" "key" "FOO" "values" (list "BAR" "BAZ")) -}} +*/}} +{{- define "common.affinities.nodes" -}} + {{- if eq .type "soft" }} + {{- include "common.affinities.nodes.soft" . -}} + {{- else if eq .type "hard" }} + {{- include "common.affinities.nodes.hard" . -}} + {{- end -}} +{{- end -}} + +{{/* +Return a topologyKey definition +{{ include "common.affinities.topologyKey" (dict "topologyKey" "BAR") -}} +*/}} +{{- define "common.affinities.topologyKey" -}} +{{ .topologyKey | default "kubernetes.io/hostname" -}} +{{- end -}} + +{{/* +Return a soft podAffinity/podAntiAffinity definition +{{ include "common.affinities.pods.soft" (dict "component" "FOO" "extraMatchLabels" .Values.extraMatchLabels "topologyKey" "BAR" "context" $) -}} +*/}} +{{- define "common.affinities.pods.soft" -}} +{{- $component := default "" .component -}} +{{- $extraMatchLabels := default (dict) .extraMatchLabels -}} +preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchLabels: {{- (include "common.labels.matchLabels" .context) | nindent 10 }} + {{- if not (empty $component) }} + {{ printf "app.kubernetes.io/component: %s" $component }} + {{- end }} + {{- range $key, $value := $extraMatchLabels }} + {{ $key }}: {{ $value | quote }} + {{- end }} + topologyKey: {{ include "common.affinities.topologyKey" (dict "topologyKey" .topologyKey) }} + weight: 1 +{{- end -}} + +{{/* +Return a hard podAffinity/podAntiAffinity definition +{{ include "common.affinities.pods.hard" (dict "component" "FOO" "extraMatchLabels" .Values.extraMatchLabels "topologyKey" "BAR" "context" $) -}} +*/}} +{{- define "common.affinities.pods.hard" -}} +{{- $component := default "" .component -}} +{{- $extraMatchLabels := default (dict) .extraMatchLabels -}} +requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: {{- (include "common.labels.matchLabels" .context) | nindent 8 }} + {{- if not (empty $component) }} + {{ printf "app.kubernetes.io/component: %s" $component }} + {{- end }} + {{- range $key, $value := $extraMatchLabels }} + {{ $key }}: {{ $value | quote }} + {{- end }} + topologyKey: {{ include "common.affinities.topologyKey" (dict "topologyKey" .topologyKey) }} +{{- end -}} + +{{/* +Return a podAffinity/podAntiAffinity definition +{{ include "common.affinities.pods" (dict "type" "soft" "key" "FOO" "values" (list "BAR" "BAZ")) -}} +*/}} +{{- define "common.affinities.pods" -}} + {{- if eq .type "soft" }} + {{- include "common.affinities.pods.soft" . -}} + {{- else if eq .type "hard" }} + {{- include "common.affinities.pods.hard" . -}} + {{- end -}} +{{- end -}} diff --git a/helm/ghost/charts/common/templates/_capabilities.tpl b/helm/ghost/charts/common/templates/_capabilities.tpl new file mode 100644 index 0000000..c6d115f --- /dev/null +++ b/helm/ghost/charts/common/templates/_capabilities.tpl @@ -0,0 +1,185 @@ +{{/* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} + +{{/* +Return the target Kubernetes version +*/}} +{{- define "common.capabilities.kubeVersion" -}} +{{- if .Values.global }} + {{- if .Values.global.kubeVersion }} + {{- .Values.global.kubeVersion -}} + {{- else }} + {{- default .Capabilities.KubeVersion.Version .Values.kubeVersion -}} + {{- end -}} +{{- else }} +{{- default .Capabilities.KubeVersion.Version .Values.kubeVersion -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for poddisruptionbudget. +*/}} +{{- define "common.capabilities.policy.apiVersion" -}} +{{- if semverCompare "<1.21-0" (include "common.capabilities.kubeVersion" .) -}} +{{- print "policy/v1beta1" -}} +{{- else -}} +{{- print "policy/v1" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for networkpolicy. +*/}} +{{- define "common.capabilities.networkPolicy.apiVersion" -}} +{{- if semverCompare "<1.7-0" (include "common.capabilities.kubeVersion" .) -}} +{{- print "extensions/v1beta1" -}} +{{- else -}} +{{- print "networking.k8s.io/v1" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for cronjob. +*/}} +{{- define "common.capabilities.cronjob.apiVersion" -}} +{{- if semverCompare "<1.21-0" (include "common.capabilities.kubeVersion" .) -}} +{{- print "batch/v1beta1" -}} +{{- else -}} +{{- print "batch/v1" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for daemonset. +*/}} +{{- define "common.capabilities.daemonset.apiVersion" -}} +{{- if semverCompare "<1.14-0" (include "common.capabilities.kubeVersion" .) -}} +{{- print "extensions/v1beta1" -}} +{{- else -}} +{{- print "apps/v1" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for deployment. +*/}} +{{- define "common.capabilities.deployment.apiVersion" -}} +{{- if semverCompare "<1.14-0" (include "common.capabilities.kubeVersion" .) -}} +{{- print "extensions/v1beta1" -}} +{{- else -}} +{{- print "apps/v1" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for statefulset. +*/}} +{{- define "common.capabilities.statefulset.apiVersion" -}} +{{- if semverCompare "<1.14-0" (include "common.capabilities.kubeVersion" .) -}} +{{- print "apps/v1beta1" -}} +{{- else -}} +{{- print "apps/v1" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for ingress. +*/}} +{{- define "common.capabilities.ingress.apiVersion" -}} +{{- if .Values.ingress -}} +{{- if .Values.ingress.apiVersion -}} +{{- .Values.ingress.apiVersion -}} +{{- else if semverCompare "<1.14-0" (include "common.capabilities.kubeVersion" .) -}} +{{- print "extensions/v1beta1" -}} +{{- else if semverCompare "<1.19-0" (include "common.capabilities.kubeVersion" .) -}} +{{- print "networking.k8s.io/v1beta1" -}} +{{- else -}} +{{- print "networking.k8s.io/v1" -}} +{{- end }} +{{- else if semverCompare "<1.14-0" (include "common.capabilities.kubeVersion" .) -}} +{{- print "extensions/v1beta1" -}} +{{- else if semverCompare "<1.19-0" (include "common.capabilities.kubeVersion" .) -}} +{{- print "networking.k8s.io/v1beta1" -}} +{{- else -}} +{{- print "networking.k8s.io/v1" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for RBAC resources. +*/}} +{{- define "common.capabilities.rbac.apiVersion" -}} +{{- if semverCompare "<1.17-0" (include "common.capabilities.kubeVersion" .) -}} +{{- print "rbac.authorization.k8s.io/v1beta1" -}} +{{- else -}} +{{- print "rbac.authorization.k8s.io/v1" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for CRDs. +*/}} +{{- define "common.capabilities.crd.apiVersion" -}} +{{- if semverCompare "<1.19-0" (include "common.capabilities.kubeVersion" .) -}} +{{- print "apiextensions.k8s.io/v1beta1" -}} +{{- else -}} +{{- print "apiextensions.k8s.io/v1" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for APIService. +*/}} +{{- define "common.capabilities.apiService.apiVersion" -}} +{{- if semverCompare "<1.10-0" (include "common.capabilities.kubeVersion" .) -}} +{{- print "apiregistration.k8s.io/v1beta1" -}} +{{- else -}} +{{- print "apiregistration.k8s.io/v1" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for Horizontal Pod Autoscaler. +*/}} +{{- define "common.capabilities.hpa.apiVersion" -}} +{{- if semverCompare "<1.23-0" (include "common.capabilities.kubeVersion" .context) -}} +{{- if .beta2 -}} +{{- print "autoscaling/v2beta2" -}} +{{- else -}} +{{- print "autoscaling/v2beta1" -}} +{{- end -}} +{{- else -}} +{{- print "autoscaling/v2" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for Vertical Pod Autoscaler. +*/}} +{{- define "common.capabilities.vpa.apiVersion" -}} +{{- if semverCompare "<1.23-0" (include "common.capabilities.kubeVersion" .context) -}} +{{- if .beta2 -}} +{{- print "autoscaling/v2beta2" -}} +{{- else -}} +{{- print "autoscaling/v2beta1" -}} +{{- end -}} +{{- else -}} +{{- print "autoscaling/v2" -}} +{{- end -}} +{{- end -}} + +{{/* +Returns true if the used Helm version is 3.3+. +A way to check the used Helm version was not introduced until version 3.3.0 with .Capabilities.HelmVersion, which contains an additional "{}}" structure. +This check is introduced as a regexMatch instead of {{ if .Capabilities.HelmVersion }} because checking for the key HelmVersion in <3.3 results in a "interface not found" error. +**To be removed when the catalog's minimun Helm version is 3.3** +*/}} +{{- define "common.capabilities.supportsHelmVersion" -}} +{{- if regexMatch "{(v[0-9])*[^}]*}}$" (.Capabilities | toString ) }} + {{- true -}} +{{- end -}} +{{- end -}} diff --git a/helm/ghost/charts/common/templates/_errors.tpl b/helm/ghost/charts/common/templates/_errors.tpl new file mode 100644 index 0000000..07ded6f --- /dev/null +++ b/helm/ghost/charts/common/templates/_errors.tpl @@ -0,0 +1,28 @@ +{{/* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} +{{/* +Through error when upgrading using empty passwords values that must not be empty. + +Usage: +{{- $validationError00 := include "common.validations.values.single.empty" (dict "valueKey" "path.to.password00" "secret" "secretName" "field" "password-00") -}} +{{- $validationError01 := include "common.validations.values.single.empty" (dict "valueKey" "path.to.password01" "secret" "secretName" "field" "password-01") -}} +{{ include "common.errors.upgrade.passwords.empty" (dict "validationErrors" (list $validationError00 $validationError01) "context" $) }} + +Required password params: + - validationErrors - String - Required. List of validation strings to be return, if it is empty it won't throw error. + - context - Context - Required. Parent context. +*/}} +{{- define "common.errors.upgrade.passwords.empty" -}} + {{- $validationErrors := join "" .validationErrors -}} + {{- if and $validationErrors .context.Release.IsUpgrade -}} + {{- $errorString := "\nPASSWORDS ERROR: You must provide your current passwords when upgrading the release." -}} + {{- $errorString = print $errorString "\n Note that even after reinstallation, old credentials may be needed as they may be kept in persistent volume claims." -}} + {{- $errorString = print $errorString "\n Further information can be obtained at https://docs.bitnami.com/general/how-to/troubleshoot-helm-chart-issues/#credential-errors-while-upgrading-chart-releases" -}} + {{- $errorString = print $errorString "\n%s" -}} + {{- printf $errorString $validationErrors | fail -}} + {{- end -}} +{{- end -}} diff --git a/helm/ghost/charts/common/templates/_images.tpl b/helm/ghost/charts/common/templates/_images.tpl new file mode 100644 index 0000000..2181f32 --- /dev/null +++ b/helm/ghost/charts/common/templates/_images.tpl @@ -0,0 +1,85 @@ +{{/* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} +{{/* +Return the proper image name +{{ include "common.images.image" ( dict "imageRoot" .Values.path.to.the.image "global" .Values.global ) }} +*/}} +{{- define "common.images.image" -}} +{{- $registryName := .imageRoot.registry -}} +{{- $repositoryName := .imageRoot.repository -}} +{{- $separator := ":" -}} +{{- $termination := .imageRoot.tag | toString -}} +{{- if .global }} + {{- if .global.imageRegistry }} + {{- $registryName = .global.imageRegistry -}} + {{- end -}} +{{- end -}} +{{- if .imageRoot.digest }} + {{- $separator = "@" -}} + {{- $termination = .imageRoot.digest | toString -}} +{{- end -}} +{{- if $registryName }} + {{- printf "%s/%s%s%s" $registryName $repositoryName $separator $termination -}} +{{- else -}} + {{- printf "%s%s%s" $repositoryName $separator $termination -}} +{{- end -}} +{{- end -}} + +{{/* +Return the proper Docker Image Registry Secret Names (deprecated: use common.images.renderPullSecrets instead) +{{ include "common.images.pullSecrets" ( dict "images" (list .Values.path.to.the.image1, .Values.path.to.the.image2) "global" .Values.global) }} +*/}} +{{- define "common.images.pullSecrets" -}} + {{- $pullSecrets := list }} + + {{- if .global }} + {{- range .global.imagePullSecrets -}} + {{- $pullSecrets = append $pullSecrets . -}} + {{- end -}} + {{- end -}} + + {{- range .images -}} + {{- range .pullSecrets -}} + {{- $pullSecrets = append $pullSecrets . -}} + {{- end -}} + {{- end -}} + + {{- if (not (empty $pullSecrets)) }} +imagePullSecrets: + {{- range $pullSecrets | uniq }} + - name: {{ . }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +Return the proper Docker Image Registry Secret Names evaluating values as templates +{{ include "common.images.renderPullSecrets" ( dict "images" (list .Values.path.to.the.image1, .Values.path.to.the.image2) "context" $) }} +*/}} +{{- define "common.images.renderPullSecrets" -}} + {{- $pullSecrets := list }} + {{- $context := .context }} + + {{- if $context.Values.global }} + {{- range $context.Values.global.imagePullSecrets -}} + {{- $pullSecrets = append $pullSecrets (include "common.tplvalues.render" (dict "value" . "context" $context)) -}} + {{- end -}} + {{- end -}} + + {{- range .images -}} + {{- range .pullSecrets -}} + {{- $pullSecrets = append $pullSecrets (include "common.tplvalues.render" (dict "value" . "context" $context)) -}} + {{- end -}} + {{- end -}} + + {{- if (not (empty $pullSecrets)) }} +imagePullSecrets: + {{- range $pullSecrets | uniq }} + - name: {{ . }} + {{- end }} + {{- end }} +{{- end -}} diff --git a/helm/ghost/charts/common/templates/_ingress.tpl b/helm/ghost/charts/common/templates/_ingress.tpl new file mode 100644 index 0000000..efa5b85 --- /dev/null +++ b/helm/ghost/charts/common/templates/_ingress.tpl @@ -0,0 +1,73 @@ +{{/* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} + +{{/* +Generate backend entry that is compatible with all Kubernetes API versions. + +Usage: +{{ include "common.ingress.backend" (dict "serviceName" "backendName" "servicePort" "backendPort" "context" $) }} + +Params: + - serviceName - String. Name of an existing service backend + - servicePort - String/Int. Port name (or number) of the service. It will be translated to different yaml depending if it is a string or an integer. + - context - Dict - Required. The context for the template evaluation. +*/}} +{{- define "common.ingress.backend" -}} +{{- $apiVersion := (include "common.capabilities.ingress.apiVersion" .context) -}} +{{- if or (eq $apiVersion "extensions/v1beta1") (eq $apiVersion "networking.k8s.io/v1beta1") -}} +serviceName: {{ .serviceName }} +servicePort: {{ .servicePort }} +{{- else -}} +service: + name: {{ .serviceName }} + port: + {{- if typeIs "string" .servicePort }} + name: {{ .servicePort }} + {{- else if or (typeIs "int" .servicePort) (typeIs "float64" .servicePort) }} + number: {{ .servicePort | int }} + {{- end }} +{{- end -}} +{{- end -}} + +{{/* +Print "true" if the API pathType field is supported +Usage: +{{ include "common.ingress.supportsPathType" . }} +*/}} +{{- define "common.ingress.supportsPathType" -}} +{{- if (semverCompare "<1.18-0" (include "common.capabilities.kubeVersion" .)) -}} +{{- print "false" -}} +{{- else -}} +{{- print "true" -}} +{{- end -}} +{{- end -}} + +{{/* +Returns true if the ingressClassname field is supported +Usage: +{{ include "common.ingress.supportsIngressClassname" . }} +*/}} +{{- define "common.ingress.supportsIngressClassname" -}} +{{- if semverCompare "<1.18-0" (include "common.capabilities.kubeVersion" .) -}} +{{- print "false" -}} +{{- else -}} +{{- print "true" -}} +{{- end -}} +{{- end -}} + +{{/* +Return true if cert-manager required annotations for TLS signed +certificates are set in the Ingress annotations +Ref: https://cert-manager.io/docs/usage/ingress/#supported-annotations +Usage: +{{ include "common.ingress.certManagerRequest" ( dict "annotations" .Values.path.to.the.ingress.annotations ) }} +*/}} +{{- define "common.ingress.certManagerRequest" -}} +{{ if or (hasKey .annotations "cert-manager.io/cluster-issuer") (hasKey .annotations "cert-manager.io/issuer") (hasKey .annotations "kubernetes.io/tls-acme") }} + {{- true -}} +{{- end -}} +{{- end -}} diff --git a/helm/ghost/charts/common/templates/_labels.tpl b/helm/ghost/charts/common/templates/_labels.tpl new file mode 100644 index 0000000..a1d7a95 --- /dev/null +++ b/helm/ghost/charts/common/templates/_labels.tpl @@ -0,0 +1,23 @@ +{{/* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} +{{/* +Kubernetes standard labels +*/}} +{{- define "common.labels.standard" -}} +app.kubernetes.io/name: {{ include "common.names.name" . }} +helm.sh/chart: {{ include "common.names.chart" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end -}} + +{{/* +Labels to use on deploy.spec.selector.matchLabels and svc.spec.selector +*/}} +{{- define "common.labels.matchLabels" -}} +app.kubernetes.io/name: {{ include "common.names.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end -}} diff --git a/helm/ghost/charts/common/templates/_names.tpl b/helm/ghost/charts/common/templates/_names.tpl new file mode 100644 index 0000000..a222924 --- /dev/null +++ b/helm/ghost/charts/common/templates/_names.tpl @@ -0,0 +1,71 @@ +{{/* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "common.names.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "common.names.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "common.names.fullname" -}} +{{- if .Values.fullnameOverride -}} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Create a default fully qualified dependency name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +Usage: +{{ include "common.names.dependency.fullname" (dict "chartName" "dependency-chart-name" "chartValues" .Values.dependency-chart "context" $) }} +*/}} +{{- define "common.names.dependency.fullname" -}} +{{- if .chartValues.fullnameOverride -}} +{{- .chartValues.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .chartName .chartValues.nameOverride -}} +{{- if contains $name .context.Release.Name -}} +{{- .context.Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .context.Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Allow the release namespace to be overridden for multi-namespace deployments in combined charts. +*/}} +{{- define "common.names.namespace" -}} +{{- default .Release.Namespace .Values.namespaceOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create a fully qualified app name adding the installation's namespace. +*/}} +{{- define "common.names.fullname.namespace" -}} +{{- printf "%s-%s" (include "common.names.fullname" .) (include "common.names.namespace" .) | trunc 63 | trimSuffix "-" -}} +{{- end -}} diff --git a/helm/ghost/charts/common/templates/_secrets.tpl b/helm/ghost/charts/common/templates/_secrets.tpl new file mode 100644 index 0000000..a193c46 --- /dev/null +++ b/helm/ghost/charts/common/templates/_secrets.tpl @@ -0,0 +1,172 @@ +{{/* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} +{{/* +Generate secret name. + +Usage: +{{ include "common.secrets.name" (dict "existingSecret" .Values.path.to.the.existingSecret "defaultNameSuffix" "mySuffix" "context" $) }} + +Params: + - existingSecret - ExistingSecret/String - Optional. The path to the existing secrets in the values.yaml given by the user + to be used instead of the default one. Allows for it to be of type String (just the secret name) for backwards compatibility. + +info: https://github.com/bitnami/charts/tree/main/bitnami/common#existingsecret + - defaultNameSuffix - String - Optional. It is used only if we have several secrets in the same deployment. + - context - Dict - Required. The context for the template evaluation. +*/}} +{{- define "common.secrets.name" -}} +{{- $name := (include "common.names.fullname" .context) -}} + +{{- if .defaultNameSuffix -}} +{{- $name = printf "%s-%s" $name .defaultNameSuffix | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{- with .existingSecret -}} +{{- if not (typeIs "string" .) -}} +{{- with .name -}} +{{- $name = . -}} +{{- end -}} +{{- else -}} +{{- $name = . -}} +{{- end -}} +{{- end -}} + +{{- printf "%s" $name -}} +{{- end -}} + +{{/* +Generate secret key. + +Usage: +{{ include "common.secrets.key" (dict "existingSecret" .Values.path.to.the.existingSecret "key" "keyName") }} + +Params: + - existingSecret - ExistingSecret/String - Optional. The path to the existing secrets in the values.yaml given by the user + to be used instead of the default one. Allows for it to be of type String (just the secret name) for backwards compatibility. + +info: https://github.com/bitnami/charts/tree/main/bitnami/common#existingsecret + - key - String - Required. Name of the key in the secret. +*/}} +{{- define "common.secrets.key" -}} +{{- $key := .key -}} + +{{- if .existingSecret -}} + {{- if not (typeIs "string" .existingSecret) -}} + {{- if .existingSecret.keyMapping -}} + {{- $key = index .existingSecret.keyMapping $.key -}} + {{- end -}} + {{- end }} +{{- end -}} + +{{- printf "%s" $key -}} +{{- end -}} + +{{/* +Generate secret password or retrieve one if already created. + +Usage: +{{ include "common.secrets.passwords.manage" (dict "secret" "secret-name" "key" "keyName" "providedValues" (list "path.to.password1" "path.to.password2") "length" 10 "strong" false "chartName" "chartName" "context" $) }} + +Params: + - secret - String - Required - Name of the 'Secret' resource where the password is stored. + - key - String - Required - Name of the key in the secret. + - providedValues - List - Required - The path to the validating value in the values.yaml, e.g: "mysql.password". Will pick first parameter with a defined value. + - length - int - Optional - Length of the generated random password. + - strong - Boolean - Optional - Whether to add symbols to the generated random password. + - chartName - String - Optional - Name of the chart used when said chart is deployed as a subchart. + - context - Context - Required - Parent context. + - failOnNew - Boolean - Optional - Default to true. If set to false, skip errors adding new keys to existing secrets. +The order in which this function returns a secret password: + 1. Already existing 'Secret' resource + (If a 'Secret' resource is found under the name provided to the 'secret' parameter to this function and that 'Secret' resource contains a key with the name passed as the 'key' parameter to this function then the value of this existing secret password will be returned) + 2. Password provided via the values.yaml + (If one of the keys passed to the 'providedValues' parameter to this function is a valid path to a key in the values.yaml and has a value, the value of the first key with a value will be returned) + 3. Randomly generated secret password + (A new random secret password with the length specified in the 'length' parameter will be generated and returned) + +*/}} +{{- define "common.secrets.passwords.manage" -}} + +{{- $password := "" }} +{{- $subchart := "" }} +{{- $failOnNew := default true .failOnNew }} +{{- $chartName := default "" .chartName }} +{{- $passwordLength := default 10 .length }} +{{- $providedPasswordKey := include "common.utils.getKeyFromList" (dict "keys" .providedValues "context" $.context) }} +{{- $providedPasswordValue := include "common.utils.getValueFromKey" (dict "key" $providedPasswordKey "context" $.context) }} +{{- $secretData := (lookup "v1" "Secret" (include "common.names.namespace" .context) .secret).data }} +{{- if $secretData }} + {{- if hasKey $secretData .key }} + {{- $password = index $secretData .key | quote }} + {{- else if $failOnNew }} + {{- printf "\nPASSWORDS ERROR: The secret \"%s\" does not contain the key \"%s\"\n" .secret .key | fail -}} + {{- end -}} +{{- else if $providedPasswordValue }} + {{- $password = $providedPasswordValue | toString | b64enc | quote }} +{{- else }} + + {{- if .context.Values.enabled }} + {{- $subchart = $chartName }} + {{- end -}} + + {{- $requiredPassword := dict "valueKey" $providedPasswordKey "secret" .secret "field" .key "subchart" $subchart "context" $.context -}} + {{- $requiredPasswordError := include "common.validations.values.single.empty" $requiredPassword -}} + {{- $passwordValidationErrors := list $requiredPasswordError -}} + {{- include "common.errors.upgrade.passwords.empty" (dict "validationErrors" $passwordValidationErrors "context" $.context) -}} + + {{- if .strong }} + {{- $subStr := list (lower (randAlpha 1)) (randNumeric 1) (upper (randAlpha 1)) | join "_" }} + {{- $password = randAscii $passwordLength }} + {{- $password = regexReplaceAllLiteral "\\W" $password "@" | substr 5 $passwordLength }} + {{- $password = printf "%s%s" $subStr $password | toString | shuffle | b64enc | quote }} + {{- else }} + {{- $password = randAlphaNum $passwordLength | b64enc | quote }} + {{- end }} +{{- end -}} +{{- printf "%s" $password -}} +{{- end -}} + +{{/* +Reuses the value from an existing secret, otherwise sets its value to a default value. + +Usage: +{{ include "common.secrets.lookup" (dict "secret" "secret-name" "key" "keyName" "defaultValue" .Values.myValue "context" $) }} + +Params: + - secret - String - Required - Name of the 'Secret' resource where the password is stored. + - key - String - Required - Name of the key in the secret. + - defaultValue - String - Required - The path to the validating value in the values.yaml, e.g: "mysql.password". Will pick first parameter with a defined value. + - context - Context - Required - Parent context. + +*/}} +{{- define "common.secrets.lookup" -}} +{{- $value := "" -}} +{{- $secretData := (lookup "v1" "Secret" (include "common.names.namespace" .context) .secret).data -}} +{{- if and $secretData (hasKey $secretData .key) -}} + {{- $value = index $secretData .key -}} +{{- else if .defaultValue -}} + {{- $value = .defaultValue | toString | b64enc -}} +{{- end -}} +{{- if $value -}} +{{- printf "%s" $value -}} +{{- end -}} +{{- end -}} + +{{/* +Returns whether a previous generated secret already exists + +Usage: +{{ include "common.secrets.exists" (dict "secret" "secret-name" "context" $) }} + +Params: + - secret - String - Required - Name of the 'Secret' resource where the password is stored. + - context - Context - Required - Parent context. +*/}} +{{- define "common.secrets.exists" -}} +{{- $secret := (lookup "v1" "Secret" (include "common.names.namespace" .context) .secret) }} +{{- if $secret }} + {{- true -}} +{{- end -}} +{{- end -}} diff --git a/helm/ghost/charts/common/templates/_storage.tpl b/helm/ghost/charts/common/templates/_storage.tpl new file mode 100644 index 0000000..16405a0 --- /dev/null +++ b/helm/ghost/charts/common/templates/_storage.tpl @@ -0,0 +1,28 @@ +{{/* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} +{{/* +Return the proper Storage Class +{{ include "common.storage.class" ( dict "persistence" .Values.path.to.the.persistence "global" $) }} +*/}} +{{- define "common.storage.class" -}} + +{{- $storageClass := .persistence.storageClass -}} +{{- if .global -}} + {{- if .global.storageClass -}} + {{- $storageClass = .global.storageClass -}} + {{- end -}} +{{- end -}} + +{{- if $storageClass -}} + {{- if (eq "-" $storageClass) -}} + {{- printf "storageClassName: \"\"" -}} + {{- else }} + {{- printf "storageClassName: %s" $storageClass -}} + {{- end -}} +{{- end -}} + +{{- end -}} diff --git a/helm/ghost/charts/common/templates/_tplvalues.tpl b/helm/ghost/charts/common/templates/_tplvalues.tpl new file mode 100644 index 0000000..dc15f7f --- /dev/null +++ b/helm/ghost/charts/common/templates/_tplvalues.tpl @@ -0,0 +1,27 @@ +{{/* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} +{{/* +Renders a value that contains template perhaps with scope if the scope is present. +Usage: +{{ include "common.tplvalues.render" ( dict "value" .Values.path.to.the.Value "context" $ ) }} +{{ include "common.tplvalues.render" ( dict "value" .Values.path.to.the.Value "context" $ "scope" $app ) }} +*/}} +{{- define "common.tplvalues.render" -}} +{{- if .scope }} + {{- if typeIs "string" .value }} + {{- tpl (cat "{{- with $.RelativeScope -}}" .value "{{- end }}") (merge (dict "RelativeScope" .scope) .context) }} + {{- else }} + {{- tpl (cat "{{- with $.RelativeScope -}}" (.value | toYaml) "{{- end }}") (merge (dict "RelativeScope" .scope) .context) }} + {{- end }} +{{- else }} + {{- if typeIs "string" .value }} + {{- tpl .value .context }} + {{- else }} + {{- tpl (.value | toYaml) .context }} + {{- end }} +{{- end -}} +{{- end -}} diff --git a/helm/ghost/charts/common/templates/_utils.tpl b/helm/ghost/charts/common/templates/_utils.tpl new file mode 100644 index 0000000..c87040c --- /dev/null +++ b/helm/ghost/charts/common/templates/_utils.tpl @@ -0,0 +1,67 @@ +{{/* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} +{{/* +Print instructions to get a secret value. +Usage: +{{ include "common.utils.secret.getvalue" (dict "secret" "secret-name" "field" "secret-value-field" "context" $) }} +*/}} +{{- define "common.utils.secret.getvalue" -}} +{{- $varname := include "common.utils.fieldToEnvVar" . -}} +export {{ $varname }}=$(kubectl get secret --namespace {{ include "common.names.namespace" .context | quote }} {{ .secret }} -o jsonpath="{.data.{{ .field }}}" | base64 -d) +{{- end -}} + +{{/* +Build env var name given a field +Usage: +{{ include "common.utils.fieldToEnvVar" dict "field" "my-password" }} +*/}} +{{- define "common.utils.fieldToEnvVar" -}} + {{- $fieldNameSplit := splitList "-" .field -}} + {{- $upperCaseFieldNameSplit := list -}} + + {{- range $fieldNameSplit -}} + {{- $upperCaseFieldNameSplit = append $upperCaseFieldNameSplit ( upper . ) -}} + {{- end -}} + + {{ join "_" $upperCaseFieldNameSplit }} +{{- end -}} + +{{/* +Gets a value from .Values given +Usage: +{{ include "common.utils.getValueFromKey" (dict "key" "path.to.key" "context" $) }} +*/}} +{{- define "common.utils.getValueFromKey" -}} +{{- $splitKey := splitList "." .key -}} +{{- $value := "" -}} +{{- $latestObj := $.context.Values -}} +{{- range $splitKey -}} + {{- if not $latestObj -}} + {{- printf "please review the entire path of '%s' exists in values" $.key | fail -}} + {{- end -}} + {{- $value = ( index $latestObj . ) -}} + {{- $latestObj = $value -}} +{{- end -}} +{{- printf "%v" (default "" $value) -}} +{{- end -}} + +{{/* +Returns first .Values key with a defined value or first of the list if all non-defined +Usage: +{{ include "common.utils.getKeyFromList" (dict "keys" (list "path.to.key1" "path.to.key2") "context" $) }} +*/}} +{{- define "common.utils.getKeyFromList" -}} +{{- $key := first .keys -}} +{{- $reverseKeys := reverse .keys }} +{{- range $reverseKeys }} + {{- $value := include "common.utils.getValueFromKey" (dict "key" . "context" $.context ) }} + {{- if $value -}} + {{- $key = . }} + {{- end -}} +{{- end -}} +{{- printf "%s" $key -}} +{{- end -}} diff --git a/helm/ghost/charts/common/templates/_warnings.tpl b/helm/ghost/charts/common/templates/_warnings.tpl new file mode 100644 index 0000000..66dffc1 --- /dev/null +++ b/helm/ghost/charts/common/templates/_warnings.tpl @@ -0,0 +1,19 @@ +{{/* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} +{{/* +Warning about using rolling tag. +Usage: +{{ include "common.warnings.rollingTag" .Values.path.to.the.imageRoot }} +*/}} +{{- define "common.warnings.rollingTag" -}} + +{{- if and (contains "bitnami/" .repository) (not (.tag | toString | regexFind "-r\\d+$|sha256:")) }} +WARNING: Rolling tag detected ({{ .repository }}:{{ .tag }}), please note that it is strongly recommended to avoid using rolling tags in a production environment. ++info https://docs.bitnami.com/containers/how-to/understand-rolling-tags-containers/ +{{- end }} + +{{- end -}} diff --git a/helm/ghost/charts/common/templates/validations/_cassandra.tpl b/helm/ghost/charts/common/templates/validations/_cassandra.tpl new file mode 100644 index 0000000..eda9aad --- /dev/null +++ b/helm/ghost/charts/common/templates/validations/_cassandra.tpl @@ -0,0 +1,77 @@ +{{/* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} +{{/* +Validate Cassandra required passwords are not empty. + +Usage: +{{ include "common.validations.values.cassandra.passwords" (dict "secret" "secretName" "subchart" false "context" $) }} +Params: + - secret - String - Required. Name of the secret where Cassandra values are stored, e.g: "cassandra-passwords-secret" + - subchart - Boolean - Optional. Whether Cassandra is used as subchart or not. Default: false +*/}} +{{- define "common.validations.values.cassandra.passwords" -}} + {{- $existingSecret := include "common.cassandra.values.existingSecret" . -}} + {{- $enabled := include "common.cassandra.values.enabled" . -}} + {{- $dbUserPrefix := include "common.cassandra.values.key.dbUser" . -}} + {{- $valueKeyPassword := printf "%s.password" $dbUserPrefix -}} + + {{- if and (or (not $existingSecret) (eq $existingSecret "\"\"")) (eq $enabled "true") -}} + {{- $requiredPasswords := list -}} + + {{- $requiredPassword := dict "valueKey" $valueKeyPassword "secret" .secret "field" "cassandra-password" -}} + {{- $requiredPasswords = append $requiredPasswords $requiredPassword -}} + + {{- include "common.validations.values.multiple.empty" (dict "required" $requiredPasswords "context" .context) -}} + + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for existingSecret. + +Usage: +{{ include "common.cassandra.values.existingSecret" (dict "context" $) }} +Params: + - subchart - Boolean - Optional. Whether Cassandra is used as subchart or not. Default: false +*/}} +{{- define "common.cassandra.values.existingSecret" -}} + {{- if .subchart -}} + {{- .context.Values.cassandra.dbUser.existingSecret | quote -}} + {{- else -}} + {{- .context.Values.dbUser.existingSecret | quote -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for enabled cassandra. + +Usage: +{{ include "common.cassandra.values.enabled" (dict "context" $) }} +*/}} +{{- define "common.cassandra.values.enabled" -}} + {{- if .subchart -}} + {{- printf "%v" .context.Values.cassandra.enabled -}} + {{- else -}} + {{- printf "%v" (not .context.Values.enabled) -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for the key dbUser + +Usage: +{{ include "common.cassandra.values.key.dbUser" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether Cassandra is used as subchart or not. Default: false +*/}} +{{- define "common.cassandra.values.key.dbUser" -}} + {{- if .subchart -}} + cassandra.dbUser + {{- else -}} + dbUser + {{- end -}} +{{- end -}} diff --git a/helm/ghost/charts/common/templates/validations/_mariadb.tpl b/helm/ghost/charts/common/templates/validations/_mariadb.tpl new file mode 100644 index 0000000..17d83a2 --- /dev/null +++ b/helm/ghost/charts/common/templates/validations/_mariadb.tpl @@ -0,0 +1,108 @@ +{{/* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} +{{/* +Validate MariaDB required passwords are not empty. + +Usage: +{{ include "common.validations.values.mariadb.passwords" (dict "secret" "secretName" "subchart" false "context" $) }} +Params: + - secret - String - Required. Name of the secret where MariaDB values are stored, e.g: "mysql-passwords-secret" + - subchart - Boolean - Optional. Whether MariaDB is used as subchart or not. Default: false +*/}} +{{- define "common.validations.values.mariadb.passwords" -}} + {{- $existingSecret := include "common.mariadb.values.auth.existingSecret" . -}} + {{- $enabled := include "common.mariadb.values.enabled" . -}} + {{- $architecture := include "common.mariadb.values.architecture" . -}} + {{- $authPrefix := include "common.mariadb.values.key.auth" . -}} + {{- $valueKeyRootPassword := printf "%s.rootPassword" $authPrefix -}} + {{- $valueKeyUsername := printf "%s.username" $authPrefix -}} + {{- $valueKeyPassword := printf "%s.password" $authPrefix -}} + {{- $valueKeyReplicationPassword := printf "%s.replicationPassword" $authPrefix -}} + + {{- if and (or (not $existingSecret) (eq $existingSecret "\"\"")) (eq $enabled "true") -}} + {{- $requiredPasswords := list -}} + + {{- $requiredRootPassword := dict "valueKey" $valueKeyRootPassword "secret" .secret "field" "mariadb-root-password" -}} + {{- $requiredPasswords = append $requiredPasswords $requiredRootPassword -}} + + {{- $valueUsername := include "common.utils.getValueFromKey" (dict "key" $valueKeyUsername "context" .context) }} + {{- if not (empty $valueUsername) -}} + {{- $requiredPassword := dict "valueKey" $valueKeyPassword "secret" .secret "field" "mariadb-password" -}} + {{- $requiredPasswords = append $requiredPasswords $requiredPassword -}} + {{- end -}} + + {{- if (eq $architecture "replication") -}} + {{- $requiredReplicationPassword := dict "valueKey" $valueKeyReplicationPassword "secret" .secret "field" "mariadb-replication-password" -}} + {{- $requiredPasswords = append $requiredPasswords $requiredReplicationPassword -}} + {{- end -}} + + {{- include "common.validations.values.multiple.empty" (dict "required" $requiredPasswords "context" .context) -}} + + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for existingSecret. + +Usage: +{{ include "common.mariadb.values.auth.existingSecret" (dict "context" $) }} +Params: + - subchart - Boolean - Optional. Whether MariaDB is used as subchart or not. Default: false +*/}} +{{- define "common.mariadb.values.auth.existingSecret" -}} + {{- if .subchart -}} + {{- .context.Values.mariadb.auth.existingSecret | quote -}} + {{- else -}} + {{- .context.Values.auth.existingSecret | quote -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for enabled mariadb. + +Usage: +{{ include "common.mariadb.values.enabled" (dict "context" $) }} +*/}} +{{- define "common.mariadb.values.enabled" -}} + {{- if .subchart -}} + {{- printf "%v" .context.Values.mariadb.enabled -}} + {{- else -}} + {{- printf "%v" (not .context.Values.enabled) -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for architecture + +Usage: +{{ include "common.mariadb.values.architecture" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether MariaDB is used as subchart or not. Default: false +*/}} +{{- define "common.mariadb.values.architecture" -}} + {{- if .subchart -}} + {{- .context.Values.mariadb.architecture -}} + {{- else -}} + {{- .context.Values.architecture -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for the key auth + +Usage: +{{ include "common.mariadb.values.key.auth" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether MariaDB is used as subchart or not. Default: false +*/}} +{{- define "common.mariadb.values.key.auth" -}} + {{- if .subchart -}} + mariadb.auth + {{- else -}} + auth + {{- end -}} +{{- end -}} diff --git a/helm/ghost/charts/common/templates/validations/_mongodb.tpl b/helm/ghost/charts/common/templates/validations/_mongodb.tpl new file mode 100644 index 0000000..bbb445b --- /dev/null +++ b/helm/ghost/charts/common/templates/validations/_mongodb.tpl @@ -0,0 +1,113 @@ +{{/* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} +{{/* +Validate MongoDB® required passwords are not empty. + +Usage: +{{ include "common.validations.values.mongodb.passwords" (dict "secret" "secretName" "subchart" false "context" $) }} +Params: + - secret - String - Required. Name of the secret where MongoDB® values are stored, e.g: "mongodb-passwords-secret" + - subchart - Boolean - Optional. Whether MongoDB® is used as subchart or not. Default: false +*/}} +{{- define "common.validations.values.mongodb.passwords" -}} + {{- $existingSecret := include "common.mongodb.values.auth.existingSecret" . -}} + {{- $enabled := include "common.mongodb.values.enabled" . -}} + {{- $authPrefix := include "common.mongodb.values.key.auth" . -}} + {{- $architecture := include "common.mongodb.values.architecture" . -}} + {{- $valueKeyRootPassword := printf "%s.rootPassword" $authPrefix -}} + {{- $valueKeyUsername := printf "%s.username" $authPrefix -}} + {{- $valueKeyDatabase := printf "%s.database" $authPrefix -}} + {{- $valueKeyPassword := printf "%s.password" $authPrefix -}} + {{- $valueKeyReplicaSetKey := printf "%s.replicaSetKey" $authPrefix -}} + {{- $valueKeyAuthEnabled := printf "%s.enabled" $authPrefix -}} + + {{- $authEnabled := include "common.utils.getValueFromKey" (dict "key" $valueKeyAuthEnabled "context" .context) -}} + + {{- if and (or (not $existingSecret) (eq $existingSecret "\"\"")) (eq $enabled "true") (eq $authEnabled "true") -}} + {{- $requiredPasswords := list -}} + + {{- $requiredRootPassword := dict "valueKey" $valueKeyRootPassword "secret" .secret "field" "mongodb-root-password" -}} + {{- $requiredPasswords = append $requiredPasswords $requiredRootPassword -}} + + {{- $valueUsername := include "common.utils.getValueFromKey" (dict "key" $valueKeyUsername "context" .context) }} + {{- $valueDatabase := include "common.utils.getValueFromKey" (dict "key" $valueKeyDatabase "context" .context) }} + {{- if and $valueUsername $valueDatabase -}} + {{- $requiredPassword := dict "valueKey" $valueKeyPassword "secret" .secret "field" "mongodb-password" -}} + {{- $requiredPasswords = append $requiredPasswords $requiredPassword -}} + {{- end -}} + + {{- if (eq $architecture "replicaset") -}} + {{- $requiredReplicaSetKey := dict "valueKey" $valueKeyReplicaSetKey "secret" .secret "field" "mongodb-replica-set-key" -}} + {{- $requiredPasswords = append $requiredPasswords $requiredReplicaSetKey -}} + {{- end -}} + + {{- include "common.validations.values.multiple.empty" (dict "required" $requiredPasswords "context" .context) -}} + + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for existingSecret. + +Usage: +{{ include "common.mongodb.values.auth.existingSecret" (dict "context" $) }} +Params: + - subchart - Boolean - Optional. Whether MongoDb is used as subchart or not. Default: false +*/}} +{{- define "common.mongodb.values.auth.existingSecret" -}} + {{- if .subchart -}} + {{- .context.Values.mongodb.auth.existingSecret | quote -}} + {{- else -}} + {{- .context.Values.auth.existingSecret | quote -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for enabled mongodb. + +Usage: +{{ include "common.mongodb.values.enabled" (dict "context" $) }} +*/}} +{{- define "common.mongodb.values.enabled" -}} + {{- if .subchart -}} + {{- printf "%v" .context.Values.mongodb.enabled -}} + {{- else -}} + {{- printf "%v" (not .context.Values.enabled) -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for the key auth + +Usage: +{{ include "common.mongodb.values.key.auth" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether MongoDB® is used as subchart or not. Default: false +*/}} +{{- define "common.mongodb.values.key.auth" -}} + {{- if .subchart -}} + mongodb.auth + {{- else -}} + auth + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for architecture + +Usage: +{{ include "common.mongodb.values.architecture" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether MongoDB® is used as subchart or not. Default: false +*/}} +{{- define "common.mongodb.values.architecture" -}} + {{- if .subchart -}} + {{- .context.Values.mongodb.architecture -}} + {{- else -}} + {{- .context.Values.architecture -}} + {{- end -}} +{{- end -}} diff --git a/helm/ghost/charts/common/templates/validations/_mysql.tpl b/helm/ghost/charts/common/templates/validations/_mysql.tpl new file mode 100644 index 0000000..ca3953f --- /dev/null +++ b/helm/ghost/charts/common/templates/validations/_mysql.tpl @@ -0,0 +1,108 @@ +{{/* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} +{{/* +Validate MySQL required passwords are not empty. + +Usage: +{{ include "common.validations.values.mysql.passwords" (dict "secret" "secretName" "subchart" false "context" $) }} +Params: + - secret - String - Required. Name of the secret where MySQL values are stored, e.g: "mysql-passwords-secret" + - subchart - Boolean - Optional. Whether MySQL is used as subchart or not. Default: false +*/}} +{{- define "common.validations.values.mysql.passwords" -}} + {{- $existingSecret := include "common.mysql.values.auth.existingSecret" . -}} + {{- $enabled := include "common.mysql.values.enabled" . -}} + {{- $architecture := include "common.mysql.values.architecture" . -}} + {{- $authPrefix := include "common.mysql.values.key.auth" . -}} + {{- $valueKeyRootPassword := printf "%s.rootPassword" $authPrefix -}} + {{- $valueKeyUsername := printf "%s.username" $authPrefix -}} + {{- $valueKeyPassword := printf "%s.password" $authPrefix -}} + {{- $valueKeyReplicationPassword := printf "%s.replicationPassword" $authPrefix -}} + + {{- if and (or (not $existingSecret) (eq $existingSecret "\"\"")) (eq $enabled "true") -}} + {{- $requiredPasswords := list -}} + + {{- $requiredRootPassword := dict "valueKey" $valueKeyRootPassword "secret" .secret "field" "mysql-root-password" -}} + {{- $requiredPasswords = append $requiredPasswords $requiredRootPassword -}} + + {{- $valueUsername := include "common.utils.getValueFromKey" (dict "key" $valueKeyUsername "context" .context) }} + {{- if not (empty $valueUsername) -}} + {{- $requiredPassword := dict "valueKey" $valueKeyPassword "secret" .secret "field" "mysql-password" -}} + {{- $requiredPasswords = append $requiredPasswords $requiredPassword -}} + {{- end -}} + + {{- if (eq $architecture "replication") -}} + {{- $requiredReplicationPassword := dict "valueKey" $valueKeyReplicationPassword "secret" .secret "field" "mysql-replication-password" -}} + {{- $requiredPasswords = append $requiredPasswords $requiredReplicationPassword -}} + {{- end -}} + + {{- include "common.validations.values.multiple.empty" (dict "required" $requiredPasswords "context" .context) -}} + + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for existingSecret. + +Usage: +{{ include "common.mysql.values.auth.existingSecret" (dict "context" $) }} +Params: + - subchart - Boolean - Optional. Whether MySQL is used as subchart or not. Default: false +*/}} +{{- define "common.mysql.values.auth.existingSecret" -}} + {{- if .subchart -}} + {{- .context.Values.mysql.auth.existingSecret | quote -}} + {{- else -}} + {{- .context.Values.auth.existingSecret | quote -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for enabled mysql. + +Usage: +{{ include "common.mysql.values.enabled" (dict "context" $) }} +*/}} +{{- define "common.mysql.values.enabled" -}} + {{- if .subchart -}} + {{- printf "%v" .context.Values.mysql.enabled -}} + {{- else -}} + {{- printf "%v" (not .context.Values.enabled) -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for architecture + +Usage: +{{ include "common.mysql.values.architecture" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether MySQL is used as subchart or not. Default: false +*/}} +{{- define "common.mysql.values.architecture" -}} + {{- if .subchart -}} + {{- .context.Values.mysql.architecture -}} + {{- else -}} + {{- .context.Values.architecture -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for the key auth + +Usage: +{{ include "common.mysql.values.key.auth" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether MySQL is used as subchart or not. Default: false +*/}} +{{- define "common.mysql.values.key.auth" -}} + {{- if .subchart -}} + mysql.auth + {{- else -}} + auth + {{- end -}} +{{- end -}} diff --git a/helm/ghost/charts/common/templates/validations/_postgresql.tpl b/helm/ghost/charts/common/templates/validations/_postgresql.tpl new file mode 100644 index 0000000..8c9aa57 --- /dev/null +++ b/helm/ghost/charts/common/templates/validations/_postgresql.tpl @@ -0,0 +1,134 @@ +{{/* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} +{{/* +Validate PostgreSQL required passwords are not empty. + +Usage: +{{ include "common.validations.values.postgresql.passwords" (dict "secret" "secretName" "subchart" false "context" $) }} +Params: + - secret - String - Required. Name of the secret where postgresql values are stored, e.g: "postgresql-passwords-secret" + - subchart - Boolean - Optional. Whether postgresql is used as subchart or not. Default: false +*/}} +{{- define "common.validations.values.postgresql.passwords" -}} + {{- $existingSecret := include "common.postgresql.values.existingSecret" . -}} + {{- $enabled := include "common.postgresql.values.enabled" . -}} + {{- $valueKeyPostgresqlPassword := include "common.postgresql.values.key.postgressPassword" . -}} + {{- $valueKeyPostgresqlReplicationEnabled := include "common.postgresql.values.key.replicationPassword" . -}} + {{- if and (or (not $existingSecret) (eq $existingSecret "\"\"")) (eq $enabled "true") -}} + {{- $requiredPasswords := list -}} + {{- $requiredPostgresqlPassword := dict "valueKey" $valueKeyPostgresqlPassword "secret" .secret "field" "postgresql-password" -}} + {{- $requiredPasswords = append $requiredPasswords $requiredPostgresqlPassword -}} + + {{- $enabledReplication := include "common.postgresql.values.enabled.replication" . -}} + {{- if (eq $enabledReplication "true") -}} + {{- $requiredPostgresqlReplicationPassword := dict "valueKey" $valueKeyPostgresqlReplicationEnabled "secret" .secret "field" "postgresql-replication-password" -}} + {{- $requiredPasswords = append $requiredPasswords $requiredPostgresqlReplicationPassword -}} + {{- end -}} + + {{- include "common.validations.values.multiple.empty" (dict "required" $requiredPasswords "context" .context) -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to decide whether evaluate global values. + +Usage: +{{ include "common.postgresql.values.use.global" (dict "key" "key-of-global" "context" $) }} +Params: + - key - String - Required. Field to be evaluated within global, e.g: "existingSecret" +*/}} +{{- define "common.postgresql.values.use.global" -}} + {{- if .context.Values.global -}} + {{- if .context.Values.global.postgresql -}} + {{- index .context.Values.global.postgresql .key | quote -}} + {{- end -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for existingSecret. + +Usage: +{{ include "common.postgresql.values.existingSecret" (dict "context" $) }} +*/}} +{{- define "common.postgresql.values.existingSecret" -}} + {{- $globalValue := include "common.postgresql.values.use.global" (dict "key" "existingSecret" "context" .context) -}} + + {{- if .subchart -}} + {{- default (.context.Values.postgresql.existingSecret | quote) $globalValue -}} + {{- else -}} + {{- default (.context.Values.existingSecret | quote) $globalValue -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for enabled postgresql. + +Usage: +{{ include "common.postgresql.values.enabled" (dict "context" $) }} +*/}} +{{- define "common.postgresql.values.enabled" -}} + {{- if .subchart -}} + {{- printf "%v" .context.Values.postgresql.enabled -}} + {{- else -}} + {{- printf "%v" (not .context.Values.enabled) -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for the key postgressPassword. + +Usage: +{{ include "common.postgresql.values.key.postgressPassword" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether postgresql is used as subchart or not. Default: false +*/}} +{{- define "common.postgresql.values.key.postgressPassword" -}} + {{- $globalValue := include "common.postgresql.values.use.global" (dict "key" "postgresqlUsername" "context" .context) -}} + + {{- if not $globalValue -}} + {{- if .subchart -}} + postgresql.postgresqlPassword + {{- else -}} + postgresqlPassword + {{- end -}} + {{- else -}} + global.postgresql.postgresqlPassword + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for enabled.replication. + +Usage: +{{ include "common.postgresql.values.enabled.replication" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether postgresql is used as subchart or not. Default: false +*/}} +{{- define "common.postgresql.values.enabled.replication" -}} + {{- if .subchart -}} + {{- printf "%v" .context.Values.postgresql.replication.enabled -}} + {{- else -}} + {{- printf "%v" .context.Values.replication.enabled -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for the key replication.password. + +Usage: +{{ include "common.postgresql.values.key.replicationPassword" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether postgresql is used as subchart or not. Default: false +*/}} +{{- define "common.postgresql.values.key.replicationPassword" -}} + {{- if .subchart -}} + postgresql.replication.password + {{- else -}} + replication.password + {{- end -}} +{{- end -}} diff --git a/helm/ghost/charts/common/templates/validations/_redis.tpl b/helm/ghost/charts/common/templates/validations/_redis.tpl new file mode 100644 index 0000000..fc0d208 --- /dev/null +++ b/helm/ghost/charts/common/templates/validations/_redis.tpl @@ -0,0 +1,81 @@ +{{/* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + + +{{/* vim: set filetype=mustache: */}} +{{/* +Validate Redis® required passwords are not empty. + +Usage: +{{ include "common.validations.values.redis.passwords" (dict "secret" "secretName" "subchart" false "context" $) }} +Params: + - secret - String - Required. Name of the secret where redis values are stored, e.g: "redis-passwords-secret" + - subchart - Boolean - Optional. Whether redis is used as subchart or not. Default: false +*/}} +{{- define "common.validations.values.redis.passwords" -}} + {{- $enabled := include "common.redis.values.enabled" . -}} + {{- $valueKeyPrefix := include "common.redis.values.keys.prefix" . -}} + {{- $standarizedVersion := include "common.redis.values.standarized.version" . }} + + {{- $existingSecret := ternary (printf "%s%s" $valueKeyPrefix "auth.existingSecret") (printf "%s%s" $valueKeyPrefix "existingSecret") (eq $standarizedVersion "true") }} + {{- $existingSecretValue := include "common.utils.getValueFromKey" (dict "key" $existingSecret "context" .context) }} + + {{- $valueKeyRedisPassword := ternary (printf "%s%s" $valueKeyPrefix "auth.password") (printf "%s%s" $valueKeyPrefix "password") (eq $standarizedVersion "true") }} + {{- $valueKeyRedisUseAuth := ternary (printf "%s%s" $valueKeyPrefix "auth.enabled") (printf "%s%s" $valueKeyPrefix "usePassword") (eq $standarizedVersion "true") }} + + {{- if and (or (not $existingSecret) (eq $existingSecret "\"\"")) (eq $enabled "true") -}} + {{- $requiredPasswords := list -}} + + {{- $useAuth := include "common.utils.getValueFromKey" (dict "key" $valueKeyRedisUseAuth "context" .context) -}} + {{- if eq $useAuth "true" -}} + {{- $requiredRedisPassword := dict "valueKey" $valueKeyRedisPassword "secret" .secret "field" "redis-password" -}} + {{- $requiredPasswords = append $requiredPasswords $requiredRedisPassword -}} + {{- end -}} + + {{- include "common.validations.values.multiple.empty" (dict "required" $requiredPasswords "context" .context) -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for enabled redis. + +Usage: +{{ include "common.redis.values.enabled" (dict "context" $) }} +*/}} +{{- define "common.redis.values.enabled" -}} + {{- if .subchart -}} + {{- printf "%v" .context.Values.redis.enabled -}} + {{- else -}} + {{- printf "%v" (not .context.Values.enabled) -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right prefix path for the values + +Usage: +{{ include "common.redis.values.key.prefix" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether redis is used as subchart or not. Default: false +*/}} +{{- define "common.redis.values.keys.prefix" -}} + {{- if .subchart -}}redis.{{- else -}}{{- end -}} +{{- end -}} + +{{/* +Checks whether the redis chart's includes the standarizations (version >= 14) + +Usage: +{{ include "common.redis.values.standarized.version" (dict "context" $) }} +*/}} +{{- define "common.redis.values.standarized.version" -}} + + {{- $standarizedAuth := printf "%s%s" (include "common.redis.values.keys.prefix" .) "auth" -}} + {{- $standarizedAuthValues := include "common.utils.getValueFromKey" (dict "key" $standarizedAuth "context" .context) }} + + {{- if $standarizedAuthValues -}} + {{- true -}} + {{- end -}} +{{- end -}} diff --git a/helm/ghost/charts/common/templates/validations/_validations.tpl b/helm/ghost/charts/common/templates/validations/_validations.tpl new file mode 100644 index 0000000..31ceda8 --- /dev/null +++ b/helm/ghost/charts/common/templates/validations/_validations.tpl @@ -0,0 +1,51 @@ +{{/* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} +{{/* +Validate values must not be empty. + +Usage: +{{- $validateValueConf00 := (dict "valueKey" "path.to.value" "secret" "secretName" "field" "password-00") -}} +{{- $validateValueConf01 := (dict "valueKey" "path.to.value" "secret" "secretName" "field" "password-01") -}} +{{ include "common.validations.values.empty" (dict "required" (list $validateValueConf00 $validateValueConf01) "context" $) }} + +Validate value params: + - valueKey - String - Required. The path to the validating value in the values.yaml, e.g: "mysql.password" + - secret - String - Optional. Name of the secret where the validating value is generated/stored, e.g: "mysql-passwords-secret" + - field - String - Optional. Name of the field in the secret data, e.g: "mysql-password" +*/}} +{{- define "common.validations.values.multiple.empty" -}} + {{- range .required -}} + {{- include "common.validations.values.single.empty" (dict "valueKey" .valueKey "secret" .secret "field" .field "context" $.context) -}} + {{- end -}} +{{- end -}} + +{{/* +Validate a value must not be empty. + +Usage: +{{ include "common.validations.value.empty" (dict "valueKey" "mariadb.password" "secret" "secretName" "field" "my-password" "subchart" "subchart" "context" $) }} + +Validate value params: + - valueKey - String - Required. The path to the validating value in the values.yaml, e.g: "mysql.password" + - secret - String - Optional. Name of the secret where the validating value is generated/stored, e.g: "mysql-passwords-secret" + - field - String - Optional. Name of the field in the secret data, e.g: "mysql-password" + - subchart - String - Optional - Name of the subchart that the validated password is part of. +*/}} +{{- define "common.validations.values.single.empty" -}} + {{- $value := include "common.utils.getValueFromKey" (dict "key" .valueKey "context" .context) }} + {{- $subchart := ternary "" (printf "%s." .subchart) (empty .subchart) }} + + {{- if not $value -}} + {{- $varname := "my-value" -}} + {{- $getCurrentValue := "" -}} + {{- if and .secret .field -}} + {{- $varname = include "common.utils.fieldToEnvVar" . -}} + {{- $getCurrentValue = printf " To get the current value:\n\n %s\n" (include "common.utils.secret.getvalue" .) -}} + {{- end -}} + {{- printf "\n '%s' must not be empty, please add '--set %s%s=$%s' to the command.%s" .valueKey $subchart .valueKey $varname $getCurrentValue -}} + {{- end -}} +{{- end -}} diff --git a/helm/ghost/charts/common/values.yaml b/helm/ghost/charts/common/values.yaml new file mode 100644 index 0000000..9abe0e1 --- /dev/null +++ b/helm/ghost/charts/common/values.yaml @@ -0,0 +1,8 @@ +# Copyright VMware, Inc. +# SPDX-License-Identifier: APACHE-2.0 + +## bitnami/common +## It is required by CI/CD tools and processes. +## @skip exampleValue +## +exampleValue: common-chart diff --git a/helm/ghost/charts/mysql/.helmignore b/helm/ghost/charts/mysql/.helmignore new file mode 100644 index 0000000..f0c1319 --- /dev/null +++ b/helm/ghost/charts/mysql/.helmignore @@ -0,0 +1,21 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*~ +# Various IDEs +.project +.idea/ +*.tmproj diff --git a/helm/ghost/charts/mysql/Chart.lock b/helm/ghost/charts/mysql/Chart.lock new file mode 100644 index 0000000..5d826bf --- /dev/null +++ b/helm/ghost/charts/mysql/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: common + repository: oci://registry-1.docker.io/bitnamicharts + version: 2.6.0 +digest: sha256:6ce7c85dcb43ad1fc5ff600850f28820ddc2f1a7c8cb25c5ff542fe1f852165a +generated: "2023-07-05T18:35:58.359207844Z" diff --git a/helm/ghost/charts/mysql/Chart.yaml b/helm/ghost/charts/mysql/Chart.yaml new file mode 100644 index 0000000..7202898 --- /dev/null +++ b/helm/ghost/charts/mysql/Chart.yaml @@ -0,0 +1,28 @@ +annotations: + category: Database + licenses: Apache-2.0 +apiVersion: v2 +appVersion: 8.0.33 +dependencies: +- name: common + repository: oci://registry-1.docker.io/bitnamicharts + tags: + - bitnami-common + version: 2.x.x +description: MySQL is a fast, reliable, scalable, and easy to use open source relational + database system. Designed to handle mission-critical, heavy-load production applications. +home: https://bitnami.com +icon: https://bitnami.com/assets/stacks/mysql/img/mysql-stack-220x234.png +keywords: +- mysql +- database +- sql +- cluster +- high availability +maintainers: +- name: VMware, Inc. + url: https://github.com/bitnami/charts +name: mysql +sources: +- https://github.com/bitnami/charts/tree/main/bitnami/mysql +version: 9.10.6 diff --git a/helm/ghost/charts/mysql/README.md b/helm/ghost/charts/mysql/README.md new file mode 100644 index 0000000..1b26989 --- /dev/null +++ b/helm/ghost/charts/mysql/README.md @@ -0,0 +1,552 @@ + + +# MySQL packaged by Bitnami + +MySQL is a fast, reliable, scalable, and easy to use open source relational database system. Designed to handle mission-critical, heavy-load production applications. + +[Overview of MySQL](http://www.mysql.com) + +Trademarks: This software listing is packaged by Bitnami. The respective trademarks mentioned in the offering are owned by the respective companies, and use of them does not imply any affiliation or endorsement. + +## TL;DR + +```console +helm install my-release oci://registry-1.docker.io/bitnamicharts/mysql +``` + +## Introduction + +This chart bootstraps a [MySQL](https://github.com/bitnami/containers/tree/main/bitnami/mysql) replication cluster deployment on a [Kubernetes](https://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. + +Bitnami charts can be used with [Kubeapps](https://kubeapps.dev/) for deployment and management of Helm Charts in clusters. + +Looking to use MySQL in production? Try [VMware Application Catalog](https://bitnami.com/enterprise), the enterprise edition of Bitnami Application Catalog. + +## Prerequisites + +- Kubernetes 1.19+ +- Helm 3.2.0+ +- PV provisioner support in the underlying infrastructure + +## Installing the Chart + +To install the chart with the release name `my-release`: + +```console +helm install my-release oci://registry-1.docker.io/bitnamicharts/mysql +``` + +These commands deploy MySQL on the Kubernetes cluster in the default configuration. The [Parameters](#parameters) section lists the parameters that can be configured during installation. + +> **Tip**: List all releases using `helm list` + +## Uninstalling the Chart + +To uninstall/delete the `my-release` deployment: + +```console +helm delete my-release +``` + +The command removes all the Kubernetes components associated with the chart and deletes the release. + +## Parameters + +### Global parameters + +| Name | Description | Value | +| ------------------------- | ----------------------------------------------- | ----- | +| `global.imageRegistry` | Global Docker image registry | `""` | +| `global.imagePullSecrets` | Global Docker registry secret names as an array | `[]` | +| `global.storageClass` | Global StorageClass for Persistent Volume(s) | `""` | + +### Common parameters + +| Name | Description | Value | +| ------------------------- | --------------------------------------------------------------------------------------------------------- | --------------- | +| `kubeVersion` | Force target Kubernetes version (using Helm capabilities if not set) | `""` | +| `nameOverride` | String to partially override common.names.fullname template (will maintain the release name) | `""` | +| `fullnameOverride` | String to fully override common.names.fullname template | `""` | +| `namespaceOverride` | String to fully override common.names.namespace | `""` | +| `clusterDomain` | Cluster domain | `cluster.local` | +| `commonAnnotations` | Common annotations to add to all MySQL resources (sub-charts are not considered). Evaluated as a template | `{}` | +| `commonLabels` | Common labels to add to all MySQL resources (sub-charts are not considered). Evaluated as a template | `{}` | +| `extraDeploy` | Array with extra yaml to deploy with the chart. Evaluated as a template | `[]` | +| `serviceBindings.enabled` | Create secret for service binding (Experimental) | `false` | +| `diagnosticMode.enabled` | Enable diagnostic mode (all probes will be disabled and the command will be overridden) | `false` | +| `diagnosticMode.command` | Command to override all containers in the deployment | `["sleep"]` | +| `diagnosticMode.args` | Args to override all containers in the deployment | `["infinity"]` | + +### MySQL common parameters + +| Name | Description | Value | +| -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------- | +| `image.registry` | MySQL image registry | `docker.io` | +| `image.repository` | MySQL image repository | `bitnami/mysql` | +| `image.tag` | MySQL image tag (immutable tags are recommended) | `8.0.33-debian-11-r30` | +| `image.digest` | MySQL image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag | `""` | +| `image.pullPolicy` | MySQL image pull policy | `IfNotPresent` | +| `image.pullSecrets` | Specify docker-registry secret names as an array | `[]` | +| `image.debug` | Specify if debug logs should be enabled | `false` | +| `architecture` | MySQL architecture (`standalone` or `replication`) | `standalone` | +| `auth.rootPassword` | Password for the `root` user. Ignored if existing secret is provided | `""` | +| `auth.createDatabase` | Whether to create the .Values.auth.database or not | `true` | +| `auth.database` | Name for a custom database to create | `my_database` | +| `auth.username` | Name for a custom user to create | `""` | +| `auth.password` | Password for the new user. Ignored if existing secret is provided | `""` | +| `auth.replicationUser` | MySQL replication user | `replicator` | +| `auth.replicationPassword` | MySQL replication user password. Ignored if existing secret is provided | `""` | +| `auth.existingSecret` | Use existing secret for password details. The secret has to contain the keys `mysql-root-password`, `mysql-replication-password` and `mysql-password` | `""` | +| `auth.usePasswordFiles` | Mount credentials as files instead of using an environment variable | `false` | +| `auth.customPasswordFiles` | Use custom password files when `auth.usePasswordFiles` is set to `true`. Define path for keys `root` and `user`, also define `replicator` if `architecture` is set to `replication` | `{}` | +| `initdbScripts` | Dictionary of initdb scripts | `{}` | +| `initdbScriptsConfigMap` | ConfigMap with the initdb scripts (Note: Overrides `initdbScripts`) | `""` | + +### MySQL Primary parameters + +| Name | Description | Value | +| ----------------------------------------------- | --------------------------------------------------------------------------------------------------------------- | ------------------- | +| `primary.name` | Name of the primary database (eg primary, master, leader, ...) | `primary` | +| `primary.command` | Override default container command on MySQL Primary container(s) (useful when using custom images) | `[]` | +| `primary.args` | Override default container args on MySQL Primary container(s) (useful when using custom images) | `[]` | +| `primary.lifecycleHooks` | for the MySQL Primary container(s) to automate configuration before or after startup | `{}` | +| `primary.hostAliases` | Deployment pod host aliases | `[]` | +| `primary.configuration` | Configure MySQL Primary with a custom my.cnf file | `""` | +| `primary.existingConfigmap` | Name of existing ConfigMap with MySQL Primary configuration. | `""` | +| `primary.updateStrategy.type` | Update strategy type for the MySQL primary statefulset | `RollingUpdate` | +| `primary.podAnnotations` | Additional pod annotations for MySQL primary pods | `{}` | +| `primary.podAffinityPreset` | MySQL primary pod affinity preset. Ignored if `primary.affinity` is set. Allowed values: `soft` or `hard` | `""` | +| `primary.podAntiAffinityPreset` | MySQL primary pod anti-affinity preset. Ignored if `primary.affinity` is set. Allowed values: `soft` or `hard` | `soft` | +| `primary.nodeAffinityPreset.type` | MySQL primary node affinity preset type. Ignored if `primary.affinity` is set. Allowed values: `soft` or `hard` | `""` | +| `primary.nodeAffinityPreset.key` | MySQL primary node label key to match Ignored if `primary.affinity` is set. | `""` | +| `primary.nodeAffinityPreset.values` | MySQL primary node label values to match. Ignored if `primary.affinity` is set. | `[]` | +| `primary.affinity` | Affinity for MySQL primary pods assignment | `{}` | +| `primary.nodeSelector` | Node labels for MySQL primary pods assignment | `{}` | +| `primary.tolerations` | Tolerations for MySQL primary pods assignment | `[]` | +| `primary.priorityClassName` | MySQL primary pods' priorityClassName | `""` | +| `primary.runtimeClassName` | MySQL primary pods' runtimeClassName | `""` | +| `primary.schedulerName` | Name of the k8s scheduler (other than default) | `""` | +| `primary.terminationGracePeriodSeconds` | In seconds, time the given to the MySQL primary pod needs to terminate gracefully | `""` | +| `primary.topologySpreadConstraints` | Topology Spread Constraints for pod assignment | `[]` | +| `primary.podManagementPolicy` | podManagementPolicy to manage scaling operation of MySQL primary pods | `""` | +| `primary.podSecurityContext.enabled` | Enable security context for MySQL primary pods | `true` | +| `primary.podSecurityContext.fsGroup` | Group ID for the mounted volumes' filesystem | `1001` | +| `primary.containerSecurityContext.enabled` | MySQL primary container securityContext | `true` | +| `primary.containerSecurityContext.runAsUser` | User ID for the MySQL primary container | `1001` | +| `primary.containerSecurityContext.runAsNonRoot` | Set MySQL primary container's Security Context runAsNonRoot | `true` | +| `primary.resources.limits` | The resources limits for MySQL primary containers | `{}` | +| `primary.resources.requests` | The requested resources for MySQL primary containers | `{}` | +| `primary.livenessProbe.enabled` | Enable livenessProbe | `true` | +| `primary.livenessProbe.initialDelaySeconds` | Initial delay seconds for livenessProbe | `5` | +| `primary.livenessProbe.periodSeconds` | Period seconds for livenessProbe | `10` | +| `primary.livenessProbe.timeoutSeconds` | Timeout seconds for livenessProbe | `1` | +| `primary.livenessProbe.failureThreshold` | Failure threshold for livenessProbe | `3` | +| `primary.livenessProbe.successThreshold` | Success threshold for livenessProbe | `1` | +| `primary.readinessProbe.enabled` | Enable readinessProbe | `true` | +| `primary.readinessProbe.initialDelaySeconds` | Initial delay seconds for readinessProbe | `5` | +| `primary.readinessProbe.periodSeconds` | Period seconds for readinessProbe | `10` | +| `primary.readinessProbe.timeoutSeconds` | Timeout seconds for readinessProbe | `1` | +| `primary.readinessProbe.failureThreshold` | Failure threshold for readinessProbe | `3` | +| `primary.readinessProbe.successThreshold` | Success threshold for readinessProbe | `1` | +| `primary.startupProbe.enabled` | Enable startupProbe | `true` | +| `primary.startupProbe.initialDelaySeconds` | Initial delay seconds for startupProbe | `15` | +| `primary.startupProbe.periodSeconds` | Period seconds for startupProbe | `10` | +| `primary.startupProbe.timeoutSeconds` | Timeout seconds for startupProbe | `1` | +| `primary.startupProbe.failureThreshold` | Failure threshold for startupProbe | `10` | +| `primary.startupProbe.successThreshold` | Success threshold for startupProbe | `1` | +| `primary.customLivenessProbe` | Override default liveness probe for MySQL primary containers | `{}` | +| `primary.customReadinessProbe` | Override default readiness probe for MySQL primary containers | `{}` | +| `primary.customStartupProbe` | Override default startup probe for MySQL primary containers | `{}` | +| `primary.extraFlags` | MySQL primary additional command line flags | `""` | +| `primary.extraEnvVars` | Extra environment variables to be set on MySQL primary containers | `[]` | +| `primary.extraEnvVarsCM` | Name of existing ConfigMap containing extra env vars for MySQL primary containers | `""` | +| `primary.extraEnvVarsSecret` | Name of existing Secret containing extra env vars for MySQL primary containers | `""` | +| `primary.extraPorts` | Extra ports to expose | `[]` | +| `primary.persistence.enabled` | Enable persistence on MySQL primary replicas using a `PersistentVolumeClaim`. If false, use emptyDir | `true` | +| `primary.persistence.existingClaim` | Name of an existing `PersistentVolumeClaim` for MySQL primary replicas | `""` | +| `primary.persistence.subPath` | The name of a volume's sub path to mount for persistence | `""` | +| `primary.persistence.storageClass` | MySQL primary persistent volume storage Class | `""` | +| `primary.persistence.annotations` | MySQL primary persistent volume claim annotations | `{}` | +| `primary.persistence.accessModes` | MySQL primary persistent volume access Modes | `["ReadWriteOnce"]` | +| `primary.persistence.size` | MySQL primary persistent volume size | `8Gi` | +| `primary.persistence.selector` | Selector to match an existing Persistent Volume | `{}` | +| `primary.extraVolumes` | Optionally specify extra list of additional volumes to the MySQL Primary pod(s) | `[]` | +| `primary.extraVolumeMounts` | Optionally specify extra list of additional volumeMounts for the MySQL Primary container(s) | `[]` | +| `primary.initContainers` | Add additional init containers for the MySQL Primary pod(s) | `[]` | +| `primary.sidecars` | Add additional sidecar containers for the MySQL Primary pod(s) | `[]` | +| `primary.service.type` | MySQL Primary K8s service type | `ClusterIP` | +| `primary.service.ports.mysql` | MySQL Primary K8s service port | `3306` | +| `primary.service.nodePorts.mysql` | MySQL Primary K8s service node port | `""` | +| `primary.service.clusterIP` | MySQL Primary K8s service clusterIP IP | `""` | +| `primary.service.loadBalancerIP` | MySQL Primary loadBalancerIP if service type is `LoadBalancer` | `""` | +| `primary.service.externalTrafficPolicy` | Enable client source IP preservation | `Cluster` | +| `primary.service.loadBalancerSourceRanges` | Addresses that are allowed when MySQL Primary service is LoadBalancer | `[]` | +| `primary.service.extraPorts` | Extra ports to expose (normally used with the `sidecar` value) | `[]` | +| `primary.service.annotations` | Additional custom annotations for MySQL primary service | `{}` | +| `primary.service.sessionAffinity` | Session Affinity for Kubernetes service, can be "None" or "ClientIP" | `None` | +| `primary.service.sessionAffinityConfig` | Additional settings for the sessionAffinity | `{}` | +| `primary.service.headless.annotations` | Additional custom annotations for headless MySQL primary service. | `{}` | +| `primary.pdb.create` | Enable/disable a Pod Disruption Budget creation for MySQL primary pods | `false` | +| `primary.pdb.minAvailable` | Minimum number/percentage of MySQL primary pods that should remain scheduled | `1` | +| `primary.pdb.maxUnavailable` | Maximum number/percentage of MySQL primary pods that may be made unavailable | `""` | +| `primary.podLabels` | MySQL Primary pod label. If labels are same as commonLabels , this will take precedence | `{}` | + +### MySQL Secondary parameters + +| Name | Description | Value | +| ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- | ------------------- | +| `secondary.name` | Name of the secondary database (eg secondary, slave, ...) | `secondary` | +| `secondary.replicaCount` | Number of MySQL secondary replicas | `1` | +| `secondary.hostAliases` | Deployment pod host aliases | `[]` | +| `secondary.command` | Override default container command on MySQL Secondary container(s) (useful when using custom images) | `[]` | +| `secondary.args` | Override default container args on MySQL Secondary container(s) (useful when using custom images) | `[]` | +| `secondary.lifecycleHooks` | for the MySQL Secondary container(s) to automate configuration before or after startup | `{}` | +| `secondary.configuration` | Configure MySQL Secondary with a custom my.cnf file | `""` | +| `secondary.existingConfigmap` | Name of existing ConfigMap with MySQL Secondary configuration. | `""` | +| `secondary.updateStrategy.type` | Update strategy type for the MySQL secondary statefulset | `RollingUpdate` | +| `secondary.podAnnotations` | Additional pod annotations for MySQL secondary pods | `{}` | +| `secondary.podAffinityPreset` | MySQL secondary pod affinity preset. Ignored if `secondary.affinity` is set. Allowed values: `soft` or `hard` | `""` | +| `secondary.podAntiAffinityPreset` | MySQL secondary pod anti-affinity preset. Ignored if `secondary.affinity` is set. Allowed values: `soft` or `hard` | `soft` | +| `secondary.nodeAffinityPreset.type` | MySQL secondary node affinity preset type. Ignored if `secondary.affinity` is set. Allowed values: `soft` or `hard` | `""` | +| `secondary.nodeAffinityPreset.key` | MySQL secondary node label key to match Ignored if `secondary.affinity` is set. | `""` | +| `secondary.nodeAffinityPreset.values` | MySQL secondary node label values to match. Ignored if `secondary.affinity` is set. | `[]` | +| `secondary.affinity` | Affinity for MySQL secondary pods assignment | `{}` | +| `secondary.nodeSelector` | Node labels for MySQL secondary pods assignment | `{}` | +| `secondary.tolerations` | Tolerations for MySQL secondary pods assignment | `[]` | +| `secondary.priorityClassName` | MySQL secondary pods' priorityClassName | `""` | +| `secondary.runtimeClassName` | MySQL secondary pods' runtimeClassName | `""` | +| `secondary.schedulerName` | Name of the k8s scheduler (other than default) | `""` | +| `secondary.terminationGracePeriodSeconds` | In seconds, time the given to the MySQL secondary pod needs to terminate gracefully | `""` | +| `secondary.topologySpreadConstraints` | Topology Spread Constraints for pod assignment | `[]` | +| `secondary.podManagementPolicy` | podManagementPolicy to manage scaling operation of MySQL secondary pods | `""` | +| `secondary.podSecurityContext.enabled` | Enable security context for MySQL secondary pods | `true` | +| `secondary.podSecurityContext.fsGroup` | Group ID for the mounted volumes' filesystem | `1001` | +| `secondary.containerSecurityContext.enabled` | MySQL secondary container securityContext | `true` | +| `secondary.containerSecurityContext.runAsUser` | User ID for the MySQL secondary container | `1001` | +| `secondary.containerSecurityContext.runAsNonRoot` | Set MySQL secondary container's Security Context runAsNonRoot | `true` | +| `secondary.resources.limits` | The resources limits for MySQL secondary containers | `{}` | +| `secondary.resources.requests` | The requested resources for MySQL secondary containers | `{}` | +| `secondary.livenessProbe.enabled` | Enable livenessProbe | `true` | +| `secondary.livenessProbe.initialDelaySeconds` | Initial delay seconds for livenessProbe | `5` | +| `secondary.livenessProbe.periodSeconds` | Period seconds for livenessProbe | `10` | +| `secondary.livenessProbe.timeoutSeconds` | Timeout seconds for livenessProbe | `1` | +| `secondary.livenessProbe.failureThreshold` | Failure threshold for livenessProbe | `3` | +| `secondary.livenessProbe.successThreshold` | Success threshold for livenessProbe | `1` | +| `secondary.readinessProbe.enabled` | Enable readinessProbe | `true` | +| `secondary.readinessProbe.initialDelaySeconds` | Initial delay seconds for readinessProbe | `5` | +| `secondary.readinessProbe.periodSeconds` | Period seconds for readinessProbe | `10` | +| `secondary.readinessProbe.timeoutSeconds` | Timeout seconds for readinessProbe | `1` | +| `secondary.readinessProbe.failureThreshold` | Failure threshold for readinessProbe | `3` | +| `secondary.readinessProbe.successThreshold` | Success threshold for readinessProbe | `1` | +| `secondary.startupProbe.enabled` | Enable startupProbe | `true` | +| `secondary.startupProbe.initialDelaySeconds` | Initial delay seconds for startupProbe | `15` | +| `secondary.startupProbe.periodSeconds` | Period seconds for startupProbe | `10` | +| `secondary.startupProbe.timeoutSeconds` | Timeout seconds for startupProbe | `1` | +| `secondary.startupProbe.failureThreshold` | Failure threshold for startupProbe | `15` | +| `secondary.startupProbe.successThreshold` | Success threshold for startupProbe | `1` | +| `secondary.customLivenessProbe` | Override default liveness probe for MySQL secondary containers | `{}` | +| `secondary.customReadinessProbe` | Override default readiness probe for MySQL secondary containers | `{}` | +| `secondary.customStartupProbe` | Override default startup probe for MySQL secondary containers | `{}` | +| `secondary.extraFlags` | MySQL secondary additional command line flags | `""` | +| `secondary.extraEnvVars` | An array to add extra environment variables on MySQL secondary containers | `[]` | +| `secondary.extraEnvVarsCM` | Name of existing ConfigMap containing extra env vars for MySQL secondary containers | `""` | +| `secondary.extraEnvVarsSecret` | Name of existing Secret containing extra env vars for MySQL secondary containers | `""` | +| `secondary.extraPorts` | Extra ports to expose | `[]` | +| `secondary.persistence.enabled` | Enable persistence on MySQL secondary replicas using a `PersistentVolumeClaim` | `true` | +| `secondary.persistence.existingClaim` | Name of an existing `PersistentVolumeClaim` for MySQL secondary replicas | `""` | +| `secondary.persistence.subPath` | The name of a volume's sub path to mount for persistence | `""` | +| `secondary.persistence.storageClass` | MySQL secondary persistent volume storage Class | `""` | +| `secondary.persistence.annotations` | MySQL secondary persistent volume claim annotations | `{}` | +| `secondary.persistence.accessModes` | MySQL secondary persistent volume access Modes | `["ReadWriteOnce"]` | +| `secondary.persistence.size` | MySQL secondary persistent volume size | `8Gi` | +| `secondary.persistence.selector` | Selector to match an existing Persistent Volume | `{}` | +| `secondary.extraVolumes` | Optionally specify extra list of additional volumes to the MySQL secondary pod(s) | `[]` | +| `secondary.extraVolumeMounts` | Optionally specify extra list of additional volumeMounts for the MySQL secondary container(s) | `[]` | +| `secondary.initContainers` | Add additional init containers for the MySQL secondary pod(s) | `[]` | +| `secondary.sidecars` | Add additional sidecar containers for the MySQL secondary pod(s) | `[]` | +| `secondary.service.type` | MySQL secondary Kubernetes service type | `ClusterIP` | +| `secondary.service.ports.mysql` | MySQL secondary Kubernetes service port | `3306` | +| `secondary.service.nodePorts.mysql` | MySQL secondary Kubernetes service node port | `""` | +| `secondary.service.clusterIP` | MySQL secondary Kubernetes service clusterIP IP | `""` | +| `secondary.service.loadBalancerIP` | MySQL secondary loadBalancerIP if service type is `LoadBalancer` | `""` | +| `secondary.service.externalTrafficPolicy` | Enable client source IP preservation | `Cluster` | +| `secondary.service.loadBalancerSourceRanges` | Addresses that are allowed when MySQL secondary service is LoadBalancer | `[]` | +| `secondary.service.extraPorts` | Extra ports to expose (normally used with the `sidecar` value) | `[]` | +| `secondary.service.annotations` | Additional custom annotations for MySQL secondary service | `{}` | +| `secondary.service.sessionAffinity` | Session Affinity for Kubernetes service, can be "None" or "ClientIP" | `None` | +| `secondary.service.sessionAffinityConfig` | Additional settings for the sessionAffinity | `{}` | +| `secondary.service.headless.annotations` | Additional custom annotations for headless MySQL secondary service. | `{}` | +| `secondary.pdb.create` | Enable/disable a Pod Disruption Budget creation for MySQL secondary pods | `false` | +| `secondary.pdb.minAvailable` | Minimum number/percentage of MySQL secondary pods that should remain scheduled | `1` | +| `secondary.pdb.maxUnavailable` | Maximum number/percentage of MySQL secondary pods that may be made unavailable | `""` | +| `secondary.podLabels` | Additional pod labels for MySQL secondary pods | `{}` | + +### RBAC parameters + +| Name | Description | Value | +| --------------------------------------------- | -------------------------------------------------------------- | ------- | +| `serviceAccount.create` | Enable the creation of a ServiceAccount for MySQL pods | `true` | +| `serviceAccount.name` | Name of the created ServiceAccount | `""` | +| `serviceAccount.annotations` | Annotations for MySQL Service Account | `{}` | +| `serviceAccount.automountServiceAccountToken` | Automount service account token for the server service account | `true` | +| `rbac.create` | Whether to create & use RBAC resources or not | `false` | +| `rbac.rules` | Custom RBAC rules to set | `[]` | + +### Network Policy + +| Name | Description | Value | +| ------------------------------------------ | --------------------------------------------------------------------------------------------------------------- | ------- | +| `networkPolicy.enabled` | Enable creation of NetworkPolicy resources | `false` | +| `networkPolicy.allowExternal` | The Policy model to apply. | `true` | +| `networkPolicy.explicitNamespacesSelector` | A Kubernetes LabelSelector to explicitly select namespaces from which ingress traffic could be allowed to MySQL | `{}` | + +### Volume Permissions parameters + +| Name | Description | Value | +| ------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | ------------------ | +| `volumePermissions.enabled` | Enable init container that changes the owner and group of the persistent volume(s) mountpoint to `runAsUser:fsGroup` | `false` | +| `volumePermissions.image.registry` | Init container volume-permissions image registry | `docker.io` | +| `volumePermissions.image.repository` | Init container volume-permissions image repository | `bitnami/os-shell` | +| `volumePermissions.image.tag` | Init container volume-permissions image tag (immutable tags are recommended) | `11-debian-11-r2` | +| `volumePermissions.image.digest` | Init container volume-permissions image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag | `""` | +| `volumePermissions.image.pullPolicy` | Init container volume-permissions image pull policy | `IfNotPresent` | +| `volumePermissions.image.pullSecrets` | Specify docker-registry secret names as an array | `[]` | +| `volumePermissions.resources` | Init container volume-permissions resources | `{}` | + +### Metrics parameters + +| Name | Description | Value | +| ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ | ------------------------- | +| `metrics.enabled` | Start a side-car prometheus exporter | `false` | +| `metrics.image.registry` | Exporter image registry | `docker.io` | +| `metrics.image.repository` | Exporter image repository | `bitnami/mysqld-exporter` | +| `metrics.image.tag` | Exporter image tag (immutable tags are recommended) | `0.14.0-debian-11-r138` | +| `metrics.image.digest` | Exporter image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag | `""` | +| `metrics.image.pullPolicy` | Exporter image pull policy | `IfNotPresent` | +| `metrics.image.pullSecrets` | Specify docker-registry secret names as an array | `[]` | +| `metrics.containerSecurityContext.enabled` | MySQL metrics container securityContext | `true` | +| `metrics.containerSecurityContext.runAsUser` | User ID for the MySQL metrics container | `1001` | +| `metrics.containerSecurityContext.runAsNonRoot` | Set MySQL metrics container's Security Context runAsNonRoot | `true` | +| `metrics.service.type` | Kubernetes service type for MySQL Prometheus Exporter | `ClusterIP` | +| `metrics.service.clusterIP` | Kubernetes service clusterIP for MySQL Prometheus Exporter | `""` | +| `metrics.service.port` | MySQL Prometheus Exporter service port | `9104` | +| `metrics.service.annotations` | Prometheus exporter service annotations | `{}` | +| `metrics.extraArgs.primary` | Extra args to be passed to mysqld_exporter on Primary pods | `[]` | +| `metrics.extraArgs.secondary` | Extra args to be passed to mysqld_exporter on Secondary pods | `[]` | +| `metrics.resources.limits` | The resources limits for MySQL prometheus exporter containers | `{}` | +| `metrics.resources.requests` | The requested resources for MySQL prometheus exporter containers | `{}` | +| `metrics.livenessProbe.enabled` | Enable livenessProbe | `true` | +| `metrics.livenessProbe.initialDelaySeconds` | Initial delay seconds for livenessProbe | `120` | +| `metrics.livenessProbe.periodSeconds` | Period seconds for livenessProbe | `10` | +| `metrics.livenessProbe.timeoutSeconds` | Timeout seconds for livenessProbe | `1` | +| `metrics.livenessProbe.failureThreshold` | Failure threshold for livenessProbe | `3` | +| `metrics.livenessProbe.successThreshold` | Success threshold for livenessProbe | `1` | +| `metrics.readinessProbe.enabled` | Enable readinessProbe | `true` | +| `metrics.readinessProbe.initialDelaySeconds` | Initial delay seconds for readinessProbe | `30` | +| `metrics.readinessProbe.periodSeconds` | Period seconds for readinessProbe | `10` | +| `metrics.readinessProbe.timeoutSeconds` | Timeout seconds for readinessProbe | `1` | +| `metrics.readinessProbe.failureThreshold` | Failure threshold for readinessProbe | `3` | +| `metrics.readinessProbe.successThreshold` | Success threshold for readinessProbe | `1` | +| `metrics.serviceMonitor.enabled` | Create ServiceMonitor Resource for scraping metrics using PrometheusOperator | `false` | +| `metrics.serviceMonitor.namespace` | Specify the namespace in which the serviceMonitor resource will be created | `""` | +| `metrics.serviceMonitor.jobLabel` | The name of the label on the target service to use as the job name in prometheus. | `""` | +| `metrics.serviceMonitor.interval` | Specify the interval at which metrics should be scraped | `30s` | +| `metrics.serviceMonitor.scrapeTimeout` | Specify the timeout after which the scrape is ended | `""` | +| `metrics.serviceMonitor.relabelings` | RelabelConfigs to apply to samples before scraping | `[]` | +| `metrics.serviceMonitor.metricRelabelings` | MetricRelabelConfigs to apply to samples before ingestion | `[]` | +| `metrics.serviceMonitor.selector` | ServiceMonitor selector labels | `{}` | +| `metrics.serviceMonitor.honorLabels` | Specify honorLabels parameter to add the scrape endpoint | `false` | +| `metrics.serviceMonitor.labels` | Used to pass Labels that are used by the Prometheus installed in your cluster to select Service Monitors to work with | `{}` | +| `metrics.serviceMonitor.annotations` | ServiceMonitor annotations | `{}` | +| `metrics.prometheusRule.enabled` | Creates a Prometheus Operator prometheusRule (also requires `metrics.enabled` to be `true` and `metrics.prometheusRule.rules`) | `false` | +| `metrics.prometheusRule.namespace` | Namespace for the prometheusRule Resource (defaults to the Release Namespace) | `""` | +| `metrics.prometheusRule.additionalLabels` | Additional labels that can be used so prometheusRule will be discovered by Prometheus | `{}` | +| `metrics.prometheusRule.rules` | Prometheus Rule definitions | `[]` | + +The above parameters map to the env variables defined in [bitnami/mysql](https://github.com/bitnami/containers/tree/main/bitnami/mysql). For more information please refer to the [bitnami/mysql](https://github.com/bitnami/containers/tree/main/bitnami/mysql) image documentation. + +Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example, + +```console +helm install my-release \ + --set auth.rootPassword=secretpassword,auth.database=app_database \ + oci://registry-1.docker.io/bitnamicharts/mysql +``` + +The above command sets the MySQL `root` account password to `secretpassword`. Additionally it creates a database named `app_database`. + +> NOTE: Once this chart is deployed, it is not possible to change the application's access credentials, such as usernames or passwords, using Helm. To change these application credentials after deployment, delete any persistent volumes (PVs) used by the chart and re-deploy it, or use the application's built-in administrative tools if available. + +Alternatively, a YAML file that specifies the values for the parameters can be provided while installing the chart. For example, + +```console +helm install my-release -f values.yaml oci://registry-1.docker.io/bitnamicharts/mysql +``` + +> **Tip**: You can use the default [values.yaml](values.yaml) + +## Configuration and installation details + +### [Rolling VS Immutable tags](https://docs.bitnami.com/containers/how-to/understand-rolling-tags-containers/) + +It is strongly recommended to use immutable tags in a production environment. This ensures your deployment does not change automatically if the same tag is updated with a different image. + +Bitnami will release a new chart updating its containers if a new version of the main container, significant changes, or critical vulnerabilities exist. + +### Use a different MySQL version + +To modify the application version used in this chart, specify a different version of the image using the `image.tag` parameter and/or a different repository using the `image.repository` parameter. Refer to the [chart documentation for more information on these parameters and how to use them with images from a private registry](https://docs.bitnami.com/kubernetes/infrastructure/mysql/configuration/change-image-version/). + +### Customize a new MySQL instance + +The [Bitnami MySQL](https://github.com/bitnami/containers/tree/main/bitnami/mysql) image allows you to use your custom scripts to initialize a fresh instance. Custom scripts may be specified using the `initdbScripts` parameter. Alternatively, an external ConfigMap may be created with all the initialization scripts and the ConfigMap passed to the chart via the `initdbScriptsConfigMap` parameter. Note that this will override the `initdbScripts` parameter. + +The allowed extensions are `.sh`, `.sql` and `.sql.gz`. + +These scripts are treated differently depending on their extension. While `.sh` scripts are executed on all the nodes, `.sql` and `.sql.gz` scripts are only executed on the primary nodes. This is because `.sh` scripts support conditional tests to identify the type of node they are running on, while such tests are not supported in `.sql` or `sql.gz` files. + +Refer to the [chart documentation for more information and a usage example](http://docs.bitnami.com/kubernetes/infrastructure/mysql/configuration/customize-new-instance/). + +### Sidecars and Init Containers + +If you have a need for additional containers to run within the same pod as MySQL, you can do so via the `sidecars` config parameter. Simply define your container according to the Kubernetes container spec. + +```yaml +sidecars: + - name: your-image-name + image: your-image + imagePullPolicy: Always + ports: + - name: portname + containerPort: 1234 +``` + +Similarly, you can add extra init containers using the `initContainers` parameter. + +```yaml +initContainers: + - name: your-image-name + image: your-image + imagePullPolicy: Always + ports: + - name: portname + containerPort: 1234 +``` + +## Persistence + +The [Bitnami MySQL](https://github.com/bitnami/containers/tree/main/bitnami/mysql) image stores the MySQL data and configurations at the `/bitnami/mysql` path of the container. + +The chart mounts a [Persistent Volume](https://kubernetes.io/docs/concepts/storage/persistent-volumes/) volume at this location. The volume is created using dynamic volume provisioning by default. An existing PersistentVolumeClaim can also be defined for this purpose. + +If you encounter errors when working with persistent volumes, refer to our [troubleshooting guide for persistent volumes](https://docs.bitnami.com/kubernetes/faq/troubleshooting/troubleshooting-persistence-volumes/). + +## Network Policy config + +To enable network policy for MySQL, install [a networking plugin that implements the Kubernetes NetworkPolicy spec](https://kubernetes.io/docs/tasks/administer-cluster/declare-network-policy#before-you-begin), and set `networkPolicy.enabled` to `true`. + +For Kubernetes v1.5 & v1.6, you must also turn on NetworkPolicy by setting the DefaultDeny namespace annotation. Note: this will enforce policy for _all_ pods in the namespace: + +```console +kubectl annotate namespace default "net.beta.kubernetes.io/network-policy={\"ingress\":{\"isolation\":\"DefaultDeny\"}}" +``` + +With NetworkPolicy enabled, traffic will be limited to just port 3306. + +For more precise policy, set `networkPolicy.allowExternal=false`. This will only allow pods with the generated client label to connect to MySQL. +This label will be displayed in the output of a successful install. + +## Pod affinity + +This chart allows you to set your custom affinity using the `XXX.affinity` parameter(s). Find more information about Pod affinity in the [Kubernetes documentation](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity). + +As an alternative, you can use the preset configurations for pod affinity, pod anti-affinity, and node affinity available at the [bitnami/common](https://github.com/bitnami/charts/tree/main/bitnami/common#affinities) chart. To do so, set the `XXX.podAffinityPreset`, `XXX.podAntiAffinityPreset`, or `XXX.nodeAffinityPreset` parameters. + +## Troubleshooting + +Find more information about how to deal with common errors related to Bitnami's Helm charts in [this troubleshooting guide](https://docs.bitnami.com/general/how-to/troubleshoot-helm-chart-issues). + +## Upgrading + +It's necessary to set the `auth.rootPassword` parameter when upgrading for readiness/liveness probes to work properly. When you install this chart for the first time, some notes will be displayed providing the credentials you must use under the 'Administrator credentials' section. Please note down the password and run the command below to upgrade your chart: + +```console +helm upgrade my-release oci://registry-1.docker.io/bitnamicharts/mysql --set auth.rootPassword=[ROOT_PASSWORD] +``` + +| Note: you need to substitute the placeholder _[ROOT_PASSWORD]_ with the value obtained in the installation notes. + +### To 9.0.0 + +This major release renames several values in this chart and adds missing features, in order to be aligned with the rest of the assets in the Bitnami charts repository. + +Affected values: + +- `schedulerName` was renamed as `primary.schedulerName` and `secondary.schedulerName`. +- The way how passwords are handled has been refactored and value `auth.forcePassword` has been removed. Now, the password configuration will have the following priority: + 1. Search for an already existing 'Secret' resource and reuse previous password. + 2. Password provided via the values.yaml + 3. If no secret existed, and no password was provided, the bitnami/mysql chart will set a randomly generated password. +- `primary.service.port` was renamed as `primary.service.ports.mysql`. +- `secondary.service.port` was renamed as `secondary.service.ports.mysql`. +- `primary.service.nodePort` was renamed as `primary.service.nodePorts.mysql`. +- `secondary.service.nodePort` was renamed as `secondary.service.nodePorts.mysql`. +- `primary.updateStrategy` and `secondary.updateStrategy` are now interpreted as an object and not a string. +- Values `primary.rollingUpdatePartition` and `secondary.rollingUpdatePartition` have been removed. In cases were they are needed, they can be set inside `.*updateStrategy`. +- `primary.pdb.enabled` was renamed as `primary.pdb.create`. +- `secondary.pdb.enabled` was renamed as `secondary.pdb.create`. +- `metrics.serviceMonitor.additionalLabels` was renamed as `metrics.serviceMonitor.labels` +- `metrics.serviceMonitor.relabellings` was removed, previously used to configured `metricRelabelings` field. We introduced two new values: `metrics.serviceMonitor.relabelings` and `metrics.serviceMonitor.metricRelabelings` that can be used to configured the serviceMonitor homonimous field. + +### To 8.0.0 + +- Several parameters were renamed or disappeared in favor of new ones on this major version: + - The terms _master_ and _slave_ have been replaced by the terms _primary_ and _secondary_. Therefore, parameters prefixed with `master` or `slave` are now prefixed with `primary` or `secondary`, respectively. + - Credentials parameters are reorganized under the `auth` parameter. + - `replication.enabled` parameter is deprecated in favor of `architecture` parameter that accepts two values: `standalone` and `replication`. +- Chart labels were adapted to follow the [Helm charts standard labels](https://helm.sh/docs/chart_best_practices/labels/#standard-labels). +- This version also introduces `bitnami/common`, a [library chart](https://helm.sh/docs/topics/library_charts/#helm) as a dependency. More documentation about this new utility could be found [here](https://github.com/bitnami/charts/tree/main/bitnami/common#bitnami-common-library-chart). Please, make sure that you have updated the chart dependencies before executing any upgrade. + +Consequences: + +- Backwards compatibility is not guaranteed. To upgrade to `8.0.0`, install a new release of the MySQL chart, and migrate the data from your previous release. You have 2 alternatives to do so: + - Create a backup of the database, and restore it on the new release using tools such as [mysqldump](https://dev.mysql.com/doc/refman/8.0/en/mysqldump.html). + - Reuse the PVC used to hold the master data on your previous release. To do so, use the `primary.persistence.existingClaim` parameter. The following example assumes that the release name is `mysql`: + +```console +helm install mysql oci://registry-1.docker.io/bitnamicharts/mysql --set auth.rootPassword=[ROOT_PASSWORD] --set primary.persistence.existingClaim=[EXISTING_PVC] +``` + +| Note: you need to substitute the placeholder _[EXISTING_PVC]_ with the name of the PVC used on your previous release, and _[ROOT_PASSWORD]_ with the root password used in your previous release. + +### To 7.0.0 + +[On November 13, 2020, Helm v2 support formally ended](https://github.com/helm/charts#status-of-the-project). This major version is the result of the required changes applied to the Helm Chart to be able to incorporate the different features added in Helm v3 and to be consistent with the Helm project itself regarding the Helm v2 EOL. + +[Learn more about this change and related upgrade considerations](https://docs.bitnami.com/kubernetes/infrastructure/mysql/administration/upgrade-helm3/). + +### To 3.0.0 + +Backwards compatibility is not guaranteed unless you modify the labels used on the chart's deployments. +Use the workaround below to upgrade from versions previous to 3.0.0. The following example assumes that the release name is mysql: + +```console +kubectl delete statefulset mysql-master --cascade=false +kubectl delete statefulset mysql-slave --cascade=false +``` + +## License + +Copyright © 2023 VMware, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. \ No newline at end of file diff --git a/helm/ghost/charts/mysql/charts/common/.helmignore b/helm/ghost/charts/mysql/charts/common/.helmignore new file mode 100644 index 0000000..50af031 --- /dev/null +++ b/helm/ghost/charts/mysql/charts/common/.helmignore @@ -0,0 +1,22 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/helm/ghost/charts/mysql/charts/common/Chart.yaml b/helm/ghost/charts/mysql/charts/common/Chart.yaml new file mode 100644 index 0000000..191699d --- /dev/null +++ b/helm/ghost/charts/mysql/charts/common/Chart.yaml @@ -0,0 +1,23 @@ +annotations: + category: Infrastructure + licenses: Apache-2.0 +apiVersion: v2 +appVersion: 2.6.0 +description: A Library Helm Chart for grouping common logic between bitnami charts. + This chart is not deployable by itself. +home: https://bitnami.com +icon: https://bitnami.com/downloads/logos/bitnami-mark.png +keywords: +- common +- helper +- template +- function +- bitnami +maintainers: +- name: VMware, Inc. + url: https://github.com/bitnami/charts +name: common +sources: +- https://github.com/bitnami/charts +type: library +version: 2.6.0 diff --git a/helm/ghost/charts/mysql/charts/common/README.md b/helm/ghost/charts/mysql/charts/common/README.md new file mode 100644 index 0000000..b48bb7a --- /dev/null +++ b/helm/ghost/charts/mysql/charts/common/README.md @@ -0,0 +1,235 @@ +# Bitnami Common Library Chart + +A [Helm Library Chart](https://helm.sh/docs/topics/library_charts/#helm) for grouping common logic between Bitnami charts. + +## TL;DR + +```yaml +dependencies: + - name: common + version: 1.x.x + repository: oci://registry-1.docker.io/bitnamicharts +``` + +```console +helm dependency update +``` + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "common.names.fullname" . }} +data: + myvalue: "Hello World" +``` + +## Introduction + +This chart provides a common template helpers which can be used to develop new charts using [Helm](https://helm.sh) package manager. + +Bitnami charts can be used with [Kubeapps](https://kubeapps.dev/) for deployment and management of Helm Charts in clusters. + +Looking to use our applications in production? Try [VMware Application Catalog](https://bitnami.com/enterprise), the enterprise edition of Bitnami Application Catalog. + +## Prerequisites + +- Kubernetes 1.19+ +- Helm 3.2.0+ + +## Parameters + +## Special input schemas + +### ImageRoot + +```yaml +registry: + type: string + description: Docker registry where the image is located + example: docker.io + +repository: + type: string + description: Repository and image name + example: bitnami/nginx + +tag: + type: string + description: image tag + example: 1.16.1-debian-10-r63 + +pullPolicy: + type: string + description: Specify a imagePullPolicy. Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' + +pullSecrets: + type: array + items: + type: string + description: Optionally specify an array of imagePullSecrets (evaluated as templates). + +debug: + type: boolean + description: Set to true if you would like to see extra information on logs + example: false + +## An instance would be: +# registry: docker.io +# repository: bitnami/nginx +# tag: 1.16.1-debian-10-r63 +# pullPolicy: IfNotPresent +# debug: false +``` + +### Persistence + +```yaml +enabled: + type: boolean + description: Whether enable persistence. + example: true + +storageClass: + type: string + description: Ghost data Persistent Volume Storage Class, If set to "-", storageClassName: "" which disables dynamic provisioning. + example: "-" + +accessMode: + type: string + description: Access mode for the Persistent Volume Storage. + example: ReadWriteOnce + +size: + type: string + description: Size the Persistent Volume Storage. + example: 8Gi + +path: + type: string + description: Path to be persisted. + example: /bitnami + +## An instance would be: +# enabled: true +# storageClass: "-" +# accessMode: ReadWriteOnce +# size: 8Gi +# path: /bitnami +``` + +### ExistingSecret + +```yaml +name: + type: string + description: Name of the existing secret. + example: mySecret +keyMapping: + description: Mapping between the expected key name and the name of the key in the existing secret. + type: object + +## An instance would be: +# name: mySecret +# keyMapping: +# password: myPasswordKey +``` + +#### Example of use + +When we store sensitive data for a deployment in a secret, some times we want to give to users the possibility of using theirs existing secrets. + +```yaml +# templates/secret.yaml +--- +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "common.names.fullname" . }} + labels: + app: {{ include "common.names.fullname" . }} +type: Opaque +data: + password: {{ .Values.password | b64enc | quote }} + +# templates/dpl.yaml +--- +... + env: + - name: PASSWORD + valueFrom: + secretKeyRef: + name: {{ include "common.secrets.name" (dict "existingSecret" .Values.existingSecret "context" $) }} + key: {{ include "common.secrets.key" (dict "existingSecret" .Values.existingSecret "key" "password") }} +... + +# values.yaml +--- +name: mySecret +keyMapping: + password: myPasswordKey +``` + +### ValidateValue + +#### NOTES.txt + +```console +{{- $validateValueConf00 := (dict "valueKey" "path.to.value00" "secret" "secretName" "field" "password-00") -}} +{{- $validateValueConf01 := (dict "valueKey" "path.to.value01" "secret" "secretName" "field" "password-01") -}} + +{{ include "common.validations.values.multiple.empty" (dict "required" (list $validateValueConf00 $validateValueConf01) "context" $) }} +``` + +If we force those values to be empty we will see some alerts + +```console +helm install test mychart --set path.to.value00="",path.to.value01="" + 'path.to.value00' must not be empty, please add '--set path.to.value00=$PASSWORD_00' to the command. To get the current value: + + export PASSWORD_00=$(kubectl get secret --namespace default secretName -o jsonpath="{.data.password-00}" | base64 -d) + + 'path.to.value01' must not be empty, please add '--set path.to.value01=$PASSWORD_01' to the command. To get the current value: + + export PASSWORD_01=$(kubectl get secret --namespace default secretName -o jsonpath="{.data.password-01}" | base64 -d) +``` + +## Upgrading + +### To 1.0.0 + +[On November 13, 2020, Helm v2 support was formally finished](https://github.com/helm/charts#status-of-the-project), this major version is the result of the required changes applied to the Helm Chart to be able to incorporate the different features added in Helm v3 and to be consistent with the Helm project itself regarding the Helm v2 EOL. + +#### What changes were introduced in this major version? + +- Previous versions of this Helm Chart use `apiVersion: v1` (installable by both Helm 2 and 3), this Helm Chart was updated to `apiVersion: v2` (installable by Helm 3 only). [Here](https://helm.sh/docs/topics/charts/#the-apiversion-field) you can find more information about the `apiVersion` field. +- Use `type: library`. [Here](https://v3.helm.sh/docs/faq/#library-chart-support) you can find more information. +- The different fields present in the *Chart.yaml* file has been ordered alphabetically in a homogeneous way for all the Bitnami Helm Charts + +#### Considerations when upgrading to this version + +- If you want to upgrade to this version from a previous one installed with Helm v3, you shouldn't face any issues +- If you want to upgrade to this version using Helm v2, this scenario is not supported as this version doesn't support Helm v2 anymore +- If you installed the previous version with Helm v2 and wants to upgrade to this version with Helm v3, please refer to the [official Helm documentation](https://helm.sh/docs/topics/v2_v3_migration/#migration-use-cases) about migrating from Helm v2 to v3 + +#### Useful links + +- +- +- + +## License + +Copyright © 2023 VMware, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/helm/ghost/charts/mysql/charts/common/templates/_affinities.tpl b/helm/ghost/charts/mysql/charts/common/templates/_affinities.tpl new file mode 100644 index 0000000..0e57102 --- /dev/null +++ b/helm/ghost/charts/mysql/charts/common/templates/_affinities.tpl @@ -0,0 +1,111 @@ +{{/* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} + +{{/* +Return a soft nodeAffinity definition +{{ include "common.affinities.nodes.soft" (dict "key" "FOO" "values" (list "BAR" "BAZ")) -}} +*/}} +{{- define "common.affinities.nodes.soft" -}} +preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: {{ .key }} + operator: In + values: + {{- range .values }} + - {{ . | quote }} + {{- end }} + weight: 1 +{{- end -}} + +{{/* +Return a hard nodeAffinity definition +{{ include "common.affinities.nodes.hard" (dict "key" "FOO" "values" (list "BAR" "BAZ")) -}} +*/}} +{{- define "common.affinities.nodes.hard" -}} +requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: {{ .key }} + operator: In + values: + {{- range .values }} + - {{ . | quote }} + {{- end }} +{{- end -}} + +{{/* +Return a nodeAffinity definition +{{ include "common.affinities.nodes" (dict "type" "soft" "key" "FOO" "values" (list "BAR" "BAZ")) -}} +*/}} +{{- define "common.affinities.nodes" -}} + {{- if eq .type "soft" }} + {{- include "common.affinities.nodes.soft" . -}} + {{- else if eq .type "hard" }} + {{- include "common.affinities.nodes.hard" . -}} + {{- end -}} +{{- end -}} + +{{/* +Return a topologyKey definition +{{ include "common.affinities.topologyKey" (dict "topologyKey" "BAR") -}} +*/}} +{{- define "common.affinities.topologyKey" -}} +{{ .topologyKey | default "kubernetes.io/hostname" -}} +{{- end -}} + +{{/* +Return a soft podAffinity/podAntiAffinity definition +{{ include "common.affinities.pods.soft" (dict "component" "FOO" "extraMatchLabels" .Values.extraMatchLabels "topologyKey" "BAR" "context" $) -}} +*/}} +{{- define "common.affinities.pods.soft" -}} +{{- $component := default "" .component -}} +{{- $extraMatchLabels := default (dict) .extraMatchLabels -}} +preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchLabels: {{- (include "common.labels.matchLabels" .context) | nindent 10 }} + {{- if not (empty $component) }} + {{ printf "app.kubernetes.io/component: %s" $component }} + {{- end }} + {{- range $key, $value := $extraMatchLabels }} + {{ $key }}: {{ $value | quote }} + {{- end }} + topologyKey: {{ include "common.affinities.topologyKey" (dict "topologyKey" .topologyKey) }} + weight: 1 +{{- end -}} + +{{/* +Return a hard podAffinity/podAntiAffinity definition +{{ include "common.affinities.pods.hard" (dict "component" "FOO" "extraMatchLabels" .Values.extraMatchLabels "topologyKey" "BAR" "context" $) -}} +*/}} +{{- define "common.affinities.pods.hard" -}} +{{- $component := default "" .component -}} +{{- $extraMatchLabels := default (dict) .extraMatchLabels -}} +requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: {{- (include "common.labels.matchLabels" .context) | nindent 8 }} + {{- if not (empty $component) }} + {{ printf "app.kubernetes.io/component: %s" $component }} + {{- end }} + {{- range $key, $value := $extraMatchLabels }} + {{ $key }}: {{ $value | quote }} + {{- end }} + topologyKey: {{ include "common.affinities.topologyKey" (dict "topologyKey" .topologyKey) }} +{{- end -}} + +{{/* +Return a podAffinity/podAntiAffinity definition +{{ include "common.affinities.pods" (dict "type" "soft" "key" "FOO" "values" (list "BAR" "BAZ")) -}} +*/}} +{{- define "common.affinities.pods" -}} + {{- if eq .type "soft" }} + {{- include "common.affinities.pods.soft" . -}} + {{- else if eq .type "hard" }} + {{- include "common.affinities.pods.hard" . -}} + {{- end -}} +{{- end -}} diff --git a/helm/ghost/charts/mysql/charts/common/templates/_capabilities.tpl b/helm/ghost/charts/mysql/charts/common/templates/_capabilities.tpl new file mode 100644 index 0000000..c6d115f --- /dev/null +++ b/helm/ghost/charts/mysql/charts/common/templates/_capabilities.tpl @@ -0,0 +1,185 @@ +{{/* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} + +{{/* +Return the target Kubernetes version +*/}} +{{- define "common.capabilities.kubeVersion" -}} +{{- if .Values.global }} + {{- if .Values.global.kubeVersion }} + {{- .Values.global.kubeVersion -}} + {{- else }} + {{- default .Capabilities.KubeVersion.Version .Values.kubeVersion -}} + {{- end -}} +{{- else }} +{{- default .Capabilities.KubeVersion.Version .Values.kubeVersion -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for poddisruptionbudget. +*/}} +{{- define "common.capabilities.policy.apiVersion" -}} +{{- if semverCompare "<1.21-0" (include "common.capabilities.kubeVersion" .) -}} +{{- print "policy/v1beta1" -}} +{{- else -}} +{{- print "policy/v1" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for networkpolicy. +*/}} +{{- define "common.capabilities.networkPolicy.apiVersion" -}} +{{- if semverCompare "<1.7-0" (include "common.capabilities.kubeVersion" .) -}} +{{- print "extensions/v1beta1" -}} +{{- else -}} +{{- print "networking.k8s.io/v1" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for cronjob. +*/}} +{{- define "common.capabilities.cronjob.apiVersion" -}} +{{- if semverCompare "<1.21-0" (include "common.capabilities.kubeVersion" .) -}} +{{- print "batch/v1beta1" -}} +{{- else -}} +{{- print "batch/v1" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for daemonset. +*/}} +{{- define "common.capabilities.daemonset.apiVersion" -}} +{{- if semverCompare "<1.14-0" (include "common.capabilities.kubeVersion" .) -}} +{{- print "extensions/v1beta1" -}} +{{- else -}} +{{- print "apps/v1" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for deployment. +*/}} +{{- define "common.capabilities.deployment.apiVersion" -}} +{{- if semverCompare "<1.14-0" (include "common.capabilities.kubeVersion" .) -}} +{{- print "extensions/v1beta1" -}} +{{- else -}} +{{- print "apps/v1" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for statefulset. +*/}} +{{- define "common.capabilities.statefulset.apiVersion" -}} +{{- if semverCompare "<1.14-0" (include "common.capabilities.kubeVersion" .) -}} +{{- print "apps/v1beta1" -}} +{{- else -}} +{{- print "apps/v1" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for ingress. +*/}} +{{- define "common.capabilities.ingress.apiVersion" -}} +{{- if .Values.ingress -}} +{{- if .Values.ingress.apiVersion -}} +{{- .Values.ingress.apiVersion -}} +{{- else if semverCompare "<1.14-0" (include "common.capabilities.kubeVersion" .) -}} +{{- print "extensions/v1beta1" -}} +{{- else if semverCompare "<1.19-0" (include "common.capabilities.kubeVersion" .) -}} +{{- print "networking.k8s.io/v1beta1" -}} +{{- else -}} +{{- print "networking.k8s.io/v1" -}} +{{- end }} +{{- else if semverCompare "<1.14-0" (include "common.capabilities.kubeVersion" .) -}} +{{- print "extensions/v1beta1" -}} +{{- else if semverCompare "<1.19-0" (include "common.capabilities.kubeVersion" .) -}} +{{- print "networking.k8s.io/v1beta1" -}} +{{- else -}} +{{- print "networking.k8s.io/v1" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for RBAC resources. +*/}} +{{- define "common.capabilities.rbac.apiVersion" -}} +{{- if semverCompare "<1.17-0" (include "common.capabilities.kubeVersion" .) -}} +{{- print "rbac.authorization.k8s.io/v1beta1" -}} +{{- else -}} +{{- print "rbac.authorization.k8s.io/v1" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for CRDs. +*/}} +{{- define "common.capabilities.crd.apiVersion" -}} +{{- if semverCompare "<1.19-0" (include "common.capabilities.kubeVersion" .) -}} +{{- print "apiextensions.k8s.io/v1beta1" -}} +{{- else -}} +{{- print "apiextensions.k8s.io/v1" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for APIService. +*/}} +{{- define "common.capabilities.apiService.apiVersion" -}} +{{- if semverCompare "<1.10-0" (include "common.capabilities.kubeVersion" .) -}} +{{- print "apiregistration.k8s.io/v1beta1" -}} +{{- else -}} +{{- print "apiregistration.k8s.io/v1" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for Horizontal Pod Autoscaler. +*/}} +{{- define "common.capabilities.hpa.apiVersion" -}} +{{- if semverCompare "<1.23-0" (include "common.capabilities.kubeVersion" .context) -}} +{{- if .beta2 -}} +{{- print "autoscaling/v2beta2" -}} +{{- else -}} +{{- print "autoscaling/v2beta1" -}} +{{- end -}} +{{- else -}} +{{- print "autoscaling/v2" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for Vertical Pod Autoscaler. +*/}} +{{- define "common.capabilities.vpa.apiVersion" -}} +{{- if semverCompare "<1.23-0" (include "common.capabilities.kubeVersion" .context) -}} +{{- if .beta2 -}} +{{- print "autoscaling/v2beta2" -}} +{{- else -}} +{{- print "autoscaling/v2beta1" -}} +{{- end -}} +{{- else -}} +{{- print "autoscaling/v2" -}} +{{- end -}} +{{- end -}} + +{{/* +Returns true if the used Helm version is 3.3+. +A way to check the used Helm version was not introduced until version 3.3.0 with .Capabilities.HelmVersion, which contains an additional "{}}" structure. +This check is introduced as a regexMatch instead of {{ if .Capabilities.HelmVersion }} because checking for the key HelmVersion in <3.3 results in a "interface not found" error. +**To be removed when the catalog's minimun Helm version is 3.3** +*/}} +{{- define "common.capabilities.supportsHelmVersion" -}} +{{- if regexMatch "{(v[0-9])*[^}]*}}$" (.Capabilities | toString ) }} + {{- true -}} +{{- end -}} +{{- end -}} diff --git a/helm/ghost/charts/mysql/charts/common/templates/_errors.tpl b/helm/ghost/charts/mysql/charts/common/templates/_errors.tpl new file mode 100644 index 0000000..07ded6f --- /dev/null +++ b/helm/ghost/charts/mysql/charts/common/templates/_errors.tpl @@ -0,0 +1,28 @@ +{{/* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} +{{/* +Through error when upgrading using empty passwords values that must not be empty. + +Usage: +{{- $validationError00 := include "common.validations.values.single.empty" (dict "valueKey" "path.to.password00" "secret" "secretName" "field" "password-00") -}} +{{- $validationError01 := include "common.validations.values.single.empty" (dict "valueKey" "path.to.password01" "secret" "secretName" "field" "password-01") -}} +{{ include "common.errors.upgrade.passwords.empty" (dict "validationErrors" (list $validationError00 $validationError01) "context" $) }} + +Required password params: + - validationErrors - String - Required. List of validation strings to be return, if it is empty it won't throw error. + - context - Context - Required. Parent context. +*/}} +{{- define "common.errors.upgrade.passwords.empty" -}} + {{- $validationErrors := join "" .validationErrors -}} + {{- if and $validationErrors .context.Release.IsUpgrade -}} + {{- $errorString := "\nPASSWORDS ERROR: You must provide your current passwords when upgrading the release." -}} + {{- $errorString = print $errorString "\n Note that even after reinstallation, old credentials may be needed as they may be kept in persistent volume claims." -}} + {{- $errorString = print $errorString "\n Further information can be obtained at https://docs.bitnami.com/general/how-to/troubleshoot-helm-chart-issues/#credential-errors-while-upgrading-chart-releases" -}} + {{- $errorString = print $errorString "\n%s" -}} + {{- printf $errorString $validationErrors | fail -}} + {{- end -}} +{{- end -}} diff --git a/helm/ghost/charts/mysql/charts/common/templates/_images.tpl b/helm/ghost/charts/mysql/charts/common/templates/_images.tpl new file mode 100644 index 0000000..2181f32 --- /dev/null +++ b/helm/ghost/charts/mysql/charts/common/templates/_images.tpl @@ -0,0 +1,85 @@ +{{/* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} +{{/* +Return the proper image name +{{ include "common.images.image" ( dict "imageRoot" .Values.path.to.the.image "global" .Values.global ) }} +*/}} +{{- define "common.images.image" -}} +{{- $registryName := .imageRoot.registry -}} +{{- $repositoryName := .imageRoot.repository -}} +{{- $separator := ":" -}} +{{- $termination := .imageRoot.tag | toString -}} +{{- if .global }} + {{- if .global.imageRegistry }} + {{- $registryName = .global.imageRegistry -}} + {{- end -}} +{{- end -}} +{{- if .imageRoot.digest }} + {{- $separator = "@" -}} + {{- $termination = .imageRoot.digest | toString -}} +{{- end -}} +{{- if $registryName }} + {{- printf "%s/%s%s%s" $registryName $repositoryName $separator $termination -}} +{{- else -}} + {{- printf "%s%s%s" $repositoryName $separator $termination -}} +{{- end -}} +{{- end -}} + +{{/* +Return the proper Docker Image Registry Secret Names (deprecated: use common.images.renderPullSecrets instead) +{{ include "common.images.pullSecrets" ( dict "images" (list .Values.path.to.the.image1, .Values.path.to.the.image2) "global" .Values.global) }} +*/}} +{{- define "common.images.pullSecrets" -}} + {{- $pullSecrets := list }} + + {{- if .global }} + {{- range .global.imagePullSecrets -}} + {{- $pullSecrets = append $pullSecrets . -}} + {{- end -}} + {{- end -}} + + {{- range .images -}} + {{- range .pullSecrets -}} + {{- $pullSecrets = append $pullSecrets . -}} + {{- end -}} + {{- end -}} + + {{- if (not (empty $pullSecrets)) }} +imagePullSecrets: + {{- range $pullSecrets | uniq }} + - name: {{ . }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +Return the proper Docker Image Registry Secret Names evaluating values as templates +{{ include "common.images.renderPullSecrets" ( dict "images" (list .Values.path.to.the.image1, .Values.path.to.the.image2) "context" $) }} +*/}} +{{- define "common.images.renderPullSecrets" -}} + {{- $pullSecrets := list }} + {{- $context := .context }} + + {{- if $context.Values.global }} + {{- range $context.Values.global.imagePullSecrets -}} + {{- $pullSecrets = append $pullSecrets (include "common.tplvalues.render" (dict "value" . "context" $context)) -}} + {{- end -}} + {{- end -}} + + {{- range .images -}} + {{- range .pullSecrets -}} + {{- $pullSecrets = append $pullSecrets (include "common.tplvalues.render" (dict "value" . "context" $context)) -}} + {{- end -}} + {{- end -}} + + {{- if (not (empty $pullSecrets)) }} +imagePullSecrets: + {{- range $pullSecrets | uniq }} + - name: {{ . }} + {{- end }} + {{- end }} +{{- end -}} diff --git a/helm/ghost/charts/mysql/charts/common/templates/_ingress.tpl b/helm/ghost/charts/mysql/charts/common/templates/_ingress.tpl new file mode 100644 index 0000000..efa5b85 --- /dev/null +++ b/helm/ghost/charts/mysql/charts/common/templates/_ingress.tpl @@ -0,0 +1,73 @@ +{{/* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} + +{{/* +Generate backend entry that is compatible with all Kubernetes API versions. + +Usage: +{{ include "common.ingress.backend" (dict "serviceName" "backendName" "servicePort" "backendPort" "context" $) }} + +Params: + - serviceName - String. Name of an existing service backend + - servicePort - String/Int. Port name (or number) of the service. It will be translated to different yaml depending if it is a string or an integer. + - context - Dict - Required. The context for the template evaluation. +*/}} +{{- define "common.ingress.backend" -}} +{{- $apiVersion := (include "common.capabilities.ingress.apiVersion" .context) -}} +{{- if or (eq $apiVersion "extensions/v1beta1") (eq $apiVersion "networking.k8s.io/v1beta1") -}} +serviceName: {{ .serviceName }} +servicePort: {{ .servicePort }} +{{- else -}} +service: + name: {{ .serviceName }} + port: + {{- if typeIs "string" .servicePort }} + name: {{ .servicePort }} + {{- else if or (typeIs "int" .servicePort) (typeIs "float64" .servicePort) }} + number: {{ .servicePort | int }} + {{- end }} +{{- end -}} +{{- end -}} + +{{/* +Print "true" if the API pathType field is supported +Usage: +{{ include "common.ingress.supportsPathType" . }} +*/}} +{{- define "common.ingress.supportsPathType" -}} +{{- if (semverCompare "<1.18-0" (include "common.capabilities.kubeVersion" .)) -}} +{{- print "false" -}} +{{- else -}} +{{- print "true" -}} +{{- end -}} +{{- end -}} + +{{/* +Returns true if the ingressClassname field is supported +Usage: +{{ include "common.ingress.supportsIngressClassname" . }} +*/}} +{{- define "common.ingress.supportsIngressClassname" -}} +{{- if semverCompare "<1.18-0" (include "common.capabilities.kubeVersion" .) -}} +{{- print "false" -}} +{{- else -}} +{{- print "true" -}} +{{- end -}} +{{- end -}} + +{{/* +Return true if cert-manager required annotations for TLS signed +certificates are set in the Ingress annotations +Ref: https://cert-manager.io/docs/usage/ingress/#supported-annotations +Usage: +{{ include "common.ingress.certManagerRequest" ( dict "annotations" .Values.path.to.the.ingress.annotations ) }} +*/}} +{{- define "common.ingress.certManagerRequest" -}} +{{ if or (hasKey .annotations "cert-manager.io/cluster-issuer") (hasKey .annotations "cert-manager.io/issuer") (hasKey .annotations "kubernetes.io/tls-acme") }} + {{- true -}} +{{- end -}} +{{- end -}} diff --git a/helm/ghost/charts/mysql/charts/common/templates/_labels.tpl b/helm/ghost/charts/mysql/charts/common/templates/_labels.tpl new file mode 100644 index 0000000..a1d7a95 --- /dev/null +++ b/helm/ghost/charts/mysql/charts/common/templates/_labels.tpl @@ -0,0 +1,23 @@ +{{/* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} +{{/* +Kubernetes standard labels +*/}} +{{- define "common.labels.standard" -}} +app.kubernetes.io/name: {{ include "common.names.name" . }} +helm.sh/chart: {{ include "common.names.chart" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end -}} + +{{/* +Labels to use on deploy.spec.selector.matchLabels and svc.spec.selector +*/}} +{{- define "common.labels.matchLabels" -}} +app.kubernetes.io/name: {{ include "common.names.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end -}} diff --git a/helm/ghost/charts/mysql/charts/common/templates/_names.tpl b/helm/ghost/charts/mysql/charts/common/templates/_names.tpl new file mode 100644 index 0000000..a222924 --- /dev/null +++ b/helm/ghost/charts/mysql/charts/common/templates/_names.tpl @@ -0,0 +1,71 @@ +{{/* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "common.names.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "common.names.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "common.names.fullname" -}} +{{- if .Values.fullnameOverride -}} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Create a default fully qualified dependency name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +Usage: +{{ include "common.names.dependency.fullname" (dict "chartName" "dependency-chart-name" "chartValues" .Values.dependency-chart "context" $) }} +*/}} +{{- define "common.names.dependency.fullname" -}} +{{- if .chartValues.fullnameOverride -}} +{{- .chartValues.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .chartName .chartValues.nameOverride -}} +{{- if contains $name .context.Release.Name -}} +{{- .context.Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .context.Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Allow the release namespace to be overridden for multi-namespace deployments in combined charts. +*/}} +{{- define "common.names.namespace" -}} +{{- default .Release.Namespace .Values.namespaceOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create a fully qualified app name adding the installation's namespace. +*/}} +{{- define "common.names.fullname.namespace" -}} +{{- printf "%s-%s" (include "common.names.fullname" .) (include "common.names.namespace" .) | trunc 63 | trimSuffix "-" -}} +{{- end -}} diff --git a/helm/ghost/charts/mysql/charts/common/templates/_secrets.tpl b/helm/ghost/charts/mysql/charts/common/templates/_secrets.tpl new file mode 100644 index 0000000..a193c46 --- /dev/null +++ b/helm/ghost/charts/mysql/charts/common/templates/_secrets.tpl @@ -0,0 +1,172 @@ +{{/* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} +{{/* +Generate secret name. + +Usage: +{{ include "common.secrets.name" (dict "existingSecret" .Values.path.to.the.existingSecret "defaultNameSuffix" "mySuffix" "context" $) }} + +Params: + - existingSecret - ExistingSecret/String - Optional. The path to the existing secrets in the values.yaml given by the user + to be used instead of the default one. Allows for it to be of type String (just the secret name) for backwards compatibility. + +info: https://github.com/bitnami/charts/tree/main/bitnami/common#existingsecret + - defaultNameSuffix - String - Optional. It is used only if we have several secrets in the same deployment. + - context - Dict - Required. The context for the template evaluation. +*/}} +{{- define "common.secrets.name" -}} +{{- $name := (include "common.names.fullname" .context) -}} + +{{- if .defaultNameSuffix -}} +{{- $name = printf "%s-%s" $name .defaultNameSuffix | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{- with .existingSecret -}} +{{- if not (typeIs "string" .) -}} +{{- with .name -}} +{{- $name = . -}} +{{- end -}} +{{- else -}} +{{- $name = . -}} +{{- end -}} +{{- end -}} + +{{- printf "%s" $name -}} +{{- end -}} + +{{/* +Generate secret key. + +Usage: +{{ include "common.secrets.key" (dict "existingSecret" .Values.path.to.the.existingSecret "key" "keyName") }} + +Params: + - existingSecret - ExistingSecret/String - Optional. The path to the existing secrets in the values.yaml given by the user + to be used instead of the default one. Allows for it to be of type String (just the secret name) for backwards compatibility. + +info: https://github.com/bitnami/charts/tree/main/bitnami/common#existingsecret + - key - String - Required. Name of the key in the secret. +*/}} +{{- define "common.secrets.key" -}} +{{- $key := .key -}} + +{{- if .existingSecret -}} + {{- if not (typeIs "string" .existingSecret) -}} + {{- if .existingSecret.keyMapping -}} + {{- $key = index .existingSecret.keyMapping $.key -}} + {{- end -}} + {{- end }} +{{- end -}} + +{{- printf "%s" $key -}} +{{- end -}} + +{{/* +Generate secret password or retrieve one if already created. + +Usage: +{{ include "common.secrets.passwords.manage" (dict "secret" "secret-name" "key" "keyName" "providedValues" (list "path.to.password1" "path.to.password2") "length" 10 "strong" false "chartName" "chartName" "context" $) }} + +Params: + - secret - String - Required - Name of the 'Secret' resource where the password is stored. + - key - String - Required - Name of the key in the secret. + - providedValues - List - Required - The path to the validating value in the values.yaml, e.g: "mysql.password". Will pick first parameter with a defined value. + - length - int - Optional - Length of the generated random password. + - strong - Boolean - Optional - Whether to add symbols to the generated random password. + - chartName - String - Optional - Name of the chart used when said chart is deployed as a subchart. + - context - Context - Required - Parent context. + - failOnNew - Boolean - Optional - Default to true. If set to false, skip errors adding new keys to existing secrets. +The order in which this function returns a secret password: + 1. Already existing 'Secret' resource + (If a 'Secret' resource is found under the name provided to the 'secret' parameter to this function and that 'Secret' resource contains a key with the name passed as the 'key' parameter to this function then the value of this existing secret password will be returned) + 2. Password provided via the values.yaml + (If one of the keys passed to the 'providedValues' parameter to this function is a valid path to a key in the values.yaml and has a value, the value of the first key with a value will be returned) + 3. Randomly generated secret password + (A new random secret password with the length specified in the 'length' parameter will be generated and returned) + +*/}} +{{- define "common.secrets.passwords.manage" -}} + +{{- $password := "" }} +{{- $subchart := "" }} +{{- $failOnNew := default true .failOnNew }} +{{- $chartName := default "" .chartName }} +{{- $passwordLength := default 10 .length }} +{{- $providedPasswordKey := include "common.utils.getKeyFromList" (dict "keys" .providedValues "context" $.context) }} +{{- $providedPasswordValue := include "common.utils.getValueFromKey" (dict "key" $providedPasswordKey "context" $.context) }} +{{- $secretData := (lookup "v1" "Secret" (include "common.names.namespace" .context) .secret).data }} +{{- if $secretData }} + {{- if hasKey $secretData .key }} + {{- $password = index $secretData .key | quote }} + {{- else if $failOnNew }} + {{- printf "\nPASSWORDS ERROR: The secret \"%s\" does not contain the key \"%s\"\n" .secret .key | fail -}} + {{- end -}} +{{- else if $providedPasswordValue }} + {{- $password = $providedPasswordValue | toString | b64enc | quote }} +{{- else }} + + {{- if .context.Values.enabled }} + {{- $subchart = $chartName }} + {{- end -}} + + {{- $requiredPassword := dict "valueKey" $providedPasswordKey "secret" .secret "field" .key "subchart" $subchart "context" $.context -}} + {{- $requiredPasswordError := include "common.validations.values.single.empty" $requiredPassword -}} + {{- $passwordValidationErrors := list $requiredPasswordError -}} + {{- include "common.errors.upgrade.passwords.empty" (dict "validationErrors" $passwordValidationErrors "context" $.context) -}} + + {{- if .strong }} + {{- $subStr := list (lower (randAlpha 1)) (randNumeric 1) (upper (randAlpha 1)) | join "_" }} + {{- $password = randAscii $passwordLength }} + {{- $password = regexReplaceAllLiteral "\\W" $password "@" | substr 5 $passwordLength }} + {{- $password = printf "%s%s" $subStr $password | toString | shuffle | b64enc | quote }} + {{- else }} + {{- $password = randAlphaNum $passwordLength | b64enc | quote }} + {{- end }} +{{- end -}} +{{- printf "%s" $password -}} +{{- end -}} + +{{/* +Reuses the value from an existing secret, otherwise sets its value to a default value. + +Usage: +{{ include "common.secrets.lookup" (dict "secret" "secret-name" "key" "keyName" "defaultValue" .Values.myValue "context" $) }} + +Params: + - secret - String - Required - Name of the 'Secret' resource where the password is stored. + - key - String - Required - Name of the key in the secret. + - defaultValue - String - Required - The path to the validating value in the values.yaml, e.g: "mysql.password". Will pick first parameter with a defined value. + - context - Context - Required - Parent context. + +*/}} +{{- define "common.secrets.lookup" -}} +{{- $value := "" -}} +{{- $secretData := (lookup "v1" "Secret" (include "common.names.namespace" .context) .secret).data -}} +{{- if and $secretData (hasKey $secretData .key) -}} + {{- $value = index $secretData .key -}} +{{- else if .defaultValue -}} + {{- $value = .defaultValue | toString | b64enc -}} +{{- end -}} +{{- if $value -}} +{{- printf "%s" $value -}} +{{- end -}} +{{- end -}} + +{{/* +Returns whether a previous generated secret already exists + +Usage: +{{ include "common.secrets.exists" (dict "secret" "secret-name" "context" $) }} + +Params: + - secret - String - Required - Name of the 'Secret' resource where the password is stored. + - context - Context - Required - Parent context. +*/}} +{{- define "common.secrets.exists" -}} +{{- $secret := (lookup "v1" "Secret" (include "common.names.namespace" .context) .secret) }} +{{- if $secret }} + {{- true -}} +{{- end -}} +{{- end -}} diff --git a/helm/ghost/charts/mysql/charts/common/templates/_storage.tpl b/helm/ghost/charts/mysql/charts/common/templates/_storage.tpl new file mode 100644 index 0000000..16405a0 --- /dev/null +++ b/helm/ghost/charts/mysql/charts/common/templates/_storage.tpl @@ -0,0 +1,28 @@ +{{/* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} +{{/* +Return the proper Storage Class +{{ include "common.storage.class" ( dict "persistence" .Values.path.to.the.persistence "global" $) }} +*/}} +{{- define "common.storage.class" -}} + +{{- $storageClass := .persistence.storageClass -}} +{{- if .global -}} + {{- if .global.storageClass -}} + {{- $storageClass = .global.storageClass -}} + {{- end -}} +{{- end -}} + +{{- if $storageClass -}} + {{- if (eq "-" $storageClass) -}} + {{- printf "storageClassName: \"\"" -}} + {{- else }} + {{- printf "storageClassName: %s" $storageClass -}} + {{- end -}} +{{- end -}} + +{{- end -}} diff --git a/helm/ghost/charts/mysql/charts/common/templates/_tplvalues.tpl b/helm/ghost/charts/mysql/charts/common/templates/_tplvalues.tpl new file mode 100644 index 0000000..dc15f7f --- /dev/null +++ b/helm/ghost/charts/mysql/charts/common/templates/_tplvalues.tpl @@ -0,0 +1,27 @@ +{{/* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} +{{/* +Renders a value that contains template perhaps with scope if the scope is present. +Usage: +{{ include "common.tplvalues.render" ( dict "value" .Values.path.to.the.Value "context" $ ) }} +{{ include "common.tplvalues.render" ( dict "value" .Values.path.to.the.Value "context" $ "scope" $app ) }} +*/}} +{{- define "common.tplvalues.render" -}} +{{- if .scope }} + {{- if typeIs "string" .value }} + {{- tpl (cat "{{- with $.RelativeScope -}}" .value "{{- end }}") (merge (dict "RelativeScope" .scope) .context) }} + {{- else }} + {{- tpl (cat "{{- with $.RelativeScope -}}" (.value | toYaml) "{{- end }}") (merge (dict "RelativeScope" .scope) .context) }} + {{- end }} +{{- else }} + {{- if typeIs "string" .value }} + {{- tpl .value .context }} + {{- else }} + {{- tpl (.value | toYaml) .context }} + {{- end }} +{{- end -}} +{{- end -}} diff --git a/helm/ghost/charts/mysql/charts/common/templates/_utils.tpl b/helm/ghost/charts/mysql/charts/common/templates/_utils.tpl new file mode 100644 index 0000000..c87040c --- /dev/null +++ b/helm/ghost/charts/mysql/charts/common/templates/_utils.tpl @@ -0,0 +1,67 @@ +{{/* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} +{{/* +Print instructions to get a secret value. +Usage: +{{ include "common.utils.secret.getvalue" (dict "secret" "secret-name" "field" "secret-value-field" "context" $) }} +*/}} +{{- define "common.utils.secret.getvalue" -}} +{{- $varname := include "common.utils.fieldToEnvVar" . -}} +export {{ $varname }}=$(kubectl get secret --namespace {{ include "common.names.namespace" .context | quote }} {{ .secret }} -o jsonpath="{.data.{{ .field }}}" | base64 -d) +{{- end -}} + +{{/* +Build env var name given a field +Usage: +{{ include "common.utils.fieldToEnvVar" dict "field" "my-password" }} +*/}} +{{- define "common.utils.fieldToEnvVar" -}} + {{- $fieldNameSplit := splitList "-" .field -}} + {{- $upperCaseFieldNameSplit := list -}} + + {{- range $fieldNameSplit -}} + {{- $upperCaseFieldNameSplit = append $upperCaseFieldNameSplit ( upper . ) -}} + {{- end -}} + + {{ join "_" $upperCaseFieldNameSplit }} +{{- end -}} + +{{/* +Gets a value from .Values given +Usage: +{{ include "common.utils.getValueFromKey" (dict "key" "path.to.key" "context" $) }} +*/}} +{{- define "common.utils.getValueFromKey" -}} +{{- $splitKey := splitList "." .key -}} +{{- $value := "" -}} +{{- $latestObj := $.context.Values -}} +{{- range $splitKey -}} + {{- if not $latestObj -}} + {{- printf "please review the entire path of '%s' exists in values" $.key | fail -}} + {{- end -}} + {{- $value = ( index $latestObj . ) -}} + {{- $latestObj = $value -}} +{{- end -}} +{{- printf "%v" (default "" $value) -}} +{{- end -}} + +{{/* +Returns first .Values key with a defined value or first of the list if all non-defined +Usage: +{{ include "common.utils.getKeyFromList" (dict "keys" (list "path.to.key1" "path.to.key2") "context" $) }} +*/}} +{{- define "common.utils.getKeyFromList" -}} +{{- $key := first .keys -}} +{{- $reverseKeys := reverse .keys }} +{{- range $reverseKeys }} + {{- $value := include "common.utils.getValueFromKey" (dict "key" . "context" $.context ) }} + {{- if $value -}} + {{- $key = . }} + {{- end -}} +{{- end -}} +{{- printf "%s" $key -}} +{{- end -}} diff --git a/helm/ghost/charts/mysql/charts/common/templates/_warnings.tpl b/helm/ghost/charts/mysql/charts/common/templates/_warnings.tpl new file mode 100644 index 0000000..66dffc1 --- /dev/null +++ b/helm/ghost/charts/mysql/charts/common/templates/_warnings.tpl @@ -0,0 +1,19 @@ +{{/* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} +{{/* +Warning about using rolling tag. +Usage: +{{ include "common.warnings.rollingTag" .Values.path.to.the.imageRoot }} +*/}} +{{- define "common.warnings.rollingTag" -}} + +{{- if and (contains "bitnami/" .repository) (not (.tag | toString | regexFind "-r\\d+$|sha256:")) }} +WARNING: Rolling tag detected ({{ .repository }}:{{ .tag }}), please note that it is strongly recommended to avoid using rolling tags in a production environment. ++info https://docs.bitnami.com/containers/how-to/understand-rolling-tags-containers/ +{{- end }} + +{{- end -}} diff --git a/helm/ghost/charts/mysql/charts/common/templates/validations/_cassandra.tpl b/helm/ghost/charts/mysql/charts/common/templates/validations/_cassandra.tpl new file mode 100644 index 0000000..eda9aad --- /dev/null +++ b/helm/ghost/charts/mysql/charts/common/templates/validations/_cassandra.tpl @@ -0,0 +1,77 @@ +{{/* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} +{{/* +Validate Cassandra required passwords are not empty. + +Usage: +{{ include "common.validations.values.cassandra.passwords" (dict "secret" "secretName" "subchart" false "context" $) }} +Params: + - secret - String - Required. Name of the secret where Cassandra values are stored, e.g: "cassandra-passwords-secret" + - subchart - Boolean - Optional. Whether Cassandra is used as subchart or not. Default: false +*/}} +{{- define "common.validations.values.cassandra.passwords" -}} + {{- $existingSecret := include "common.cassandra.values.existingSecret" . -}} + {{- $enabled := include "common.cassandra.values.enabled" . -}} + {{- $dbUserPrefix := include "common.cassandra.values.key.dbUser" . -}} + {{- $valueKeyPassword := printf "%s.password" $dbUserPrefix -}} + + {{- if and (or (not $existingSecret) (eq $existingSecret "\"\"")) (eq $enabled "true") -}} + {{- $requiredPasswords := list -}} + + {{- $requiredPassword := dict "valueKey" $valueKeyPassword "secret" .secret "field" "cassandra-password" -}} + {{- $requiredPasswords = append $requiredPasswords $requiredPassword -}} + + {{- include "common.validations.values.multiple.empty" (dict "required" $requiredPasswords "context" .context) -}} + + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for existingSecret. + +Usage: +{{ include "common.cassandra.values.existingSecret" (dict "context" $) }} +Params: + - subchart - Boolean - Optional. Whether Cassandra is used as subchart or not. Default: false +*/}} +{{- define "common.cassandra.values.existingSecret" -}} + {{- if .subchart -}} + {{- .context.Values.cassandra.dbUser.existingSecret | quote -}} + {{- else -}} + {{- .context.Values.dbUser.existingSecret | quote -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for enabled cassandra. + +Usage: +{{ include "common.cassandra.values.enabled" (dict "context" $) }} +*/}} +{{- define "common.cassandra.values.enabled" -}} + {{- if .subchart -}} + {{- printf "%v" .context.Values.cassandra.enabled -}} + {{- else -}} + {{- printf "%v" (not .context.Values.enabled) -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for the key dbUser + +Usage: +{{ include "common.cassandra.values.key.dbUser" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether Cassandra is used as subchart or not. Default: false +*/}} +{{- define "common.cassandra.values.key.dbUser" -}} + {{- if .subchart -}} + cassandra.dbUser + {{- else -}} + dbUser + {{- end -}} +{{- end -}} diff --git a/helm/ghost/charts/mysql/charts/common/templates/validations/_mariadb.tpl b/helm/ghost/charts/mysql/charts/common/templates/validations/_mariadb.tpl new file mode 100644 index 0000000..17d83a2 --- /dev/null +++ b/helm/ghost/charts/mysql/charts/common/templates/validations/_mariadb.tpl @@ -0,0 +1,108 @@ +{{/* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} +{{/* +Validate MariaDB required passwords are not empty. + +Usage: +{{ include "common.validations.values.mariadb.passwords" (dict "secret" "secretName" "subchart" false "context" $) }} +Params: + - secret - String - Required. Name of the secret where MariaDB values are stored, e.g: "mysql-passwords-secret" + - subchart - Boolean - Optional. Whether MariaDB is used as subchart or not. Default: false +*/}} +{{- define "common.validations.values.mariadb.passwords" -}} + {{- $existingSecret := include "common.mariadb.values.auth.existingSecret" . -}} + {{- $enabled := include "common.mariadb.values.enabled" . -}} + {{- $architecture := include "common.mariadb.values.architecture" . -}} + {{- $authPrefix := include "common.mariadb.values.key.auth" . -}} + {{- $valueKeyRootPassword := printf "%s.rootPassword" $authPrefix -}} + {{- $valueKeyUsername := printf "%s.username" $authPrefix -}} + {{- $valueKeyPassword := printf "%s.password" $authPrefix -}} + {{- $valueKeyReplicationPassword := printf "%s.replicationPassword" $authPrefix -}} + + {{- if and (or (not $existingSecret) (eq $existingSecret "\"\"")) (eq $enabled "true") -}} + {{- $requiredPasswords := list -}} + + {{- $requiredRootPassword := dict "valueKey" $valueKeyRootPassword "secret" .secret "field" "mariadb-root-password" -}} + {{- $requiredPasswords = append $requiredPasswords $requiredRootPassword -}} + + {{- $valueUsername := include "common.utils.getValueFromKey" (dict "key" $valueKeyUsername "context" .context) }} + {{- if not (empty $valueUsername) -}} + {{- $requiredPassword := dict "valueKey" $valueKeyPassword "secret" .secret "field" "mariadb-password" -}} + {{- $requiredPasswords = append $requiredPasswords $requiredPassword -}} + {{- end -}} + + {{- if (eq $architecture "replication") -}} + {{- $requiredReplicationPassword := dict "valueKey" $valueKeyReplicationPassword "secret" .secret "field" "mariadb-replication-password" -}} + {{- $requiredPasswords = append $requiredPasswords $requiredReplicationPassword -}} + {{- end -}} + + {{- include "common.validations.values.multiple.empty" (dict "required" $requiredPasswords "context" .context) -}} + + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for existingSecret. + +Usage: +{{ include "common.mariadb.values.auth.existingSecret" (dict "context" $) }} +Params: + - subchart - Boolean - Optional. Whether MariaDB is used as subchart or not. Default: false +*/}} +{{- define "common.mariadb.values.auth.existingSecret" -}} + {{- if .subchart -}} + {{- .context.Values.mariadb.auth.existingSecret | quote -}} + {{- else -}} + {{- .context.Values.auth.existingSecret | quote -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for enabled mariadb. + +Usage: +{{ include "common.mariadb.values.enabled" (dict "context" $) }} +*/}} +{{- define "common.mariadb.values.enabled" -}} + {{- if .subchart -}} + {{- printf "%v" .context.Values.mariadb.enabled -}} + {{- else -}} + {{- printf "%v" (not .context.Values.enabled) -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for architecture + +Usage: +{{ include "common.mariadb.values.architecture" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether MariaDB is used as subchart or not. Default: false +*/}} +{{- define "common.mariadb.values.architecture" -}} + {{- if .subchart -}} + {{- .context.Values.mariadb.architecture -}} + {{- else -}} + {{- .context.Values.architecture -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for the key auth + +Usage: +{{ include "common.mariadb.values.key.auth" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether MariaDB is used as subchart or not. Default: false +*/}} +{{- define "common.mariadb.values.key.auth" -}} + {{- if .subchart -}} + mariadb.auth + {{- else -}} + auth + {{- end -}} +{{- end -}} diff --git a/helm/ghost/charts/mysql/charts/common/templates/validations/_mongodb.tpl b/helm/ghost/charts/mysql/charts/common/templates/validations/_mongodb.tpl new file mode 100644 index 0000000..bbb445b --- /dev/null +++ b/helm/ghost/charts/mysql/charts/common/templates/validations/_mongodb.tpl @@ -0,0 +1,113 @@ +{{/* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} +{{/* +Validate MongoDB® required passwords are not empty. + +Usage: +{{ include "common.validations.values.mongodb.passwords" (dict "secret" "secretName" "subchart" false "context" $) }} +Params: + - secret - String - Required. Name of the secret where MongoDB® values are stored, e.g: "mongodb-passwords-secret" + - subchart - Boolean - Optional. Whether MongoDB® is used as subchart or not. Default: false +*/}} +{{- define "common.validations.values.mongodb.passwords" -}} + {{- $existingSecret := include "common.mongodb.values.auth.existingSecret" . -}} + {{- $enabled := include "common.mongodb.values.enabled" . -}} + {{- $authPrefix := include "common.mongodb.values.key.auth" . -}} + {{- $architecture := include "common.mongodb.values.architecture" . -}} + {{- $valueKeyRootPassword := printf "%s.rootPassword" $authPrefix -}} + {{- $valueKeyUsername := printf "%s.username" $authPrefix -}} + {{- $valueKeyDatabase := printf "%s.database" $authPrefix -}} + {{- $valueKeyPassword := printf "%s.password" $authPrefix -}} + {{- $valueKeyReplicaSetKey := printf "%s.replicaSetKey" $authPrefix -}} + {{- $valueKeyAuthEnabled := printf "%s.enabled" $authPrefix -}} + + {{- $authEnabled := include "common.utils.getValueFromKey" (dict "key" $valueKeyAuthEnabled "context" .context) -}} + + {{- if and (or (not $existingSecret) (eq $existingSecret "\"\"")) (eq $enabled "true") (eq $authEnabled "true") -}} + {{- $requiredPasswords := list -}} + + {{- $requiredRootPassword := dict "valueKey" $valueKeyRootPassword "secret" .secret "field" "mongodb-root-password" -}} + {{- $requiredPasswords = append $requiredPasswords $requiredRootPassword -}} + + {{- $valueUsername := include "common.utils.getValueFromKey" (dict "key" $valueKeyUsername "context" .context) }} + {{- $valueDatabase := include "common.utils.getValueFromKey" (dict "key" $valueKeyDatabase "context" .context) }} + {{- if and $valueUsername $valueDatabase -}} + {{- $requiredPassword := dict "valueKey" $valueKeyPassword "secret" .secret "field" "mongodb-password" -}} + {{- $requiredPasswords = append $requiredPasswords $requiredPassword -}} + {{- end -}} + + {{- if (eq $architecture "replicaset") -}} + {{- $requiredReplicaSetKey := dict "valueKey" $valueKeyReplicaSetKey "secret" .secret "field" "mongodb-replica-set-key" -}} + {{- $requiredPasswords = append $requiredPasswords $requiredReplicaSetKey -}} + {{- end -}} + + {{- include "common.validations.values.multiple.empty" (dict "required" $requiredPasswords "context" .context) -}} + + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for existingSecret. + +Usage: +{{ include "common.mongodb.values.auth.existingSecret" (dict "context" $) }} +Params: + - subchart - Boolean - Optional. Whether MongoDb is used as subchart or not. Default: false +*/}} +{{- define "common.mongodb.values.auth.existingSecret" -}} + {{- if .subchart -}} + {{- .context.Values.mongodb.auth.existingSecret | quote -}} + {{- else -}} + {{- .context.Values.auth.existingSecret | quote -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for enabled mongodb. + +Usage: +{{ include "common.mongodb.values.enabled" (dict "context" $) }} +*/}} +{{- define "common.mongodb.values.enabled" -}} + {{- if .subchart -}} + {{- printf "%v" .context.Values.mongodb.enabled -}} + {{- else -}} + {{- printf "%v" (not .context.Values.enabled) -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for the key auth + +Usage: +{{ include "common.mongodb.values.key.auth" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether MongoDB® is used as subchart or not. Default: false +*/}} +{{- define "common.mongodb.values.key.auth" -}} + {{- if .subchart -}} + mongodb.auth + {{- else -}} + auth + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for architecture + +Usage: +{{ include "common.mongodb.values.architecture" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether MongoDB® is used as subchart or not. Default: false +*/}} +{{- define "common.mongodb.values.architecture" -}} + {{- if .subchart -}} + {{- .context.Values.mongodb.architecture -}} + {{- else -}} + {{- .context.Values.architecture -}} + {{- end -}} +{{- end -}} diff --git a/helm/ghost/charts/mysql/charts/common/templates/validations/_mysql.tpl b/helm/ghost/charts/mysql/charts/common/templates/validations/_mysql.tpl new file mode 100644 index 0000000..ca3953f --- /dev/null +++ b/helm/ghost/charts/mysql/charts/common/templates/validations/_mysql.tpl @@ -0,0 +1,108 @@ +{{/* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} +{{/* +Validate MySQL required passwords are not empty. + +Usage: +{{ include "common.validations.values.mysql.passwords" (dict "secret" "secretName" "subchart" false "context" $) }} +Params: + - secret - String - Required. Name of the secret where MySQL values are stored, e.g: "mysql-passwords-secret" + - subchart - Boolean - Optional. Whether MySQL is used as subchart or not. Default: false +*/}} +{{- define "common.validations.values.mysql.passwords" -}} + {{- $existingSecret := include "common.mysql.values.auth.existingSecret" . -}} + {{- $enabled := include "common.mysql.values.enabled" . -}} + {{- $architecture := include "common.mysql.values.architecture" . -}} + {{- $authPrefix := include "common.mysql.values.key.auth" . -}} + {{- $valueKeyRootPassword := printf "%s.rootPassword" $authPrefix -}} + {{- $valueKeyUsername := printf "%s.username" $authPrefix -}} + {{- $valueKeyPassword := printf "%s.password" $authPrefix -}} + {{- $valueKeyReplicationPassword := printf "%s.replicationPassword" $authPrefix -}} + + {{- if and (or (not $existingSecret) (eq $existingSecret "\"\"")) (eq $enabled "true") -}} + {{- $requiredPasswords := list -}} + + {{- $requiredRootPassword := dict "valueKey" $valueKeyRootPassword "secret" .secret "field" "mysql-root-password" -}} + {{- $requiredPasswords = append $requiredPasswords $requiredRootPassword -}} + + {{- $valueUsername := include "common.utils.getValueFromKey" (dict "key" $valueKeyUsername "context" .context) }} + {{- if not (empty $valueUsername) -}} + {{- $requiredPassword := dict "valueKey" $valueKeyPassword "secret" .secret "field" "mysql-password" -}} + {{- $requiredPasswords = append $requiredPasswords $requiredPassword -}} + {{- end -}} + + {{- if (eq $architecture "replication") -}} + {{- $requiredReplicationPassword := dict "valueKey" $valueKeyReplicationPassword "secret" .secret "field" "mysql-replication-password" -}} + {{- $requiredPasswords = append $requiredPasswords $requiredReplicationPassword -}} + {{- end -}} + + {{- include "common.validations.values.multiple.empty" (dict "required" $requiredPasswords "context" .context) -}} + + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for existingSecret. + +Usage: +{{ include "common.mysql.values.auth.existingSecret" (dict "context" $) }} +Params: + - subchart - Boolean - Optional. Whether MySQL is used as subchart or not. Default: false +*/}} +{{- define "common.mysql.values.auth.existingSecret" -}} + {{- if .subchart -}} + {{- .context.Values.mysql.auth.existingSecret | quote -}} + {{- else -}} + {{- .context.Values.auth.existingSecret | quote -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for enabled mysql. + +Usage: +{{ include "common.mysql.values.enabled" (dict "context" $) }} +*/}} +{{- define "common.mysql.values.enabled" -}} + {{- if .subchart -}} + {{- printf "%v" .context.Values.mysql.enabled -}} + {{- else -}} + {{- printf "%v" (not .context.Values.enabled) -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for architecture + +Usage: +{{ include "common.mysql.values.architecture" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether MySQL is used as subchart or not. Default: false +*/}} +{{- define "common.mysql.values.architecture" -}} + {{- if .subchart -}} + {{- .context.Values.mysql.architecture -}} + {{- else -}} + {{- .context.Values.architecture -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for the key auth + +Usage: +{{ include "common.mysql.values.key.auth" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether MySQL is used as subchart or not. Default: false +*/}} +{{- define "common.mysql.values.key.auth" -}} + {{- if .subchart -}} + mysql.auth + {{- else -}} + auth + {{- end -}} +{{- end -}} diff --git a/helm/ghost/charts/mysql/charts/common/templates/validations/_postgresql.tpl b/helm/ghost/charts/mysql/charts/common/templates/validations/_postgresql.tpl new file mode 100644 index 0000000..8c9aa57 --- /dev/null +++ b/helm/ghost/charts/mysql/charts/common/templates/validations/_postgresql.tpl @@ -0,0 +1,134 @@ +{{/* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} +{{/* +Validate PostgreSQL required passwords are not empty. + +Usage: +{{ include "common.validations.values.postgresql.passwords" (dict "secret" "secretName" "subchart" false "context" $) }} +Params: + - secret - String - Required. Name of the secret where postgresql values are stored, e.g: "postgresql-passwords-secret" + - subchart - Boolean - Optional. Whether postgresql is used as subchart or not. Default: false +*/}} +{{- define "common.validations.values.postgresql.passwords" -}} + {{- $existingSecret := include "common.postgresql.values.existingSecret" . -}} + {{- $enabled := include "common.postgresql.values.enabled" . -}} + {{- $valueKeyPostgresqlPassword := include "common.postgresql.values.key.postgressPassword" . -}} + {{- $valueKeyPostgresqlReplicationEnabled := include "common.postgresql.values.key.replicationPassword" . -}} + {{- if and (or (not $existingSecret) (eq $existingSecret "\"\"")) (eq $enabled "true") -}} + {{- $requiredPasswords := list -}} + {{- $requiredPostgresqlPassword := dict "valueKey" $valueKeyPostgresqlPassword "secret" .secret "field" "postgresql-password" -}} + {{- $requiredPasswords = append $requiredPasswords $requiredPostgresqlPassword -}} + + {{- $enabledReplication := include "common.postgresql.values.enabled.replication" . -}} + {{- if (eq $enabledReplication "true") -}} + {{- $requiredPostgresqlReplicationPassword := dict "valueKey" $valueKeyPostgresqlReplicationEnabled "secret" .secret "field" "postgresql-replication-password" -}} + {{- $requiredPasswords = append $requiredPasswords $requiredPostgresqlReplicationPassword -}} + {{- end -}} + + {{- include "common.validations.values.multiple.empty" (dict "required" $requiredPasswords "context" .context) -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to decide whether evaluate global values. + +Usage: +{{ include "common.postgresql.values.use.global" (dict "key" "key-of-global" "context" $) }} +Params: + - key - String - Required. Field to be evaluated within global, e.g: "existingSecret" +*/}} +{{- define "common.postgresql.values.use.global" -}} + {{- if .context.Values.global -}} + {{- if .context.Values.global.postgresql -}} + {{- index .context.Values.global.postgresql .key | quote -}} + {{- end -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for existingSecret. + +Usage: +{{ include "common.postgresql.values.existingSecret" (dict "context" $) }} +*/}} +{{- define "common.postgresql.values.existingSecret" -}} + {{- $globalValue := include "common.postgresql.values.use.global" (dict "key" "existingSecret" "context" .context) -}} + + {{- if .subchart -}} + {{- default (.context.Values.postgresql.existingSecret | quote) $globalValue -}} + {{- else -}} + {{- default (.context.Values.existingSecret | quote) $globalValue -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for enabled postgresql. + +Usage: +{{ include "common.postgresql.values.enabled" (dict "context" $) }} +*/}} +{{- define "common.postgresql.values.enabled" -}} + {{- if .subchart -}} + {{- printf "%v" .context.Values.postgresql.enabled -}} + {{- else -}} + {{- printf "%v" (not .context.Values.enabled) -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for the key postgressPassword. + +Usage: +{{ include "common.postgresql.values.key.postgressPassword" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether postgresql is used as subchart or not. Default: false +*/}} +{{- define "common.postgresql.values.key.postgressPassword" -}} + {{- $globalValue := include "common.postgresql.values.use.global" (dict "key" "postgresqlUsername" "context" .context) -}} + + {{- if not $globalValue -}} + {{- if .subchart -}} + postgresql.postgresqlPassword + {{- else -}} + postgresqlPassword + {{- end -}} + {{- else -}} + global.postgresql.postgresqlPassword + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for enabled.replication. + +Usage: +{{ include "common.postgresql.values.enabled.replication" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether postgresql is used as subchart or not. Default: false +*/}} +{{- define "common.postgresql.values.enabled.replication" -}} + {{- if .subchart -}} + {{- printf "%v" .context.Values.postgresql.replication.enabled -}} + {{- else -}} + {{- printf "%v" .context.Values.replication.enabled -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for the key replication.password. + +Usage: +{{ include "common.postgresql.values.key.replicationPassword" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether postgresql is used as subchart or not. Default: false +*/}} +{{- define "common.postgresql.values.key.replicationPassword" -}} + {{- if .subchart -}} + postgresql.replication.password + {{- else -}} + replication.password + {{- end -}} +{{- end -}} diff --git a/helm/ghost/charts/mysql/charts/common/templates/validations/_redis.tpl b/helm/ghost/charts/mysql/charts/common/templates/validations/_redis.tpl new file mode 100644 index 0000000..fc0d208 --- /dev/null +++ b/helm/ghost/charts/mysql/charts/common/templates/validations/_redis.tpl @@ -0,0 +1,81 @@ +{{/* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + + +{{/* vim: set filetype=mustache: */}} +{{/* +Validate Redis® required passwords are not empty. + +Usage: +{{ include "common.validations.values.redis.passwords" (dict "secret" "secretName" "subchart" false "context" $) }} +Params: + - secret - String - Required. Name of the secret where redis values are stored, e.g: "redis-passwords-secret" + - subchart - Boolean - Optional. Whether redis is used as subchart or not. Default: false +*/}} +{{- define "common.validations.values.redis.passwords" -}} + {{- $enabled := include "common.redis.values.enabled" . -}} + {{- $valueKeyPrefix := include "common.redis.values.keys.prefix" . -}} + {{- $standarizedVersion := include "common.redis.values.standarized.version" . }} + + {{- $existingSecret := ternary (printf "%s%s" $valueKeyPrefix "auth.existingSecret") (printf "%s%s" $valueKeyPrefix "existingSecret") (eq $standarizedVersion "true") }} + {{- $existingSecretValue := include "common.utils.getValueFromKey" (dict "key" $existingSecret "context" .context) }} + + {{- $valueKeyRedisPassword := ternary (printf "%s%s" $valueKeyPrefix "auth.password") (printf "%s%s" $valueKeyPrefix "password") (eq $standarizedVersion "true") }} + {{- $valueKeyRedisUseAuth := ternary (printf "%s%s" $valueKeyPrefix "auth.enabled") (printf "%s%s" $valueKeyPrefix "usePassword") (eq $standarizedVersion "true") }} + + {{- if and (or (not $existingSecret) (eq $existingSecret "\"\"")) (eq $enabled "true") -}} + {{- $requiredPasswords := list -}} + + {{- $useAuth := include "common.utils.getValueFromKey" (dict "key" $valueKeyRedisUseAuth "context" .context) -}} + {{- if eq $useAuth "true" -}} + {{- $requiredRedisPassword := dict "valueKey" $valueKeyRedisPassword "secret" .secret "field" "redis-password" -}} + {{- $requiredPasswords = append $requiredPasswords $requiredRedisPassword -}} + {{- end -}} + + {{- include "common.validations.values.multiple.empty" (dict "required" $requiredPasswords "context" .context) -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for enabled redis. + +Usage: +{{ include "common.redis.values.enabled" (dict "context" $) }} +*/}} +{{- define "common.redis.values.enabled" -}} + {{- if .subchart -}} + {{- printf "%v" .context.Values.redis.enabled -}} + {{- else -}} + {{- printf "%v" (not .context.Values.enabled) -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right prefix path for the values + +Usage: +{{ include "common.redis.values.key.prefix" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether redis is used as subchart or not. Default: false +*/}} +{{- define "common.redis.values.keys.prefix" -}} + {{- if .subchart -}}redis.{{- else -}}{{- end -}} +{{- end -}} + +{{/* +Checks whether the redis chart's includes the standarizations (version >= 14) + +Usage: +{{ include "common.redis.values.standarized.version" (dict "context" $) }} +*/}} +{{- define "common.redis.values.standarized.version" -}} + + {{- $standarizedAuth := printf "%s%s" (include "common.redis.values.keys.prefix" .) "auth" -}} + {{- $standarizedAuthValues := include "common.utils.getValueFromKey" (dict "key" $standarizedAuth "context" .context) }} + + {{- if $standarizedAuthValues -}} + {{- true -}} + {{- end -}} +{{- end -}} diff --git a/helm/ghost/charts/mysql/charts/common/templates/validations/_validations.tpl b/helm/ghost/charts/mysql/charts/common/templates/validations/_validations.tpl new file mode 100644 index 0000000..31ceda8 --- /dev/null +++ b/helm/ghost/charts/mysql/charts/common/templates/validations/_validations.tpl @@ -0,0 +1,51 @@ +{{/* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} +{{/* +Validate values must not be empty. + +Usage: +{{- $validateValueConf00 := (dict "valueKey" "path.to.value" "secret" "secretName" "field" "password-00") -}} +{{- $validateValueConf01 := (dict "valueKey" "path.to.value" "secret" "secretName" "field" "password-01") -}} +{{ include "common.validations.values.empty" (dict "required" (list $validateValueConf00 $validateValueConf01) "context" $) }} + +Validate value params: + - valueKey - String - Required. The path to the validating value in the values.yaml, e.g: "mysql.password" + - secret - String - Optional. Name of the secret where the validating value is generated/stored, e.g: "mysql-passwords-secret" + - field - String - Optional. Name of the field in the secret data, e.g: "mysql-password" +*/}} +{{- define "common.validations.values.multiple.empty" -}} + {{- range .required -}} + {{- include "common.validations.values.single.empty" (dict "valueKey" .valueKey "secret" .secret "field" .field "context" $.context) -}} + {{- end -}} +{{- end -}} + +{{/* +Validate a value must not be empty. + +Usage: +{{ include "common.validations.value.empty" (dict "valueKey" "mariadb.password" "secret" "secretName" "field" "my-password" "subchart" "subchart" "context" $) }} + +Validate value params: + - valueKey - String - Required. The path to the validating value in the values.yaml, e.g: "mysql.password" + - secret - String - Optional. Name of the secret where the validating value is generated/stored, e.g: "mysql-passwords-secret" + - field - String - Optional. Name of the field in the secret data, e.g: "mysql-password" + - subchart - String - Optional - Name of the subchart that the validated password is part of. +*/}} +{{- define "common.validations.values.single.empty" -}} + {{- $value := include "common.utils.getValueFromKey" (dict "key" .valueKey "context" .context) }} + {{- $subchart := ternary "" (printf "%s." .subchart) (empty .subchart) }} + + {{- if not $value -}} + {{- $varname := "my-value" -}} + {{- $getCurrentValue := "" -}} + {{- if and .secret .field -}} + {{- $varname = include "common.utils.fieldToEnvVar" . -}} + {{- $getCurrentValue = printf " To get the current value:\n\n %s\n" (include "common.utils.secret.getvalue" .) -}} + {{- end -}} + {{- printf "\n '%s' must not be empty, please add '--set %s%s=$%s' to the command.%s" .valueKey $subchart .valueKey $varname $getCurrentValue -}} + {{- end -}} +{{- end -}} diff --git a/helm/ghost/charts/mysql/charts/common/values.yaml b/helm/ghost/charts/mysql/charts/common/values.yaml new file mode 100644 index 0000000..9abe0e1 --- /dev/null +++ b/helm/ghost/charts/mysql/charts/common/values.yaml @@ -0,0 +1,8 @@ +# Copyright VMware, Inc. +# SPDX-License-Identifier: APACHE-2.0 + +## bitnami/common +## It is required by CI/CD tools and processes. +## @skip exampleValue +## +exampleValue: common-chart diff --git a/helm/ghost/charts/mysql/templates/NOTES.txt b/helm/ghost/charts/mysql/templates/NOTES.txt new file mode 100644 index 0000000..ecf604c --- /dev/null +++ b/helm/ghost/charts/mysql/templates/NOTES.txt @@ -0,0 +1,75 @@ +CHART NAME: {{ .Chart.Name }} +CHART VERSION: {{ .Chart.Version }} +APP VERSION: {{ .Chart.AppVersion }} + +** Please be patient while the chart is being deployed ** + +{{- if .Values.diagnosticMode.enabled }} +The chart has been deployed in diagnostic mode. All probes have been disabled and the command has been overwritten with: + + command: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.command "context" $) | nindent 4 }} + args: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.args "context" $) | nindent 4 }} + +Get the list of pods by executing: + + kubectl get pods --namespace {{ include "common.names.namespace" . }} -l app.kubernetes.io/instance={{ .Release.Name }} + +Access the pod you want to debug by executing + + kubectl exec --namespace {{ include "common.names.namespace" . }} -ti -- bash + +In order to replicate the container startup scripts execute this command: + + /opt/bitnami/scripts/mysql/entrypoint.sh /opt/bitnami/scripts/mysql/run.sh + +{{- else }} + +Tip: + + Watch the deployment status using the command: kubectl get pods -w --namespace {{ include "common.names.namespace" . }} + +Services: + + echo Primary: {{ include "mysql.primary.fullname" . }}.{{ include "common.names.namespace" . }}.svc.{{ .Values.clusterDomain }}:{{ .Values.primary.service.ports.mysql }} +{{- if eq .Values.architecture "replication" }} + echo Secondary: {{ include "mysql.secondary.fullname" . }}.{{ include "common.names.namespace" . }}.svc.{{ .Values.clusterDomain }}:{{ .Values.secondary.service.ports.mysql }} +{{- end }} + +Execute the following to get the administrator credentials: + + echo Username: root + MYSQL_ROOT_PASSWORD=$(kubectl get secret --namespace {{ include "common.names.namespace" . }} {{ template "mysql.secretName" . }} -o jsonpath="{.data.mysql-root-password}" | base64 -d) + +To connect to your database: + + 1. Run a pod that you can use as a client: + + kubectl run {{ include "common.names.fullname" . }}-client --rm --tty -i --restart='Never' --image {{ template "mysql.image" . }} --namespace {{ include "common.names.namespace" . }} --env MYSQL_ROOT_PASSWORD=$MYSQL_ROOT_PASSWORD --command -- bash + + 2. To connect to primary service (read/write): + + mysql -h {{ include "mysql.primary.fullname" . }}.{{ include "common.names.namespace" . }}.svc.{{ .Values.clusterDomain }} -uroot -p"$MYSQL_ROOT_PASSWORD" + +{{- if eq .Values.architecture "replication" }} + + 3. To connect to secondary service (read-only): + + mysql -h {{ include "mysql.secondary.fullname" . }}.{{ include "common.names.namespace" . }}.svc.{{ .Values.clusterDomain }} -uroot -p"$MYSQL_ROOT_PASSWORD" +{{- end }} + +{{ if and (.Values.networkPolicy.enabled) (not .Values.networkPolicy.allowExternal) }} +Note: Since NetworkPolicy is enabled, only pods with label {{ template "common.names.fullname" . }}-client=true" will be able to connect to MySQL. +{{- end }} + +{{- if .Values.metrics.enabled }} + +To access the MySQL Prometheus metrics from outside the cluster execute the following commands: + + kubectl port-forward --namespace {{ include "common.names.namespace" . }} svc/{{ printf "%s-metrics" (include "common.names.fullname" .) }} {{ .Values.metrics.service.port }}:{{ .Values.metrics.service.port }} & + curl http://127.0.0.1:{{ .Values.metrics.service.port }}/metrics + +{{- end }} + +{{ include "mysql.validateValues" . }} +{{ include "mysql.checkRollingTags" . }} +{{- end }} diff --git a/helm/ghost/charts/mysql/templates/_helpers.tpl b/helm/ghost/charts/mysql/templates/_helpers.tpl new file mode 100644 index 0000000..21c6889 --- /dev/null +++ b/helm/ghost/charts/mysql/templates/_helpers.tpl @@ -0,0 +1,166 @@ +{{/* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} + +{{- define "mysql.primary.fullname" -}} +{{- if eq .Values.architecture "replication" }} +{{- printf "%s-%s" (include "common.names.fullname" .) .Values.primary.name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- include "common.names.fullname" . -}} +{{- end -}} +{{- end -}} + +{{- define "mysql.secondary.fullname" -}} +{{- printf "%s-%s" (include "common.names.fullname" .) .Values.secondary.name | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Return the proper MySQL image name +*/}} +{{- define "mysql.image" -}} +{{- include "common.images.image" (dict "imageRoot" .Values.image "global" .Values.global) }} +{{- end -}} + +{{/* +Return the proper metrics image name +*/}} +{{- define "mysql.metrics.image" -}} +{{- include "common.images.image" (dict "imageRoot" .Values.metrics.image "global" .Values.global) }} +{{- end -}} + +{{/* +Return the proper image name (for the init container volume-permissions image) +*/}} +{{- define "mysql.volumePermissions.image" -}} +{{- include "common.images.image" (dict "imageRoot" .Values.volumePermissions.image "global" .Values.global) }} +{{- end -}} + +{{/* +Return the proper Docker Image Registry Secret Names +*/}} +{{- define "mysql.imagePullSecrets" -}} +{{- include "common.images.pullSecrets" (dict "images" (list .Values.image .Values.metrics.image .Values.volumePermissions.image) "global" .Values.global) }} +{{- end -}} + +{{/* +Get the initialization scripts ConfigMap name. +*/}} +{{- define "mysql.initdbScriptsCM" -}} +{{- if .Values.initdbScriptsConfigMap -}} + {{- printf "%s" (tpl .Values.initdbScriptsConfigMap $) -}} +{{- else -}} + {{- printf "%s-init-scripts" (include "mysql.primary.fullname" .) -}} +{{- end -}} +{{- end -}} + +{{/* + Returns the proper service account name depending if an explicit service account name is set + in the values file. If the name is not set it will default to either mysql.fullname if serviceAccount.create + is true or default otherwise. +*/}} +{{- define "mysql.serviceAccountName" -}} + {{- if .Values.serviceAccount.create -}} + {{ default (include "common.names.fullname" .) .Values.serviceAccount.name }} + {{- else -}} + {{ default "default" .Values.serviceAccount.name }} + {{- end -}} +{{- end -}} + +{{/* +Return the configmap with the MySQL Primary configuration +*/}} +{{- define "mysql.primary.configmapName" -}} +{{- if .Values.primary.existingConfigmap -}} + {{- printf "%s" (tpl .Values.primary.existingConfigmap $) -}} +{{- else -}} + {{- printf "%s" (include "mysql.primary.fullname" .) -}} +{{- end -}} +{{- end -}} + +{{/* +Return true if a configmap object should be created for MySQL Secondary +*/}} +{{- define "mysql.primary.createConfigmap" -}} +{{- if and .Values.primary.configuration (not .Values.primary.existingConfigmap) }} + {{- true -}} +{{- else -}} +{{- end -}} +{{- end -}} + +{{/* +Return the configmap with the MySQL Primary configuration +*/}} +{{- define "mysql.secondary.configmapName" -}} +{{- if .Values.secondary.existingConfigmap -}} + {{- printf "%s" (tpl .Values.secondary.existingConfigmap $) -}} +{{- else -}} + {{- printf "%s" (include "mysql.secondary.fullname" .) -}} +{{- end -}} +{{- end -}} + +{{/* +Return true if a configmap object should be created for MySQL Secondary +*/}} +{{- define "mysql.secondary.createConfigmap" -}} +{{- if and (eq .Values.architecture "replication") .Values.secondary.configuration (not .Values.secondary.existingConfigmap) }} + {{- true -}} +{{- else -}} +{{- end -}} +{{- end -}} + +{{/* +Return the secret with MySQL credentials +*/}} +{{- define "mysql.secretName" -}} + {{- if .Values.auth.existingSecret -}} + {{- printf "%s" (tpl .Values.auth.existingSecret $) -}} + {{- else -}} + {{- printf "%s" (include "common.names.fullname" .) -}} + {{- end -}} +{{- end -}} + +{{/* +Return true if a secret object should be created for MySQL +*/}} +{{- define "mysql.createSecret" -}} +{{- if and (not .Values.auth.existingSecret) (not .Values.auth.customPasswordFiles) }} + {{- true -}} +{{- end -}} +{{- end -}} + +{{/* +Returns the available value for certain key in an existing secret (if it exists), +otherwise it generates a random value. +*/}} +{{- define "getValueFromSecret" }} + {{- $len := (default 16 .Length) | int -}} + {{- $obj := (lookup "v1" "Secret" .Namespace .Name).data -}} + {{- if $obj }} + {{- index $obj .Key | b64dec -}} + {{- else -}} + {{- randAlphaNum $len -}} + {{- end -}} +{{- end }} + +{{/* Check if there are rolling tags in the images */}} +{{- define "mysql.checkRollingTags" -}} +{{- include "common.warnings.rollingTag" .Values.image }} +{{- include "common.warnings.rollingTag" .Values.metrics.image }} +{{- include "common.warnings.rollingTag" .Values.volumePermissions.image }} +{{- end -}} + +{{/* +Compile all warnings into a single message, and call fail. +*/}} +{{- define "mysql.validateValues" -}} +{{- $messages := list -}} +{{- $messages := without $messages "" -}} +{{- $message := join "\n" $messages -}} + +{{- if $message -}} +{{- printf "\nVALUES VALIDATION:\n%s" $message | fail -}} +{{- end -}} +{{- end -}} diff --git a/helm/ghost/charts/mysql/templates/extra-list.yaml b/helm/ghost/charts/mysql/templates/extra-list.yaml new file mode 100644 index 0000000..2d35a58 --- /dev/null +++ b/helm/ghost/charts/mysql/templates/extra-list.yaml @@ -0,0 +1,9 @@ +{{- /* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- range .Values.extraDeploy }} +--- +{{ include "common.tplvalues.render" (dict "value" . "context" $) }} +{{- end }} diff --git a/helm/ghost/charts/mysql/templates/metrics-svc.yaml b/helm/ghost/charts/mysql/templates/metrics-svc.yaml new file mode 100644 index 0000000..4f583da --- /dev/null +++ b/helm/ghost/charts/mysql/templates/metrics-svc.yaml @@ -0,0 +1,37 @@ +{{- /* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if .Values.metrics.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ printf "%s-metrics" (include "common.names.fullname" .) }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + app.kubernetes.io/component: metrics + {{- if or .Values.metrics.service.annotations .Values.commonAnnotations }} + annotations: + {{- if .Values.metrics.service.annotations }} + {{- include "common.tplvalues.render" (dict "value" .Values.metrics.service.annotations "context" $) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} + {{- end }} +spec: + type: {{ .Values.metrics.service.type }} + {{- if and .Values.metrics.service.clusterIP (eq .Values.metrics.service.type "ClusterIP") }} + clusterIP: {{ .Values.metrics.service.clusterIP }} + {{- end }} + ports: + - port: {{ .Values.metrics.service.port }} + targetPort: metrics + protocol: TCP + name: metrics + selector: {{- include "common.labels.matchLabels" $ | nindent 4 }} +{{- end }} diff --git a/helm/ghost/charts/mysql/templates/networkpolicy.yaml b/helm/ghost/charts/mysql/templates/networkpolicy.yaml new file mode 100644 index 0000000..45a67db --- /dev/null +++ b/helm/ghost/charts/mysql/templates/networkpolicy.yaml @@ -0,0 +1,45 @@ +{{- /* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if .Values.networkPolicy.enabled }} +kind: NetworkPolicy +apiVersion: {{ template "common.capabilities.networkPolicy.apiVersion" . }} +metadata: + name: {{ template "common.names.fullname" . }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + podSelector: + matchLabels: + {{- include "common.labels.matchLabels" . | nindent 6 }} + ingress: + # Allow inbound connections + - ports: + - port: {{ .Values.primary.service.ports.mysql }} + {{- if not .Values.networkPolicy.allowExternal }} + from: + - podSelector: + matchLabels: + {{ template "common.names.fullname" . }}-client: "true" + {{- if .Values.networkPolicy.explicitNamespacesSelector }} + namespaceSelector: +{{ toYaml .Values.networkPolicy.explicitNamespacesSelector | indent 12 }} + {{- end }} + - podSelector: + matchLabels: + {{- include "common.labels.matchLabels" . | nindent 14 }} + {{- end }} + {{- if .Values.metrics.enabled }} + # Allow prometheus scrapes + - ports: + - port: 9104 + {{- end }} +{{- end }} diff --git a/helm/ghost/charts/mysql/templates/primary/configmap.yaml b/helm/ghost/charts/mysql/templates/primary/configmap.yaml new file mode 100644 index 0000000..8471424 --- /dev/null +++ b/helm/ghost/charts/mysql/templates/primary/configmap.yaml @@ -0,0 +1,23 @@ +{{- /* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if (include "mysql.primary.createConfigmap" .) }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "mysql.primary.fullname" . }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + app.kubernetes.io/component: primary + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +data: + my.cnf: |- + {{- include "common.tplvalues.render" ( dict "value" .Values.primary.configuration "context" $ ) | nindent 4 }} +{{- end -}} diff --git a/helm/ghost/charts/mysql/templates/primary/initialization-configmap.yaml b/helm/ghost/charts/mysql/templates/primary/initialization-configmap.yaml new file mode 100644 index 0000000..c3d17ee --- /dev/null +++ b/helm/ghost/charts/mysql/templates/primary/initialization-configmap.yaml @@ -0,0 +1,22 @@ +{{- /* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if and .Values.initdbScripts (not .Values.initdbScriptsConfigMap) }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ printf "%s-init-scripts" (include "mysql.primary.fullname" .) }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + app.kubernetes.io/component: primary + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +data: +{{- include "common.tplvalues.render" (dict "value" .Values.initdbScripts "context" .) | nindent 2 }} +{{- end }} diff --git a/helm/ghost/charts/mysql/templates/primary/pdb.yaml b/helm/ghost/charts/mysql/templates/primary/pdb.yaml new file mode 100644 index 0000000..0d59b13 --- /dev/null +++ b/helm/ghost/charts/mysql/templates/primary/pdb.yaml @@ -0,0 +1,30 @@ +{{- /* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if .Values.primary.pdb.create }} +apiVersion: {{ include "common.capabilities.policy.apiVersion" . }} +kind: PodDisruptionBudget +metadata: + name: {{ include "mysql.primary.fullname" . }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + app.kubernetes.io/component: primary + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + {{- if .Values.primary.pdb.minAvailable }} + minAvailable: {{ .Values.primary.pdb.minAvailable }} + {{- end }} + {{- if .Values.primary.pdb.maxUnavailable }} + maxUnavailable: {{ .Values.primary.pdb.maxUnavailable }} + {{- end }} + selector: + matchLabels: {{ include "common.labels.matchLabels" . | nindent 6 }} + app.kubernetes.io/component: primary +{{- end }} diff --git a/helm/ghost/charts/mysql/templates/primary/statefulset.yaml b/helm/ghost/charts/mysql/templates/primary/statefulset.yaml new file mode 100644 index 0000000..0aa7c1f --- /dev/null +++ b/helm/ghost/charts/mysql/templates/primary/statefulset.yaml @@ -0,0 +1,393 @@ +{{- /* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +apiVersion: {{ include "common.capabilities.statefulset.apiVersion" . }} +kind: StatefulSet +metadata: + name: {{ include "mysql.primary.fullname" . }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + app.kubernetes.io/component: primary + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + replicas: 1 + podManagementPolicy: {{ .Values.primary.podManagementPolicy | quote }} + selector: + matchLabels: {{ include "common.labels.matchLabels" . | nindent 6 }} + app.kubernetes.io/component: primary + serviceName: {{ include "mysql.primary.fullname" . }} + {{- if .Values.primary.updateStrategy }} + updateStrategy: {{- toYaml .Values.primary.updateStrategy | nindent 4 }} + {{- end }} + template: + metadata: + annotations: + {{- if (include "mysql.primary.createConfigmap" .) }} + checksum/configuration: {{ include (print $.Template.BasePath "/primary/configmap.yaml") . | sha256sum }} + {{- end }} + {{- if .Values.primary.podAnnotations }} + {{- include "common.tplvalues.render" (dict "value" .Values.primary.podAnnotations "context" $) | nindent 8 }} + {{- end }} + labels: {{- include "common.labels.standard" . | nindent 8 }} + app.kubernetes.io/component: primary + {{- if .Values.primary.podLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.primary.podLabels "context" $ ) | nindent 8 }} + {{- end }} + spec: + serviceAccountName: {{ template "mysql.serviceAccountName" . }} + {{- include "mysql.imagePullSecrets" . | nindent 6 }} + {{- if .Values.primary.hostAliases }} + hostAliases: {{- include "common.tplvalues.render" (dict "value" .Values.primary.hostAliases "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.primary.affinity }} + affinity: {{- include "common.tplvalues.render" (dict "value" .Values.primary.affinity "context" $) | nindent 8 }} + {{- else }} + affinity: + podAffinity: {{- include "common.affinities.pods" (dict "type" .Values.primary.podAffinityPreset "context" $) | nindent 10 }} + podAntiAffinity: {{- include "common.affinities.pods" (dict "type" .Values.primary.podAntiAffinityPreset "context" $) | nindent 10 }} + nodeAffinity: {{- include "common.affinities.nodes" (dict "type" .Values.primary.nodeAffinityPreset.type "key" .Values.primary.nodeAffinityPreset.key "values" .Values.primary.nodeAffinityPreset.values) | nindent 10 }} + {{- end }} + {{- if .Values.primary.nodeSelector }} + nodeSelector: {{- include "common.tplvalues.render" (dict "value" .Values.primary.nodeSelector "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.primary.tolerations }} + tolerations: {{- include "common.tplvalues.render" (dict "value" .Values.primary.tolerations "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.primary.priorityClassName }} + priorityClassName: {{ .Values.primary.priorityClassName | quote }} + {{- end }} + {{- if .Values.primary.runtimeClassName }} + runtimeClassName: {{ .Values.primary.runtimeClassName | quote }} + {{- end }} + {{- if .Values.primary.schedulerName }} + schedulerName: {{ .Values.primary.schedulerName | quote }} + {{- end }} + {{- if .Values.primary.topologySpreadConstraints }} + topologySpreadConstraints: {{- include "common.tplvalues.render" (dict "value" .Values.primary.topologySpreadConstraints "context" .) | nindent 8 }} + {{- end }} + {{- if .Values.primary.podSecurityContext.enabled }} + securityContext: {{- omit .Values.primary.podSecurityContext "enabled" | toYaml | nindent 8 }} + {{- end }} + {{- if .Values.primary.terminationGracePeriodSeconds }} + terminationGracePeriodSeconds: {{ .Values.primary.terminationGracePeriodSeconds }} + {{- end }} + initContainers: + {{- if and .Values.primary.podSecurityContext.enabled .Values.volumePermissions.enabled .Values.primary.persistence.enabled }} + - name: volume-permissions + image: {{ include "mysql.volumePermissions.image" . }} + imagePullPolicy: {{ .Values.volumePermissions.image.pullPolicy | quote }} + command: + - /bin/bash + - -ec + - | + mkdir -p "/bitnami/mysql" + chown "{{ .Values.primary.containerSecurityContext.runAsUser }}:{{ .Values.primary.podSecurityContext.fsGroup }}" "/bitnami/mysql" + find "/bitnami/mysql" -mindepth 1 -maxdepth 1 -not -name ".snapshot" -not -name "lost+found" | xargs -r chown -R "{{ .Values.primary.containerSecurityContext.runAsUser }}:{{ .Values.primary.podSecurityContext.fsGroup }}" + securityContext: + runAsUser: 0 + {{- if .Values.volumePermissions.resources }} + resources: {{- toYaml .Values.volumePermissions.resources | nindent 12 }} + {{- end }} + volumeMounts: + - name: data + mountPath: /bitnami/mysql + {{- if .Values.primary.persistence.subPath }} + subPath: {{ .Values.primary.persistence.subPath }} + {{- end }} + {{- end }} + {{- if .Values.primary.initContainers }} + {{- include "common.tplvalues.render" (dict "value" .Values.primary.initContainers "context" $) | nindent 8 }} + {{- end }} + containers: + - name: mysql + image: {{ include "mysql.image" . }} + imagePullPolicy: {{ .Values.image.pullPolicy | quote }} + {{- if .Values.primary.containerSecurityContext.enabled }} + securityContext: {{- omit .Values.primary.containerSecurityContext "enabled" | toYaml | nindent 12 }} + {{- end }} + {{- if .Values.diagnosticMode.enabled }} + command: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.command "context" $) | nindent 12 }} + {{- else if .Values.primary.command }} + command: {{- include "common.tplvalues.render" (dict "value" .Values.primary.command "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.diagnosticMode.enabled }} + args: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.args "context" $) | nindent 12 }} + {{- else if .Values.primary.args }} + args: {{- include "common.tplvalues.render" (dict "value" .Values.primary.args "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.primary.lifecycleHooks }} + lifecycle: {{- include "common.tplvalues.render" (dict "value" .Values.primary.lifecycleHooks "context" $) | nindent 12 }} + {{- end }} + env: + - name: BITNAMI_DEBUG + value: {{ ternary "true" "false" (or .Values.image.debug .Values.diagnosticMode.enabled) | quote }} + {{- if .Values.auth.usePasswordFiles }} + - name: MYSQL_ROOT_PASSWORD_FILE + value: {{ default "/opt/bitnami/mysql/secrets/mysql-root-password" .Values.auth.customPasswordFiles.root }} + {{- else }} + - name: MYSQL_ROOT_PASSWORD + valueFrom: + secretKeyRef: + name: {{ template "mysql.secretName" . }} + key: mysql-root-password + {{- end }} + {{- if not (empty .Values.auth.username) }} + - name: MYSQL_USER + value: {{ .Values.auth.username | quote }} + {{- if .Values.auth.usePasswordFiles }} + - name: MYSQL_PASSWORD_FILE + value: {{ default "/opt/bitnami/mysql/secrets/mysql-password" .Values.auth.customPasswordFiles.user }} + {{- else }} + - name: MYSQL_PASSWORD + valueFrom: + secretKeyRef: + name: {{ template "mysql.secretName" . }} + key: mysql-password + {{- end }} + {{- end }} + {{- if and .Values.auth.createDatabase .Values.auth.database }} + - name: MYSQL_DATABASE + value: {{ .Values.auth.database | quote }} + {{- end }} + {{- if eq .Values.architecture "replication" }} + - name: MYSQL_REPLICATION_MODE + value: "master" + - name: MYSQL_REPLICATION_USER + value: {{ .Values.auth.replicationUser | quote }} + {{- if .Values.auth.usePasswordFiles }} + - name: MYSQL_REPLICATION_PASSWORD_FILE + value: {{ default "/opt/bitnami/mysql/secrets/mysql-replication-password" .Values.auth.customPasswordFiles.replicator }} + {{- else }} + - name: MYSQL_REPLICATION_PASSWORD + valueFrom: + secretKeyRef: + name: {{ template "mysql.secretName" . }} + key: mysql-replication-password + {{- end }} + {{- end }} + {{- if .Values.primary.extraFlags }} + - name: MYSQL_EXTRA_FLAGS + value: "{{ .Values.primary.extraFlags }}" + {{- end }} + {{- if .Values.primary.extraEnvVars }} + {{- include "common.tplvalues.render" (dict "value" .Values.primary.extraEnvVars "context" $) | nindent 12 }} + {{- end }} + envFrom: + {{- if .Values.primary.extraEnvVarsCM }} + - configMapRef: + name: {{ include "common.tplvalues.render" (dict "value" .Values.primary.extraEnvVarsCM "context" $) }} + {{- end }} + {{- if .Values.primary.extraEnvVarsSecret }} + - secretRef: + name: {{ include "common.tplvalues.render" (dict "value" .Values.primary.extraEnvVarsSecret "context" $) }} + {{- end }} + ports: + - name: mysql + containerPort: 3306 + {{- if .Values.primary.extraPorts }} + {{- include "common.tplvalues.render" (dict "value" .Values.primary.extraPorts "context" $) | nindent 12 }} + {{- end }} + {{- if not .Values.diagnosticMode.enabled }} + {{- if .Values.primary.customLivenessProbe }} + livenessProbe: {{- include "common.tplvalues.render" (dict "value" .Values.primary.customLivenessProbe "context" $) | nindent 12 }} + {{- else if .Values.primary.livenessProbe.enabled }} + livenessProbe: {{- include "common.tplvalues.render" (dict "value" (omit .Values.primary.livenessProbe "enabled") "context" $) | nindent 12 }} + exec: + command: + - /bin/bash + - -ec + - | + password_aux="${MYSQL_ROOT_PASSWORD:-}" + if [[ -f "${MYSQL_ROOT_PASSWORD_FILE:-}" ]]; then + password_aux=$(cat "$MYSQL_ROOT_PASSWORD_FILE") + fi + mysqladmin status -uroot -p"${password_aux}" + {{- end }} + {{- if .Values.primary.customReadinessProbe }} + readinessProbe: {{- include "common.tplvalues.render" (dict "value" .Values.primary.customReadinessProbe "context" $) | nindent 12 }} + {{- else if .Values.primary.readinessProbe.enabled }} + readinessProbe: {{- include "common.tplvalues.render" (dict "value" (omit .Values.primary.readinessProbe "enabled") "context" $) | nindent 12 }} + exec: + command: + - /bin/bash + - -ec + - | + password_aux="${MYSQL_ROOT_PASSWORD:-}" + if [[ -f "${MYSQL_ROOT_PASSWORD_FILE:-}" ]]; then + password_aux=$(cat "$MYSQL_ROOT_PASSWORD_FILE") + fi + mysqladmin status -uroot -p"${password_aux}" + {{- end }} + {{- if .Values.primary.customStartupProbe }} + startupProbe: {{- include "common.tplvalues.render" (dict "value" .Values.primary.customStartupProbe "context" $) | nindent 12 }} + {{- else if .Values.primary.startupProbe.enabled }} + startupProbe: {{- include "common.tplvalues.render" (dict "value" (omit .Values.primary.startupProbe "enabled") "context" $) | nindent 12 }} + exec: + command: + - /bin/bash + - -ec + - | + password_aux="${MYSQL_ROOT_PASSWORD:-}" + if [[ -f "${MYSQL_ROOT_PASSWORD_FILE:-}" ]]; then + password_aux=$(cat "$MYSQL_ROOT_PASSWORD_FILE") + fi + mysqladmin status -uroot -p"${password_aux}" + {{- end }} + {{- end }} + {{- if .Values.primary.resources }} + resources: {{ toYaml .Values.primary.resources | nindent 12 }} + {{- end }} + volumeMounts: + - name: data + mountPath: /bitnami/mysql + {{- if .Values.primary.persistence.subPath }} + subPath: {{ .Values.primary.persistence.subPath }} + {{- end }} + {{- if or .Values.initdbScriptsConfigMap .Values.initdbScripts }} + - name: custom-init-scripts + mountPath: /docker-entrypoint-initdb.d + {{- end }} + {{- if or .Values.primary.configuration .Values.primary.existingConfigmap }} + - name: config + mountPath: /opt/bitnami/mysql/conf/my.cnf + subPath: my.cnf + {{- end }} + {{- if and .Values.auth.usePasswordFiles (not .Values.auth.customPasswordFiles) }} + - name: mysql-credentials + mountPath: /opt/bitnami/mysql/secrets/ + {{- end }} + {{- if .Values.primary.extraVolumeMounts }} + {{- include "common.tplvalues.render" (dict "value" .Values.primary.extraVolumeMounts "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.metrics.enabled }} + - name: metrics + image: {{ include "mysql.metrics.image" . }} + imagePullPolicy: {{ .Values.metrics.image.pullPolicy | quote }} + {{- if .Values.metrics.containerSecurityContext.enabled }} + securityContext: {{- omit .Values.metrics.containerSecurityContext "enabled" | toYaml | nindent 12 }} + {{- end }} + env: + {{- if .Values.auth.usePasswordFiles }} + - name: MYSQL_ROOT_PASSWORD_FILE + value: {{ default "/opt/bitnami/mysqld-exporter/secrets/mysql-root-password" .Values.auth.customPasswordFiles.root }} + {{- else }} + - name: MYSQL_ROOT_PASSWORD + valueFrom: + secretKeyRef: + name: {{ include "mysql.secretName" . }} + key: mysql-root-password + {{- end }} + {{- if .Values.diagnosticMode.enabled }} + command: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.command "context" $) | nindent 12 }} + args: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.args "context" $) | nindent 12 }} + {{- else }} + command: + - /bin/bash + - -ec + - | + password_aux="${MYSQL_ROOT_PASSWORD:-}" + if [[ -f "${MYSQL_ROOT_PASSWORD_FILE:-}" ]]; then + password_aux=$(cat "$MYSQL_ROOT_PASSWORD_FILE") + fi + DATA_SOURCE_NAME="root:${password_aux}@(localhost:3306)/" /bin/mysqld_exporter {{- range .Values.metrics.extraArgs.primary }} {{ . }} {{- end }} + {{- end }} + ports: + - name: metrics + containerPort: 9104 + {{- if not .Values.diagnosticMode.enabled }} + {{- if .Values.metrics.livenessProbe.enabled }} + livenessProbe: {{- omit .Values.metrics.livenessProbe "enabled" | toYaml | nindent 12 }} + httpGet: + path: /metrics + port: metrics + {{- end }} + {{- if .Values.metrics.readinessProbe.enabled }} + readinessProbe: {{- omit .Values.metrics.readinessProbe "enabled" | toYaml | nindent 12 }} + httpGet: + path: /metrics + port: metrics + {{- end }} + {{- end }} + {{- if .Values.metrics.resources }} + resources: {{- toYaml .Values.metrics.resources | nindent 12 }} + {{- end }} + {{- if and .Values.auth.usePasswordFiles (not .Values.auth.customPasswordFiles) }} + volumeMounts: + - name: mysql-credentials + mountPath: /opt/bitnami/mysqld-exporter/secrets/ + {{- end }} + {{- end }} + {{- if .Values.primary.sidecars }} + {{- include "common.tplvalues.render" (dict "value" .Values.primary.sidecars "context" $) | nindent 8 }} + {{- end }} + volumes: + {{- if or .Values.primary.configuration .Values.primary.existingConfigmap }} + - name: config + configMap: + name: {{ include "mysql.primary.configmapName" . }} + {{- end }} + {{- if or .Values.initdbScriptsConfigMap .Values.initdbScripts }} + - name: custom-init-scripts + configMap: + name: {{ include "mysql.initdbScriptsCM" . }} + {{- end }} + {{- if and .Values.auth.usePasswordFiles (not .Values.auth.customPasswordFiles) }} + - name: mysql-credentials + secret: + secretName: {{ include "mysql.secretName" . }} + items: + - key: mysql-root-password + path: mysql-root-password + - key: mysql-password + path: mysql-password + {{- if eq .Values.architecture "replication" }} + - key: mysql-replication-password + path: mysql-replication-password + {{- end }} + {{- end }} + {{- if .Values.primary.extraVolumes }} + {{- include "common.tplvalues.render" (dict "value" .Values.primary.extraVolumes "context" $) | nindent 8 }} + {{- end }} + {{- if and .Values.primary.persistence.enabled .Values.primary.persistence.existingClaim }} + - name: data + persistentVolumeClaim: + claimName: {{ tpl .Values.primary.persistence.existingClaim . }} + {{- else if not .Values.primary.persistence.enabled }} + - name: data + emptyDir: {} + {{- else if and .Values.primary.persistence.enabled (not .Values.primary.persistence.existingClaim) }} + volumeClaimTemplates: + - metadata: + name: data + labels: {{ include "common.labels.matchLabels" . | nindent 10 }} + app.kubernetes.io/component: primary + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" (dict "value" .Values.commonLabels "context" $) | nindent 10 }} + {{- end }} + annotations: + {{- if .Values.primary.persistence.annotations }} + {{- include "common.tplvalues.render" (dict "value" .Values.primary.persistence.annotations "context" $) | nindent 10 }} + {{- end }} + {{- if .Values.commonAnnotations }} + {{- include "common.tplvalues.render" (dict "value" .Values.commonAnnotations "context" $) | nindent 10 }} + {{- end }} + spec: + accessModes: + {{- range .Values.primary.persistence.accessModes }} + - {{ . | quote }} + {{- end }} + resources: + requests: + storage: {{ .Values.primary.persistence.size | quote }} + {{- include "common.storage.class" (dict "persistence" .Values.primary.persistence "global" .Values.global) | nindent 8 }} + {{- if .Values.primary.persistence.selector }} + selector: {{- include "common.tplvalues.render" (dict "value" .Values.primary.persistence.selector "context" $) | nindent 10 }} + {{- end -}} + {{- end }} diff --git a/helm/ghost/charts/mysql/templates/primary/svc-headless.yaml b/helm/ghost/charts/mysql/templates/primary/svc-headless.yaml new file mode 100644 index 0000000..749afb6 --- /dev/null +++ b/helm/ghost/charts/mysql/templates/primary/svc-headless.yaml @@ -0,0 +1,34 @@ +{{- /* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +apiVersion: v1 +kind: Service +metadata: + name: {{ include "mysql.primary.fullname" . }}-headless + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + app.kubernetes.io/component: primary + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if or .Values.primary.service.headless.annotations .Values.commonAnnotations }} + annotations: + {{- if .Values.primary.service.headless.annotations }} + {{- include "common.tplvalues.render" (dict "value" .Values.primary.service.headless.annotations "context" $) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} + {{- end }} +spec: + type: ClusterIP + clusterIP: None + publishNotReadyAddresses: true + ports: + - name: mysql + port: {{ .Values.primary.service.ports.mysql }} + targetPort: mysql + selector: {{ include "common.labels.matchLabels" . | nindent 4 }} + app.kubernetes.io/component: primary diff --git a/helm/ghost/charts/mysql/templates/primary/svc.yaml b/helm/ghost/charts/mysql/templates/primary/svc.yaml new file mode 100644 index 0000000..2ee9cdc --- /dev/null +++ b/helm/ghost/charts/mysql/templates/primary/svc.yaml @@ -0,0 +1,57 @@ +{{- /* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +apiVersion: v1 +kind: Service +metadata: + name: {{ include "mysql.primary.fullname" . }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + app.kubernetes.io/component: primary + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + annotations: + {{- if .Values.commonAnnotations }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.primary.service.annotations }} + {{- include "common.tplvalues.render" ( dict "value" .Values.primary.service.annotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + type: {{ .Values.primary.service.type }} + {{- if and .Values.primary.service.clusterIP (eq .Values.primary.service.type "ClusterIP") }} + clusterIP: {{ .Values.primary.service.clusterIP }} + {{- end }} + {{- if .Values.primary.service.sessionAffinity }} + sessionAffinity: {{ .Values.primary.service.sessionAffinity }} + {{- end }} + {{- if .Values.primary.service.sessionAffinityConfig }} + sessionAffinityConfig: {{- include "common.tplvalues.render" (dict "value" .Values.primary.service.sessionAffinityConfig "context" $) | nindent 4 }} + {{- end }} + {{- if or (eq .Values.primary.service.type "LoadBalancer") (eq .Values.primary.service.type "NodePort") }} + externalTrafficPolicy: {{ .Values.primary.service.externalTrafficPolicy | quote }} + {{- end }} + {{- if and (eq .Values.primary.service.type "LoadBalancer") (not (empty .Values.primary.service.loadBalancerSourceRanges)) }} + loadBalancerSourceRanges: {{ .Values.primary.service.loadBalancerSourceRanges }} + {{- end }} + {{- if and (eq .Values.primary.service.type "LoadBalancer") (not (empty .Values.primary.service.loadBalancerIP)) }} + loadBalancerIP: {{ .Values.primary.service.loadBalancerIP }} + {{- end }} + ports: + - name: mysql + port: {{ .Values.primary.service.ports.mysql }} + protocol: TCP + targetPort: mysql + {{- if (and (or (eq .Values.primary.service.type "NodePort") (eq .Values.primary.service.type "LoadBalancer")) .Values.primary.service.nodePorts.mysql) }} + nodePort: {{ .Values.primary.service.nodePorts.mysql }} + {{- else if eq .Values.primary.service.type "ClusterIP" }} + nodePort: null + {{- end }} + {{- if .Values.primary.service.extraPorts }} + {{- include "common.tplvalues.render" (dict "value" .Values.primary.service.extraPorts "context" $) | nindent 4 }} + {{- end }} + selector: {{ include "common.labels.matchLabels" . | nindent 4 }} + app.kubernetes.io/component: primary diff --git a/helm/ghost/charts/mysql/templates/prometheusrule.yaml b/helm/ghost/charts/mysql/templates/prometheusrule.yaml new file mode 100644 index 0000000..acf1cee --- /dev/null +++ b/helm/ghost/charts/mysql/templates/prometheusrule.yaml @@ -0,0 +1,27 @@ +{{- /* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if and .Values.metrics.enabled .Values.metrics.prometheusRule.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: {{ include "common.names.fullname" . }} + namespace: {{ default .Release.Namespace .Values.metrics.prometheusRule.namespace }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + app.kubernetes.io/component: metrics + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.metrics.prometheusRule.additionalLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.metrics.prometheusRule.additionalLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + groups: + - name: {{ include "common.names.fullname" . }} + rules: {{- include "common.tplvalues.render" ( dict "value" .Values.metrics.prometheusRule.rules "context" $ ) | nindent 6 }} +{{- end }} diff --git a/helm/ghost/charts/mysql/templates/role.yaml b/helm/ghost/charts/mysql/templates/role.yaml new file mode 100644 index 0000000..ed05cf4 --- /dev/null +++ b/helm/ghost/charts/mysql/templates/role.yaml @@ -0,0 +1,29 @@ +{{- /* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if and .Values.serviceAccount.create .Values.rbac.create }} +apiVersion: {{ include "common.capabilities.rbac.apiVersion" . }} +kind: Role +metadata: + name: {{ include "common.names.fullname" . }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +rules: + - apiGroups: + - "" + resources: + - endpoints + verbs: + - get + {{- if .Values.rbac.rules }} + {{- include "common.tplvalues.render" ( dict "value" .Values.rbac.rules "context" $ ) | nindent 2 }} + {{- end }} +{{- end }} diff --git a/helm/ghost/charts/mysql/templates/rolebinding.yaml b/helm/ghost/charts/mysql/templates/rolebinding.yaml new file mode 100644 index 0000000..43594db --- /dev/null +++ b/helm/ghost/charts/mysql/templates/rolebinding.yaml @@ -0,0 +1,26 @@ +{{- /* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if and .Values.serviceAccount.create .Values.rbac.create }} +kind: RoleBinding +apiVersion: {{ include "common.capabilities.rbac.apiVersion" . }} +metadata: + name: {{ include "common.names.fullname" . }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +subjects: + - kind: ServiceAccount + name: {{ include "mysql.serviceAccountName" . }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ include "common.names.fullname" . -}} +{{- end }} diff --git a/helm/ghost/charts/mysql/templates/secondary/configmap.yaml b/helm/ghost/charts/mysql/templates/secondary/configmap.yaml new file mode 100644 index 0000000..19537c0 --- /dev/null +++ b/helm/ghost/charts/mysql/templates/secondary/configmap.yaml @@ -0,0 +1,23 @@ +{{- /* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if (include "mysql.secondary.createConfigmap" .) }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "mysql.secondary.fullname" . }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + app.kubernetes.io/component: secondary + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +data: + my.cnf: |- + {{- include "common.tplvalues.render" ( dict "value" .Values.secondary.configuration "context" $ ) | nindent 4 }} +{{- end -}} diff --git a/helm/ghost/charts/mysql/templates/secondary/pdb.yaml b/helm/ghost/charts/mysql/templates/secondary/pdb.yaml new file mode 100644 index 0000000..501c7aa --- /dev/null +++ b/helm/ghost/charts/mysql/templates/secondary/pdb.yaml @@ -0,0 +1,30 @@ +{{- /* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if and (eq .Values.architecture "replication") .Values.secondary.pdb.create }} +apiVersion: {{ include "common.capabilities.policy.apiVersion" . }} +kind: PodDisruptionBudget +metadata: + name: {{ include "mysql.secondary.fullname" . }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + app.kubernetes.io/component: secondary + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + {{- if .Values.secondary.pdb.minAvailable }} + minAvailable: {{ .Values.secondary.pdb.minAvailable }} + {{- end }} + {{- if .Values.secondary.pdb.maxUnavailable }} + maxUnavailable: {{ .Values.secondary.pdb.maxUnavailable }} + {{- end }} + selector: + matchLabels: {{ include "common.labels.matchLabels" . | nindent 6 }} + app.kubernetes.io/component: secondary +{{- end }} diff --git a/helm/ghost/charts/mysql/templates/secondary/statefulset.yaml b/helm/ghost/charts/mysql/templates/secondary/statefulset.yaml new file mode 100644 index 0000000..56857f7 --- /dev/null +++ b/helm/ghost/charts/mysql/templates/secondary/statefulset.yaml @@ -0,0 +1,374 @@ +{{- /* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if eq .Values.architecture "replication" }} +apiVersion: {{ include "common.capabilities.statefulset.apiVersion" . }} +kind: StatefulSet +metadata: + name: {{ include "mysql.secondary.fullname" . }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + app.kubernetes.io/component: secondary + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + replicas: {{ .Values.secondary.replicaCount }} + podManagementPolicy: {{ .Values.secondary.podManagementPolicy | quote }} + selector: + matchLabels: {{ include "common.labels.matchLabels" . | nindent 6 }} + app.kubernetes.io/component: secondary + serviceName: {{ include "mysql.secondary.fullname" . }} + {{- if .Values.secondary.updateStrategy }} + updateStrategy: {{- toYaml .Values.secondary.updateStrategy | nindent 4 }} + {{- end }} + template: + metadata: + annotations: + {{- if (include "mysql.secondary.createConfigmap" .) }} + checksum/configuration: {{ include (print $.Template.BasePath "/secondary/configmap.yaml") . | sha256sum }} + {{- end }} + {{- if .Values.secondary.podAnnotations }} + {{- include "common.tplvalues.render" (dict "value" .Values.secondary.podAnnotations "context" $) | nindent 8 }} + {{- end }} + labels: {{- include "common.labels.standard" . | nindent 8 }} + app.kubernetes.io/component: secondary + {{- if .Values.secondary.podLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.secondary.podLabels "context" $ ) | nindent 8 }} + {{- end }} + spec: + serviceAccountName: {{ include "mysql.serviceAccountName" . }} + {{- include "mysql.imagePullSecrets" . | nindent 6 }} + {{- if .Values.secondary.hostAliases }} + hostAliases: {{- include "common.tplvalues.render" (dict "value" .Values.secondary.hostAliases "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.secondary.affinity }} + affinity: {{- include "common.tplvalues.render" (dict "value" .Values.secondary.affinity "context" $) | nindent 8 }} + {{- else }} + affinity: + podAffinity: {{- include "common.affinities.pods" (dict "type" .Values.secondary.podAffinityPreset "context" $) | nindent 10 }} + podAntiAffinity: {{- include "common.affinities.pods" (dict "type" .Values.secondary.podAntiAffinityPreset "context" $) | nindent 10 }} + nodeAffinity: {{- include "common.affinities.nodes" (dict "type" .Values.secondary.nodeAffinityPreset.type "key" .Values.secondary.nodeAffinityPreset.key "values" .Values.secondary.nodeAffinityPreset.values) | nindent 10 }} + {{- end }} + {{- if .Values.secondary.nodeSelector }} + nodeSelector: {{- include "common.tplvalues.render" (dict "value" .Values.secondary.nodeSelector "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.secondary.tolerations }} + tolerations: {{- include "common.tplvalues.render" (dict "value" .Values.secondary.tolerations "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.secondary.priorityClassName }} + priorityClassName: {{ .Values.secondary.priorityClassName | quote }} + {{- end }} + {{- if .Values.secondary.runtimeClassName }} + runtimeClassName: {{ .Values.secondary.runtimeClassName | quote }} + {{- end }} + {{- if .Values.secondary.schedulerName }} + schedulerName: {{ .Values.secondary.schedulerName | quote }} + {{- end }} + {{- if .Values.secondary.topologySpreadConstraints }} + topologySpreadConstraints: {{- include "common.tplvalues.render" (dict "value" .Values.secondary.topologySpreadConstraints "context" .) | nindent 8 }} + {{- end }} + {{- if .Values.secondary.podSecurityContext.enabled }} + securityContext: {{- omit .Values.secondary.podSecurityContext "enabled" | toYaml | nindent 8 }} + {{- end }} + {{- if .Values.secondary.terminationGracePeriodSeconds }} + terminationGracePeriodSeconds: {{ .Values.secondary.terminationGracePeriodSeconds }} + {{- end }} + initContainers: + {{- if and .Values.secondary.podSecurityContext.enabled .Values.volumePermissions.enabled .Values.secondary.persistence.enabled }} + - name: volume-permissions + image: {{ include "mysql.volumePermissions.image" . }} + imagePullPolicy: {{ .Values.volumePermissions.image.pullPolicy | quote }} + command: + - /bin/bash + - -ec + - | + mkdir -p "/bitnami/mysql" + chown "{{ .Values.secondary.containerSecurityContext.runAsUser }}:{{ .Values.secondary.podSecurityContext.fsGroup }}" "/bitnami/mysql" + find "/bitnami/mysql" -mindepth 1 -maxdepth 1 -not -name ".snapshot" -not -name "lost+found" | xargs -r chown -R "{{ .Values.secondary.containerSecurityContext.runAsUser }}:{{ .Values.secondary.podSecurityContext.fsGroup }}" + securityContext: + runAsUser: 0 + {{- if .Values.volumePermissions.resources }} + resources: {{- toYaml .Values.volumePermissions.resources | nindent 12 }} + {{- end }} + volumeMounts: + - name: data + mountPath: /bitnami/mysql + {{- if .Values.secondary.persistence.subPath }} + subPath: {{ .Values.secondary.persistence.subPath }} + {{- end }} + {{- end }} + {{- if .Values.secondary.initContainers }} + {{- include "common.tplvalues.render" (dict "value" .Values.secondary.initContainers "context" $) | nindent 8 }} + {{- end }} + containers: + - name: mysql + image: {{ include "mysql.image" . }} + imagePullPolicy: {{ .Values.image.pullPolicy | quote }} + {{- if .Values.secondary.containerSecurityContext.enabled }} + securityContext: {{- omit .Values.secondary.containerSecurityContext "enabled" | toYaml | nindent 12 }} + {{- end }} + {{- if .Values.diagnosticMode.enabled }} + command: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.command "context" $) | nindent 12 }} + {{- else if .Values.secondary.command }} + command: {{- include "common.tplvalues.render" (dict "value" .Values.secondary.command "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.diagnosticMode.enabled }} + args: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.args "context" $) | nindent 12 }} + {{- else if .Values.secondary.args }} + args: {{- include "common.tplvalues.render" (dict "value" .Values.secondary.args "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.secondary.lifecycleHooks }} + lifecycle: {{- include "common.tplvalues.render" (dict "value" .Values.secondary.lifecycleHooks "context" $) | nindent 12 }} + {{- end }} + env: + - name: BITNAMI_DEBUG + value: {{ ternary "true" "false" (or .Values.image.debug .Values.diagnosticMode.enabled) | quote }} + - name: MYSQL_REPLICATION_MODE + value: "slave" + - name: MYSQL_MASTER_HOST + value: {{ include "mysql.primary.fullname" . }} + - name: MYSQL_MASTER_PORT_NUMBER + value: {{ .Values.primary.service.ports.mysql | quote }} + - name: MYSQL_MASTER_ROOT_USER + value: "root" + - name: MYSQL_REPLICATION_USER + value: {{ .Values.auth.replicationUser | quote }} + {{- if .Values.auth.usePasswordFiles }} + - name: MYSQL_MASTER_ROOT_PASSWORD_FILE + value: {{ default "/opt/bitnami/mysql/secrets/mysql-root-password" .Values.auth.customPasswordFiles.root }} + - name: MYSQL_REPLICATION_PASSWORD_FILE + value: {{ default "/opt/bitnami/mysql/secrets/mysql-replication-password" .Values.auth.customPasswordFiles.replicator }} + {{- else }} + - name: MYSQL_MASTER_ROOT_PASSWORD + valueFrom: + secretKeyRef: + name: {{ template "mysql.secretName" . }} + key: mysql-root-password + - name: MYSQL_REPLICATION_PASSWORD + valueFrom: + secretKeyRef: + name: {{ template "mysql.secretName" . }} + key: mysql-replication-password + {{- end }} + {{- if .Values.secondary.extraFlags }} + - name: MYSQL_EXTRA_FLAGS + value: "{{ .Values.secondary.extraFlags }}" + {{- end }} + {{- if .Values.secondary.extraEnvVars }} + {{- include "common.tplvalues.render" (dict "value" .Values.secondary.extraEnvVars "context" $) | nindent 12 }} + {{- end }} + envFrom: + {{- if .Values.secondary.extraEnvVarsCM }} + - configMapRef: + name: {{ include "common.tplvalues.render" (dict "value" .Values.secondary.extraEnvVarsCM "context" $) }} + {{- end }} + {{- if .Values.secondary.extraEnvVarsSecret }} + - secretRef: + name: {{ include "common.tplvalues.render" (dict "value" .Values.secondary.extraEnvVarsSecret "context" $) }} + {{- end }} + ports: + - name: mysql + containerPort: 3306 + {{- if .Values.secondary.extraPorts }} + {{- include "common.tplvalues.render" (dict "value" .Values.secondary.extraPorts "context" $) | nindent 12 }} + {{- end }} + {{- if not .Values.diagnosticMode.enabled }} + {{- if .Values.secondary.customLivenessProbe }} + livenessProbe: {{- include "common.tplvalues.render" (dict "value" .Values.secondary.customLivenessProbe "context" $) | nindent 12 }} + {{- else if .Values.secondary.livenessProbe.enabled }} + livenessProbe: {{- include "common.tplvalues.render" (dict "value" (omit .Values.secondary.livenessProbe "enabled") "context" $) | nindent 12 }} + exec: + command: + - /bin/bash + - -ec + - | + password_aux="${MYSQL_MASTER_ROOT_PASSWORD:-}" + if [[ -f "${MYSQL_MASTER_ROOT_PASSWORD_FILE:-}" ]]; then + password_aux=$(cat "$MYSQL_MASTER_ROOT_PASSWORD_FILE") + fi + mysqladmin status -uroot -p"${password_aux}" + {{- end }} + {{- if .Values.secondary.customReadinessProbe }} + readinessProbe: {{- include "common.tplvalues.render" (dict "value" .Values.secondary.customReadinessProbe "context" $) | nindent 12 }} + {{- else if .Values.secondary.readinessProbe.enabled }} + readinessProbe: {{- include "common.tplvalues.render" (dict "value" (omit .Values.secondary.readinessProbe "enabled") "context" $) | nindent 12 }} + exec: + command: + - /bin/bash + - -ec + - | + password_aux="${MYSQL_MASTER_ROOT_PASSWORD:-}" + if [[ -f "${MYSQL_MASTER_ROOT_PASSWORD_FILE:-}" ]]; then + password_aux=$(cat "$MYSQL_MASTER_ROOT_PASSWORD_FILE") + fi + mysqladmin status -uroot -p"${password_aux}" + {{- end }} + {{- if .Values.secondary.customStartupProbe }} + startupProbe: {{- include "common.tplvalues.render" (dict "value" .Values.secondary.customStartupProbe "context" $) | nindent 12 }} + {{- else if .Values.secondary.startupProbe.enabled }} + startupProbe: {{- include "common.tplvalues.render" (dict "value" (omit .Values.secondary.startupProbe "enabled") "context" $) | nindent 12 }} + exec: + command: + - /bin/bash + - -ec + - | + password_aux="${MYSQL_MASTER_ROOT_PASSWORD:-}" + if [[ -f "${MYSQL_MASTER_ROOT_PASSWORD_FILE:-}" ]]; then + password_aux=$(cat "$MYSQL_MASTER_ROOT_PASSWORD_FILE") + fi + mysqladmin status -uroot -p"${password_aux}" + {{- end }} + {{- end }} + {{- if .Values.secondary.resources }} + resources: {{ toYaml .Values.secondary.resources | nindent 12 }} + {{- end }} + volumeMounts: + - name: data + mountPath: /bitnami/mysql + {{- if .Values.secondary.persistence.subPath }} + subPath: {{ .Values.secondary.persistence.subPath }} + {{- end }} + {{- if or .Values.initdbScriptsConfigMap .Values.initdbScripts }} + - name: custom-init-scripts + mountPath: /docker-entrypoint-initdb.d + {{- end }} + {{- if or .Values.secondary.configuration .Values.secondary.existingConfigmap }} + - name: config + mountPath: /opt/bitnami/mysql/conf/my.cnf + subPath: my.cnf + {{- end }} + {{- if and .Values.auth.usePasswordFiles (not .Values.auth.customPasswordFiles) }} + - name: mysql-credentials + mountPath: /opt/bitnami/mysql/secrets/ + {{- end }} + {{- if .Values.secondary.extraVolumeMounts }} + {{- include "common.tplvalues.render" (dict "value" .Values.secondary.extraVolumeMounts "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.metrics.enabled }} + - name: metrics + image: {{ include "mysql.metrics.image" . }} + imagePullPolicy: {{ .Values.metrics.image.pullPolicy | quote }} + {{- if .Values.metrics.containerSecurityContext.enabled }} + securityContext: {{- omit .Values.metrics.containerSecurityContext "enabled" | toYaml | nindent 12 }} + {{- end }} + env: + {{- if .Values.auth.usePasswordFiles }} + - name: MYSQL_ROOT_PASSWORD_FILE + value: {{ default "/opt/bitnami/mysqld-exporter/secrets/mysql-root-password" .Values.auth.customPasswordFiles.root }} + {{- else }} + - name: MYSQL_ROOT_PASSWORD + valueFrom: + secretKeyRef: + name: {{ template "mysql.secretName" . }} + key: mysql-root-password + {{- end }} + {{- if .Values.diagnosticMode.enabled }} + command: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.command "context" $) | nindent 12 }} + args: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.args "context" $) | nindent 12 }} + {{- else }} + command: + - /bin/bash + - -ec + - | + password_aux="${MYSQL_ROOT_PASSWORD:-}" + if [[ -f "${MYSQL_ROOT_PASSWORD_FILE:-}" ]]; then + password_aux=$(cat "$MYSQL_ROOT_PASSWORD_FILE") + fi + DATA_SOURCE_NAME="root:${password_aux}@(localhost:3306)/" /bin/mysqld_exporter {{- range .Values.metrics.extraArgs.secondary }} {{ . }} {{- end }} + {{- end }} + ports: + - name: metrics + containerPort: 9104 + {{- if not .Values.diagnosticMode.enabled }} + {{- if .Values.metrics.livenessProbe.enabled }} + livenessProbe: {{- omit .Values.metrics.livenessProbe "enabled" | toYaml | nindent 12 }} + httpGet: + path: /metrics + port: metrics + {{- end }} + {{- if .Values.metrics.readinessProbe.enabled }} + readinessProbe: {{- omit .Values.metrics.readinessProbe "enabled" | toYaml | nindent 12 }} + httpGet: + path: /metrics + port: metrics + {{- end }} + {{- end }} + {{- if .Values.metrics.resources }} + resources: {{- toYaml .Values.metrics.resources | nindent 12 }} + {{- end }} + {{- if and .Values.auth.usePasswordFiles (not .Values.auth.customPasswordFiles) }} + volumeMounts: + - name: mysql-credentials + mountPath: /opt/bitnami/mysqld-exporter/secrets/ + {{- end }} + {{- end }} + {{- if .Values.secondary.sidecars }} + {{- include "common.tplvalues.render" (dict "value" .Values.secondary.sidecars "context" $) | nindent 8 }} + {{- end }} + volumes: + {{- if or .Values.initdbScriptsConfigMap .Values.initdbScripts }} + - name: custom-init-scripts + configMap: + name: {{ include "mysql.initdbScriptsCM" . }} + {{- end }} + {{- if or .Values.secondary.configuration .Values.secondary.existingConfigmap }} + - name: config + configMap: + name: {{ include "mysql.secondary.configmapName" . }} + {{- end }} + {{- if and .Values.auth.usePasswordFiles (not .Values.auth.customPasswordFiles) }} + - name: mysql-credentials + secret: + secretName: {{ template "mysql.secretName" . }} + items: + - key: mysql-root-password + path: mysql-root-password + - key: mysql-replication-password + path: mysql-replication-password + {{- end }} + {{- if .Values.secondary.extraVolumes }} + {{- include "common.tplvalues.render" (dict "value" .Values.secondary.extraVolumes "context" $) | nindent 8 }} + {{- end }} + {{- if and .Values.secondary.persistence.enabled .Values.secondary.persistence.existingClaim }} + - name: data + persistentVolumeClaim: + claimName: {{ tpl .Values.secondary.persistence.existingClaim . }} + {{- else if not .Values.secondary.persistence.enabled }} + - name: data + emptyDir: {} + {{- else }} + volumeClaimTemplates: + - metadata: + name: data + labels: {{ include "common.labels.matchLabels" . | nindent 10 }} + app.kubernetes.io/component: secondary + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" (dict "value" .Values.commonLabels "context" $) | nindent 10 }} + {{- end }} + annotations: + {{- if .Values.secondary.persistence.annotations }} + {{- include "common.tplvalues.render" (dict "value" .Values.secondary.persistence.annotations "context" $) | nindent 10 }} + {{- end }} + {{- if .Values.commonAnnotations }} + {{- include "common.tplvalues.render" (dict "value" .Values.commonAnnotations "context" $) | nindent 10 }} + {{- end }} + spec: + accessModes: + {{- range .Values.secondary.persistence.accessModes }} + - {{ . | quote }} + {{- end }} + resources: + requests: + storage: {{ .Values.secondary.persistence.size | quote }} + {{- include "common.storage.class" (dict "persistence" .Values.secondary.persistence "global" .Values.global) | nindent 8 }} + {{- if .Values.secondary.persistence.selector }} + selector: {{- include "common.tplvalues.render" (dict "value" .Values.secondary.persistence.selector "context" $) | nindent 10 }} + {{- end -}} + {{- end }} +{{- end }} diff --git a/helm/ghost/charts/mysql/templates/secondary/svc-headless.yaml b/helm/ghost/charts/mysql/templates/secondary/svc-headless.yaml new file mode 100644 index 0000000..1e64d81 --- /dev/null +++ b/helm/ghost/charts/mysql/templates/secondary/svc-headless.yaml @@ -0,0 +1,36 @@ +{{- /* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if eq .Values.architecture "replication" }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "mysql.secondary.fullname" . }}-headless + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + app.kubernetes.io/component: secondary + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if or .Values.secondary.service.headless.annotations .Values.commonAnnotations }} + annotations: + {{- if .Values.secondary.service.headless.annotations }} + {{- include "common.tplvalues.render" (dict "value" .Values.secondary.service.headless.annotations "context" $) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} + {{- end }} +spec: + type: ClusterIP + clusterIP: None + publishNotReadyAddresses: true + ports: + - name: mysql + port: {{ .Values.secondary.service.ports.mysql }} + targetPort: mysql + selector: {{ include "common.labels.matchLabels" . | nindent 4 }} + app.kubernetes.io/component: secondary +{{- end }} diff --git a/helm/ghost/charts/mysql/templates/secondary/svc.yaml b/helm/ghost/charts/mysql/templates/secondary/svc.yaml new file mode 100644 index 0000000..90ce08f --- /dev/null +++ b/helm/ghost/charts/mysql/templates/secondary/svc.yaml @@ -0,0 +1,59 @@ +{{- /* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if eq .Values.architecture "replication" }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "mysql.secondary.fullname" . }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + app.kubernetes.io/component: secondary + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + annotations: + {{- if .Values.commonAnnotations }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.secondary.service.annotations }} + {{- include "common.tplvalues.render" ( dict "value" .Values.secondary.service.annotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + type: {{ .Values.secondary.service.type }} + {{- if and .Values.secondary.service.clusterIP (eq .Values.secondary.service.type "ClusterIP") }} + clusterIP: {{ .Values.secondary.service.clusterIP }} + {{- end }} + {{- if .Values.secondary.service.sessionAffinity }} + sessionAffinity: {{ .Values.secondary.service.sessionAffinity }} + {{- end }} + {{- if .Values.secondary.service.sessionAffinityConfig }} + sessionAffinityConfig: {{- include "common.tplvalues.render" (dict "value" .Values.secondary.service.sessionAffinityConfig "context" $) | nindent 4 }} + {{- end }} + {{- if or (eq .Values.secondary.service.type "LoadBalancer") (eq .Values.secondary.service.type "NodePort") }} + externalTrafficPolicy: {{ .Values.secondary.service.externalTrafficPolicy | quote }} + {{- end }} + {{- if and (eq .Values.secondary.service.type "LoadBalancer") (not (empty .Values.secondary.service.loadBalancerSourceRanges)) }} + loadBalancerSourceRanges: {{ .Values.secondary.service.loadBalancerSourceRanges }} + {{- end }} + {{- if and (eq .Values.secondary.service.type "LoadBalancer") (not (empty .Values.secondary.service.loadBalancerIP)) }} + loadBalancerIP: {{ .Values.secondary.service.loadBalancerIP }} + {{- end }} + ports: + - name: mysql + port: {{ .Values.secondary.service.ports.mysql }} + protocol: TCP + targetPort: mysql + {{- if (and (or (eq .Values.secondary.service.type "NodePort") (eq .Values.secondary.service.type "LoadBalancer")) .Values.secondary.service.nodePorts.mysql) }} + nodePort: {{ .Values.secondary.service.nodePorts.mysql }} + {{- else if eq .Values.secondary.service.type "ClusterIP" }} + nodePort: null + {{- end }} + {{- if .Values.secondary.service.extraPorts }} + {{- include "common.tplvalues.render" (dict "value" .Values.secondary.service.extraPorts "context" $) | nindent 4 }} + {{- end }} + selector: {{ include "common.labels.matchLabels" . | nindent 4 }} + app.kubernetes.io/component: secondary +{{- end }} diff --git a/helm/ghost/charts/mysql/templates/secrets.yaml b/helm/ghost/charts/mysql/templates/secrets.yaml new file mode 100644 index 0000000..4f1be99 --- /dev/null +++ b/helm/ghost/charts/mysql/templates/secrets.yaml @@ -0,0 +1,83 @@ +{{- /* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- $host := include "mysql.primary.fullname" . }} +{{- $port := print .Values.primary.service.ports.mysql }} +{{- $rootPassword := include "common.secrets.passwords.manage" (dict "secret" (include "mysql.secretName" .) "key" "mysql-root-password" "length" 10 "providedValues" (list "auth.rootPassword") "context" $) | trimAll "\"" | b64dec }} +{{- $password := include "common.secrets.passwords.manage" (dict "secret" (include "mysql.secretName" .) "key" "mysql-password" "length" 10 "providedValues" (list "auth.password") "context" $) | trimAll "\"" | b64dec }} +{{- if eq (include "mysql.createSecret" .) "true" }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "common.names.fullname" . }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +type: Opaque +data: + mysql-root-password: {{ print $rootPassword | b64enc | quote }} + mysql-password: {{ print $password | b64enc | quote }} + {{- if eq .Values.architecture "replication" }} + mysql-replication-password: {{ include "common.secrets.passwords.manage" (dict "secret" (include "common.names.fullname" .) "key" "mysql-replication-password" "length" 10 "providedValues" (list "auth.replicationPassword") "context" $) }} + {{- end }} +{{- end }} +{{- if .Values.serviceBindings.enabled }} +--- +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "common.names.fullname" . }}-svcbind-root + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +type: servicebinding.io/mysql +data: + provider: {{ print "bitnami" | b64enc | quote }} + type: {{ print "mysql" | b64enc | quote }} + host: {{ print $host | b64enc | quote }} + port: {{ print $port | b64enc | quote }} + username: {{ print "root" | b64enc | quote }} + password: {{ print $rootPassword | b64enc | quote }} + uri: {{ printf "mysql://root:%s@%s:%s" $rootPassword $host $port | b64enc | quote }} + +{{- if .Values.auth.username }} +{{- $database := .Values.auth.database }} +--- +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "common.names.fullname" . }}-svcbind-custom-user + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +type: servicebinding.io/mysql +data: + provider: {{ print "bitnami" | b64enc | quote }} + type: {{ print "mysql" | b64enc | quote }} + host: {{ print $host | b64enc | quote }} + port: {{ print $port | b64enc | quote }} + username: {{ print .Values.auth.username | b64enc | quote }} + {{- if $database }} + database: {{ print $database | b64enc | quote }} + {{- end }} + password: {{ print $password | b64enc | quote }} + uri: {{ printf "mysql://%s:%s@%s:%s/%s" .Values.auth.username $password $host $port $database | b64enc | quote }} +{{- end }} +{{- end }} diff --git a/helm/ghost/charts/mysql/templates/serviceaccount.yaml b/helm/ghost/charts/mysql/templates/serviceaccount.yaml new file mode 100644 index 0000000..4c62829 --- /dev/null +++ b/helm/ghost/charts/mysql/templates/serviceaccount.yaml @@ -0,0 +1,28 @@ +{{- /* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if .Values.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "mysql.serviceAccountName" . }} + namespace: {{ include "common.names.namespace" . | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + annotations: + {{- if .Values.commonAnnotations }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.serviceAccount.annotations }} + {{- include "common.tplvalues.render" ( dict "value" .Values.serviceAccount.annotations "context" $ ) | nindent 4 }} + {{- end }} +automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }} +{{- if (not .Values.auth.customPasswordFiles) }} +secrets: + - name: {{ template "mysql.secretName" . }} +{{- end }} +{{- end }} diff --git a/helm/ghost/charts/mysql/templates/servicemonitor.yaml b/helm/ghost/charts/mysql/templates/servicemonitor.yaml new file mode 100644 index 0000000..7062120 --- /dev/null +++ b/helm/ghost/charts/mysql/templates/servicemonitor.yaml @@ -0,0 +1,54 @@ +{{- /* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if and .Values.metrics.enabled .Values.metrics.serviceMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ include "common.names.fullname" . }} + namespace: {{ default (include "common.names.namespace" .) .Values.metrics.serviceMonitor.namespace }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.metrics.serviceMonitor.labels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.metrics.serviceMonitor.labels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + annotations: + {{- if .Values.commonAnnotations }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.metrics.serviceMonitor.annotations }} + {{- include "common.tplvalues.render" ( dict "value" .Values.metrics.serviceMonitor.annotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + jobLabel: {{ .Values.metrics.serviceMonitor.jobLabel | quote }} + endpoints: + - port: metrics + {{- if .Values.metrics.serviceMonitor.interval }} + interval: {{ .Values.metrics.serviceMonitor.interval }} + {{- end }} + {{- if .Values.metrics.serviceMonitor.scrapeTimeout }} + scrapeTimeout: {{ .Values.metrics.serviceMonitor.scrapeTimeout }} + {{- end }} + {{- if .Values.metrics.serviceMonitor.honorLabels }} + honorLabels: {{ .Values.metrics.serviceMonitor.honorLabels }} + {{- end }} + {{- if .Values.metrics.serviceMonitor.metricRelabelings }} + metricRelabelings: {{- include "common.tplvalues.render" ( dict "value" .Values.metrics.serviceMonitor.metricRelabelings "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.metrics.serviceMonitor.relabelings }} + relabelings: {{- include "common.tplvalues.render" ( dict "value" .Values.metrics.serviceMonitor.relabelings "context" $) | nindent 8 }} + {{- end }} + namespaceSelector: + matchNames: + - {{ include "common.names.namespace" . | quote }} + selector: + matchLabels: {{- include "common.labels.matchLabels" . | nindent 6 }} + app.kubernetes.io/component: metrics + {{- if .Values.metrics.serviceMonitor.selector }} + {{- include "common.tplvalues.render" (dict "value" .Values.metrics.serviceMonitor.selector "context" $) | nindent 6 }} + {{- end }} +{{- end }} diff --git a/helm/ghost/charts/mysql/values.schema.json b/helm/ghost/charts/mysql/values.schema.json new file mode 100644 index 0000000..df59156 --- /dev/null +++ b/helm/ghost/charts/mysql/values.schema.json @@ -0,0 +1,195 @@ +{ + "$schema": "http://json-schema.org/schema#", + "type": "object", + "properties": { + "architecture": { + "type": "string", + "title": "MySQL architecture", + "form": true, + "description": "Allowed values: `standalone` or `replication`", + "enum": ["standalone", "replication"] + }, + "auth": { + "type": "object", + "title": "Authentication configuration", + "form": true, + "required": ["username", "password"], + "if": { + "properties": { + "createDatabase": { "enum": [ true ] } + } + }, + "then": { + "properties": { + "database": { + "pattern": "[a-zA-Z0-9]{1,64}" + } + } + }, + "properties": { + "rootPassword": { + "type": "string", + "title": "MySQL root password", + "description": "Defaults to a random 10-character alphanumeric string if not set" + }, + "database": { + "type": "string", + "title": "MySQL custom database name", + "maxLength": 64 + }, + "username": { + "type": "string", + "title": "MySQL custom username" + }, + "password": { + "type": "string", + "title": "MySQL custom password" + }, + "replicationUser": { + "type": "string", + "title": "MySQL replication username" + }, + "replicationPassword": { + "type": "string", + "title": "MySQL replication password" + }, + "createDatabase": { + "type": "boolean", + "title": "MySQL create custom database" + } + } + }, + "primary": { + "type": "object", + "title": "Primary database configuration", + "form": true, + "properties": { + "podSecurityContext": { + "type": "object", + "title": "MySQL primary Pod security context", + "properties": { + "enabled": { + "type": "boolean", + "default": false + }, + "fsGroup": { + "type": "integer", + "default": 1001, + "hidden": { + "value": false, + "path": "primary/podSecurityContext/enabled" + } + } + } + }, + "containerSecurityContext": { + "type": "object", + "title": "MySQL primary container security context", + "properties": { + "enabled": { + "type": "boolean", + "default": false + }, + "runAsUser": { + "type": "integer", + "default": 1001, + "hidden": { + "value": false, + "path": "primary/containerSecurityContext/enabled" + } + } + } + }, + "persistence": { + "type": "object", + "title": "Enable persistence using Persistent Volume Claims", + "properties": { + "enabled": { + "type": "boolean", + "default": true, + "title": "If true, use a Persistent Volume Claim, If false, use emptyDir" + }, + "size": { + "type": "string", + "title": "Persistent Volume Size", + "form": true, + "render": "slider", + "sliderMin": 1, + "sliderUnit": "Gi", + "hidden": { + "value": false, + "path": "primary/persistence/enabled" + } + } + } + } + } + }, + "secondary": { + "type": "object", + "title": "Secondary database configuration", + "form": true, + "properties": { + "podSecurityContext": { + "type": "object", + "title": "MySQL secondary Pod security context", + "properties": { + "enabled": { + "type": "boolean", + "default": false + }, + "fsGroup": { + "type": "integer", + "default": 1001, + "hidden": { + "value": false, + "path": "secondary/podSecurityContext/enabled" + } + } + } + }, + "containerSecurityContext": { + "type": "object", + "title": "MySQL secondary container security context", + "properties": { + "enabled": { + "type": "boolean", + "default": false + }, + "runAsUser": { + "type": "integer", + "default": 1001, + "hidden": { + "value": false, + "path": "secondary/containerSecurityContext/enabled" + } + } + } + }, + "persistence": { + "type": "object", + "title": "Enable persistence using Persistent Volume Claims", + "properties": { + "enabled": { + "type": "boolean", + "default": true, + "title": "If true, use a Persistent Volume Claim, If false, use emptyDir" + }, + "size": { + "type": "string", + "title": "Persistent Volume Size", + "form": true, + "render": "slider", + "sliderMin": 1, + "sliderUnit": "Gi", + "hidden": { + "value": false, + "path": "secondary/persistence/enabled" + } + } + } + } + } + } + } +} diff --git a/helm/ghost/charts/mysql/values.yaml b/helm/ghost/charts/mysql/values.yaml new file mode 100644 index 0000000..e1bbb55 --- /dev/null +++ b/helm/ghost/charts/mysql/values.yaml @@ -0,0 +1,1248 @@ +# Copyright VMware, Inc. +# SPDX-License-Identifier: APACHE-2.0 + +## @section Global parameters +## Global Docker image parameters +## Please, note that this will override the image parameters, including dependencies, configured to use the global value +## Current available global Docker image parameters: imageRegistry, imagePullSecrets and storageClass +## + +## @param global.imageRegistry Global Docker image registry +## @param global.imagePullSecrets Global Docker registry secret names as an array +## @param global.storageClass Global StorageClass for Persistent Volume(s) +## +global: + imageRegistry: "" + ## E.g. + ## imagePullSecrets: + ## - myRegistryKeySecretName + ## + imagePullSecrets: [] + storageClass: "" + +## @section Common parameters +## + +## @param kubeVersion Force target Kubernetes version (using Helm capabilities if not set) +## +kubeVersion: "" +## @param nameOverride String to partially override common.names.fullname template (will maintain the release name) +## +nameOverride: "" +## @param fullnameOverride String to fully override common.names.fullname template +## +fullnameOverride: "" +## @param namespaceOverride String to fully override common.names.namespace +## +namespaceOverride: "" +## @param clusterDomain Cluster domain +## +clusterDomain: cluster.local +## @param commonAnnotations Common annotations to add to all MySQL resources (sub-charts are not considered). Evaluated as a template +## +commonAnnotations: {} +## @param commonLabels Common labels to add to all MySQL resources (sub-charts are not considered). Evaluated as a template +## +commonLabels: {} +## @param extraDeploy Array with extra yaml to deploy with the chart. Evaluated as a template +## +extraDeploy: [] + +## @param serviceBindings.enabled Create secret for service binding (Experimental) +## Ref: https://servicebinding.io/service-provider/ +## +serviceBindings: + enabled: false + +## Enable diagnostic mode in the deployment +## +diagnosticMode: + ## @param diagnosticMode.enabled Enable diagnostic mode (all probes will be disabled and the command will be overridden) + ## + enabled: false + ## @param diagnosticMode.command Command to override all containers in the deployment + ## + command: + - sleep + ## @param diagnosticMode.args Args to override all containers in the deployment + ## + args: + - infinity + +## @section MySQL common parameters +## + +## Bitnami MySQL image +## ref: https://hub.docker.com/r/bitnami/mysql/tags/ +## @param image.registry MySQL image registry +## @param image.repository MySQL image repository +## @param image.tag MySQL image tag (immutable tags are recommended) +## @param image.digest MySQL image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag +## @param image.pullPolicy MySQL image pull policy +## @param image.pullSecrets Specify docker-registry secret names as an array +## @param image.debug Specify if debug logs should be enabled +## +image: + registry: docker.io + repository: bitnami/mysql + tag: 8.0.33-debian-11-r30 + digest: "" + ## Specify a imagePullPolicy + ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' + ## ref: https://kubernetes.io/docs/user-guide/images/#pre-pulling-images + ## + pullPolicy: IfNotPresent + ## Optionally specify an array of imagePullSecrets (secrets must be manually created in the namespace) + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ + ## Example: + ## pullSecrets: + ## - myRegistryKeySecretName + ## + pullSecrets: [] + ## Set to true if you would like to see extra information on logs + ## It turns BASH and/or NAMI debugging in the image + ## + debug: false +## @param architecture MySQL architecture (`standalone` or `replication`) +## +architecture: standalone +## MySQL Authentication parameters +## +auth: + ## @param auth.rootPassword Password for the `root` user. Ignored if existing secret is provided + ## ref: https://github.com/bitnami/containers/tree/main/bitnami/mysql#setting-the-root-password-on-first-run + ## + rootPassword: "" + ## @param auth.createDatabase Whether to create the .Values.auth.database or not + ## ref: https://github.com/bitnami/containers/tree/main/bitnami/mysql#creating-a-database-on-first-run + ## + createDatabase: true + ## @param auth.database Name for a custom database to create + ## ref: https://github.com/bitnami/containers/tree/main/bitnami/mysql#creating-a-database-on-first-run + ## + database: "my_database" + ## @param auth.username Name for a custom user to create + ## ref: https://github.com/bitnami/containers/tree/main/bitnami/mysql#creating-a-database-user-on-first-run + ## + username: "" + ## @param auth.password Password for the new user. Ignored if existing secret is provided + ## + password: "" + ## @param auth.replicationUser MySQL replication user + ## ref: https://github.com/bitnami/containers/tree/main/bitnami/mysql#setting-up-a-replication-cluster + ## + replicationUser: replicator + ## @param auth.replicationPassword MySQL replication user password. Ignored if existing secret is provided + ## + replicationPassword: "" + ## @param auth.existingSecret Use existing secret for password details. The secret has to contain the keys `mysql-root-password`, `mysql-replication-password` and `mysql-password` + ## NOTE: When it's set the auth.rootPassword, auth.password, auth.replicationPassword are ignored. + ## + existingSecret: "" + ## @param auth.usePasswordFiles Mount credentials as files instead of using an environment variable + ## + usePasswordFiles: false + ## @param auth.customPasswordFiles Use custom password files when `auth.usePasswordFiles` is set to `true`. Define path for keys `root` and `user`, also define `replicator` if `architecture` is set to `replication` + ## Example: + ## customPasswordFiles: + ## root: /vault/secrets/mysql-root + ## user: /vault/secrets/mysql-user + ## replicator: /vault/secrets/mysql-replicator + ## + customPasswordFiles: {} +## @param initdbScripts Dictionary of initdb scripts +## Specify dictionary of scripts to be run at first boot +## Example: +## initdbScripts: +## my_init_script.sh: | +## #!/bin/bash +## echo "Do something." +## +initdbScripts: {} +## @param initdbScriptsConfigMap ConfigMap with the initdb scripts (Note: Overrides `initdbScripts`) +## +initdbScriptsConfigMap: "" + +## @section MySQL Primary parameters +## + +primary: + ## @param primary.name Name of the primary database (eg primary, master, leader, ...) + ## + name: primary + ## @param primary.command Override default container command on MySQL Primary container(s) (useful when using custom images) + ## + command: [] + ## @param primary.args Override default container args on MySQL Primary container(s) (useful when using custom images) + ## + args: [] + ## @param primary.lifecycleHooks for the MySQL Primary container(s) to automate configuration before or after startup + ## + lifecycleHooks: {} + ## @param primary.hostAliases Deployment pod host aliases + ## https://kubernetes.io/docs/concepts/services-networking/add-entries-to-pod-etc-hosts-with-host-aliases/ + ## + hostAliases: [] + ## @param primary.configuration [string] Configure MySQL Primary with a custom my.cnf file + ## ref: https://mysql.com/kb/en/mysql/configuring-mysql-with-mycnf/#example-of-configuration-file + ## + configuration: |- + [mysqld] + default_authentication_plugin=mysql_native_password + skip-name-resolve + explicit_defaults_for_timestamp + basedir=/opt/bitnami/mysql + plugin_dir=/opt/bitnami/mysql/lib/plugin + port=3306 + socket=/opt/bitnami/mysql/tmp/mysql.sock + datadir=/bitnami/mysql/data + tmpdir=/opt/bitnami/mysql/tmp + max_allowed_packet=16M + bind-address=* + pid-file=/opt/bitnami/mysql/tmp/mysqld.pid + log-error=/opt/bitnami/mysql/logs/mysqld.log + character-set-server=UTF8 + collation-server=utf8_general_ci + slow_query_log=0 + long_query_time=10.0 + + [client] + port=3306 + socket=/opt/bitnami/mysql/tmp/mysql.sock + default-character-set=UTF8 + plugin_dir=/opt/bitnami/mysql/lib/plugin + + [manager] + port=3306 + socket=/opt/bitnami/mysql/tmp/mysql.sock + pid-file=/opt/bitnami/mysql/tmp/mysqld.pid + ## @param primary.existingConfigmap Name of existing ConfigMap with MySQL Primary configuration. + ## NOTE: When it's set the 'configuration' parameter is ignored + ## + existingConfigmap: "" + ## @param primary.updateStrategy.type Update strategy type for the MySQL primary statefulset + ## ref: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#update-strategies + ## + updateStrategy: + type: RollingUpdate + ## @param primary.podAnnotations Additional pod annotations for MySQL primary pods + ## ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ + ## + podAnnotations: {} + ## @param primary.podAffinityPreset MySQL primary pod affinity preset. Ignored if `primary.affinity` is set. Allowed values: `soft` or `hard` + ## ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity + ## + podAffinityPreset: "" + ## @param primary.podAntiAffinityPreset MySQL primary pod anti-affinity preset. Ignored if `primary.affinity` is set. Allowed values: `soft` or `hard` + ## ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity + ## + podAntiAffinityPreset: soft + ## MySQL Primary node affinity preset + ## ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#node-affinity + ## + nodeAffinityPreset: + ## @param primary.nodeAffinityPreset.type MySQL primary node affinity preset type. Ignored if `primary.affinity` is set. Allowed values: `soft` or `hard` + ## + type: "" + ## @param primary.nodeAffinityPreset.key MySQL primary node label key to match Ignored if `primary.affinity` is set. + ## E.g. + ## key: "kubernetes.io/e2e-az-name" + ## + key: "" + ## @param primary.nodeAffinityPreset.values MySQL primary node label values to match. Ignored if `primary.affinity` is set. + ## E.g. + ## values: + ## - e2e-az1 + ## - e2e-az2 + ## + values: [] + ## @param primary.affinity Affinity for MySQL primary pods assignment + ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity + ## Note: podAffinityPreset, podAntiAffinityPreset, and nodeAffinityPreset will be ignored when it's set + ## + affinity: {} + ## @param primary.nodeSelector Node labels for MySQL primary pods assignment + ## ref: https://kubernetes.io/docs/user-guide/node-selection/ + ## + nodeSelector: {} + ## @param primary.tolerations Tolerations for MySQL primary pods assignment + ## ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ + ## + tolerations: [] + ## @param primary.priorityClassName MySQL primary pods' priorityClassName + ## + priorityClassName: "" + ## @param primary.runtimeClassName MySQL primary pods' runtimeClassName + ## + runtimeClassName: "" + ## @param primary.schedulerName Name of the k8s scheduler (other than default) + ## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ + ## + schedulerName: "" + ## @param primary.terminationGracePeriodSeconds In seconds, time the given to the MySQL primary pod needs to terminate gracefully + ## ref: https://kubernetes.io/docs/concepts/workloads/pods/pod/#termination-of-pods + ## + terminationGracePeriodSeconds: "" + ## @param primary.topologySpreadConstraints Topology Spread Constraints for pod assignment + ## https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ + ## The value is evaluated as a template + ## + topologySpreadConstraints: [] + ## @param primary.podManagementPolicy podManagementPolicy to manage scaling operation of MySQL primary pods + ## ref: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#pod-management-policies + ## + podManagementPolicy: "" + ## MySQL primary Pod security context + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod + ## @param primary.podSecurityContext.enabled Enable security context for MySQL primary pods + ## @param primary.podSecurityContext.fsGroup Group ID for the mounted volumes' filesystem + ## + podSecurityContext: + enabled: true + fsGroup: 1001 + ## MySQL primary container security context + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container + ## @param primary.containerSecurityContext.enabled MySQL primary container securityContext + ## @param primary.containerSecurityContext.runAsUser User ID for the MySQL primary container + ## @param primary.containerSecurityContext.runAsNonRoot Set MySQL primary container's Security Context runAsNonRoot + ## + containerSecurityContext: + enabled: true + runAsUser: 1001 + runAsNonRoot: true + ## MySQL primary container's resource requests and limits + ## ref: https://kubernetes.io/docs/user-guide/compute-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:'. + ## @param primary.resources.limits The resources limits for MySQL primary containers + ## @param primary.resources.requests The requested resources for MySQL primary containers + ## + resources: + ## Example: + ## limits: + ## cpu: 250m + ## memory: 256Mi + ## + limits: {} + ## Examples: + ## requests: + ## cpu: 250m + ## memory: 256Mi + ## + requests: {} + ## Configure extra options for liveness probe + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes + ## @param primary.livenessProbe.enabled Enable livenessProbe + ## @param primary.livenessProbe.initialDelaySeconds Initial delay seconds for livenessProbe + ## @param primary.livenessProbe.periodSeconds Period seconds for livenessProbe + ## @param primary.livenessProbe.timeoutSeconds Timeout seconds for livenessProbe + ## @param primary.livenessProbe.failureThreshold Failure threshold for livenessProbe + ## @param primary.livenessProbe.successThreshold Success threshold for livenessProbe + ## + livenessProbe: + enabled: true + initialDelaySeconds: 5 + periodSeconds: 10 + timeoutSeconds: 1 + failureThreshold: 3 + successThreshold: 1 + ## Configure extra options for readiness probe + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes + ## @param primary.readinessProbe.enabled Enable readinessProbe + ## @param primary.readinessProbe.initialDelaySeconds Initial delay seconds for readinessProbe + ## @param primary.readinessProbe.periodSeconds Period seconds for readinessProbe + ## @param primary.readinessProbe.timeoutSeconds Timeout seconds for readinessProbe + ## @param primary.readinessProbe.failureThreshold Failure threshold for readinessProbe + ## @param primary.readinessProbe.successThreshold Success threshold for readinessProbe + ## + readinessProbe: + enabled: true + initialDelaySeconds: 5 + periodSeconds: 10 + timeoutSeconds: 1 + failureThreshold: 3 + successThreshold: 1 + ## Configure extra options for startupProbe probe + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes + ## @param primary.startupProbe.enabled Enable startupProbe + ## @param primary.startupProbe.initialDelaySeconds Initial delay seconds for startupProbe + ## @param primary.startupProbe.periodSeconds Period seconds for startupProbe + ## @param primary.startupProbe.timeoutSeconds Timeout seconds for startupProbe + ## @param primary.startupProbe.failureThreshold Failure threshold for startupProbe + ## @param primary.startupProbe.successThreshold Success threshold for startupProbe + ## + startupProbe: + enabled: true + initialDelaySeconds: 15 + periodSeconds: 10 + timeoutSeconds: 1 + failureThreshold: 10 + successThreshold: 1 + ## @param primary.customLivenessProbe Override default liveness probe for MySQL primary containers + ## + customLivenessProbe: {} + ## @param primary.customReadinessProbe Override default readiness probe for MySQL primary containers + ## + customReadinessProbe: {} + ## @param primary.customStartupProbe Override default startup probe for MySQL primary containers + ## + customStartupProbe: {} + ## @param primary.extraFlags MySQL primary additional command line flags + ## Can be used to specify command line flags, for example: + ## E.g. + ## extraFlags: "--max-connect-errors=1000 --max_connections=155" + ## + extraFlags: "" + ## @param primary.extraEnvVars Extra environment variables to be set on MySQL primary containers + ## E.g. + ## extraEnvVars: + ## - name: TZ + ## value: "Europe/Paris" + ## + extraEnvVars: [] + ## @param primary.extraEnvVarsCM Name of existing ConfigMap containing extra env vars for MySQL primary containers + ## + extraEnvVarsCM: "" + ## @param primary.extraEnvVarsSecret Name of existing Secret containing extra env vars for MySQL primary containers + ## + extraEnvVarsSecret: "" + ## @param primary.extraPorts Extra ports to expose + ## + extraPorts: [] + ## Enable persistence using Persistent Volume Claims + ## ref: https://kubernetes.io/docs/user-guide/persistent-volumes/ + ## + persistence: + ## @param primary.persistence.enabled Enable persistence on MySQL primary replicas using a `PersistentVolumeClaim`. If false, use emptyDir + ## + enabled: true + ## @param primary.persistence.existingClaim Name of an existing `PersistentVolumeClaim` for MySQL primary replicas + ## NOTE: When it's set the rest of persistence parameters are ignored + ## + existingClaim: "" + ## @param primary.persistence.subPath The name of a volume's sub path to mount for persistence + ## + subPath: "" + ## @param primary.persistence.storageClass MySQL primary persistent volume storage Class + ## If defined, storageClassName: + ## If set to "-", storageClassName: "", which disables dynamic provisioning + ## If undefined (the default) or set to null, no storageClassName spec is + ## set, choosing the default provisioner. (gp2 on AWS, standard on + ## GKE, AWS & OpenStack) + ## + storageClass: "" + ## @param primary.persistence.annotations MySQL primary persistent volume claim annotations + ## + annotations: {} + ## @param primary.persistence.accessModes MySQL primary persistent volume access Modes + ## + accessModes: + - ReadWriteOnce + ## @param primary.persistence.size MySQL primary persistent volume size + ## + size: 8Gi + ## @param primary.persistence.selector Selector to match an existing Persistent Volume + ## selector: + ## matchLabels: + ## app: my-app + ## + selector: {} + ## @param primary.extraVolumes Optionally specify extra list of additional volumes to the MySQL Primary pod(s) + ## + extraVolumes: [] + ## @param primary.extraVolumeMounts Optionally specify extra list of additional volumeMounts for the MySQL Primary container(s) + ## + extraVolumeMounts: [] + ## @param primary.initContainers Add additional init containers for the MySQL Primary pod(s) + ## + initContainers: [] + ## @param primary.sidecars Add additional sidecar containers for the MySQL Primary pod(s) + ## + sidecars: [] + ## MySQL Primary Service parameters + ## + service: + ## @param primary.service.type MySQL Primary K8s service type + ## + type: ClusterIP + ## @param primary.service.ports.mysql MySQL Primary K8s service port + ## + ports: + mysql: 3306 + ## @param primary.service.nodePorts.mysql MySQL Primary K8s service node port + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + ## + nodePorts: + mysql: "" + ## @param primary.service.clusterIP MySQL Primary K8s service clusterIP IP + ## e.g: + ## clusterIP: None + ## + clusterIP: "" + ## @param primary.service.loadBalancerIP MySQL Primary loadBalancerIP if service type is `LoadBalancer` + ## Set the LoadBalancer service type to internal only + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#internal-load-balancer + ## + loadBalancerIP: "" + ## @param primary.service.externalTrafficPolicy Enable client source IP preservation + ## ref https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#preserving-the-client-source-ip + ## + externalTrafficPolicy: Cluster + ## @param primary.service.loadBalancerSourceRanges Addresses that are allowed when MySQL Primary service is LoadBalancer + ## https://kubernetes.io/docs/tasks/access-application-cluster/configure-cloud-provider-firewall/#restrict-access-for-loadbalancer-service + ## E.g. + ## loadBalancerSourceRanges: + ## - 10.10.10.0/24 + ## + loadBalancerSourceRanges: [] + ## @param primary.service.extraPorts Extra ports to expose (normally used with the `sidecar` value) + ## + extraPorts: [] + ## @param primary.service.annotations Additional custom annotations for MySQL primary service + ## + annotations: {} + ## @param primary.service.sessionAffinity Session Affinity for Kubernetes service, can be "None" or "ClientIP" + ## If "ClientIP", consecutive client requests will be directed to the same Pod + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + ## + sessionAffinity: None + ## @param primary.service.sessionAffinityConfig Additional settings for the sessionAffinity + ## sessionAffinityConfig: + ## clientIP: + ## timeoutSeconds: 300 + ## + sessionAffinityConfig: {} + ## Headless service properties + ## + headless: + ## @param primary.service.headless.annotations Additional custom annotations for headless MySQL primary service. + ## + annotations: {} + + ## MySQL primary Pod Disruption Budget configuration + ## ref: https://kubernetes.io/docs/tasks/run-application/configure-pdb/ + ## + pdb: + ## @param primary.pdb.create Enable/disable a Pod Disruption Budget creation for MySQL primary pods + ## + create: false + ## @param primary.pdb.minAvailable Minimum number/percentage of MySQL primary pods that should remain scheduled + ## + minAvailable: 1 + ## @param primary.pdb.maxUnavailable Maximum number/percentage of MySQL primary pods that may be made unavailable + ## + maxUnavailable: "" + ## @param primary.podLabels MySQL Primary pod label. If labels are same as commonLabels , this will take precedence + ## + podLabels: {} + +## @section MySQL Secondary parameters +## + +secondary: + ## @param secondary.name Name of the secondary database (eg secondary, slave, ...) + ## + name: secondary + ## @param secondary.replicaCount Number of MySQL secondary replicas + ## + replicaCount: 1 + ## @param secondary.hostAliases Deployment pod host aliases + ## https://kubernetes.io/docs/concepts/services-networking/add-entries-to-pod-etc-hosts-with-host-aliases/ + ## + hostAliases: [] + ## @param secondary.command Override default container command on MySQL Secondary container(s) (useful when using custom images) + ## + command: [] + ## @param secondary.args Override default container args on MySQL Secondary container(s) (useful when using custom images) + ## + args: [] + ## @param secondary.lifecycleHooks for the MySQL Secondary container(s) to automate configuration before or after startup + ## + lifecycleHooks: {} + ## @param secondary.configuration [string] Configure MySQL Secondary with a custom my.cnf file + ## ref: https://mysql.com/kb/en/mysql/configuring-mysql-with-mycnf/#example-of-configuration-file + ## + configuration: |- + [mysqld] + default_authentication_plugin=mysql_native_password + skip-name-resolve + explicit_defaults_for_timestamp + basedir=/opt/bitnami/mysql + plugin_dir=/opt/bitnami/mysql/lib/plugin + port=3306 + socket=/opt/bitnami/mysql/tmp/mysql.sock + datadir=/bitnami/mysql/data + tmpdir=/opt/bitnami/mysql/tmp + max_allowed_packet=16M + bind-address=* + pid-file=/opt/bitnami/mysql/tmp/mysqld.pid + log-error=/opt/bitnami/mysql/logs/mysqld.log + character-set-server=UTF8 + collation-server=utf8_general_ci + slow_query_log=0 + long_query_time=10.0 + + [client] + port=3306 + socket=/opt/bitnami/mysql/tmp/mysql.sock + default-character-set=UTF8 + plugin_dir=/opt/bitnami/mysql/lib/plugin + + [manager] + port=3306 + socket=/opt/bitnami/mysql/tmp/mysql.sock + pid-file=/opt/bitnami/mysql/tmp/mysqld.pid + ## @param secondary.existingConfigmap Name of existing ConfigMap with MySQL Secondary configuration. + ## NOTE: When it's set the 'configuration' parameter is ignored + ## + existingConfigmap: "" + ## @param secondary.updateStrategy.type Update strategy type for the MySQL secondary statefulset + ## ref: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#update-strategies + ## + updateStrategy: + type: RollingUpdate + ## @param secondary.podAnnotations Additional pod annotations for MySQL secondary pods + ## ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ + ## + podAnnotations: {} + ## @param secondary.podAffinityPreset MySQL secondary pod affinity preset. Ignored if `secondary.affinity` is set. Allowed values: `soft` or `hard` + ## ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity + ## + podAffinityPreset: "" + ## @param secondary.podAntiAffinityPreset MySQL secondary pod anti-affinity preset. Ignored if `secondary.affinity` is set. Allowed values: `soft` or `hard` + ## ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity + ## Allowed values: soft, hard + ## + podAntiAffinityPreset: soft + ## MySQL Secondary node affinity preset + ## ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#node-affinity + ## + nodeAffinityPreset: + ## @param secondary.nodeAffinityPreset.type MySQL secondary node affinity preset type. Ignored if `secondary.affinity` is set. Allowed values: `soft` or `hard` + ## + type: "" + ## @param secondary.nodeAffinityPreset.key MySQL secondary node label key to match Ignored if `secondary.affinity` is set. + ## E.g. + ## key: "kubernetes.io/e2e-az-name" + ## + key: "" + ## @param secondary.nodeAffinityPreset.values MySQL secondary node label values to match. Ignored if `secondary.affinity` is set. + ## E.g. + ## values: + ## - e2e-az1 + ## - e2e-az2 + ## + values: [] + ## @param secondary.affinity Affinity for MySQL secondary pods assignment + ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity + ## Note: podAffinityPreset, podAntiAffinityPreset, and nodeAffinityPreset will be ignored when it's set + ## + affinity: {} + ## @param secondary.nodeSelector Node labels for MySQL secondary pods assignment + ## ref: https://kubernetes.io/docs/user-guide/node-selection/ + ## + nodeSelector: {} + ## @param secondary.tolerations Tolerations for MySQL secondary pods assignment + ## ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ + ## + tolerations: [] + ## @param secondary.priorityClassName MySQL secondary pods' priorityClassName + ## + priorityClassName: "" + ## @param secondary.runtimeClassName MySQL secondary pods' runtimeClassName + ## + runtimeClassName: "" + ## @param secondary.schedulerName Name of the k8s scheduler (other than default) + ## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ + ## + schedulerName: "" + ## @param secondary.terminationGracePeriodSeconds In seconds, time the given to the MySQL secondary pod needs to terminate gracefully + ## ref: https://kubernetes.io/docs/concepts/workloads/pods/pod/#termination-of-pods + ## + terminationGracePeriodSeconds: "" + ## @param secondary.topologySpreadConstraints Topology Spread Constraints for pod assignment + ## https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ + ## The value is evaluated as a template + ## + topologySpreadConstraints: [] + ## @param secondary.podManagementPolicy podManagementPolicy to manage scaling operation of MySQL secondary pods + ## ref: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#pod-management-policies + ## + podManagementPolicy: "" + ## MySQL secondary Pod security context + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod + ## @param secondary.podSecurityContext.enabled Enable security context for MySQL secondary pods + ## @param secondary.podSecurityContext.fsGroup Group ID for the mounted volumes' filesystem + ## + podSecurityContext: + enabled: true + fsGroup: 1001 + ## MySQL secondary container security context + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container + ## @param secondary.containerSecurityContext.enabled MySQL secondary container securityContext + ## @param secondary.containerSecurityContext.runAsUser User ID for the MySQL secondary container + ## @param secondary.containerSecurityContext.runAsNonRoot Set MySQL secondary container's Security Context runAsNonRoot + ## + containerSecurityContext: + enabled: true + runAsUser: 1001 + runAsNonRoot: true + ## MySQL secondary container's resource requests and limits + ## ref: https://kubernetes.io/docs/user-guide/compute-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:'. + ## @param secondary.resources.limits The resources limits for MySQL secondary containers + ## @param secondary.resources.requests The requested resources for MySQL secondary containers + ## + resources: + ## Example: + ## limits: + ## cpu: 250m + ## memory: 256Mi + ## + limits: {} + ## Examples: + ## requests: + ## cpu: 250m + ## memory: 256Mi + ## + requests: {} + ## Configure extra options for liveness probe + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes + ## @param secondary.livenessProbe.enabled Enable livenessProbe + ## @param secondary.livenessProbe.initialDelaySeconds Initial delay seconds for livenessProbe + ## @param secondary.livenessProbe.periodSeconds Period seconds for livenessProbe + ## @param secondary.livenessProbe.timeoutSeconds Timeout seconds for livenessProbe + ## @param secondary.livenessProbe.failureThreshold Failure threshold for livenessProbe + ## @param secondary.livenessProbe.successThreshold Success threshold for livenessProbe + ## + livenessProbe: + enabled: true + initialDelaySeconds: 5 + periodSeconds: 10 + timeoutSeconds: 1 + failureThreshold: 3 + successThreshold: 1 + ## Configure extra options for readiness probe + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes + ## @param secondary.readinessProbe.enabled Enable readinessProbe + ## @param secondary.readinessProbe.initialDelaySeconds Initial delay seconds for readinessProbe + ## @param secondary.readinessProbe.periodSeconds Period seconds for readinessProbe + ## @param secondary.readinessProbe.timeoutSeconds Timeout seconds for readinessProbe + ## @param secondary.readinessProbe.failureThreshold Failure threshold for readinessProbe + ## @param secondary.readinessProbe.successThreshold Success threshold for readinessProbe + ## + readinessProbe: + enabled: true + initialDelaySeconds: 5 + periodSeconds: 10 + timeoutSeconds: 1 + failureThreshold: 3 + successThreshold: 1 + ## Configure extra options for startupProbe probe + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes + ## @param secondary.startupProbe.enabled Enable startupProbe + ## @param secondary.startupProbe.initialDelaySeconds Initial delay seconds for startupProbe + ## @param secondary.startupProbe.periodSeconds Period seconds for startupProbe + ## @param secondary.startupProbe.timeoutSeconds Timeout seconds for startupProbe + ## @param secondary.startupProbe.failureThreshold Failure threshold for startupProbe + ## @param secondary.startupProbe.successThreshold Success threshold for startupProbe + ## + startupProbe: + enabled: true + initialDelaySeconds: 15 + periodSeconds: 10 + timeoutSeconds: 1 + failureThreshold: 15 + successThreshold: 1 + ## @param secondary.customLivenessProbe Override default liveness probe for MySQL secondary containers + ## + customLivenessProbe: {} + ## @param secondary.customReadinessProbe Override default readiness probe for MySQL secondary containers + ## + customReadinessProbe: {} + ## @param secondary.customStartupProbe Override default startup probe for MySQL secondary containers + ## + customStartupProbe: {} + ## @param secondary.extraFlags MySQL secondary additional command line flags + ## Can be used to specify command line flags, for example: + ## E.g. + ## extraFlags: "--max-connect-errors=1000 --max_connections=155" + ## + extraFlags: "" + ## @param secondary.extraEnvVars An array to add extra environment variables on MySQL secondary containers + ## E.g. + ## extraEnvVars: + ## - name: TZ + ## value: "Europe/Paris" + ## + extraEnvVars: [] + ## @param secondary.extraEnvVarsCM Name of existing ConfigMap containing extra env vars for MySQL secondary containers + ## + extraEnvVarsCM: "" + ## @param secondary.extraEnvVarsSecret Name of existing Secret containing extra env vars for MySQL secondary containers + ## + extraEnvVarsSecret: "" + ## @param secondary.extraPorts Extra ports to expose + ## + extraPorts: [] + ## Enable persistence using Persistent Volume Claims + ## ref: https://kubernetes.io/docs/user-guide/persistent-volumes/ + ## + persistence: + ## @param secondary.persistence.enabled Enable persistence on MySQL secondary replicas using a `PersistentVolumeClaim` + ## + enabled: true + ## @param secondary.persistence.existingClaim Name of an existing `PersistentVolumeClaim` for MySQL secondary replicas + ## NOTE: When it's set the rest of persistence parameters are ignored + ## + existingClaim: "" + ## @param secondary.persistence.subPath The name of a volume's sub path to mount for persistence + ## + subPath: "" + ## @param secondary.persistence.storageClass MySQL secondary persistent volume storage Class + ## If defined, storageClassName: + ## If set to "-", storageClassName: "", which disables dynamic provisioning + ## If undefined (the default) or set to null, no storageClassName spec is + ## set, choosing the default provisioner. (gp2 on AWS, standard on + ## GKE, AWS & OpenStack) + ## + storageClass: "" + ## @param secondary.persistence.annotations MySQL secondary persistent volume claim annotations + ## + annotations: {} + ## @param secondary.persistence.accessModes MySQL secondary persistent volume access Modes + ## + accessModes: + - ReadWriteOnce + ## @param secondary.persistence.size MySQL secondary persistent volume size + ## + size: 8Gi + ## @param secondary.persistence.selector Selector to match an existing Persistent Volume + ## selector: + ## matchLabels: + ## app: my-app + ## + selector: {} + ## @param secondary.extraVolumes Optionally specify extra list of additional volumes to the MySQL secondary pod(s) + ## + extraVolumes: [] + ## @param secondary.extraVolumeMounts Optionally specify extra list of additional volumeMounts for the MySQL secondary container(s) + ## + extraVolumeMounts: [] + ## @param secondary.initContainers Add additional init containers for the MySQL secondary pod(s) + ## + initContainers: [] + ## @param secondary.sidecars Add additional sidecar containers for the MySQL secondary pod(s) + ## + sidecars: [] + ## MySQL Secondary Service parameters + ## + service: + ## @param secondary.service.type MySQL secondary Kubernetes service type + ## + type: ClusterIP + ## @param secondary.service.ports.mysql MySQL secondary Kubernetes service port + ## + ports: + mysql: 3306 + ## @param secondary.service.nodePorts.mysql MySQL secondary Kubernetes service node port + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + ## + nodePorts: + mysql: "" + ## @param secondary.service.clusterIP MySQL secondary Kubernetes service clusterIP IP + ## e.g: + ## clusterIP: None + ## + clusterIP: "" + ## @param secondary.service.loadBalancerIP MySQL secondary loadBalancerIP if service type is `LoadBalancer` + ## Set the LoadBalancer service type to internal only + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#internal-load-balancer + ## + loadBalancerIP: "" + ## @param secondary.service.externalTrafficPolicy Enable client source IP preservation + ## ref https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#preserving-the-client-source-ip + ## + externalTrafficPolicy: Cluster + ## @param secondary.service.loadBalancerSourceRanges Addresses that are allowed when MySQL secondary service is LoadBalancer + ## https://kubernetes.io/docs/tasks/access-application-cluster/configure-cloud-provider-firewall/#restrict-access-for-loadbalancer-service + ## E.g. + ## loadBalancerSourceRanges: + ## - 10.10.10.0/24 + ## + loadBalancerSourceRanges: [] + ## @param secondary.service.extraPorts Extra ports to expose (normally used with the `sidecar` value) + ## + extraPorts: [] + ## @param secondary.service.annotations Additional custom annotations for MySQL secondary service + ## + annotations: {} + ## @param secondary.service.sessionAffinity Session Affinity for Kubernetes service, can be "None" or "ClientIP" + ## If "ClientIP", consecutive client requests will be directed to the same Pod + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + ## + sessionAffinity: None + ## @param secondary.service.sessionAffinityConfig Additional settings for the sessionAffinity + ## sessionAffinityConfig: + ## clientIP: + ## timeoutSeconds: 300 + ## + sessionAffinityConfig: {} + ## Headless service properties + ## + headless: + ## @param secondary.service.headless.annotations Additional custom annotations for headless MySQL secondary service. + ## + annotations: {} + + ## MySQL secondary Pod Disruption Budget configuration + ## ref: https://kubernetes.io/docs/tasks/run-application/configure-pdb/ + ## + pdb: + ## @param secondary.pdb.create Enable/disable a Pod Disruption Budget creation for MySQL secondary pods + ## + create: false + ## @param secondary.pdb.minAvailable Minimum number/percentage of MySQL secondary pods that should remain scheduled + ## + minAvailable: 1 + ## @param secondary.pdb.maxUnavailable Maximum number/percentage of MySQL secondary pods that may be made unavailable + ## + maxUnavailable: "" + ## @param secondary.podLabels Additional pod labels for MySQL secondary pods + ## + podLabels: {} + +## @section RBAC parameters +## + +## MySQL pods ServiceAccount +## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ +## +serviceAccount: + ## @param serviceAccount.create Enable the creation of a ServiceAccount for MySQL pods + ## + create: true + ## @param serviceAccount.name Name of the created ServiceAccount + ## If not set and create is true, a name is generated using the mysql.fullname template + ## + name: "" + ## @param serviceAccount.annotations Annotations for MySQL Service Account + ## + annotations: {} + ## @param serviceAccount.automountServiceAccountToken Automount service account token for the server service account + ## + automountServiceAccountToken: true + +## Role Based Access +## ref: https://kubernetes.io/docs/admin/authorization/rbac/ +## +rbac: + ## @param rbac.create Whether to create & use RBAC resources or not + ## + create: false + ## @param rbac.rules Custom RBAC rules to set + ## e.g: + ## rules: + ## - apiGroups: + ## - "" + ## resources: + ## - pods + ## verbs: + ## - get + ## - list + ## + rules: [] + +## @section Network Policy +## + +## MySQL Nework Policy configuration +## +networkPolicy: + ## @param networkPolicy.enabled Enable creation of NetworkPolicy resources + ## + enabled: false + ## @param networkPolicy.allowExternal The Policy model to apply. + ## When set to false, only pods with the correct + ## client label will have network access to the port MySQL is listening + ## on. When true, MySQL will accept connections from any source + ## (with the correct destination port). + ## + allowExternal: true + ## @param networkPolicy.explicitNamespacesSelector A Kubernetes LabelSelector to explicitly select namespaces from which ingress traffic could be allowed to MySQL + ## If explicitNamespacesSelector is missing or set to {}, only client Pods that are in the networkPolicy's namespace + ## and that match other criteria, the ones that have the good label, can reach the DB. + ## But sometimes, we want the DB to be accessible to clients from other namespaces, in this case, we can use this + ## LabelSelector to select these namespaces, note that the networkPolicy's namespace should also be explicitly added. + ## + ## Example: + ## explicitNamespacesSelector: + ## matchLabels: + ## role: frontend + ## matchExpressions: + ## - {key: role, operator: In, values: [frontend]} + ## + explicitNamespacesSelector: {} + +## @section Volume Permissions parameters +## + +## Init containers parameters: +## volumePermissions: Change the owner and group of the persistent volume mountpoint to runAsUser:fsGroup values from the securityContext section. +## +volumePermissions: + ## @param volumePermissions.enabled Enable init container that changes the owner and group of the persistent volume(s) mountpoint to `runAsUser:fsGroup` + ## + enabled: false + ## @param volumePermissions.image.registry Init container volume-permissions image registry + ## @param volumePermissions.image.repository Init container volume-permissions image repository + ## @param volumePermissions.image.tag Init container volume-permissions image tag (immutable tags are recommended) + ## @param volumePermissions.image.digest Init container volume-permissions image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag + ## @param volumePermissions.image.pullPolicy Init container volume-permissions image pull policy + ## @param volumePermissions.image.pullSecrets Specify docker-registry secret names as an array + ## + image: + registry: docker.io + repository: bitnami/os-shell + tag: 11-debian-11-r2 + digest: "" + pullPolicy: IfNotPresent + ## Optionally specify an array of imagePullSecrets. + ## Secrets must be manually created in the namespace. + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ + ## e.g: + ## pullSecrets: + ## - myRegistryKeySecretName + ## + pullSecrets: [] + ## @param volumePermissions.resources Init container volume-permissions resources + ## + resources: {} + +## @section Metrics parameters +## + +## Mysqld Prometheus exporter parameters +## +metrics: + ## @param metrics.enabled Start a side-car prometheus exporter + ## + enabled: false + ## @param metrics.image.registry Exporter image registry + ## @param metrics.image.repository Exporter image repository + ## @param metrics.image.tag Exporter image tag (immutable tags are recommended) + ## @param metrics.image.digest Exporter image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag + ## @param metrics.image.pullPolicy Exporter image pull policy + ## @param metrics.image.pullSecrets Specify docker-registry secret names as an array + ## + image: + registry: docker.io + repository: bitnami/mysqld-exporter + tag: 0.14.0-debian-11-r138 + digest: "" + pullPolicy: IfNotPresent + ## Optionally specify an array of imagePullSecrets. + ## Secrets must be manually created in the namespace. + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ + ## e.g: + ## pullSecrets: + ## - myRegistryKeySecretName + ## + pullSecrets: [] + ## MySQL metrics container security context + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container + ## @param metrics.containerSecurityContext.enabled MySQL metrics container securityContext + ## @param metrics.containerSecurityContext.runAsUser User ID for the MySQL metrics container + ## @param metrics.containerSecurityContext.runAsNonRoot Set MySQL metrics container's Security Context runAsNonRoot + ## + containerSecurityContext: + enabled: true + runAsUser: 1001 + runAsNonRoot: true + ## MySQL Prometheus exporter service parameters + ## Mysqld Prometheus exporter liveness and readiness probes + ## ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#container-probes + ## @param metrics.service.type Kubernetes service type for MySQL Prometheus Exporter + ## @param metrics.service.clusterIP Kubernetes service clusterIP for MySQL Prometheus Exporter + ## @param metrics.service.port MySQL Prometheus Exporter service port + ## @param metrics.service.annotations [object] Prometheus exporter service annotations + ## + service: + type: ClusterIP + port: 9104 + clusterIP: "" + annotations: + prometheus.io/scrape: "true" + prometheus.io/port: "{{ .Values.metrics.service.port }}" + ## @param metrics.extraArgs.primary Extra args to be passed to mysqld_exporter on Primary pods + ## @param metrics.extraArgs.secondary Extra args to be passed to mysqld_exporter on Secondary pods + ## ref: https://github.com/prometheus/mysqld_exporter/ + ## E.g. + ## - --collect.auto_increment.columns + ## - --collect.binlog_size + ## - --collect.engine_innodb_status + ## - --collect.engine_tokudb_status + ## - --collect.global_status + ## - --collect.global_variables + ## - --collect.info_schema.clientstats + ## - --collect.info_schema.innodb_metrics + ## - --collect.info_schema.innodb_tablespaces + ## - --collect.info_schema.innodb_cmp + ## - --collect.info_schema.innodb_cmpmem + ## - --collect.info_schema.processlist + ## - --collect.info_schema.processlist.min_time + ## - --collect.info_schema.query_response_time + ## - --collect.info_schema.tables + ## - --collect.info_schema.tables.databases + ## - --collect.info_schema.tablestats + ## - --collect.info_schema.userstats + ## - --collect.perf_schema.eventsstatements + ## - --collect.perf_schema.eventsstatements.digest_text_limit + ## - --collect.perf_schema.eventsstatements.limit + ## - --collect.perf_schema.eventsstatements.timelimit + ## - --collect.perf_schema.eventswaits + ## - --collect.perf_schema.file_events + ## - --collect.perf_schema.file_instances + ## - --collect.perf_schema.indexiowaits + ## - --collect.perf_schema.tableiowaits + ## - --collect.perf_schema.tablelocks + ## - --collect.perf_schema.replication_group_member_stats + ## - --collect.slave_status + ## - --collect.slave_hosts + ## - --collect.heartbeat + ## - --collect.heartbeat.database + ## - --collect.heartbeat.table + ## + extraArgs: + primary: [] + secondary: [] + ## Mysqld Prometheus exporter resource requests and limits + ## ref: https://kubernetes.io/docs/user-guide/compute-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:'. + ## @param metrics.resources.limits The resources limits for MySQL prometheus exporter containers + ## @param metrics.resources.requests The requested resources for MySQL prometheus exporter containers + ## + resources: + ## Example: + ## limits: + ## cpu: 100m + ## memory: 256Mi + ## + limits: {} + ## Examples: + ## requests: + ## cpu: 100m + ## memory: 256Mi + ## + requests: {} + ## Mysqld Prometheus exporter liveness probe + ## ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#container-probes + ## @param metrics.livenessProbe.enabled Enable livenessProbe + ## @param metrics.livenessProbe.initialDelaySeconds Initial delay seconds for livenessProbe + ## @param metrics.livenessProbe.periodSeconds Period seconds for livenessProbe + ## @param metrics.livenessProbe.timeoutSeconds Timeout seconds for livenessProbe + ## @param metrics.livenessProbe.failureThreshold Failure threshold for livenessProbe + ## @param metrics.livenessProbe.successThreshold Success threshold for livenessProbe + ## + livenessProbe: + enabled: true + initialDelaySeconds: 120 + periodSeconds: 10 + timeoutSeconds: 1 + successThreshold: 1 + failureThreshold: 3 + ## Mysqld Prometheus exporter readiness probe + ## ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#container-probes + ## @param metrics.readinessProbe.enabled Enable readinessProbe + ## @param metrics.readinessProbe.initialDelaySeconds Initial delay seconds for readinessProbe + ## @param metrics.readinessProbe.periodSeconds Period seconds for readinessProbe + ## @param metrics.readinessProbe.timeoutSeconds Timeout seconds for readinessProbe + ## @param metrics.readinessProbe.failureThreshold Failure threshold for readinessProbe + ## @param metrics.readinessProbe.successThreshold Success threshold for readinessProbe + ## + readinessProbe: + enabled: true + initialDelaySeconds: 30 + periodSeconds: 10 + timeoutSeconds: 1 + successThreshold: 1 + failureThreshold: 3 + ## Prometheus Service Monitor + ## ref: https://github.com/coreos/prometheus-operator + ## + serviceMonitor: + ## @param metrics.serviceMonitor.enabled Create ServiceMonitor Resource for scraping metrics using PrometheusOperator + ## + enabled: false + ## @param metrics.serviceMonitor.namespace Specify the namespace in which the serviceMonitor resource will be created + ## + namespace: "" + ## @param metrics.serviceMonitor.jobLabel The name of the label on the target service to use as the job name in prometheus. + ## + jobLabel: "" + ## @param metrics.serviceMonitor.interval Specify the interval at which metrics should be scraped + ## + interval: 30s + ## @param metrics.serviceMonitor.scrapeTimeout Specify the timeout after which the scrape is ended + ## e.g: + ## scrapeTimeout: 30s + ## + scrapeTimeout: "" + ## @param metrics.serviceMonitor.relabelings RelabelConfigs to apply to samples before scraping + ## ref: https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#relabelconfig + ## + relabelings: [] + ## @param metrics.serviceMonitor.metricRelabelings MetricRelabelConfigs to apply to samples before ingestion + ## ref: https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#relabelconfig + ## + metricRelabelings: [] + ## @param metrics.serviceMonitor.selector ServiceMonitor selector labels + ## ref: https://github.com/bitnami/charts/tree/main/bitnami/prometheus-operator#prometheus-configuration + ## + ## selector: + ## prometheus: my-prometheus + ## + selector: {} + ## @param metrics.serviceMonitor.honorLabels Specify honorLabels parameter to add the scrape endpoint + ## + honorLabels: false + ## @param metrics.serviceMonitor.labels Used to pass Labels that are used by the Prometheus installed in your cluster to select Service Monitors to work with + ## ref: https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#prometheusspec + ## + labels: {} + ## @param metrics.serviceMonitor.annotations ServiceMonitor annotations + ## + annotations: {} + + ## Prometheus Operator prometheusRule configuration + ## + prometheusRule: + ## @param metrics.prometheusRule.enabled Creates a Prometheus Operator prometheusRule (also requires `metrics.enabled` to be `true` and `metrics.prometheusRule.rules`) + ## + enabled: false + ## @param metrics.prometheusRule.namespace Namespace for the prometheusRule Resource (defaults to the Release Namespace) + ## + namespace: "" + ## @param metrics.prometheusRule.additionalLabels Additional labels that can be used so prometheusRule will be discovered by Prometheus + ## + additionalLabels: {} + ## @param metrics.prometheusRule.rules Prometheus Rule definitions + ## - alert: Mysql-Down + ## expr: absent(up{job="mysql"} == 1) + ## for: 5m + ## labels: + ## severity: warning + ## service: mariadb + ## annotations: + ## message: 'MariaDB instance {{`{{`}} $labels.instance {{`}}`}} is down' + ## summary: MariaDB instance is down + ## + rules: [] diff --git a/helm/ghost/override_values_blog.yaml b/helm/ghost/override_values_blog.yaml new file mode 100644 index 0000000..0f27102 --- /dev/null +++ b/helm/ghost/override_values_blog.yaml @@ -0,0 +1,51 @@ +image: + debug: true + +ghostUsername: dsk +ghostPassword: dskadmin1234 +ghostEmail: minchulahn@ex-em.com +ghostBlogTitle: DataSaker Blog +ghostHost: blog.datasaker.io +allowEmptyPassword: false +ghostEnableHttps: true + +extraEnvVars: + - name: LOG_LEVEL + value: DEBUG + +resources: + requests: + cpu: "250m" + memory: "512Mi" + limits: + cpu: "250m" + memory: "512Mi" + +service: + type: NodePort + nodePorts: + https: 30091 + +persistence: + storageClass: "nfs-provisioner-mgmt-nas" + accessModes: + - ReadWriteMany + +mysql: + auth: + rootPassword: dskadmin1234 + database: datasaker + username: dsk + password: dskadmin1234 + primary: + service: + type: NodePort + nodePorts: + mysql: 30096 + resources: + requests: + cpu: "250m" + memory: "1Gi" + limits: + cpu: "250m" + memory: "1Gi" diff --git a/helm/ghost/override_values_docs.yaml b/helm/ghost/override_values_docs.yaml new file mode 100644 index 0000000..b349005 --- /dev/null +++ b/helm/ghost/override_values_docs.yaml @@ -0,0 +1,43 @@ +image: + debug: true + +ghostUsername: dsk +ghostPassword: dskadmin1234 +ghostEmail: minchulahn@ex-em.com +ghostBlogTitle: DataSaker Docs +ghostHost: docs.datasaker.io +allowEmptyPassword: false +ghostEnableHttps: true + +extraEnvVars: + - name: LOG_LEVEL + value: DEBUG + +resources: + requests: + cpu: "500m" + memory: "1G" + limits: + cpu: "500m" + memory: "1G" + +service: + type: NodePort + nodePorts: + https: 30092 + +persistence: + storageClass: "nfs-provisioner-mgmt-nas" + accessModes: + - ReadWriteMany + +mysql: + enabled: false + +externalDatabase: + host: 10.10.43.240 + port: 30096 + user: root + password: dskadmin1234 + database: docs + existingSecret: ghost-mysql diff --git a/helm/ghost/templates/NOTES.txt b/helm/ghost/templates/NOTES.txt new file mode 100644 index 0000000..144d27b --- /dev/null +++ b/helm/ghost/templates/NOTES.txt @@ -0,0 +1,149 @@ +CHART NAME: {{ .Chart.Name }} +CHART VERSION: {{ .Chart.Version }} +APP VERSION: {{ .Chart.AppVersion }} + +** Please be patient while the chart is being deployed ** + +{{- $ghostPasswordKey := ( include "common.secrets.key" (dict "existingSecret" .Values.existingSecret "key" "ghost-password") ) -}} +{{- $ghostSecretName := (include "common.names.fullname" .) -}} +{{- $databaseSecretName := include "ghost.databaseSecretName" . -}} + +{{- if or .Values.mysql.enabled .Values.externalDatabase.host -}} + +{{- if empty (include "ghost.host" .) -}} +############################################################################### +### ERROR: You did not provide an external host in your 'helm install' call ### +############################################################################### + +This deployment will be incomplete until you configure Ghost with a resolvable +host. To configure Ghost with the URL of your service: + +1. Get the Ghost URL by running: + + {{- if contains "NodePort" .Values.service.type }} + + export APP_HOST=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") + + {{- else if contains "LoadBalancer" .Values.service.type }} + + NOTE: It may take a few minutes for the LoadBalancer IP to be available. + Watch the status with: 'kubectl get svc --namespace {{ .Release.Namespace }} -w {{ template "common.names.fullname" . }}' + + export APP_HOST=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "common.names.fullname" . }} --template "{{ "{{ range (index .status.loadBalancer.ingress 0) }}{{ . }}{{ end }}" }}") + + {{- end }} + + {{ include "common.utils.secret.getvalue" (dict "secret" $ghostSecretName "field" $ghostPasswordKey "context" $) }} + {{ include "common.utils.secret.getvalue" (dict "secret" $databaseSecretName "field" "mysql-root-password" "context" $) }} + {{ include "common.utils.secret.getvalue" (dict "secret" $databaseSecretName "field" "mysql-password" "context" $) }} + +2. Complete your Ghost deployment by running: + +{{- if .Values.mysql.enabled }} + + helm upgrade --namespace {{ .Release.Namespace }} {{ .Release.Name }} oci://registry-1.docker.io/bitnamicharts/{{ .Chart.Name }} \ + --set service.type={{ .Values.service.type }},ghostHost=$APP_HOST,ghostPassword=$GHOST_PASSWORD,mysql.auth.rootPassword=$MYSQL_ROOT_PASSWORD,mysql.auth.password=$MYSQL_PASSWORD{{- if .Values.global }}{{- if .Values.global.imagePullSecrets }},global.imagePullSecrets={{ .Values.global.imagePullSecrets }}{{- end }}{{- end }} + +{{- else }} + + ## PLEASE UPDATE THE EXTERNAL DATABASE CONNECTION PARAMETERS IN THE FOLLOWING COMMAND AS NEEDED ## + + helm upgrade --namespace {{ .Release.Namespace }} {{ .Release.Name }} oci://registry-1.docker.io/bitnamicharts/{{ .Chart.Name }} \ + --set service.type={{ .Values.service.type }},ghostHost=$APP_HOST,ghostPassword=$APP_PASSWORD,{{- if contains "NodePort" .Values.service.type }}service.nodePort=$APP_PORT,{{- end }}mysql.enabled=false{{- if not (empty .Values.externalDatabase.host) }},externalDatabase.host={{ .Values.externalDatabase.host }}{{- end }}{{- if not (empty .Values.externalDatabase.user) }},externalDatabase.user={{ .Values.externalDatabase.user }}{{- end }}{{- if not (empty .Values.externalDatabase.password) }},externalDatabase.password={{ .Values.externalDatabase.password }}{{- end }}{{- if not (empty .Values.externalDatabase.database) }},externalDatabase.database={{ .Values.externalDatabase.database }}{{- end }} + +{{- end }} + +{{- else -}} + +{{- if .Values.ingress.enabled }} + +1. Get the Ghost URL and associate its hostname to your cluster external IP: + + export CLUSTER_IP=$(minikube ip) # On Minikube. Use: `kubectl cluster-info` on others K8s clusters + echo "Ghost URL: http{{ if .Values.ingress.tls }}s{{ end }}://{{ .Values.ingress.hostname }}" + echo "$CLUSTER_IP {{ .Values.ingress.hostname }}" | sudo tee -a /etc/hosts + +{{- else }} + +1. Get the Ghost URL by running: + +{{- if eq .Values.service.type "ClusterIP" }} + + echo Blog URL : http://127.0.0.1:{{ default "80" (coalesce .Values.service.ports.http .Values.service.port) }}{{ .Values.ghostPath }} + echo Admin URL : http://127.0.0.1:{{ default "80" (coalesce .Values.service.ports.http .Values.service.port) }}{{ default "/" .Values.ghostPath }}ghost + kubectl port-forward --namespace {{ .Release.Namespace }} svc/{{ template "common.names.fullname" . }} {{ default "80" (coalesce .Values.service.ports.http .Values.service.port) }}:{{ default "80" (coalesce .Values.service.ports.http .Values.service.port) }} + +{{- else if eq .Values.service.type "NodePort" }} + + export APP_HOST=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") + export APP_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "common.names.fullname" . }}) + + echo Blog URL : http://$APP_HOST:$APP_PORT{{ .Values.ghostPath }} + echo Admin URL : http://$APP_HOST:$APP_PORT{{ default "/" .Values.ghostPath }}ghost + +{{- else }} + + echo Blog URL : http://{{ include "ghost.host" . }} + echo Admin URL : http://{{ include "ghost.host" . }}ghost + +{{- end }} +{{- end }} + +2. Get your Ghost login credentials by running: + + echo Email: {{ .Values.ghostEmail }} + echo Password: $(kubectl get secret --namespace {{ .Release.Namespace }} {{ template "common.names.fullname" . }} -o jsonpath="{.data.{{- $ghostPasswordKey -}}}" | base64 -d) + +{{- end }} + +{{- else -}} + +######################################################################################## +### ERROR: You did not provide an external database host in your 'helm install' call ### +######################################################################################## + +This deployment will be incomplete until you configure Ghost with a resolvable database +host. To configure Ghost to use and external database host: + +1. Complete your Ghost deployment by running: + +{{- if contains "NodePort" .Values.service.type }} + + export APP_HOST=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") + +{{- else if contains "LoadBalancer" .Values.service.type }} + + NOTE: It may take a few minutes for the LoadBalancer IP to be available. + Watch the status with: 'kubectl get svc --namespace {{ .Release.Namespace }} -w {{ template "common.names.fullname" . }}' + + export APP_HOST=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "common.names.fullname" . }} --template "{{ "{{ range (index .status.loadBalancer.ingress 0) }}{{ . }}{{ end }}" }}") + +{{- else }} + + export APP_HOST=127.0.0.1 + +{{- end }} + + {{ include "common.utils.secret.getvalue" (dict "secret" $ghostSecretName "field" $ghostPasswordKey "context" $) }} + + ## PLEASE UPDATE THE EXTERNAL DATABASE CONNECTION PARAMETERS IN THE FOLLOWING COMMAND AS NEEDED ## + + helm upgrade --namespace {{ .Release.Namespace }} {{ .Release.Name }} oci://registry-1.docker.io/bitnamicharts/{{ .Chart.Name }} \ + --set ghostPassword=$APP_PASSWORD,ghostHost=$APP_HOST,service.type={{ .Values.service.type }},mysql.enabled=false{{- if not (empty .Values.externalDatabase.user) }},externalDatabase.user={{ .Values.externalDatabase.user }}{{- end }}{{- if not (empty .Values.externalDatabase.password) }},externalDatabase.password={{ .Values.externalDatabase.password }}{{- end }}{{- if not (empty .Values.externalDatabase.database) }},externalDatabase.database={{ .Values.externalDatabase.database }}{{- end }},externalDatabase.host=YOUR_EXTERNAL_DATABASE_HOST +{{- end }} + +{{ include "common.warnings.rollingTag" .Values.image }} + +{{- include "ghost.validateValues" . }} +{{- include "common.warnings.rollingTag" .Values.image }} +{{- $passwordValidationErrors := list -}} +{{- if not .Values.existingSecret -}} + {{- $requiredGhostPassword := dict "valueKey" "ghostPassword" "secret" $ghostSecretName "field" "ghost-password" "context" $ -}} + {{- $requiredGhostPasswordError := include "common.validations.values.single.empty" $requiredGhostPassword -}} + {{- $passwordValidationErrors = append $passwordValidationErrors $requiredGhostPasswordError -}} +{{- end -}} +{{- if .Values.mysql.enabled }} + {{- $mysqlPasswordValidationErrors := include "common.validations.values.mysql.passwords" (dict "secret" $databaseSecretName "subchart" true "context" $) -}} + {{- $passwordValidationErrors = append $passwordValidationErrors $mysqlPasswordValidationErrors -}} +{{- end }} +{{- include "common.errors.upgrade.passwords.empty" (dict "validationErrors" $passwordValidationErrors "context" $) -}} diff --git a/helm/ghost/templates/_helpers.tpl b/helm/ghost/templates/_helpers.tpl new file mode 100644 index 0000000..7c94dd8 --- /dev/null +++ b/helm/ghost/templates/_helpers.tpl @@ -0,0 +1,164 @@ +{{/* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{/* vim: set filetype=mustache: */}} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +*/}} +{{- define "ghost.mysql.fullname" -}} +{{- printf "%s-%s" .Release.Name "mysql" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Return the proper Ghost image name +*/}} +{{- define "ghost.image" -}} +{{ include "common.images.image" (dict "imageRoot" .Values.image "global" .Values.global) }} +{{- end -}} + +{{/* +Return the proper image name to change the volume permissions +*/}} +{{- define "ghost.volumePermissions.image" -}} +{{ include "common.images.image" (dict "imageRoot" .Values.volumePermissions.image "global" .Values.global) }} +{{- end -}} + +{{/* +Return the proper Docker Image Registry Secret Names +*/}} +{{- define "ghost.imagePullSecrets" -}} +{{ include "common.images.pullSecrets" (dict "images" (list .Values.image .Values.volumePermissions.image) "global" .Values.global) }} +{{- end -}} + +{{/* +Create the name of the service account to use +*/}} +{{- define "ghost.serviceAccountName" -}} +{{- if .Values.serviceAccount.create -}} + {{ default (include "common.names.fullname" .) .Values.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +Get the user defined LoadBalancerIP for this release. +Note, returns 127.0.0.1 if using ClusterIP. +*/}} +{{- define "ghost.serviceIP" -}} +{{- if eq .Values.service.type "ClusterIP" -}} +127.0.0.1 +{{- else -}} +{{- .Values.service.loadBalancerIP | default "" -}} +{{- end -}} +{{- end -}} + +{{/* +Gets the host to be used for this application. +If not using ClusterIP, or if a host or LoadBalancerIP is not defined, the value will be empty. +*/}} +{{- define "ghost.host" -}} +{{- if .Values.ingress.enabled }} + {{- printf "%s%s" .Values.ingress.hostname .Values.ingress.path | default "" -}} +{{- else if .Values.ghostHost -}} + {{- printf "%s%s" .Values.ghostHost .Values.ghostPath | default "" -}} +{{- else -}} + {{- include "ghost.serviceIP" . -}} +{{- end -}} +{{- end -}} + +{{/* +Return the MySQL Hostname +*/}} +{{- define "ghost.databaseHost" -}} +{{- if .Values.mysql.enabled }} + {{- if eq .Values.mysql.architecture "replication" }} + {{- printf "%s-%s" (include "ghost.mysql.fullname" .) "primary" | trunc 63 | trimSuffix "-" -}} + {{- else -}} + {{- printf "%s" (include "ghost.mysql.fullname" .) -}} + {{- end -}} +{{- else -}} + {{- printf "%s" .Values.externalDatabase.host -}} +{{- end -}} +{{- end -}} + +{{/* +Return the MySQL Port +*/}} +{{- define "ghost.databasePort" -}} +{{- if .Values.mysql.enabled }} + {{- printf "3306" -}} +{{- else -}} + {{- printf "%d" (.Values.externalDatabase.port | int ) -}} +{{- end -}} +{{- end -}} + +{{/* +Return the MySQL Database Name +*/}} +{{- define "ghost.databaseName" -}} +{{- if .Values.mysql.enabled }} + {{- printf "%s" .Values.mysql.auth.database -}} +{{- else -}} + {{- printf "%s" .Values.externalDatabase.database -}} +{{- end -}} +{{- end -}} + +{{/* +Return the MySQL User +*/}} +{{- define "ghost.databaseUser" -}} +{{- if .Values.mysql.enabled }} + {{- printf "%s" .Values.mysql.auth.username -}} +{{- else -}} + {{- printf "%s" .Values.externalDatabase.user -}} +{{- end -}} +{{- end -}} + +{{/* +Return the MySQL Secret Name +*/}} +{{- define "ghost.databaseSecretName" -}} +{{- if .Values.mysql.enabled }} + {{- if .Values.mysql.auth.existingSecret -}} + {{- printf "%s" .Values.mysql.auth.existingSecret -}} + {{- else -}} + {{- printf "%s" (include "ghost.mysql.fullname" .) -}} + {{- end -}} +{{- else if .Values.externalDatabase.existingSecret -}} + {{- printf "%s" .Values.externalDatabase.existingSecret -}} +{{- else -}} + {{- printf "%s-externaldb" (include "common.names.fullname" .) -}} +{{- end -}} +{{- end -}} + +{{/* +Compile all warnings into a single message. +*/}} +{{- define "ghost.validateValues" -}} +{{- $messages := list -}} +{{- $messages := append $messages (include "ghost.validateValues.database" .) -}} +{{- $messages := without $messages "" -}} +{{- $message := join "\n" $messages -}} +{{- if $message -}} +{{- printf "\nVALUES VALIDATION:\n%s" $message | fail -}} +{{- end -}} +{{- end -}} + +{{/* Validate values of Ghost - Database */}} +{{- define "ghost.validateValues.database" -}} +{{- if and (not .Values.mysql.enabled) (or (empty .Values.externalDatabase.host) (empty .Values.externalDatabase.port) (empty .Values.externalDatabase.database)) -}} +ghost: database + You disable the MySQL installation but you did not provide the required parameters + to use an external database. To use an external database, please ensure you provide + (at least) the following values: + + externalDatabase.host=DB_SERVER_HOST + externalDatabase.database=DB_NAME + externalDatabase.port=DB_SERVER_PORT +{{- end -}} +{{- end -}} diff --git a/helm/ghost/templates/deployment.yaml b/helm/ghost/templates/deployment.yaml new file mode 100644 index 0000000..71cd046 --- /dev/null +++ b/helm/ghost/templates/deployment.yaml @@ -0,0 +1,302 @@ +{{- /* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if include "ghost.host" . -}} +apiVersion: {{ include "common.capabilities.deployment.apiVersion" . }} +kind: Deployment +metadata: + name: {{ include "common.names.fullname" . }} + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + app.kubernetes.io/component: ghost + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.service.annotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.service.annotations "context" $) | nindent 4 }} + {{- end }} +spec: + selector: + matchLabels: {{- include "common.labels.matchLabels" . | nindent 6 }} + replicas: {{ .Values.replicaCount }} + strategy: {{- include "common.tplvalues.render" (dict "value" .Values.updateStrategy "context" $ ) | nindent 4 }} + template: + metadata: + labels: {{- include "common.labels.standard" . | nindent 8 }} + app.kubernetes.io/component: ghost + {{- if .Values.podLabels }} + {{- include "common.tplvalues.render" (dict "value" .Values.podLabels "context" $) | nindent 8 }} + {{- end }} + annotations: + {{- if or (not .Values.existingSecret) (and (not .Values.smtpExistingSecret) .Values.smtpPassword) }} + checksum/secrets: {{ include (print $.Template.BasePath "/secrets.yaml") . | sha256sum }} + {{- end }} + {{- if .Values.podAnnotations }} + {{- include "common.tplvalues.render" ( dict "value" .Values.podAnnotations "context" $ ) | nindent 8 }} + {{- end }} + spec: + {{- include "ghost.imagePullSecrets" . | nindent 6 }} + {{- if .Values.hostAliases }} + hostAliases: {{- include "common.tplvalues.render" (dict "value" .Values.hostAliases "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.affinity }} + affinity: {{- include "common.tplvalues.render" (dict "value" .Values.affinity "context" $) | nindent 8 }} + {{- else }} + affinity: + podAffinity: {{- include "common.affinities.pods" (dict "type" .Values.podAffinityPreset "context" $) | nindent 10 }} + podAntiAffinity: {{- include "common.affinities.pods" (dict "type" .Values.podAntiAffinityPreset "context" $) | nindent 10 }} + nodeAffinity: {{- include "common.affinities.nodes" (dict "type" .Values.nodeAffinityPreset.type "key" .Values.nodeAffinityPreset.key "values" .Values.nodeAffinityPreset.values) | nindent 10 }} + {{- end }} + {{- if .Values.nodeSelector }} + nodeSelector: {{- include "common.tplvalues.render" (dict "value" .Values.nodeSelector "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.tolerations }} + tolerations: {{- include "common.tplvalues.render" (dict "value" .Values.tolerations "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.priorityClassName }} + priorityClassName: {{ .Values.priorityClassName | quote }} + {{- end }} + serviceAccountName: {{ include "ghost.serviceAccountName" . }} + {{- if .Values.schedulerName }} + schedulerName: {{ .Values.schedulerName }} + {{- end }} + {{- if .Values.topologySpreadConstraints }} + topologySpreadConstraints: {{- include "common.tplvalues.render" (dict "value" .Values.topologySpreadConstraints "context" .) | nindent 8 }} + {{- end }} + {{- if .Values.podSecurityContext.enabled }} + securityContext: {{- omit .Values.podSecurityContext "enabled" | toYaml | nindent 8 }} + {{- end }} + {{- if or (and .Values.volumePermissions.enabled .Values.persistence.enabled) .Values.initContainers }} + initContainers: + {{- if and .Values.volumePermissions.enabled .Values.persistence.enabled }} + - name: volume-permissions + image: {{ include "ghost.volumePermissions.image" . }} + imagePullPolicy: {{ .Values.volumePermissions.image.pullPolicy | quote }} + command: + - /bin/bash + args: + - -ec + - | + mkdir -p /bitnami/ghost + chown -R "{{ .Values.containerSecurityContext.runAsUser }}:{{ .Values.podSecurityContext.fsGroup }}" /bitnami/ghost + {{- if eq ( toString ( .Values.volumePermissions.securityContext.runAsUser )) "auto" }} + securityContext: {{- omit .Values.volumePermissions.securityContext "runAsUser" | toYaml | nindent 12 }} + {{- else }} + securityContext: {{- .Values.volumePermissions.securityContext | toYaml | nindent 12 }} + {{- end }} + {{- if .Values.volumePermissions.resources }} + resources: {{- toYaml .Values.volumePermissions.resources | nindent 12 }} + {{- end }} + volumeMounts: + - name: ghost-data + mountPath: /bitnami/ghost + {{- if .Values.persistence.subPath }} + subPath: {{ .Values.persistence.subPath }} + {{- end }} + {{- end }} + {{- if .Values.initContainers }} + {{- include "common.tplvalues.render" (dict "value" .Values.initContainers "context" $) | nindent 8 }} + {{- end }} + {{- end }} + containers: + - name: {{ include "common.names.fullname" . }} + image: {{ include "ghost.image" . }} + imagePullPolicy: {{ .Values.image.pullPolicy | quote }} + {{- if .Values.containerSecurityContext.enabled }} + securityContext: {{- omit .Values.containerSecurityContext "enabled" | toYaml | nindent 12 }} + {{- end }} + {{- if .Values.lifecycleHooks }} + lifecycle: {{- include "common.tplvalues.render" (dict "value" .Values.lifecycleHooks "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.command }} + command: {{- include "common.tplvalues.render" (dict "value" .Values.command "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.args }} + args: {{- include "common.tplvalues.render" (dict "value" .Values.args "context" $) | nindent 12 }} + {{- end }} + env: + - name: BITNAMI_DEBUG + value: {{ ternary "true" "false" .Values.image.debug | quote }} + - name: ALLOW_EMPTY_PASSWORD + value: {{ ternary "yes" "no" .Values.allowEmptyPassword | quote }} + - name: GHOST_DATABASE_HOST + value: {{ include "ghost.databaseHost" . | quote }} + - name: GHOST_DATABASE_PORT_NUMBER + value: {{ include "ghost.databasePort" . | quote }} + - name: GHOST_DATABASE_NAME + value: {{ include "ghost.databaseName" . | quote }} + - name: GHOST_DATABASE_USER + value: {{ include "ghost.databaseUser" . | quote }} + - name: GHOST_DATABASE_PASSWORD + valueFrom: + secretKeyRef: + name: {{ include "ghost.databaseSecretName" . }} + key: mysql-password + {{- if (and (not .Values.mysql.enabled) .Values.externalDatabase.ssl) }} + - name: GHOST_DATABASE_ENABLE_SSL + value: {{ .Values.externalDatabase.ssl | quote }} + - name: MYSQL_CLIENT_ENABLE_SSL + value: {{ ternary "yes" "no" .Values.externalDatabase.ssl | quote }} + - name: GHOST_DATABASE_SSL_CA_FILE + value: {{ .Values.externalDatabase.sslCaFile | quote }} + {{- end }} + - name: GHOST_HOST + value: {{ include "ghost.host" . | quote }} + - name: GHOST_PORT_NUMBER + value: {{ ternary .Values.containerPorts.https .Values.containerPorts.http .Values.ghostEnableHttps | quote }} + - name: GHOST_USERNAME + value: {{ .Values.ghostUsername | quote }} + - name: GHOST_PASSWORD + valueFrom: + secretKeyRef: + name: {{ include "common.secrets.name" (dict "existingSecret" .Values.existingSecret "context" $) }} + key: {{ include "common.secrets.key" (dict "existingSecret" .Values.existingSecret "key" "ghost-password") }} + - name: GHOST_EMAIL + value: {{ .Values.ghostEmail | quote }} + - name: GHOST_BLOG_TITLE + value: {{ .Values.ghostBlogTitle | quote }} + - name: GHOST_ENABLE_HTTPS + value: {{ ternary "yes" "no" .Values.ghostEnableHttps | quote }} + - name: GHOST_EXTERNAL_HTTP_PORT_NUMBER + value: {{ coalesce .Values.service.ports.http .Values.service.port| quote }} + - name: GHOST_EXTERNAL_HTTPS_PORT_NUMBER + value: {{ coalesce .Values.service.ports.https .Values.service.httpsPort| quote }} + - name: GHOST_SKIP_BOOTSTRAP + value: {{ ternary "yes" "no" .Values.ghostSkipInstall | quote }} + {{- if .Values.smtpHost }} + - name: GHOST_SMTP_HOST + value: {{ .Values.smtpHost | quote }} + {{- end }} + {{- if .Values.smtpPort }} + - name: GHOST_SMTP_PORT + value: {{ .Values.smtpPort | quote }} + {{- end }} + {{- if .Values.smtpUser }} + - name: GHOST_SMTP_USER + value: {{ .Values.smtpUser | quote }} + {{- end }} + {{- if .Values.smtpPassword }} + - name: GHOST_SMTP_PASSWORD + valueFrom: + secretKeyRef: + name: {{ include "common.secrets.name" (dict "existingSecret" .Values.existingSecret "context" $) }} + key: {{ include "common.secrets.key" (dict "existingSecret" .Values.existingSecret "key" "smtp-password") }} + {{- end }} + {{- if .Values.smtpService }} + - name: GHOST_SMTP_SERVICE + value: {{ .Values.smtpService | quote }} + {{- end }} + {{- if .Values.smtpProtocol }} + - name: GHOST_SMTP_PROTOCOL + value: {{ .Values.smtpProtocol | quote }} + {{- end }} + {{- if .Values.extraEnvVars }} + {{- include "common.tplvalues.render" ( dict "value" .Values.extraEnvVars "context" $ ) | nindent 12 }} + {{- end }} + {{- if or .Values.extraEnvVarsCM .Values.extraEnvVarsSecret }} + envFrom: + {{- if .Values.extraEnvVarsCM }} + - configMapRef: + name: {{ include "common.tplvalues.render" (dict "value" .Values.extraEnvVarsCM "context" $) }} + {{- end }} + {{- if .Values.extraEnvVarsSecret }} + - secretRef: + name: {{ include "common.tplvalues.render" (dict "value" .Values.extraEnvVarsSecret "context" $) }} + {{- end }} + {{- end }} + ports: + {{- if .Values.ghostEnableHttps }} + - name: https + containerPort: {{ .Values.containerPorts.https }} + protocol: TCP + {{- else }} + - name: http + containerPort: {{ .Values.containerPorts.http }} + protocol: TCP + {{- end }} + {{- if .Values.customStartupProbe }} + startupProbe: {{- include "common.tplvalues.render" (dict "value" .Values.customStartupProbe "context" $) | nindent 12 }} + {{- else if .Values.startupProbe.enabled }} + startupProbe: + httpGet: + path: / + port: {{ ternary "https" "http" .Values.ghostEnableHttps | quote }} + scheme: HTTP + {{- if .Values.ghostEnableHttps }} + httpHeaders: + - name: x-forwarded-proto + value: https + {{- end }} + initialDelaySeconds: {{ .Values.startupProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.startupProbe.periodSeconds }} + timeoutSeconds: {{ .Values.startupProbe.timeoutSeconds }} + failureThreshold: {{ .Values.startupProbe.failureThreshold }} + successThreshold: {{ .Values.startupProbe.successThreshold }} + {{- end }} + {{- if .Values.customLivenessProbe }} + livenessProbe: {{- include "common.tplvalues.render" (dict "value" .Values.customLivenessProbe "context" $) | nindent 12 }} + {{- else if .Values.livenessProbe.enabled }} + livenessProbe: + httpGet: + path: / + port: {{ ternary "https" "http" .Values.ghostEnableHttps | quote }} + scheme: HTTP + {{- if .Values.ghostEnableHttps }} + httpHeaders: + - name: x-forwarded-proto + value: https + {{- end }} + initialDelaySeconds: {{ .Values.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.livenessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.livenessProbe.timeoutSeconds }} + failureThreshold: {{ .Values.livenessProbe.failureThreshold }} + successThreshold: {{ .Values.livenessProbe.successThreshold }} + {{- end }} + {{- if .Values.customReadinessProbe }} + readinessProbe: {{- include "common.tplvalues.render" (dict "value" .Values.customReadinessProbe "context" $) | nindent 12 }} + {{- else if .Values.readinessProbe.enabled }} + readinessProbe: + httpGet: + path: / + port: {{ ternary "https" "http" .Values.ghostEnableHttps | quote }} + scheme: HTTP + {{- if .Values.ghostEnableHttps }} + httpHeaders: + - name: x-forwarded-proto + value: https + {{- end }} + initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.readinessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.readinessProbe.timeoutSeconds }} + failureThreshold: {{ .Values.readinessProbe.failureThreshold }} + successThreshold: {{ .Values.readinessProbe.successThreshold }} + {{- end }} + {{- if .Values.resources }} + resources: {{- toYaml .Values.resources | nindent 12 }} + {{- end }} + volumeMounts: + - name: ghost-data + mountPath: /bitnami/ghost + {{- if .Values.persistence.subPath }} + subPath: {{ .Values.persistence.subPath }} + {{- end }} + {{- if .Values.extraVolumeMounts }} + {{- include "common.tplvalues.render" (dict "value" .Values.extraVolumeMounts "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.sidecars }} + {{- include "common.tplvalues.render" ( dict "value" .Values.sidecars "context" $) | nindent 8 }} + {{- end }} + volumes: + - name: ghost-data + {{- if .Values.persistence.enabled }} + persistentVolumeClaim: + claimName: {{ default (include "common.names.fullname" .) .Values.persistence.existingClaim }} + {{- else }} + emptyDir: {} + {{- end }} + {{- if .Values.extraVolumes }} + {{- include "common.tplvalues.render" (dict "value" .Values.extraVolumes "context" $) | nindent 8 }} + {{- end }} +{{- end -}} diff --git a/helm/ghost/templates/external-db-secrets.yaml b/helm/ghost/templates/external-db-secrets.yaml new file mode 100644 index 0000000..eadd203 --- /dev/null +++ b/helm/ghost/templates/external-db-secrets.yaml @@ -0,0 +1,24 @@ +{{- /* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if (not (or .Values.mysql.enabled .Values.externalDatabase.existingSecret)) }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ printf "%s-externaldb" (include "common.names.fullname" .) | trunc 63 | trimSuffix "-" }} + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + app.kubernetes.io/component: ghost + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +type: Opaque +data: + mysql-password: {{ .Values.externalDatabase.password | b64enc | quote }} +{{- end }} + diff --git a/helm/ghost/templates/extra-list.yaml b/helm/ghost/templates/extra-list.yaml new file mode 100644 index 0000000..2d35a58 --- /dev/null +++ b/helm/ghost/templates/extra-list.yaml @@ -0,0 +1,9 @@ +{{- /* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- range .Values.extraDeploy }} +--- +{{ include "common.tplvalues.render" (dict "value" . "context" $) }} +{{- end }} diff --git a/helm/ghost/templates/ingress.yaml b/helm/ghost/templates/ingress.yaml new file mode 100644 index 0000000..c720c6e --- /dev/null +++ b/helm/ghost/templates/ingress.yaml @@ -0,0 +1,71 @@ +{{- /* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if .Values.ingress.enabled }} +apiVersion: {{ include "common.capabilities.ingress.apiVersion" . }} +kind: Ingress +metadata: + name: {{ template "common.names.fullname" . }} + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + app.kubernetes.io/component: ghost + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if or .Values.ingress.annotations .Values.commonAnnotations .Values.ingress.certManager }} + annotations: + {{- if .Values.ingress.certManager }} + kubernetes.io/tls-acme: "true" + {{- end }} + {{- if .Values.ingress.annotations }} + {{- include "common.tplvalues.render" ( dict "value" .Values.ingress.annotations "context" $) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} + {{- end }} +spec: + {{- if and .Values.ingress.ingressClassName (eq "true" (include "common.ingress.supportsIngressClassname" .)) }} + ingressClassName: {{ .Values.ingress.ingressClassName | quote }} + {{- end }} + rules: + {{- if .Values.ingress.hostname }} + - host: {{ .Values.ingress.hostname }} + http: + paths: + {{- if .Values.ingress.extraPaths }} + {{- toYaml .Values.ingress.extraPaths | nindent 10 }} + {{- end }} + - path: {{ .Values.ingress.path }} + {{- if eq "true" (include "common.ingress.supportsPathType" .) }} + pathType: {{ .Values.ingress.pathType }} + {{- end }} + backend: {{- include "common.ingress.backend" (dict "serviceName" (include "common.names.fullname" .) "servicePort" (ternary "https" "http" $.Values.ghostEnableHttps) "context" $) | nindent 14 }} + {{- end }} + {{- range .Values.ingress.extraHosts }} + - host: {{ .name | quote }} + http: + paths: + - path: {{ default "/" .path }} + {{- if eq "true" (include "common.ingress.supportsPathType" $) }} + pathType: {{ default "ImplementationSpecific" .pathType }} + {{- end }} + backend: {{- include "common.ingress.backend" (dict "serviceName" (include "common.names.fullname" $) "servicePort" (ternary "https" "http" $.Values.ghostEnableHttps) "context" $) | nindent 14 }} + {{- end }} + {{- if .Values.ingress.extraRules }} + {{- include "common.tplvalues.render" (dict "value" .Values.ingress.extraRules "context" $) | nindent 4 }} + {{- end }} + {{- if or (and .Values.ingress.tls (or (include "common.ingress.certManagerRequest" ( dict "annotations" .Values.ingress.annotations )) .Values.ingress.selfSigned)) .Values.ingress.extraTls }} + tls: + {{- if and .Values.ingress.tls (or (include "common.ingress.certManagerRequest" ( dict "annotations" .Values.ingress.annotations )) .Values.ingress.selfSigned) }} + - hosts: + - {{ .Values.ingress.hostname | quote }} + secretName: {{ printf "%s-tls" .Values.ingress.hostname }} + {{- end }} + {{- if .Values.ingress.extraTls }} + {{- include "common.tplvalues.render" (dict "value" .Values.ingress.extraTls "context" $) | nindent 4 }} + {{- end }} + {{- end }} +{{- end }} diff --git a/helm/ghost/templates/networkpolicy-backend-ingress.yaml b/helm/ghost/templates/networkpolicy-backend-ingress.yaml new file mode 100644 index 0000000..8e37eb1 --- /dev/null +++ b/helm/ghost/templates/networkpolicy-backend-ingress.yaml @@ -0,0 +1,33 @@ +{{- /* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if and .Values.networkPolicy.enabled .Values.networkPolicy.ingressRules.backendOnlyAccessibleByFrontend }} +apiVersion: {{ include "common.capabilities.networkPolicy.apiVersion" . }} +kind: NetworkPolicy +metadata: + name: {{ printf "%s-backend" (include "common.names.fullname" .) }} + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" (dict "value" .Values.commonLabels "context" $) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" (dict "value" .Values.commonAnnotations "context" $) | nindent 4 }} + {{- end }} +spec: + podSelector: + matchLabels: + {{- if .Values.networkPolicy.ingressRules.customBackendSelector }} + {{- include "common.tplvalues.render" (dict "value" .Values.networkPolicy.ingressRules.customBackendSelector "context" $) | nindent 6 }} + {{- else }} + app.kubernetes.io/name: mysql + app.kubernetes.io/instance: {{ .Release.Name }} + {{- end }} + ingress: + - from: + - podSelector: + matchLabels: + {{- include "common.labels.matchLabels" . | nindent 14 }} +{{- end }} diff --git a/helm/ghost/templates/networkpolicy-egress.yaml b/helm/ghost/templates/networkpolicy-egress.yaml new file mode 100644 index 0000000..a595cf7 --- /dev/null +++ b/helm/ghost/templates/networkpolicy-egress.yaml @@ -0,0 +1,38 @@ +{{- /* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if and .Values.networkPolicy.enabled (or .Values.networkPolicy.egressRules.denyConnectionsToExternal .Values.networkPolicy.egressRules.customRules) }} +apiVersion: {{ include "common.capabilities.networkPolicy.apiVersion" . }} +kind: NetworkPolicy +metadata: + name: {{ printf "%s-egress" (include "common.names.fullname" .) }} + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" (dict "value" .Values.commonLabels "context" $) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" (dict "value" .Values.commonAnnotations "context" $) | nindent 4 }} + {{- end }} +spec: + podSelector: + matchLabels: + app.kubernetes.io/instance: {{ .Release.Name }} + policyTypes: + - Egress + egress: + {{- if .Values.networkPolicy.egressRules.denyConnectionsToExternal }} + - ports: + - port: 53 + protocol: UDP + - port: 53 + protocol: TCP + - to: + - namespaceSelector: {} + {{- end }} + {{- if .Values.networkPolicy.egressRules.customRules }} + {{- include "common.tplvalues.render" (dict "value" .Values.networkPolicy.egressRules.customRules "context" $) | nindent 4 }} + {{- end }} +{{- end }} diff --git a/helm/ghost/templates/networkpolicy-ingress.yaml b/helm/ghost/templates/networkpolicy-ingress.yaml new file mode 100644 index 0000000..d8f5965 --- /dev/null +++ b/helm/ghost/templates/networkpolicy-ingress.yaml @@ -0,0 +1,53 @@ +{{- /* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if and .Values.networkPolicy.enabled (or .Values.networkPolicy.ingress.enabled .Values.networkPolicy.ingressRules.accessOnlyFrom.enabled) }} +apiVersion: {{ include "common.capabilities.networkPolicy.apiVersion" . }} +kind: NetworkPolicy +metadata: + name: {{ printf "%s-ingress" (include "common.names.fullname" .) }} + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" (dict "value" .Values.commonLabels "context" $) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" (dict "value" .Values.commonAnnotations "context" $) | nindent 4 }} + {{- end }} +spec: + podSelector: + matchLabels: + {{- include "common.labels.standard" . | nindent 6 }} + ingress: + {{- if and .Values.ingress.enabled .Values.networkPolicy.ingress.enabled (or .Values.networkPolicy.ingress.namespaceSelector .Values.networkPolicy.ingress.podSelector) }} + - from: + {{- if .Values.networkPolicy.ingress.namespaceSelector }} + - namespaceSelector: + matchLabels: + {{- include "common.tplvalues.render" (dict "value" .Values.networkPolicy.ingress.namespaceSelector "context" $) | nindent 14 }} + {{- end }} + {{- if .Values.networkPolicy.ingress.podSelector }} + - podSelector: + matchLabels: + {{- include "common.tplvalues.render" (dict "value" .Values.networkPolicy.ingress.podSelector "context" $) | nindent 14 }} + {{- end }} + {{- end }} + {{- if and .Values.networkPolicy.ingressRules.accessOnlyFrom.enabled (or .Values.networkPolicy.ingressRules.accessOnlyFrom.namespaceSelector .Values.networkPolicy.ingressRules.accessOnlyFrom.podSelector) }} + - from: + {{- if .Values.networkPolicy.ingressRules.accessOnlyFrom.namespaceSelector }} + - namespaceSelector: + matchLabels: + {{- include "common.tplvalues.render" (dict "value" .Values.networkPolicy.ingressRules.accessOnlyFrom.namespaceSelector "context" $) | nindent 14 }} + {{- end }} + {{- if .Values.networkPolicy.ingressRules.accessOnlyFrom.podSelector }} + - podSelector: + matchLabels: + {{- include "common.tplvalues.render" (dict "value" .Values.networkPolicy.ingressRules.accessOnlyFrom.podSelector "context" $) | nindent 14 }} + {{- end }} + {{- end }} + {{- if .Values.networkPolicy.ingressRules.customRules }} + {{- include "common.tplvalues.render" (dict "value" .Values.networkPolicy.ingressRules.customRules "context" $) | nindent 4 }} + {{- end }} +{{- end }} diff --git a/helm/ghost/templates/pvc.yaml b/helm/ghost/templates/pvc.yaml new file mode 100644 index 0000000..8690498 --- /dev/null +++ b/helm/ghost/templates/pvc.yaml @@ -0,0 +1,39 @@ +{{- /* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if and (include "ghost.host" .) .Values.persistence.enabled (not .Values.persistence.existingClaim) -}} +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: + name: {{ include "common.names.fullname" . }} + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + app.kubernetes.io/component: ghost + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if or .Values.persistence.annotations .Values.commonAnnotations }} + annotations: + {{- if .Values.persistence.annotations }} + {{- include "common.tplvalues.render" ( dict "value" .Values.persistence.annotations "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} + {{- end }} +spec: + accessModes: + {{- if not (empty .Values.persistence.accessModes) }} + {{- range .Values.persistence.accessModes }} + - {{ . | quote }} + {{- end }} + {{- else }} + - {{ .Values.persistence.accessMode | quote }} + {{- end }} + resources: + requests: + storage: {{ .Values.persistence.size | quote }} + {{- include "common.storage.class" (dict "persistence" .Values.persistence "global" .Values.global) | nindent 2 }} +{{- end -}} diff --git a/helm/ghost/templates/secrets.yaml b/helm/ghost/templates/secrets.yaml new file mode 100644 index 0000000..5f925fe --- /dev/null +++ b/helm/ghost/templates/secrets.yaml @@ -0,0 +1,33 @@ +{{- /* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if or (not .Values.existingSecret) (and (not .Values.smtpExistingSecret) .Values.smtpPassword) }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "common.names.fullname" . }} + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +type: Opaque +data: + {{- if not .Values.existingSecret }} + {{- if .Values.ghostPassword }} + ghost-password: {{ .Values.ghostPassword | b64enc | quote }} + {{- else }} + ghost-password: {{ randAlphaNum 10 | b64enc | quote }} + {{- end }} + {{- end }} + {{- if and .Values.smtpPassword (not .Values.smtpExistingSecret) }} + {{- if .Values.smtpPassword }} + smtp-password: {{ .Values.smtpPassword | b64enc | quote }} + {{- end }} + {{- end }} +{{- end }} diff --git a/helm/ghost/templates/service-account.yaml b/helm/ghost/templates/service-account.yaml new file mode 100644 index 0000000..27a9f3f --- /dev/null +++ b/helm/ghost/templates/service-account.yaml @@ -0,0 +1,25 @@ +{{- /* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if .Values.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "ghost.serviceAccountName" . }} + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + app.kubernetes.io/component: ghost + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + annotations: + {{- if .Values.commonAnnotations }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.serviceAccount.annotations }} + {{- include "common.tplvalues.render" (dict "value" .Values.serviceAccount.annotations "context" $) | nindent 4 }} + {{- end }} +automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }} +{{- end }} diff --git a/helm/ghost/templates/svc.yaml b/helm/ghost/templates/svc.yaml new file mode 100644 index 0000000..7247708 --- /dev/null +++ b/helm/ghost/templates/svc.yaml @@ -0,0 +1,71 @@ +{{- /* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +apiVersion: v1 +kind: Service +metadata: + name: {{ include "common.names.fullname" . }} + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + app.kubernetes.io/component: ghost + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if or .Values.service.annotations .Values.commonAnnotations }} + annotations: + {{- if .Values.service.annotations }} + {{- include "common.tplvalues.render" ( dict "value" .Values.service.annotations "context" $) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} + {{- end }} +spec: + type: {{ .Values.service.type }} + {{- if and .Values.service.clusterIP (eq .Values.service.type "ClusterIP") }} + clusterIP: {{ .Values.service.clusterIP }} + {{- end }} + {{- if (or (eq .Values.service.type "LoadBalancer") (eq .Values.service.type "NodePort")) }} + externalTrafficPolicy: {{ .Values.service.externalTrafficPolicy | quote }} + {{- end }} + {{- if (and (eq .Values.service.type "LoadBalancer") .Values.service.loadBalancerSourceRanges) }} + loadBalancerSourceRanges: {{- toYaml . | nindent 4 }} + {{- end }} + {{- if (and (eq .Values.service.type "LoadBalancer") (not (empty .Values.service.loadBalancerIP))) }} + loadBalancerIP: {{ .Values.service.loadBalancerIP }} + {{- end }} + {{- if .Values.service.sessionAffinity }} + sessionAffinity: {{ .Values.service.sessionAffinity }} + {{- end }} + {{- if .Values.service.sessionAffinityConfig }} + sessionAffinityConfig: {{- include "common.tplvalues.render" (dict "value" .Values.service.sessionAffinityConfig "context" $) | nindent 4 }} + {{- end }} + ports: + {{- if .Values.ghostEnableHttps }} + - name: https + port: {{ coalesce .Values.service.ports.https .Values.service.httpsPort }} + protocol: TCP + targetPort: https + {{- if (and (or (eq .Values.service.type "NodePort") (eq .Values.service.type "LoadBalancer")) (not (empty .Values.service.nodePorts.https))) }} + nodePort: {{ .Values.service.nodePorts.https }} + {{- else if eq .Values.service.type "ClusterIP" }} + nodePort: null + {{- end }} + {{- else }} + - name: http + port: {{ coalesce .Values.service.ports.http .Values.service.port }} + protocol: TCP + targetPort: http + {{- if (and (or (eq .Values.service.type "NodePort") (eq .Values.service.type "LoadBalancer")) (not (empty .Values.service.nodePorts.http))) }} + nodePort: {{ .Values.service.nodePorts.http }} + {{- else if eq .Values.service.type "ClusterIP" }} + nodePort: null + {{- end }} + {{- end }} + {{- if .Values.service.extraPorts }} + {{- include "common.tplvalues.render" (dict "value" .Values.service.extraPorts "context" $) | nindent 4 }} + {{- end }} + selector: {{- include "common.labels.matchLabels" . | nindent 4 }} + app.kubernetes.io/component: ghost diff --git a/helm/ghost/templates/tls-secrets.yaml b/helm/ghost/templates/tls-secrets.yaml new file mode 100644 index 0000000..2288018 --- /dev/null +++ b/helm/ghost/templates/tls-secrets.yaml @@ -0,0 +1,50 @@ +{{- /* +Copyright VMware, Inc. +SPDX-License-Identifier: APACHE-2.0 +*/}} + +{{- if .Values.ingress.enabled }} +{{- if .Values.ingress.secrets }} +{{- range .Values.ingress.secrets }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ .name }} + namespace: {{ $.Release.Namespace | quote }} + labels: {{- include "common.labels.standard" $ | nindent 4 }} + {{- if $.Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" $.Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if $.Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" $.Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +type: kubernetes.io/tls +data: + tls.crt: {{ .certificate | b64enc }} + tls.key: {{ .key | b64enc }} +--- +{{- end }} +{{- end }} +{{- if and .Values.ingress.tls .Values.ingress.selfSigned }} +{{- $secretName := printf "%s-tls" .Values.ingress.hostname }} +{{- $ca := genCA "ghost-ca" 365 }} +{{- $cert := genSignedCert .Values.ingress.hostname nil (list .Values.ingress.hostname) 365 $ca }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ $secretName }} + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +type: kubernetes.io/tls +data: + tls.crt: {{ include "common.secrets.lookup" (dict "secret" $secretName "key" "tls.crt" "defaultValue" $cert.Cert "context" $) }} + tls.key: {{ include "common.secrets.lookup" (dict "secret" $secretName "key" "tls.key" "defaultValue" $cert.Key "context" $) }} + ca.crt: {{ include "common.secrets.lookup" (dict "secret" $secretName "key" "ca.crt" "defaultValue" $ca.Cert "context" $) }} +{{- end }} +{{- end }} diff --git a/helm/ghost/values.schema.json b/helm/ghost/values.schema.json new file mode 100644 index 0000000..07f24c1 --- /dev/null +++ b/helm/ghost/values.schema.json @@ -0,0 +1,186 @@ +{ + "$schema": "http://json-schema.org/schema#", + "type": "object", + "properties": { + "ghostUsername": { + "type": "string", + "title": "User", + "form": true + }, + "ghostPassword": { + "type": "string", + "title": "Password", + "form": true, + "description": "Defaults to a random 10-character alphanumeric string if not set" + }, + "ghostEmail": { + "type": "string", + "title": "Admin email", + "form": true + }, + "ghostBlogTitle": { + "type": "string", + "title": "Blog Name", + "form": true + }, + "ghostHost": { + "type": "string", + "title": "Host", + "form": true, + "description": "Hostname used to generate application URLs" + }, + "persistence": { + "type": "object", + "properties": { + "size": { + "type": "string", + "title": "Persistent Volume Size", + "form": true, + "render": "slider", + "sliderMin": 1, + "sliderMax": 100, + "sliderUnit": "Gi" + } + } + }, + "mysql": { + "type": "object", + "form": true, + "title": "MySQL Details", + "properties": { + "enabled": { + "type": "boolean", + "title": "Use a new MySQL database hosted in the cluster", + "form": true, + "description": "Whether to deploy a mysql server to satisfy the applications database requirements. To use an external database switch this off and configure the external database parameters" + }, + "primary": { + "type": "object", + "properties": { + "persistence": { + "type": "object", + "properties": { + "size": { + "type": "string", + "title": "Volume Size", + "form": true, + "hidden": { + "value": false, + "path": "mysql/enabled" + }, + "render": "slider", + "sliderMin": 1, + "sliderMax": 100, + "sliderUnit": "Gi" + } + } + } + } + } + } + }, + "externalDatabase": { + "type": "object", + "title": "External Database Details", + "description": "If MySQL is disabled. Use this section to specify the external database details", + "form": true, + "properties": { + "host": { + "type": "string", + "form": true, + "title": "Database Host", + "hidden": "mysql/enabled" + }, + "user": { + "type": "string", + "form": true, + "title": "Database Username", + "hidden": "mysql/enabled" + }, + "password": { + "type": "string", + "form": true, + "title": "Database Password", + "hidden": "mysql/enabled" + }, + "database": { + "type": "string", + "form": true, + "title": "Database Name", + "hidden": "mysql/enabled" + }, + "port": { + "type": "integer", + "form": true, + "title": "Database Port", + "hidden": "mysql/enabled" + }, + "ssl": { + "type": "boolean", + "form": true, + "title": "Database SSL", + "hidden": "mysql/enabled" + }, + "sslCaFile": { + "type": "string", + "form": true, + "title": "Database SSL CA filepath", + "hidden": "mysql/enabled" + } + } + }, + "resources": { + "type": "object", + "title": "Required Resources", + "description": "Configure resource requests", + "form": true, + "properties": { + "requests": { + "type": "object", + "properties": { + "memory": { + "type": "string", + "form": true, + "render": "slider", + "title": "Memory Request", + "sliderMin": 10, + "sliderMax": 2048, + "sliderUnit": "Mi" + }, + "cpu": { + "type": "string", + "form": true, + "render": "slider", + "title": "CPU Request", + "sliderMin": 10, + "sliderMax": 2000, + "sliderUnit": "m" + } + } + } + } + }, + "securityContext": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "title": "Enable Pod Security Context", + "description": "When disabled, an initContainer will be used to set required folder permissions", + "form": true + } + } + }, + "serviceAccount": { + "type": "object", + "properties": { + "name": { + "type": "string", + "title": "Service Account Name", + "description": "Service Account Name to use", + "form": true + } + } + } + } +} diff --git a/helm/ghost/values.yaml b/helm/ghost/values.yaml new file mode 100644 index 0000000..ffe4f79 --- /dev/null +++ b/helm/ghost/values.yaml @@ -0,0 +1,765 @@ +# Copyright VMware, Inc. +# SPDX-License-Identifier: APACHE-2.0 + +## @section Global parameters +## Global Docker image parameters +## Please, note that this will override the image parameters, including dependencies, configured to use the global value +## Current available global Docker image parameters: imageRegistry, imagePullSecrets and storageClass + +## @param global.imageRegistry Global Docker image registry +## @param global.imagePullSecrets Global Docker registry secret names as an array +## @param global.storageClass Global StorageClass for Persistent Volume(s) +## +global: + imageRegistry: "" + ## E.g. + ## imagePullSecrets: + ## - myRegistryKeySecretName + ## + imagePullSecrets: [] + storageClass: "" + +## @section Common parameters + +## @param kubeVersion Override Kubernetes version +## +kubeVersion: "" +## @param nameOverride String to partially override common.names.fullname +## +nameOverride: "" +## @param fullnameOverride String to fully override common.names.fullname +## +fullnameOverride: "" +## @param commonLabels Labels to add to all deployed objects +## +commonLabels: {} +## @param commonAnnotations Annotations to add to all deployed objects +## +commonAnnotations: {} +## @param clusterDomain Kubernetes cluster domain name +## +clusterDomain: cluster.local +## @param extraDeploy Array of extra objects to deploy with the release +## +extraDeploy: [] + +## @section Ghost Image parameters + +## Bitnami Ghost image +## ref: https://hub.docker.com/r/bitnami/ghost/tags/ +## @param image.registry Ghost image registry +## @param image.repository Ghost image repository +## @param image.tag Ghost image tag (immutable tags are recommended) +## @param image.digest Ghost image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag +## @param image.pullPolicy Ghost image pull policy +## @param image.pullSecrets Ghost image pull secrets +## @param image.debug Enable image debug mode +## +image: + registry: docker.io + repository: bitnami/ghost + tag: 5.54.3-debian-11-r0 + digest: "" + ## Specify a imagePullPolicy + ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' + ## ref: https://kubernetes.io/docs/user-guide/images/#pre-pulling-images + ## + pullPolicy: IfNotPresent + ## Optionally specify an array of imagePullSecrets. + ## Secrets must be manually created in the namespace. + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ + ## e.g: + ## pullSecrets: + ## - myRegistryKeySecretName + ## + pullSecrets: [] + ## Enable debug mode + ## + debug: false + +## @section Ghost Configuration parameters +## Ghost settings based on environment variables +## ref: https://github.com/bitnami/containers/tree/main/bitnami/ghost#configuration + +## @param ghostUsername Ghost user name +## +ghostUsername: user +## @param ghostPassword Ghost user password +## Defaults to a random 10-character alphanumeric string if not set +## +ghostPassword: "" +## @param existingSecret Name of existing secret containing Ghost credentials +## NOTE: Must contain key `ghost-password` +## NOTE: When it's set, the `ghostPassword` parameter is ignored +## +existingSecret: "" +## @param ghostEmail Ghost user email +## +ghostEmail: user@example.com +## @param ghostBlogTitle Ghost Blog title +## +ghostBlogTitle: User's Blog +## @param ghostHost Ghost host to create application URLs +## +ghostHost: "" +## @param ghostPath URL sub path where to server the Ghost application +## +ghostPath: / +## @param ghostEnableHttps Configure Ghost to build application URLs using https +## +ghostEnableHttps: false +## SMTP mail delivery configuration +## ref: https://github.com/bitnami/containers/tree/main/bitnami/ghost/#smtp-configuration +## @param smtpHost SMTP server host +## @param smtpPort SMTP server port +## @param smtpUser SMTP username +## @param smtpPassword SMTP user password +## @param smtpService SMTP service +## @param smtpProtocol SMTP protocol (ssl or tls) +## +smtpHost: "" +smtpPort: "" +smtpUser: "" +smtpPassword: "" +smtpService: "" +smtpProtocol: "" +## @param smtpExistingSecret The name of an existing secret with SMTP credentials +## NOTE: Must contain key `smtp-password` +## NOTE: When it's set, the `smtpPassword` parameter is ignored +## +smtpExistingSecret: "" +## @param allowEmptyPassword Allow the container to be started with blank passwords +## +allowEmptyPassword: true +## @param ghostSkipInstall Skip performing the initial bootstrapping for Ghost +## +ghostSkipInstall: false +## @param command Override default container command (useful when using custom images) +## +command: [] +## @param args Override default container args (useful when using custom images) +## +args: [] +## @param extraEnvVars Array with extra environment variables to add to the Ghost container +## e.g: +## extraEnvVars: +## - name: FOO +## value: "bar" +## +extraEnvVars: [] +## @param extraEnvVarsCM Name of existing ConfigMap containing extra env vars +## +extraEnvVarsCM: "" +## @param extraEnvVarsSecret Name of existing Secret containing extra env vars +## +extraEnvVarsSecret: "" + +## @section Ghost deployment parameters + +## @param replicaCount Number of Ghost replicas to deploy +## NOTE: ReadWriteMany PVC(s) are required if replicaCount > 1 +## +replicaCount: 1 +## @param updateStrategy.type Ghost deployment strategy type +## ref: https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#strategy +## NOTE: Set it to `Recreate` if you use a PV that cannot be mounted on multiple pods +## e.g: +## updateStrategy: +## type: RollingUpdate +## rollingUpdate: +## maxSurge: 25% +## maxUnavailable: 25% +## +updateStrategy: + type: RollingUpdate +## @param priorityClassName Ghost pod priority class name +## +priorityClassName: "" +## @param schedulerName Name of the k8s scheduler (other than default) +## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ +## +schedulerName: "" +## @param topologySpreadConstraints Topology Spread Constraints for pod assignment +## https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ +## The value is evaluated as a template +## +topologySpreadConstraints: [] +## @param hostAliases Ghost pod host aliases +## https://kubernetes.io/docs/concepts/services-networking/add-entries-to-pod-etc-hosts-with-host-aliases/ +## +hostAliases: [] +## @param extraVolumes Optionally specify extra list of additional volumes for Ghost pods +## +extraVolumes: [] +## @param extraVolumeMounts Optionally specify extra list of additional volumeMounts for Ghost container(s) +## +extraVolumeMounts: [] +## @param sidecars Add additional sidecar containers to the Ghost pod +## e.g: +## sidecars: +## - name: your-image-name +## image: your-image +## imagePullPolicy: Always +## ports: +## - name: portname +## containerPort: 1234 +## +sidecars: [] +## @param initContainers Add additional init containers to the Ghost pods +## ref: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/ +## e.g: +## initContainers: +## - name: your-image-name +## image: your-image +## imagePullPolicy: Always +## ports: +## - name: portname +## containerPort: 1234 +## +initContainers: [] +## @param lifecycleHooks Add lifecycle hooks to the Ghost deployment +## +lifecycleHooks: {} +## @param podLabels Extra labels for Ghost pods +## ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ +## +podLabels: {} +## @param podAnnotations Annotations for Ghost pods +## ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ +## +podAnnotations: {} +## @param podAffinityPreset Pod affinity preset. Ignored if `affinity` is set. Allowed values: `soft` or `hard` +## ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity +## +podAffinityPreset: "" +## @param podAntiAffinityPreset Pod anti-affinity preset. Ignored if `affinity` is set. Allowed values: `soft` or `hard` +## Ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity +## +podAntiAffinityPreset: soft +## Node affinity preset +## Ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#node-affinity +## +nodeAffinityPreset: + ## @param nodeAffinityPreset.type Node affinity preset type. Ignored if `affinity` is set. Allowed values: `soft` or `hard` + ## + type: "" + ## @param nodeAffinityPreset.key Node label key to match. Ignored if `affinity` is set + ## + key: "" + ## @param nodeAffinityPreset.values Node label values to match. Ignored if `affinity` is set + ## E.g. + ## values: + ## - e2e-az1 + ## - e2e-az2 + ## + values: [] +## @param affinity Affinity for pod assignment +## Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity +## NOTE: podAffinityPreset, podAntiAffinityPreset, and nodeAffinityPreset will be ignored when it's set +## +affinity: {} +## @param nodeSelector Node labels for pod assignment +## ref: https://kubernetes.io/docs/user-guide/node-selection/ +## +nodeSelector: {} +## @param tolerations Tolerations for pod assignment +## ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ +## +tolerations: [] +## Ghost containers' resource requests and limits +## ref: https://kubernetes.io/docs/user-guide/compute-resources/ +## @param resources.limits The resources limits for the Ghost container +## @param resources.requests The requested resources for the Ghost container +## +resources: + limits: {} + requests: {} +## Container ports +## @param containerPorts.http Ghost HTTP container port +## @param containerPorts.https Ghost HTTPS container port +## +containerPorts: + http: 2368 + https: 2368 +## Configure Pods Security Context +## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod +## @param podSecurityContext.enabled Enabled Ghost pods' Security Context +## @param podSecurityContext.fsGroup Set Ghost pod's Security Context fsGroup +## +podSecurityContext: + enabled: true + fsGroup: 1001 +## Configure Container Security Context (only main container) +## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container +## @param containerSecurityContext.enabled Enabled Ghost containers' Security Context +## @param containerSecurityContext.runAsUser Set Ghost container's Security Context runAsUser +## @param containerSecurityContext.runAsNonRoot Set Ghost container's Security Context runAsNonRoot +## +containerSecurityContext: + enabled: true + runAsUser: 1001 + runAsNonRoot: true +## Configure extra options for Ghost containers' liveness, readiness and startup probes +## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes +## @param startupProbe.enabled Enable startupProbe +## @param startupProbe.initialDelaySeconds Initial delay seconds for startupProbe +## @param startupProbe.periodSeconds Period seconds for startupProbe +## @param startupProbe.timeoutSeconds Timeout seconds for startupProbe +## @param startupProbe.failureThreshold Failure threshold for startupProbe +## @param startupProbe.successThreshold Success threshold for startupProbe +## +startupProbe: + enabled: false + initialDelaySeconds: 120 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 6 + successThreshold: 1 +## @param livenessProbe.enabled Enable livenessProbe +## @param livenessProbe.initialDelaySeconds Initial delay seconds for livenessProbe +## @param livenessProbe.periodSeconds Period seconds for livenessProbe +## @param livenessProbe.timeoutSeconds Timeout seconds for livenessProbe +## @param livenessProbe.failureThreshold Failure threshold for livenessProbe +## @param livenessProbe.successThreshold Success threshold for livenessProbe +## +livenessProbe: + enabled: true + initialDelaySeconds: 120 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 6 + successThreshold: 1 +## @param readinessProbe.enabled Enable readinessProbe +## @param readinessProbe.initialDelaySeconds Initial delay seconds for readinessProbe +## @param readinessProbe.periodSeconds Period seconds for readinessProbe +## @param readinessProbe.timeoutSeconds Timeout seconds for readinessProbe +## @param readinessProbe.failureThreshold Failure threshold for readinessProbe +## @param readinessProbe.successThreshold Success threshold for readinessProbe +## +readinessProbe: + enabled: true + initialDelaySeconds: 30 + periodSeconds: 5 + timeoutSeconds: 3 + failureThreshold: 6 + successThreshold: 1 +## @param customLivenessProbe Custom livenessProbe that overrides the default one +## +customLivenessProbe: {} +## @param customReadinessProbe Custom readinessProbe that overrides the default one +# +customReadinessProbe: {} + +## @section Traffic Exposure Parameters + +## Ghost service parameters +## +service: + ## @param service.type Ghost service type + ## + type: LoadBalancer + ## @param service.ports.http Ghost service HTTP port + ## @param service.ports.https Ghost service HTTPS port + ## + ports: + http: 80 + https: 443 + ## Node ports to expose + ## @param service.nodePorts.http Node port for HTTP + ## @param service.nodePorts.https Node port for HTTPS + ## NOTE: choose port between <30000-32767> + ## + nodePorts: + http: "" + https: "" + ## @param service.clusterIP Ghost service Cluster IP + ## e.g.: + ## clusterIP: None + ## + clusterIP: "" + ## @param service.loadBalancerIP Ghost service Load Balancer IP + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-loadbalancer + ## + loadBalancerIP: "" + ## @param service.loadBalancerSourceRanges Ghost service Load Balancer sources + ## ref: https://kubernetes.io/docs/tasks/access-application-cluster/configure-cloud-provider-firewall/#restrict-access-for-loadbalancer-service + ## e.g: + ## loadBalancerSourceRanges: + ## - 10.10.10.0/24 + ## + loadBalancerSourceRanges: [] + ## @param service.externalTrafficPolicy Ghost service external traffic policy + ## ref https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#preserving-the-client-source-ip + ## + externalTrafficPolicy: Cluster + ## @param service.annotations Additional custom annotations for Ghost service + ## + annotations: {} + ## @param service.extraPorts Extra port to expose on Ghost service + ## + extraPorts: [] + ## @param service.sessionAffinity Session Affinity for Kubernetes service, can be "None" or "ClientIP" + ## If "ClientIP", consecutive client requests will be directed to the same Pod + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + ## + sessionAffinity: None + ## @param service.sessionAffinityConfig Additional settings for the sessionAffinity + ## sessionAffinityConfig: + ## clientIP: + ## timeoutSeconds: 300 + sessionAffinityConfig: {} +## Configure the ingress resource that allows you to access the Ghost installation +## ref: https://kubernetes.io/docs/user-guide/ingress/ +## +ingress: + ## @param ingress.enabled Enable ingress record generation for Ghost + ## + enabled: false + ## @param ingress.pathType Ingress path type + ## + pathType: ImplementationSpecific + ## @param ingress.apiVersion Force Ingress API version (automatically detected if not set) + ## + apiVersion: "" + ## @param ingress.hostname Default host for the ingress record + ## + hostname: ghost.local + ## @param ingress.path Default path for the ingress record + ## NOTE: You may need to set this to '/*' in order to use this with ALB ingress controllers + ## + path: / + ## @param ingress.annotations Additional annotations for the Ingress resource. To enable certificate autogeneration, place here your cert-manager annotations. + ## For a full list of possible ingress annotations, please see + ## ref: https://github.com/kubernetes/ingress-nginx/blob/master/docs/user-guide/nginx-configuration/annotations.md + ## Use this parameter to set the required annotations for cert-manager, see + ## ref: https://cert-manager.io/docs/usage/ingress/#supported-annotations + ## + ## e.g: + ## annotations: + ## kubernetes.io/ingress.class: nginx + ## cert-manager.io/cluster-issuer: cluster-issuer-name + ## + annotations: {} + ## @param ingress.tls Enable TLS configuration for the host defined at `ingress.hostname` parameter + ## TLS certificates will be retrieved from a TLS secret with name: `{{- printf "%s-tls" .Values.ingress.hostname }}` + ## You can: + ## - Use the `ingress.secrets` parameter to create this TLS secret + ## - Rely on cert-manager to create it by setting the corresponding annotations + ## - Rely on Helm to create self-signed certificates by setting `ingress.selfSigned=true` + ## + tls: false + ## DEPRECATED: Use ingress.annotations instead of ingress.certManager + ## certManager: false + ## + + ## @param ingress.selfSigned Create a TLS secret for this ingress record using self-signed certificates generated by Helm + ## + selfSigned: false + ## @param ingress.extraHosts An array with additional hostname(s) to be covered with the ingress record + ## e.g: + ## extraHosts: + ## - name: ghost.local + ## path: / + ## + extraHosts: [] + ## @param ingress.extraPaths An array with additional arbitrary paths that may need to be added to the ingress under the main host + ## e.g: + ## extraPaths: + ## - path: /* + ## backend: + ## serviceName: ssl-redirect + ## servicePort: use-annotation + ## + extraPaths: [] + ## @param ingress.extraTls TLS configuration for additional hostname(s) to be covered with this ingress record + ## ref: https://kubernetes.io/docs/concepts/services-networking/ingress/#tls + ## e.g: + ## extraTls: + ## - hosts: + ## - ghost.local + ## secretName: ghost.local-tls + ## + extraTls: [] + ## @param ingress.secrets Custom TLS certificates as secrets + ## NOTE: 'key' and 'certificate' are expected in PEM format + ## NOTE: 'name' should line up with a 'secretName' set further up + ## If it is not set and you're using cert-manager, this is unneeded, as it will create a secret for you with valid certificates + ## If it is not set and you're NOT using cert-manager either, self-signed certificates will be created valid for 365 days + ## It is also possible to create and manage the certificates outside of this helm chart + ## Please see README.md for more information + ## e.g: + ## secrets: + ## - name: ghost.local-tls + ## key: |- + ## -----BEGIN RSA PRIVATE KEY----- + ## ... + ## -----END RSA PRIVATE KEY----- + ## certificate: |- + ## -----BEGIN CERTIFICATE----- + ## ... + ## -----END CERTIFICATE----- + ## + secrets: [] + ## @param ingress.ingressClassName IngressClass that will be be used to implement the Ingress (Kubernetes 1.18+) + ## This is supported in Kubernetes 1.18+ and required if you have more than one IngressClass marked as the default for your cluster . + ## ref: https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/ + ## + ingressClassName: "" + ## @param ingress.extraRules Additional rules to be covered with this ingress record + ## ref: https://kubernetes.io/docs/concepts/services-networking/ingress/#ingress-rules + ## e.g: + ## extraRules: + ## - host: example.local + ## http: + ## path: / + ## backend: + ## service: + ## name: example-svc + ## port: + ## name: http + ## + extraRules: [] +## @section Persistence Parameters + +## Persistence Parameters +## ref: https://kubernetes.io/docs/user-guide/persistent-volumes/ +## +persistence: + ## @param persistence.enabled Enable persistence using Persistent Volume Claims + ## + enabled: true + ## @param persistence.storageClass Persistent Volume storage class + ## If defined, storageClassName: + ## If set to "-", storageClassName: "", which disables dynamic provisioning + ## If undefined (the default) or set to null, no storageClassName spec is set, choosing the default provisioner + ## + storageClass: "" + ## @param persistence.annotations Additional custom annotations for the PVC + ## + annotations: {} + ## @param persistence.accessModes [array] Persistent Volume access modes + ## + accessModes: + - ReadWriteOnce + ## @param persistence.size Persistent Volume size + ## + size: 8Gi + ## @param persistence.existingClaim The name of an existing PVC to use for persistence + ## + existingClaim: "" + ## @param persistence.subPath The name of a volume's sub path to mount for persistence + ## + subPath: "" +## 'volumePermissions' init container parameters +## Changes the owner and group of the persistent volume mount point to runAsUser:fsGroup values +## based on the podSecurityContext/containerSecurityContext parameters +## +volumePermissions: + ## @param volumePermissions.enabled Enable init container that changes the owner/group of the PV mount point to `runAsUser:fsGroup` + ## + enabled: false + ## OS Shell + Utility image + ## ref: https://hub.docker.com/r/bitnami/os-shell/tags/ + ## @param volumePermissions.image.registry OS Shell + Utility image registry + ## @param volumePermissions.image.repository OS Shell + Utility image repository + ## @param volumePermissions.image.tag OS Shell + Utility image tag (immutable tags are recommended) + ## @param volumePermissions.image.digest OS Shell + Utility image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag + ## @param volumePermissions.image.pullPolicy OS Shell + Utility image pull policy + ## @param volumePermissions.image.pullSecrets OS Shell + Utility image pull secrets + ## + image: + registry: docker.io + repository: bitnami/os-shell + tag: 11-debian-11-r11 + digest: "" + pullPolicy: IfNotPresent + ## Optionally specify an array of imagePullSecrets. + ## Secrets must be manually created in the namespace. + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ + ## e.g: + ## pullSecrets: + ## - myRegistryKeySecretName + ## + pullSecrets: [] + ## Init container's resource requests and limits + ## ref: https://kubernetes.io/docs/user-guide/compute-resources/ + ## @param volumePermissions.resources.limits The resources limits for the init container + ## @param volumePermissions.resources.requests The requested resources for the init container + ## + resources: + limits: {} + requests: {} + ## Init container Container Security Context + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container + ## @param volumePermissions.securityContext.runAsUser Set init container's Security Context runAsUser + ## NOTE: when runAsUser is set to special value "auto", init container will try to chown the + ## data folder to auto-determined user&group, using commands: `id -u`:`id -G | cut -d" " -f2` + ## "auto" is especially useful for OpenShift which has scc with dynamic user ids (and 0 is not allowed) + ## + securityContext: + runAsUser: 0 + +## @section Database Parameters + +## MySQL chart configuration +## ref: https://github.com/bitnami/charts/blob/main/bitnami/mysql/values.yaml +## +mysql: + ## @param mysql.enabled Deploy a MySQL server to satisfy the applications database requirements + ## To use an external database set this to false and configure the `externalDatabase.*` parameters + ## + enabled: true + ## @param mysql.architecture MySQL architecture. Allowed values: `standalone` or `replication` + ## + architecture: standalone + ## MySQL Authentication parameters + ## @param mysql.auth.rootPassword MySQL root password + ## @param mysql.auth.database MySQL custom database + ## @param mysql.auth.username MySQL custom user name + ## @param mysql.auth.password MySQL custom user password + ## @param mysql.auth.existingSecret Existing secret with MySQL credentials + ## ref: https://github.com/bitnami/containers/tree/main/bitnami/mysql#setting-the-root-password-on-first-run + ## https://github.com/bitnami/containers/tree/main/bitnami/mysql/#creating-a-database-on-first-run + ## https://github.com/bitnami/containers/tree/main/bitnami/mysql/#creating-a-database-user-on-first-run + auth: + rootPassword: "" + database: bitnami_ghost + username: bn_ghost + password: "" + existingSecret: "" + ## MySQL Primary configuration + ## + primary: + ## MySQL Primary Persistence parameters + ## ref: https://kubernetes.io/docs/user-guide/persistent-volumes/ + ## @param mysql.primary.persistence.enabled Enable persistence on MySQL using PVC(s) + ## @param mysql.primary.persistence.storageClass Persistent Volume storage class + ## @param mysql.primary.persistence.accessModes [array] Persistent Volume access modes + ## @param mysql.primary.persistence.size Persistent Volume size + ## + persistence: + enabled: true + storageClass: "" + accessModes: + - ReadWriteOnce + size: 8Gi +## External Database Configuration +## All of these values are only used if `mysql.enabled=false` +## +externalDatabase: + ## @param externalDatabase.host External Database server host + ## + host: localhost + ## @param externalDatabase.port External Database server port + ## + port: 3306 + ## @param externalDatabase.user External Database username + ## + user: bn_ghost + ## @param externalDatabase.password External Database user password + ## + password: "" + ## @param externalDatabase.database External Database database name + ## + database: bitnami_ghost + ## @param externalDatabase.existingSecret The name of an existing secret with database credentials + ## NOTE: Must contain key `mysql-password` + ## NOTE: When it's set, the `externalDatabase.password` parameter is ignored + ## + existingSecret: "" + ## @param externalDatabase.ssl External Database ssl + ## + ssl: false + ## @param externalDatabase.sslCaFile External Database ssl CA filepath + ## + sslCaFile: "" + +## @section NetworkPolicy parameters + +## Add networkpolicies +## +networkPolicy: + ## @param networkPolicy.enabled Enable network policies + ## If ingress.enabled or metrics.enabled are true, configure networkPolicy.ingress and networkPolicy.metrics selectors respectively to allow communication + ## + enabled: false + ## @param networkPolicy.ingress.enabled Enable network policy for Ingress Proxies + ## @param networkPolicy.ingress.namespaceSelector Ingress Proxy namespace selector labels. These labels will be used to identify the Ingress Proxy's namespace. + ## @param networkPolicy.ingress.podSelector Ingress Proxy pods selector labels. These labels will be used to identify the Ingress Proxy pods. + ## + ingress: + enabled: false + ## e.g: + ## podSelector: + ## label: ingress + ## + podSelector: {} + ## e.g: + ## namespaceSelector: + ## label: ingress + ## + namespaceSelector: {} + ## @param networkPolicy.ingressRules.backendOnlyAccessibleByFrontend Enable ingress rule that makes the backend (mysql) only accessible by Ghost's pods. + ## @param networkPolicy.ingressRules.customBackendSelector Backend selector labels. These labels will be used to identify the backend pods. + ## @param networkPolicy.ingressRules.accessOnlyFrom.enabled Enable ingress rule that makes Ghost only accessible from a particular origin + ## @param networkPolicy.ingressRules.accessOnlyFrom.namespaceSelector Namespace selector label that is allowed to access Ghost. This label will be used to identified the allowed namespace(s). + ## @param networkPolicy.ingressRules.accessOnlyFrom.podSelector Pods selector label that is allowed to access Ghost. This label will be used to identified the allowed pod(s). + ## @param networkPolicy.ingressRules.customRules Custom network policy ingress rule + ## + ingressRules: + ## mysql backend only can be accessed from Ghost + ## + backendOnlyAccessibleByFrontend: false + customBackendSelector: {} + ## Allow only from the indicated: + ## + accessOnlyFrom: + enabled: false + ## e.g: + ## namespaceSelector: + ## label: ingress + ## + namespaceSelector: {} + ## e.g: + ## podSelector: + ## label: access + ## + podSelector: {} + ## custom ingress rules + ## e.g: + ## customRules: + ## - from: + ## - namespaceSelector: + ## matchLabels: + ## label: example + ## + customRules: {} + ## @param networkPolicy.egressRules.denyConnectionsToExternal Enable egress rule that denies outgoing traffic outside the cluster, except for DNS (port 53). + ## @param networkPolicy.egressRules.customRules Custom network policy rule + ## + egressRules: + ## Deny connections to external. This is not compatible with an external database. + ## + denyConnectionsToExternal: false + ## Additional custom egress rules + ## e.g: + ## customRules: + ## - to: + ## - namespaceSelector: + ## matchLabels: + ## label: example + ## + customRules: {} + +## Pods Service Account +## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ +## @param serviceAccount.create Specifies whether a ServiceAccount should be created +## @param serviceAccount.name Name of the service account to use. If not set and create is true, a name is generated using the fullname template. +## @param serviceAccount.automountServiceAccountToken Automount service account token for the server service account +## @param serviceAccount.annotations Annotations for service account. Evaluated as a template. Only used if `create` is `true`. +## +serviceAccount: + create: true + name: "" + automountServiceAccountToken: true + annotations: {} diff --git a/helm/grafana/.helmignore b/helm/grafana/.helmignore new file mode 100644 index 0000000..8cade13 --- /dev/null +++ b/helm/grafana/.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 +*~ +# Various IDEs +.vscode +.project +.idea/ +*.tmproj +OWNERS diff --git a/helm/grafana/Chart.yaml b/helm/grafana/Chart.yaml new file mode 100644 index 0000000..8a2dc33 --- /dev/null +++ b/helm/grafana/Chart.yaml @@ -0,0 +1,22 @@ +apiVersion: v2 +appVersion: 9.3.8 +description: The leading tool for querying and visualizing time series and metrics. +home: https://grafana.net +icon: https://raw.githubusercontent.com/grafana/grafana/master/public/img/logo_transparent_400x.png +kubeVersion: ^1.8.0-0 +maintainers: +- email: zanhsieh@gmail.com + name: zanhsieh +- email: rluckie@cisco.com + name: rtluckie +- email: maor.friedman@redhat.com + name: maorfr +- email: miroslav.hadzhiev@gmail.com + name: Xtigyro +- email: mail@torstenwalter.de + name: torstenwalter +name: grafana +sources: +- https://github.com/grafana/grafana +type: application +version: 6.51.2 diff --git a/helm/grafana/README.md b/helm/grafana/README.md new file mode 100644 index 0000000..cd8d316 --- /dev/null +++ b/helm/grafana/README.md @@ -0,0 +1,651 @@ +# Grafana Helm Chart + +* Installs the web dashboarding system [Grafana](http://grafana.org/) + +## Get Repo Info + +```console +helm repo add grafana https://grafana.github.io/helm-charts +helm repo update +``` + +_See [helm repo](https://helm.sh/docs/helm/helm_repo/) for command documentation._ + +## Installing the Chart + +To install the chart with the release name `my-release`: + +```console +helm install my-release grafana/grafana +``` + +## Uninstalling the Chart + +To uninstall/delete the my-release deployment: + +```console +helm delete my-release +``` + +The command removes all the Kubernetes components associated with the chart and deletes the release. + +## Upgrading an existing Release to a new major version + +A major chart version change (like v1.2.3 -> v2.0.0) indicates that there is an +incompatible breaking change needing manual actions. + +### To 4.0.0 (And 3.12.1) + +This version requires Helm >= 2.12.0. + +### To 5.0.0 + +You have to add --force to your helm upgrade command as the labels of the chart have changed. + +### To 6.0.0 + +This version requires Helm >= 3.1.0. + +## Configuration + +| Parameter | Description | Default | +|-------------------------------------------|-----------------------------------------------|---------------------------------------------------------| +| `replicas` | Number of nodes | `1` | +| `podDisruptionBudget.minAvailable` | Pod disruption minimum available | `nil` | +| `podDisruptionBudget.maxUnavailable` | Pod disruption maximum unavailable | `nil` | +| `deploymentStrategy` | Deployment strategy | `{ "type": "RollingUpdate" }` | +| `livenessProbe` | Liveness Probe settings | `{ "httpGet": { "path": "/api/health", "port": 3000 } "initialDelaySeconds": 60, "timeoutSeconds": 30, "failureThreshold": 10 }` | +| `readinessProbe` | Readiness Probe settings | `{ "httpGet": { "path": "/api/health", "port": 3000 } }`| +| `securityContext` | Deployment securityContext | `{"runAsUser": 472, "runAsGroup": 472, "fsGroup": 472}` | +| `priorityClassName` | Name of Priority Class to assign pods | `nil` | +| `image.repository` | Image repository | `grafana/grafana` | +| `image.tag` | Overrides the Grafana image tag whose default is the chart appVersion (`Must be >= 5.0.0`) | `` | +| `image.sha` | Image sha (optional) | `` | +| `image.pullPolicy` | Image pull policy | `IfNotPresent` | +| `image.pullSecrets` | Image pull secrets (can be templated) | `[]` | +| `service.enabled` | Enable grafana service | `true` | +| `service.type` | Kubernetes service type | `ClusterIP` | +| `service.port` | Kubernetes port where service is exposed | `80` | +| `service.portName` | Name of the port on the service | `service` | +| `service.appProtocol` | Adds the appProtocol field to the service | `` | +| `service.targetPort` | Internal service is port | `3000` | +| `service.nodePort` | Kubernetes service nodePort | `nil` | +| `service.annotations` | Service annotations (can be templated) | `{}` | +| `service.labels` | Custom labels | `{}` | +| `service.clusterIP` | internal cluster service IP | `nil` | +| `service.loadBalancerIP` | IP address to assign to load balancer (if supported) | `nil` | +| `service.loadBalancerSourceRanges` | list of IP CIDRs allowed access to lb (if supported) | `[]` | +| `service.externalIPs` | service external IP addresses | `[]` | +| `headlessService` | Create a headless service | `false` | +| `extraExposePorts` | Additional service ports for sidecar containers| `[]` | +| `hostAliases` | adds rules to the pod's /etc/hosts | `[]` | +| `ingress.enabled` | Enables Ingress | `false` | +| `ingress.annotations` | Ingress annotations (values are templated) | `{}` | +| `ingress.labels` | Custom labels | `{}` | +| `ingress.path` | Ingress accepted path | `/` | +| `ingress.pathType` | Ingress type of path | `Prefix` | +| `ingress.hosts` | Ingress accepted hostnames | `["chart-example.local"]` | +| `ingress.extraPaths` | Ingress extra paths to prepend to every host configuration. Useful when configuring [custom actions with AWS ALB Ingress Controller](https://kubernetes-sigs.github.io/aws-alb-ingress-controller/guide/ingress/annotation/#actions). Requires `ingress.hosts` to have one or more host entries. | `[]` | +| `ingress.tls` | Ingress TLS configuration | `[]` | +| `resources` | CPU/Memory resource requests/limits | `{}` | +| `nodeSelector` | Node labels for pod assignment | `{}` | +| `tolerations` | Toleration labels for pod assignment | `[]` | +| `affinity` | Affinity settings for pod assignment | `{}` | +| `extraInitContainers` | Init containers to add to the grafana pod | `{}` | +| `extraContainers` | Sidecar containers to add to the grafana pod | `""` | +| `extraContainerVolumes` | Volumes that can be mounted in sidecar containers | `[]` | +| `extraLabels` | Custom labels for all manifests | `{}` | +| `schedulerName` | Name of the k8s scheduler (other than default) | `nil` | +| `persistence.enabled` | Use persistent volume to store data | `false` | +| `persistence.type` | Type of persistence (`pvc` or `statefulset`) | `pvc` | +| `persistence.size` | Size of persistent volume claim | `10Gi` | +| `persistence.existingClaim` | Use an existing PVC to persist data (can be templated) | `nil` | +| `persistence.storageClassName` | Type of persistent volume claim | `nil` | +| `persistence.accessModes` | Persistence access modes | `[ReadWriteOnce]` | +| `persistence.annotations` | PersistentVolumeClaim annotations | `{}` | +| `persistence.finalizers` | PersistentVolumeClaim finalizers | `[ "kubernetes.io/pvc-protection" ]` | +| `persistence.extraPvcLabels` | Extra labels to apply to a PVC. | `{}` | +| `persistence.subPath` | Mount a sub dir of the persistent volume (can be templated) | `nil` | +| `persistence.inMemory.enabled` | If persistence is not enabled, whether to mount the local storage in-memory to improve performance | `false` | +| `persistence.inMemory.sizeLimit` | SizeLimit for the in-memory local storage | `nil` | +| `initChownData.enabled` | If false, don't reset data ownership at startup | true | +| `initChownData.image.repository` | init-chown-data container image repository | `busybox` | +| `initChownData.image.tag` | init-chown-data container image tag | `1.31.1` | +| `initChownData.image.sha` | init-chown-data container image sha (optional)| `""` | +| `initChownData.image.pullPolicy` | init-chown-data container image pull policy | `IfNotPresent` | +| `initChownData.resources` | init-chown-data pod resource requests & limits | `{}` | +| `schedulerName` | Alternate scheduler name | `nil` | +| `env` | Extra environment variables passed to pods | `{}` | +| `envValueFrom` | Environment variables from alternate sources. See the API docs on [EnvVarSource](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#envvarsource-v1-core) for format details. Can be templated | `{}` | +| `envFromSecret` | Name of a Kubernetes secret (must be manually created in the same namespace) containing values to be added to the environment. Can be templated | `""` | +| `envFromSecrets` | List of Kubernetes secrets (must be manually created in the same namespace) containing values to be added to the environment. Can be templated | `[]` | +| `envFromConfigMaps` | List of Kubernetes ConfigMaps (must be manually created in the same namespace) containing values to be added to the environment. Can be templated | `[]` | +| `envRenderSecret` | Sensible environment variables passed to pods and stored as secret | `{}` | +| `enableServiceLinks` | Inject Kubernetes services as environment variables. | `true` | +| `extraSecretMounts` | Additional grafana server secret mounts | `[]` | +| `extraVolumeMounts` | Additional grafana server volume mounts | `[]` | +| `createConfigmap` | Enable creating the grafana configmap | `true` | +| `extraConfigmapMounts` | Additional grafana server configMap volume mounts (values are templated) | `[]` | +| `extraEmptyDirMounts` | Additional grafana server emptyDir volume mounts | `[]` | +| `plugins` | Plugins to be loaded along with Grafana | `[]` | +| `datasources` | Configure grafana datasources (passed through tpl) | `{}` | +| `alerting` | Configure grafana alerting (passed through tpl) | `{}` | +| `notifiers` | Configure grafana notifiers | `{}` | +| `dashboardProviders` | Configure grafana dashboard providers | `{}` | +| `dashboards` | Dashboards to import | `{}` | +| `dashboardsConfigMaps` | ConfigMaps reference that contains dashboards | `{}` | +| `grafana.ini` | Grafana's primary configuration | `{}` | +| `global.imagePullSecrets` | Global image pull secrets (can be templated). Allows either an array of {name: pullSecret} maps (k8s-style), or an array of strings (more common helm-style). | `[]` | +| `ldap.enabled` | Enable LDAP authentication | `false` | +| `ldap.existingSecret` | The name of an existing secret containing the `ldap.toml` file, this must have the key `ldap-toml`. | `""` | +| `ldap.config` | Grafana's LDAP configuration | `""` | +| `annotations` | Deployment annotations | `{}` | +| `labels` | Deployment labels | `{}` | +| `podAnnotations` | Pod annotations | `{}` | +| `podLabels` | Pod labels | `{}` | +| `podPortName` | Name of the grafana port on the pod | `grafana` | +| `lifecycleHooks` | Lifecycle hooks for podStart and preStop [Example](https://kubernetes.io/docs/tasks/configure-pod-container/attach-handler-lifecycle-event/#define-poststart-and-prestop-handlers) | `{}` | +| `sidecar.image.repository` | Sidecar image repository | `quay.io/kiwigrid/k8s-sidecar` | +| `sidecar.image.tag` | Sidecar image tag | `1.22.0` | +| `sidecar.image.sha` | Sidecar image sha (optional) | `""` | +| `sidecar.imagePullPolicy` | Sidecar image pull policy | `IfNotPresent` | +| `sidecar.resources` | Sidecar resources | `{}` | +| `sidecar.securityContext` | Sidecar securityContext | `{}` | +| `sidecar.enableUniqueFilenames` | Sets the kiwigrid/k8s-sidecar UNIQUE_FILENAMES environment variable. If set to `true` the sidecar will create unique filenames where duplicate data keys exist between ConfigMaps and/or Secrets within the same or multiple Namespaces. | `false` | +| `sidecar.alerts.enabled` | Enables the cluster wide search for alerts and adds/updates/deletes them in grafana |`false` | +| `sidecar.alerts.label` | Label that config maps with alerts should have to be added | `grafana_alert` | +| `sidecar.alerts.labelValue` | Label value that config maps with alerts should have to be added | `""` | +| `sidecar.alerts.searchNamespace` | Namespaces list. If specified, the sidecar will search for alerts config-maps inside these namespaces. Otherwise the namespace in which the sidecar is running will be used. It's also possible to specify ALL to search in all namespaces. | `nil` | +| `sidecar.alerts.watchMethod` | Method to use to detect ConfigMap changes. With WATCH the sidecar will do a WATCH requests, with SLEEP it will list all ConfigMaps, then sleep for 60 seconds. | `WATCH` | +| `sidecar.alerts.resource` | Should the sidecar looks into secrets, configmaps or both. | `both` | +| `sidecar.alerts.reloadURL` | Full url of datasource configuration reload API endpoint, to invoke after a config-map change | `"http://localhost:3000/api/admin/provisioning/alerting/reload"` | +| `sidecar.alerts.skipReload` | Enabling this omits defining the REQ_URL and REQ_METHOD environment variables | `false` | +| `sidecar.alerts.initDatasources` | Set to true to deploy the datasource sidecar as an initContainer in addition to a container. This is needed if skipReload is true, to load any alerts defined at startup time. | `false` | +| `sidecar.dashboards.enabled` | Enables the cluster wide search for dashboards and adds/updates/deletes them in grafana | `false` | +| `sidecar.dashboards.SCProvider` | Enables creation of sidecar provider | `true` | +| `sidecar.dashboards.provider.name` | Unique name of the grafana provider | `sidecarProvider` | +| `sidecar.dashboards.provider.orgid` | Id of the organisation, to which the dashboards should be added | `1` | +| `sidecar.dashboards.provider.folder` | Logical folder in which grafana groups dashboards | `""` | +| `sidecar.dashboards.provider.disableDelete` | Activate to avoid the deletion of imported dashboards | `false` | +| `sidecar.dashboards.provider.allowUiUpdates` | Allow updating provisioned dashboards from the UI | `false` | +| `sidecar.dashboards.provider.type` | Provider type | `file` | +| `sidecar.dashboards.provider.foldersFromFilesStructure` | Allow Grafana to replicate dashboard structure from filesystem. | `false` | +| `sidecar.dashboards.watchMethod` | Method to use to detect ConfigMap changes. With WATCH the sidecar will do a WATCH requests, with SLEEP it will list all ConfigMaps, then sleep for 60 seconds. | `WATCH` | +| `sidecar.skipTlsVerify` | Set to true to skip tls verification for kube api calls | `nil` | +| `sidecar.dashboards.label` | Label that config maps with dashboards should have to be added | `grafana_dashboard` | +| `sidecar.dashboards.labelValue` | Label value that config maps with dashboards should have to be added | `""` | +| `sidecar.dashboards.folder` | Folder in the pod that should hold the collected dashboards (unless `sidecar.dashboards.defaultFolderName` is set). This path will be mounted. | `/tmp/dashboards` | +| `sidecar.dashboards.folderAnnotation` | The annotation the sidecar will look for in configmaps to override the destination folder for files | `nil` | +| `sidecar.dashboards.defaultFolderName` | The default folder name, it will create a subfolder under the `sidecar.dashboards.folder` and put dashboards in there instead | `nil` | +| `sidecar.dashboards.searchNamespace` | Namespaces list. If specified, the sidecar will search for dashboards config-maps inside these namespaces. Otherwise the namespace in which the sidecar is running will be used. It's also possible to specify ALL to search in all namespaces. | `nil` | +| `sidecar.dashboards.script` | Absolute path to shell script to execute after a configmap got reloaded. | `nil` | +| `sidecar.dashboards.reloadURL` | Full url of dashboards configuration reload API endpoint, to invoke after a config-map change | `"http://localhost:3000/api/admin/provisioning/dashboards/reload"` | +| `sidecar.dashboards.skipReload` | Enabling this omits defining the REQ_URL and REQ_METHOD environment variables | `false` | +| `sidecar.dashboards.resource` | Should the sidecar looks into secrets, configmaps or both. | `both` | +| `sidecar.dashboards.extraMounts` | Additional dashboard sidecar volume mounts. | `[]` | +| `sidecar.datasources.enabled` | Enables the cluster wide search for datasources and adds/updates/deletes them in grafana |`false` | +| `sidecar.datasources.label` | Label that config maps with datasources should have to be added | `grafana_datasource` | +| `sidecar.datasources.labelValue` | Label value that config maps with datasources should have to be added | `""` | +| `sidecar.datasources.searchNamespace` | Namespaces list. If specified, the sidecar will search for datasources config-maps inside these namespaces. Otherwise the namespace in which the sidecar is running will be used. It's also possible to specify ALL to search in all namespaces. | `nil` | +| `sidecar.datasources.watchMethod` | Method to use to detect ConfigMap changes. With WATCH the sidecar will do a WATCH requests, with SLEEP it will list all ConfigMaps, then sleep for 60 seconds. | `WATCH` | +| `sidecar.datasources.resource` | Should the sidecar looks into secrets, configmaps or both. | `both` | +| `sidecar.datasources.reloadURL` | Full url of datasource configuration reload API endpoint, to invoke after a config-map change | `"http://localhost:3000/api/admin/provisioning/datasources/reload"` | +| `sidecar.datasources.skipReload` | Enabling this omits defining the REQ_URL and REQ_METHOD environment variables | `false` | +| `sidecar.datasources.initDatasources` | Set to true to deploy the datasource sidecar as an initContainer in addition to a container. This is needed if skipReload is true, to load any datasources defined at startup time. | `false` | +| `sidecar.notifiers.enabled` | Enables the cluster wide search for notifiers and adds/updates/deletes them in grafana | `false` | +| `sidecar.notifiers.label` | Label that config maps with notifiers should have to be added | `grafana_notifier` | +| `sidecar.notifiers.labelValue` | Label value that config maps with notifiers should have to be added | `""` | +| `sidecar.notifiers.searchNamespace` | Namespaces list. If specified, the sidecar will search for notifiers config-maps (or secrets) inside these namespaces. Otherwise the namespace in which the sidecar is running will be used. It's also possible to specify ALL to search in all namespaces. | `nil` | +| `sidecar.notifiers.watchMethod` | Method to use to detect ConfigMap changes. With WATCH the sidecar will do a WATCH requests, with SLEEP it will list all ConfigMaps, then sleep for 60 seconds. | `WATCH` | +| `sidecar.notifiers.resource` | Should the sidecar looks into secrets, configmaps or both. | `both` | +| `sidecar.notifiers.reloadURL` | Full url of notifier configuration reload API endpoint, to invoke after a config-map change | `"http://localhost:3000/api/admin/provisioning/notifications/reload"` | +| `sidecar.notifiers.skipReload` | Enabling this omits defining the REQ_URL and REQ_METHOD environment variables | `false` | +| `sidecar.notifiers.initNotifiers` | Set to true to deploy the notifier sidecar as an initContainer in addition to a container. This is needed if skipReload is true, to load any notifiers defined at startup time. | `false` | +| `smtp.existingSecret` | The name of an existing secret containing the SMTP credentials. | `""` | +| `smtp.userKey` | The key in the existing SMTP secret containing the username. | `"user"` | +| `smtp.passwordKey` | The key in the existing SMTP secret containing the password. | `"password"` | +| `admin.existingSecret` | The name of an existing secret containing the admin credentials (can be templated). | `""` | +| `admin.userKey` | The key in the existing admin secret containing the username. | `"admin-user"` | +| `admin.passwordKey` | The key in the existing admin secret containing the password. | `"admin-password"` | +| `serviceAccount.autoMount` | Automount the service account token in the pod| `true` | +| `serviceAccount.annotations` | ServiceAccount annotations | | +| `serviceAccount.create` | Create service account | `true` | +| `serviceAccount.labels` | ServiceAccount labels | `{}` | +| `serviceAccount.name` | Service account name to use, when empty will be set to created account if `serviceAccount.create` is set else to `default` | `` | +| `serviceAccount.nameTest` | Service account name to use for test, when empty will be set to created account if `serviceAccount.create` is set else to `default` | `nil` | +| `rbac.create` | Create and use RBAC resources | `true` | +| `rbac.namespaced` | Creates Role and Rolebinding instead of the default ClusterRole and ClusteRoleBindings for the grafana instance | `false` | +| `rbac.useExistingRole` | Set to a rolename to use existing role - skipping role creating - but still doing serviceaccount and rolebinding to the rolename set here. | `nil` | +| `rbac.pspEnabled` | Create PodSecurityPolicy (with `rbac.create`, grant roles permissions as well) | `true` | +| `rbac.pspUseAppArmor` | Enforce AppArmor in created PodSecurityPolicy (requires `rbac.pspEnabled`) | `true` | +| `rbac.extraRoleRules` | Additional rules to add to the Role | [] | +| `rbac.extraClusterRoleRules` | Additional rules to add to the ClusterRole | [] | +| `command` | Define command to be executed by grafana container at startup | `nil` | +| `args` | Define additional args if command is used | `nil` | +| `testFramework.enabled` | Whether to create test-related resources | `true` | +| `testFramework.image` | `test-framework` image repository. | `bats/bats` | +| `testFramework.tag` | `test-framework` image tag. | `v1.4.1` | +| `testFramework.imagePullPolicy` | `test-framework` image pull policy. | `IfNotPresent` | +| `testFramework.securityContext` | `test-framework` securityContext | `{}` | +| `downloadDashboards.env` | Environment variables to be passed to the `download-dashboards` container | `{}` | +| `downloadDashboards.envFromSecret` | Name of a Kubernetes secret (must be manually created in the same namespace) containing values to be added to the environment. Can be templated | `""` | +| `downloadDashboards.resources` | Resources of `download-dashboards` container | `{}` | +| `downloadDashboardsImage.repository` | Curl docker image repo | `curlimages/curl` | +| `downloadDashboardsImage.tag` | Curl docker image tag | `7.73.0` | +| `downloadDashboardsImage.sha` | Curl docker image sha (optional) | `""` | +| `downloadDashboardsImage.pullPolicy` | Curl docker image pull policy | `IfNotPresent` | +| `namespaceOverride` | Override the deployment namespace | `""` (`Release.Namespace`) | +| `serviceMonitor.enabled` | Use servicemonitor from prometheus operator | `false` | +| `serviceMonitor.namespace` | Namespace this servicemonitor is installed in | | +| `serviceMonitor.interval` | How frequently Prometheus should scrape | `1m` | +| `serviceMonitor.path` | Path to scrape | `/metrics` | +| `serviceMonitor.scheme` | Scheme to use for metrics scraping | `http` | +| `serviceMonitor.tlsConfig` | TLS configuration block for the endpoint | `{}` | +| `serviceMonitor.labels` | Labels for the servicemonitor passed to Prometheus Operator | `{}` | +| `serviceMonitor.scrapeTimeout` | Timeout after which the scrape is ended | `30s` | +| `serviceMonitor.relabelings` | MetricRelabelConfigs to apply to samples before ingestion. | `[]` | +| `revisionHistoryLimit` | Number of old ReplicaSets to retain | `10` | +| `imageRenderer.enabled` | Enable the image-renderer deployment & service | `false` | +| `imageRenderer.image.repository` | image-renderer Image repository | `grafana/grafana-image-renderer` | +| `imageRenderer.image.tag` | image-renderer Image tag | `latest` | +| `imageRenderer.image.sha` | image-renderer Image sha (optional) | `""` | +| `imageRenderer.image.pullPolicy` | image-renderer ImagePullPolicy | `Always` | +| `imageRenderer.env` | extra env-vars for image-renderer | `{}` | +| `imageRenderer.serviceAccountName` | image-renderer deployment serviceAccountName | `""` | +| `imageRenderer.securityContext` | image-renderer deployment securityContext | `{}` | +| `imageRenderer.hostAliases` | image-renderer deployment Host Aliases | `[]` | +| `imageRenderer.priorityClassName` | image-renderer deployment priority class | `''` | +| `imageRenderer.service.enabled` | Enable the image-renderer service | `true` | +| `imageRenderer.service.portName` | image-renderer service port name | `http` | +| `imageRenderer.service.port` | image-renderer port used by deployment | `8081` | +| `imageRenderer.service.targetPort` | image-renderer service port used by service | `8081` | +| `imageRenderer.appProtocol` | Adds the appProtocol field to the service | `` | +| `imageRenderer.grafanaSubPath` | Grafana sub path to use for image renderer callback url | `''` | +| `imageRenderer.podPortName` | name of the image-renderer port on the pod | `http` | +| `imageRenderer.revisionHistoryLimit` | number of image-renderer replica sets to keep | `10` | +| `imageRenderer.networkPolicy.limitIngress` | Enable a NetworkPolicy to limit inbound traffic from only the created grafana pods | `true` | +| `imageRenderer.networkPolicy.limitEgress` | Enable a NetworkPolicy to limit outbound traffic to only the created grafana pods | `false` | +| `imageRenderer.resources` | Set resource limits for image-renderer pdos | `{}` | +| `imageRenderer.nodeSelector` | Node labels for pod assignment | `{}` | +| `imageRenderer.tolerations` | Toleration labels for pod assignment | `[]` | +| `imageRenderer.affinity` | Affinity settings for pod assignment | `{}` | +| `networkPolicy.enabled` | Enable creation of NetworkPolicy resources. | `false` | +| `networkPolicy.allowExternal` | Don't require client label for connections | `true` | +| `networkPolicy.explicitNamespacesSelector` | A Kubernetes LabelSelector to explicitly select namespaces from which traffic could be allowed | `{}` | +| `networkPolicy.ingress` | Enable the creation of an ingress network policy | `true` | +| `networkPolicy.egress.enabled` | Enable the creation of an egress network policy | `false` | +| `networkPolicy.egress.ports` | An array of ports to allow for the egress | `[]` | +| `enableKubeBackwardCompatibility` | Enable backward compatibility of kubernetes where pod's defintion version below 1.13 doesn't have the enableServiceLinks option | `false` | + +### Example ingress with path + +With grafana 6.3 and above + +```yaml +grafana.ini: + server: + domain: monitoring.example.com + root_url: "%(protocol)s://%(domain)s/grafana" + serve_from_sub_path: true +ingress: + enabled: true + hosts: + - "monitoring.example.com" + path: "/grafana" +``` + +### Example of extraVolumeMounts + +Volume can be type persistentVolumeClaim or hostPath but not both at same time. +If neither existingClaim or hostPath argument is given then type is emptyDir. + +```yaml +- extraVolumeMounts: + - name: plugins + mountPath: /var/lib/grafana/plugins + subPath: configs/grafana/plugins + existingClaim: existing-grafana-claim + readOnly: false + - name: dashboards + mountPath: /var/lib/grafana/dashboards + hostPath: /usr/shared/grafana/dashboards + readOnly: false +``` + +## Import dashboards + +There are a few methods to import dashboards to Grafana. Below are some examples and explanations as to how to use each method: + +```yaml +dashboards: + default: + some-dashboard: + json: | + { + "annotations": + + ... + # Complete json file here + ... + + "title": "Some Dashboard", + "uid": "abcd1234", + "version": 1 + } + custom-dashboard: + # This is a path to a file inside the dashboards directory inside the chart directory + file: dashboards/custom-dashboard.json + prometheus-stats: + # Ref: https://grafana.com/dashboards/2 + gnetId: 2 + revision: 2 + datasource: Prometheus + loki-dashboard-quick-search: + gnetId: 12019 + revision: 2 + datasource: + - name: DS_PROMETHEUS + value: Prometheus + - name: DS_LOKI + value: Loki + local-dashboard: + url: https://raw.githubusercontent.com/user/repository/master/dashboards/dashboard.json +``` + +## BASE64 dashboards + +Dashboards could be stored on a server that does not return JSON directly and instead of it returns a Base64 encoded file (e.g. Gerrit) +A new parameter has been added to the url use case so if you specify a b64content value equals to true after the url entry a Base64 decoding is applied before save the file to disk. +If this entry is not set or is equals to false not decoding is applied to the file before saving it to disk. + +### Gerrit use case + +Gerrit API for download files has the following schema: where {project-name} and +{file-id} usually has '/' in their values and so they MUST be replaced by %2F so if project-name is user/repo, branch-id is master and file-id is equals to dir1/dir2/dashboard +the url value is + +## Sidecar for dashboards + +If the parameter `sidecar.dashboards.enabled` is set, a sidecar container is deployed in the grafana +pod. This container watches all configmaps (or secrets) in the cluster and filters out the ones with +a label as defined in `sidecar.dashboards.label`. The files defined in those configmaps are written +to a folder and accessed by grafana. Changes to the configmaps are monitored and the imported +dashboards are deleted/updated. + +A recommendation is to use one configmap per dashboard, as a reduction of multiple dashboards inside +one configmap is currently not properly mirrored in grafana. + +Example dashboard config: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: sample-grafana-dashboard + labels: + grafana_dashboard: "1" +data: + k8s-dashboard.json: |- + [...] +``` + +## Sidecar for datasources + +If the parameter `sidecar.datasources.enabled` is set, an init container is deployed in the grafana +pod. This container lists all secrets (or configmaps, though not recommended) in the cluster and +filters out the ones with a label as defined in `sidecar.datasources.label`. The files defined in +those secrets are written to a folder and accessed by grafana on startup. Using these yaml files, +the data sources in grafana can be imported. + +Secrets are recommended over configmaps for this usecase because datasources usually contain private +data like usernames and passwords. Secrets are the more appropriate cluster resource to manage those. + +Example values to add a datasource adapted from [Grafana](http://docs.grafana.org/administration/provisioning/#example-datasource-config-file): + +```yaml +datasources: + datasources.yaml: + apiVersion: 1 + datasources: + # name of the datasource. Required + - name: Graphite + # datasource type. Required + type: graphite + # access mode. proxy or direct (Server or Browser in the UI). Required + access: proxy + # org id. will default to orgId 1 if not specified + orgId: 1 + # url + url: http://localhost:8080 + # database password, if used + password: + # database user, if used + user: + # database name, if used + database: + # enable/disable basic auth + basicAuth: + # basic auth username + basicAuthUser: + # basic auth password + basicAuthPassword: + # enable/disable with credentials headers + withCredentials: + # mark as default datasource. Max one per org + isDefault: + # fields that will be converted to json and stored in json_data + jsonData: + graphiteVersion: "1.1" + tlsAuth: true + tlsAuthWithCACert: true + # json object of data that will be encrypted. + secureJsonData: + tlsCACert: "..." + tlsClientCert: "..." + tlsClientKey: "..." + version: 1 + # allow users to edit datasources from the UI. + editable: false +``` + +## Sidecar for notifiers + +If the parameter `sidecar.notifiers.enabled` is set, an init container is deployed in the grafana +pod. This container lists all secrets (or configmaps, though not recommended) in the cluster and +filters out the ones with a label as defined in `sidecar.notifiers.label`. The files defined in +those secrets are written to a folder and accessed by grafana on startup. Using these yaml files, +the notification channels in grafana can be imported. The secrets must be created before +`helm install` so that the notifiers init container can list the secrets. + +Secrets are recommended over configmaps for this usecase because alert notification channels usually contain +private data like SMTP usernames and passwords. Secrets are the more appropriate cluster resource to manage those. + +Example datasource config adapted from [Grafana](https://grafana.com/docs/grafana/latest/administration/provisioning/#alert-notification-channels): + +```yaml +notifiers: + - name: notification-channel-1 + type: slack + uid: notifier1 + # either + org_id: 2 + # or + org_name: Main Org. + is_default: true + send_reminder: true + frequency: 1h + disable_resolve_message: false + # See `Supported Settings` section for settings supporter for each + # alert notification type. + settings: + recipient: 'XXX' + token: 'xoxb' + uploadImage: true + url: https://slack.com + +delete_notifiers: + - name: notification-channel-1 + uid: notifier1 + org_id: 2 + - name: notification-channel-2 + # default org_id: 1 +``` + +## Provision alert rules, contact points, notification policies and notification templates + +There are two methods to provision alerting configuration in Grafana. Below are some examples and explanations as to how to use each method: + +```yaml +alerting: + team1-alert-rules.yaml: + file: alerting/team1/rules.yaml + team2-alert-rules.yaml: + file: alerting/team2/rules.yaml + team3-alert-rules.yaml: + file: alerting/team3/rules.yaml + notification-policies.yaml: + file: alerting/shared/notification-policies.yaml + notification-templates.yaml: + file: alerting/shared/notification-templates.yaml + contactpoints.yaml: + apiVersion: 1 + contactPoints: + - orgId: 1 + name: Slack channel + receivers: + - uid: default-receiver + type: slack + settings: + # Webhook URL to be filled in + url: "" + # We need to escape double curly braces for the tpl function. + text: '{{ `{{ template "default.message" . }}` }}' + title: '{{ `{{ template "default.title" . }}` }}' +``` + +There are two possibilities: + +* Inlining the file contents as described in the example `values.yaml` and the official [Grafana documentation](https://grafana.com/docs/grafana/next/alerting/set-up/provision-alerting-resources/file-provisioning/). +* Importing a file using a relative path starting from the chart root directory. + +### Important notes on file provisioning + +* The chart supports importing YAML and JSON files. +* The filename must be unique, otherwise one volume mount will overwrite the other. +* In case of inlining, double curly braces that arise from the Grafana configuration format and are not intended as templates for the chart must be escaped. +* The number of total files under `alerting:` is not limited. Each file will end up as a volume mount in the corresponding provisioning folder of the deployed Grafana instance. +* The file size for each import is limited by what the function `.Files.Get` can handle, which suffices for most cases. + +## How to serve Grafana with a path prefix (/grafana) + +In order to serve Grafana with a prefix (e.g., ), add the following to your values.yaml. + +```yaml +ingress: + enabled: true + annotations: + kubernetes.io/ingress.class: "nginx" + nginx.ingress.kubernetes.io/rewrite-target: /$1 + nginx.ingress.kubernetes.io/use-regex: "true" + + path: /grafana/?(.*) + hosts: + - k8s.example.dev + +grafana.ini: + server: + root_url: http://localhost:3000/grafana # this host can be localhost +``` + +## How to securely reference secrets in grafana.ini + +This example uses Grafana [file providers](https://grafana.com/docs/grafana/latest/administration/configuration/#file-provider) for secret values and the `extraSecretMounts` configuration flag (Additional grafana server secret mounts) to mount the secrets. + +In grafana.ini: + +```yaml +grafana.ini: + [auth.generic_oauth] + enabled = true + client_id = $__file{/etc/secrets/auth_generic_oauth/client_id} + client_secret = $__file{/etc/secrets/auth_generic_oauth/client_secret} +``` + +Existing secret, or created along with helm: + +```yaml +--- +apiVersion: v1 +kind: Secret +metadata: + name: auth-generic-oauth-secret +type: Opaque +stringData: + client_id: + client_secret: +``` + +Include in the `extraSecretMounts` configuration flag: + +```yaml +- extraSecretMounts: + - name: auth-generic-oauth-secret-mount + secretName: auth-generic-oauth-secret + defaultMode: 0440 + mountPath: /etc/secrets/auth_generic_oauth + readOnly: true +``` + +### extraSecretMounts using a Container Storage Interface (CSI) provider + +This example uses a CSI driver e.g. retrieving secrets using [Azure Key Vault Provider](https://github.com/Azure/secrets-store-csi-driver-provider-azure) + +```yaml +- extraSecretMounts: + - name: secrets-store-inline + mountPath: /run/secrets + readOnly: true + csi: + driver: secrets-store.csi.k8s.io + readOnly: true + volumeAttributes: + secretProviderClass: "my-provider" + nodePublishSecretRef: + name: akv-creds +``` + +## Image Renderer Plug-In + +This chart supports enabling [remote image rendering](https://github.com/grafana/grafana-image-renderer/blob/master/README.md#run-in-docker) + +```yaml +imageRenderer: + enabled: true +``` + +### Image Renderer NetworkPolicy + +By default the image-renderer pods will have a network policy which only allows ingress traffic from the created grafana instance + +### High Availability for unified alerting + +If you want to run Grafana in a high availability cluster you need to enable +the headless service by setting `headlessService: true` in your `values.yaml` +file. + +As next step you have to setup the `grafana.ini` in your `values.yaml` in a way +that it will make use of the headless service to obtain all the IPs of the +cluster. You should replace ``{{ Name }}`` with the name of your helm deployment. + +```yaml +grafana.ini: + ... + unified_alerting: + enabled: true + ha_peers: {{ Name }}-headless:9094 + ha_listen_address: ${POD_IP}:9094 + ha_advertise_address: ${POD_IP}:9094 + + alerting: + enabled: false +``` diff --git a/helm/grafana/ci/default-values.yaml b/helm/grafana/ci/default-values.yaml new file mode 100644 index 0000000..fc2ba60 --- /dev/null +++ b/helm/grafana/ci/default-values.yaml @@ -0,0 +1 @@ +# Leave this file empty to ensure that CI runs builds against the default configuration in values.yaml. diff --git a/helm/grafana/ci/with-affinity-values.yaml b/helm/grafana/ci/with-affinity-values.yaml new file mode 100644 index 0000000..f5b9b53 --- /dev/null +++ b/helm/grafana/ci/with-affinity-values.yaml @@ -0,0 +1,16 @@ +affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/instance: grafana-test + app.kubernetes.io/name: grafana + topologyKey: failure-domain.beta.kubernetes.io/zone + weight: 100 + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/instance: grafana-test + app.kubernetes.io/name: grafana + topologyKey: kubernetes.io/hostname diff --git a/helm/grafana/ci/with-dashboard-json-values.yaml b/helm/grafana/ci/with-dashboard-json-values.yaml new file mode 100644 index 0000000..e0c4e41 --- /dev/null +++ b/helm/grafana/ci/with-dashboard-json-values.yaml @@ -0,0 +1,53 @@ +dashboards: + my-provider: + my-awesome-dashboard: + # An empty but valid dashboard + json: | + { + "__inputs": [], + "__requires": [ + { + "type": "grafana", + "id": "grafana", + "name": "Grafana", + "version": "6.3.5" + } + ], + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "id": null, + "links": [], + "panels": [], + "schemaVersion": 19, + "style": "dark", + "tags": [], + "templating": { + "list": [] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": ["5s"] + }, + "timezone": "", + "title": "Dummy Dashboard", + "uid": "IdcYQooWk", + "version": 1 + } + datasource: Prometheus diff --git a/helm/grafana/ci/with-dashboard-values.yaml b/helm/grafana/ci/with-dashboard-values.yaml new file mode 100644 index 0000000..7b662c5 --- /dev/null +++ b/helm/grafana/ci/with-dashboard-values.yaml @@ -0,0 +1,19 @@ +dashboards: + my-provider: + my-awesome-dashboard: + gnetId: 10000 + revision: 1 + datasource: Prometheus +dashboardProviders: + dashboardproviders.yaml: + apiVersion: 1 + providers: + - name: 'my-provider' + orgId: 1 + folder: '' + type: file + updateIntervalSeconds: 10 + disableDeletion: true + editable: true + options: + path: /var/lib/grafana/dashboards/my-provider diff --git a/helm/grafana/ci/with-extraconfigmapmounts-values.yaml b/helm/grafana/ci/with-extraconfigmapmounts-values.yaml new file mode 100644 index 0000000..5cc44a0 --- /dev/null +++ b/helm/grafana/ci/with-extraconfigmapmounts-values.yaml @@ -0,0 +1,7 @@ +extraConfigmapMounts: + - name: '{{ include "grafana.fullname" . }}' + configMap: '{{ include "grafana.fullname" . }}' + mountPath: /var/lib/grafana/dashboards/test-dashboard.json + # This is not a realistic test, but for this we only care about extraConfigmapMounts not being empty and pointing to an existing ConfigMap + subPath: grafana.ini + readOnly: true diff --git a/helm/grafana/ci/with-image-renderer-values.yaml b/helm/grafana/ci/with-image-renderer-values.yaml new file mode 100644 index 0000000..32f3074 --- /dev/null +++ b/helm/grafana/ci/with-image-renderer-values.yaml @@ -0,0 +1,19 @@ +podLabels: + customLableA: Aaaaa +imageRenderer: + enabled: true + env: + RENDERING_ARGS: --disable-gpu,--window-size=1280x758 + RENDERING_MODE: clustered + podLabels: + customLableB: Bbbbb + networkPolicy: + limitIngress: true + limitEgress: true + resources: + limits: + cpu: 1000m + memory: 1000Mi + requests: + cpu: 500m + memory: 50Mi diff --git a/helm/grafana/ci/with-persistence.yaml b/helm/grafana/ci/with-persistence.yaml new file mode 100644 index 0000000..b92ca02 --- /dev/null +++ b/helm/grafana/ci/with-persistence.yaml @@ -0,0 +1,3 @@ +persistence: + type: pvc + enabled: true diff --git a/helm/grafana/dashboards/custom-dashboard.json b/helm/grafana/dashboards/custom-dashboard.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/helm/grafana/dashboards/custom-dashboard.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/helm/grafana/templates/NOTES.txt b/helm/grafana/templates/NOTES.txt new file mode 100644 index 0000000..f399f43 --- /dev/null +++ b/helm/grafana/templates/NOTES.txt @@ -0,0 +1,54 @@ +1. Get your '{{ .Values.adminUser }}' user password by running: + + kubectl get secret --namespace {{ include "grafana.namespace" . }} {{ include "grafana.fullname" . }} -o jsonpath="{.data.admin-password}" | base64 --decode ; echo + +2. The Grafana server can be accessed via port {{ .Values.service.port }} on the following DNS name from within your cluster: + + {{ include "grafana.fullname" . }}.{{ include "grafana.namespace" . }}.svc.cluster.local +{{ if .Values.ingress.enabled }} + If you bind grafana to 80, please update values in values.yaml and reinstall: + ``` + securityContext: + runAsUser: 0 + runAsGroup: 0 + fsGroup: 0 + + command: + - "setcap" + - "'cap_net_bind_service=+ep'" + - "/usr/sbin/grafana-server &&" + - "sh" + - "/run.sh" + ``` + Details refer to https://grafana.com/docs/installation/configuration/#http-port. + Or grafana would always crash. + + From outside the cluster, the server URL(s) are: + {{- range .Values.ingress.hosts }} + http://{{ . }} + {{- end }} +{{- else }} + Get the Grafana URL to visit by running these commands in the same shell: + {{- if contains "NodePort" .Values.service.type }} + export NODE_PORT=$(kubectl get --namespace {{ include "grafana.namespace" . }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "grafana.fullname" . }}) + export NODE_IP=$(kubectl get nodes --namespace {{ include "grafana.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 svc --namespace {{ include "grafana.namespace" . }} -w {{ include "grafana.fullname" . }}' + export SERVICE_IP=$(kubectl get svc --namespace {{ include "grafana.namespace" . }} {{ include "grafana.fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}') + http://$SERVICE_IP:{{ .Values.service.port -}} + {{- else if contains "ClusterIP" .Values.service.type }} + export POD_NAME=$(kubectl get pods --namespace {{ include "grafana.namespace" . }} -l "app.kubernetes.io/name={{ include "grafana.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") + kubectl --namespace {{ include "grafana.namespace" . }} port-forward $POD_NAME 3000 + {{- end }} +{{- end }} + +3. Login with the password from step 1 and the username: {{ .Values.adminUser }} + +{{- if not .Values.persistence.enabled }} +################################################################################# +###### WARNING: Persistence is disabled!!! You will lose your data when ##### +###### the Grafana pod is terminated. ##### +################################################################################# +{{- end }} diff --git a/helm/grafana/templates/_helpers.tpl b/helm/grafana/templates/_helpers.tpl new file mode 100644 index 0000000..8307e10 --- /dev/null +++ b/helm/grafana/templates/_helpers.tpl @@ -0,0 +1,201 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "grafana.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 "grafana.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 "grafana.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create the name of the service account +*/}} +{{- define "grafana.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "grafana.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} + +{{- define "grafana.serviceAccountNameTest" -}} +{{- if .Values.serviceAccount.create }} +{{- default (print (include "grafana.fullname" .) "-test") .Values.serviceAccount.nameTest }} +{{- else }} +{{- default "default" .Values.serviceAccount.nameTest }} +{{- end }} +{{- end }} + +{{/* +Allow the release namespace to be overridden for multi-namespace deployments in combined charts +*/}} +{{- define "grafana.namespace" -}} +{{- if .Values.namespaceOverride }} +{{- .Values.namespaceOverride }} +{{- else }} +{{- .Release.Namespace }} +{{- end }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "grafana.labels" -}} +helm.sh/chart: {{ include "grafana.chart" . }} +{{ include "grafana.selectorLabels" . }} +{{- if or .Chart.AppVersion .Values.image.tag }} +app.kubernetes.io/version: {{ mustRegexReplaceAllLiteral "@sha.*" .Values.image.tag "" | default .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- with .Values.extraLabels }} +{{ toYaml . }} +{{- end }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "grafana.selectorLabels" -}} +app.kubernetes.io/name: {{ include "grafana.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "grafana.imageRenderer.labels" -}} +helm.sh/chart: {{ include "grafana.chart" . }} +{{ include "grafana.imageRenderer.selectorLabels" . }} +{{- if or .Chart.AppVersion .Values.image.tag }} +app.kubernetes.io/version: {{ mustRegexReplaceAllLiteral "@sha.*" .Values.image.tag "" | default .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels ImageRenderer +*/}} +{{- define "grafana.imageRenderer.selectorLabels" -}} +app.kubernetes.io/name: {{ include "grafana.name" . }}-image-renderer +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Looks if there's an existing secret and reuse its password. If not it generates +new password and use it. +*/}} +{{- define "grafana.password" -}} +{{- $secret := (lookup "v1" "Secret" (include "grafana.namespace" .) (include "grafana.fullname" .) ) }} +{{- if $secret }} +{{- index $secret "data" "admin-password" }} +{{- else }} +{{- (randAlphaNum 40) | b64enc | quote }} +{{- end }} +{{- end }} + +{{/* +Return the appropriate apiVersion for rbac. +*/}} +{{- define "grafana.rbac.apiVersion" -}} +{{- if $.Capabilities.APIVersions.Has "rbac.authorization.k8s.io/v1" }} +{{- print "rbac.authorization.k8s.io/v1" }} +{{- else }} +{{- print "rbac.authorization.k8s.io/v1beta1" }} +{{- end }} +{{- end }} + +{{/* +Return the appropriate apiVersion for ingress. +*/}} +{{- define "grafana.ingress.apiVersion" -}} +{{- if and ($.Capabilities.APIVersions.Has "networking.k8s.io/v1") (semverCompare ">= 1.19-0" .Capabilities.KubeVersion.Version) }} +{{- print "networking.k8s.io/v1" }} +{{- else if $.Capabilities.APIVersions.Has "networking.k8s.io/v1beta1" }} +{{- print "networking.k8s.io/v1beta1" }} +{{- else }} +{{- print "extensions/v1beta1" }} +{{- end }} +{{- end }} + +{{/* +Return the appropriate apiVersion for Horizontal Pod Autoscaler. +*/}} +{{- define "grafana.hpa.apiVersion" -}} +{{- if $.Capabilities.APIVersions.Has "autoscaling/v2/HorizontalPodAutoscaler" }} +{{- print "autoscaling/v2" }} +{{- else if $.Capabilities.APIVersions.Has "autoscaling/v2beta2/HorizontalPodAutoscaler" }} +{{- print "autoscaling/v2beta2" }} +{{- else }} +{{- print "autoscaling/v2beta1" }} +{{- end }} +{{- end }} + +{{/* +Return the appropriate apiVersion for podDisruptionBudget. +*/}} +{{- define "grafana.podDisruptionBudget.apiVersion" -}} +{{- if $.Capabilities.APIVersions.Has "policy/v1/PodDisruptionBudget" }} +{{- print "policy/v1" }} +{{- else }} +{{- print "policy/v1beta1" }} +{{- end }} +{{- end }} + +{{/* +Return if ingress is stable. +*/}} +{{- define "grafana.ingress.isStable" -}} +{{- eq (include "grafana.ingress.apiVersion" .) "networking.k8s.io/v1" }} +{{- end }} + +{{/* +Return if ingress supports ingressClassName. +*/}} +{{- define "grafana.ingress.supportsIngressClassName" -}} +{{- or (eq (include "grafana.ingress.isStable" .) "true") (and (eq (include "grafana.ingress.apiVersion" .) "networking.k8s.io/v1beta1") (semverCompare ">= 1.18-0" .Capabilities.KubeVersion.Version)) }} +{{- end }} + +{{/* +Return if ingress supports pathType. +*/}} +{{- define "grafana.ingress.supportsPathType" -}} +{{- or (eq (include "grafana.ingress.isStable" .) "true") (and (eq (include "grafana.ingress.apiVersion" .) "networking.k8s.io/v1beta1") (semverCompare ">= 1.18-0" .Capabilities.KubeVersion.Version)) }} +{{- end }} + +{{/* +Formats imagePullSecrets. Input is (dict "root" . "imagePullSecrets" .{specific imagePullSecrets}) +*/}} +{{- define "grafana.imagePullSecrets" -}} +{{- $root := .root }} +{{- range (concat .root.Values.global.imagePullSecrets .imagePullSecrets) }} +{{- if eq (typeOf .) "map[string]interface {}" }} +- {{ toYaml (dict "name" (tpl .name $root)) | trim }} +{{- else }} +- name: {{ tpl . $root }} +{{- end }} +{{- end }} +{{- end }} diff --git a/helm/grafana/templates/_pod.tpl b/helm/grafana/templates/_pod.tpl new file mode 100644 index 0000000..68a9b4b --- /dev/null +++ b/helm/grafana/templates/_pod.tpl @@ -0,0 +1,1159 @@ +{{- define "grafana.pod" -}} +{{- $sts := list "sts" "StatefulSet" "statefulset" -}} +{{- $root := . -}} +{{- with .Values.schedulerName }} +schedulerName: "{{ . }}" +{{- end }} +serviceAccountName: {{ include "grafana.serviceAccountName" . }} +automountServiceAccountToken: {{ .Values.serviceAccount.autoMount }} +{{- with .Values.securityContext }} +securityContext: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- with .Values.hostAliases }} +hostAliases: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- with .Values.priorityClassName }} +priorityClassName: {{ . }} +{{- end }} +{{- if ( or .Values.persistence.enabled .Values.dashboards .Values.extraInitContainers (and .Values.sidecar.datasources.enabled .Values.sidecar.datasources.initDatasources) (and .Values.sidecar.notifiers.enabled .Values.sidecar.notifiers.initNotifiers)) }} +initContainers: +{{- end }} +{{- if ( and .Values.persistence.enabled .Values.initChownData.enabled ) }} + - name: init-chown-data + {{- if .Values.initChownData.image.sha }} + image: "{{ .Values.initChownData.image.repository }}:{{ .Values.initChownData.image.tag }}@sha256:{{ .Values.initChownData.image.sha }}" + {{- else }} + image: "{{ .Values.initChownData.image.repository }}:{{ .Values.initChownData.image.tag }}" + {{- end }} + imagePullPolicy: {{ .Values.initChownData.image.pullPolicy }} + {{- with .Values.initChownData.securityContext }} + securityContext: + {{- toYaml . | nindent 6 }} + {{- end }} + command: + - chown + - -R + - {{ .Values.securityContext.runAsUser }}:{{ .Values.securityContext.runAsGroup }} + - /var/lib/grafana + {{- with .Values.initChownData.resources }} + resources: + {{- toYaml . | nindent 6 }} + {{- end }} + volumeMounts: + - name: storage + mountPath: "/var/lib/grafana" + {{- with .Values.persistence.subPath }} + subPath: {{ tpl . $root }} + {{- end }} +{{- end }} +{{- if .Values.dashboards }} + - name: download-dashboards + {{- if .Values.downloadDashboardsImage.sha }} + image: "{{ .Values.downloadDashboardsImage.repository }}:{{ .Values.downloadDashboardsImage.tag }}@sha256:{{ .Values.downloadDashboardsImage.sha }}" + {{- else }} + image: "{{ .Values.downloadDashboardsImage.repository }}:{{ .Values.downloadDashboardsImage.tag }}" + {{- end }} + imagePullPolicy: {{ .Values.downloadDashboardsImage.pullPolicy }} + command: ["/bin/sh"] + args: [ "-c", "mkdir -p /var/lib/grafana/dashboards/default && /bin/sh -x /etc/grafana/download_dashboards.sh" ] + {{- with .Values.downloadDashboards.resources }} + resources: + {{- toYaml . | nindent 6 }} + {{- end }} + env: + {{- range $key, $value := .Values.downloadDashboards.env }} + - name: "{{ $key }}" + value: "{{ $value }}" + {{- end }} + {{- range $key, $value := .Values.downloadDashboards.envValueFrom }} + - name: {{ $key | quote }} + valueFrom: + {{- tpl (toYaml $value) $ | nindent 10 }} + {{- end }} + {{- with .Values.downloadDashboards.securityContext }} + securityContext: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.downloadDashboards.envFromSecret }} + envFrom: + - secretRef: + name: {{ tpl . $root }} + {{- end }} + volumeMounts: + - name: config + mountPath: "/etc/grafana/download_dashboards.sh" + subPath: download_dashboards.sh + - name: storage + mountPath: "/var/lib/grafana" + {{- with .Values.persistence.subPath }} + subPath: {{ tpl . $root }} + {{- end }} + {{- range .Values.extraSecretMounts }} + - name: {{ .name }} + mountPath: {{ .mountPath }} + readOnly: {{ .readOnly }} + {{- end }} +{{- end }} +{{- if and .Values.sidecar.datasources.enabled .Values.sidecar.datasources.initDatasources }} + - name: {{ include "grafana.name" . }}-init-sc-datasources + {{- if .Values.sidecar.image.sha }} + image: "{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}@sha256:{{ .Values.sidecar.image.sha }}" + {{- else }} + image: "{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}" + {{- end }} + imagePullPolicy: {{ .Values.sidecar.imagePullPolicy }} + env: + {{- range $key, $value := .Values.sidecar.datasources.env }} + - name: "{{ $key }}" + value: "{{ $value }}" + {{- end }} + {{- if .Values.sidecar.datasources.ignoreAlreadyProcessed }} + - name: IGNORE_ALREADY_PROCESSED + value: "true" + {{- end }} + - name: METHOD + value: "LIST" + - name: LABEL + value: "{{ .Values.sidecar.datasources.label }}" + {{- with .Values.sidecar.datasources.labelValue }} + - name: LABEL_VALUE + value: {{ quote . }} + {{- end }} + {{- if or .Values.sidecar.logLevel .Values.sidecar.datasources.logLevel }} + - name: LOG_LEVEL + value: {{ default .Values.sidecar.logLevel .Values.sidecar.datasources.logLevel }} + {{- end }} + - name: FOLDER + value: "/etc/grafana/provisioning/datasources" + - name: RESOURCE + value: {{ quote .Values.sidecar.datasources.resource }} + {{- with .Values.sidecar.enableUniqueFilenames }} + - name: UNIQUE_FILENAMES + value: "{{ . }}" + {{- end }} + {{- if .Values.sidecar.datasources.searchNamespace }} + - name: NAMESPACE + value: "{{ tpl (.Values.sidecar.datasources.searchNamespace | join ",") . }}" + {{- end }} + {{- with .Values.sidecar.skipTlsVerify }} + - name: SKIP_TLS_VERIFY + value: "{{ . }}" + {{- end }} + {{- with .Values.sidecar.resources }} + resources: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.sidecar.securityContext }} + securityContext: + {{- toYaml . | nindent 6 }} + {{- end }} + volumeMounts: + - name: sc-datasources-volume + mountPath: "/etc/grafana/provisioning/datasources" +{{- end }} +{{- if and .Values.sidecar.notifiers.enabled .Values.sidecar.notifiers.initNotifiers }} + - name: {{ include "grafana.name" . }}-init-sc-notifiers + {{- if .Values.sidecar.image.sha }} + image: "{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}@sha256:{{ .Values.sidecar.image.sha }}" + {{- else }} + image: "{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}" + {{- end }} + imagePullPolicy: {{ .Values.sidecar.imagePullPolicy }} + env: + {{- range $key, $value := .Values.sidecar.notifiers.env }} + - name: "{{ $key }}" + value: "{{ $value }}" + {{- end }} + {{- if .Values.sidecar.notifiers.ignoreAlreadyProcessed }} + - name: IGNORE_ALREADY_PROCESSED + value: "true" + {{- end }} + - name: METHOD + value: LIST + - name: LABEL + value: "{{ .Values.sidecar.notifiers.label }}" + {{- with .Values.sidecar.notifiers.labelValue }} + - name: LABEL_VALUE + value: {{ quote . }} + {{- end }} + {{- if or .Values.sidecar.logLevel .Values.sidecar.notifiers.logLevel }} + - name: LOG_LEVEL + value: {{ default .Values.sidecar.logLevel .Values.sidecar.notifiers.logLevel }} + {{- end }} + - name: FOLDER + value: "/etc/grafana/provisioning/notifiers" + - name: RESOURCE + value: {{ quote .Values.sidecar.notifiers.resource }} + {{- with .Values.sidecar.enableUniqueFilenames }} + - name: UNIQUE_FILENAMES + value: "{{ . }}" + {{- end }} + {{- with .Values.sidecar.notifiers.searchNamespace }} + - name: NAMESPACE + value: "{{ tpl (. | join ",") $root }}" + {{- end }} + {{- with .Values.sidecar.skipTlsVerify }} + - name: SKIP_TLS_VERIFY + value: "{{ . }}" + {{- end }} + {{- with .Values.sidecar.livenessProbe }} + livenessProbe: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.sidecar.readinessProbe }} + readinessProbe: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.sidecar.resources }} + resources: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.sidecar.securityContext }} + securityContext: + {{- toYaml . | nindent 6 }} + {{- end }} + volumeMounts: + - name: sc-notifiers-volume + mountPath: "/etc/grafana/provisioning/notifiers" +{{- end}} +{{- with .Values.extraInitContainers }} + {{- tpl (toYaml .) $root | nindent 2 }} +{{- end }} +{{- if or .Values.image.pullSecrets .Values.global.imagePullSecrets }} +imagePullSecrets: + {{- include "grafana.imagePullSecrets" (dict "root" $root "imagePullSecrets" .Values.image.pullSecrets) | nindent 2 }} +{{- end }} +{{- if not .Values.enableKubeBackwardCompatibility }} +enableServiceLinks: {{ .Values.enableServiceLinks }} +{{- end }} +containers: +{{- if .Values.sidecar.alerts.enabled }} + - name: {{ include "grafana.name" . }}-sc-alerts + {{- if .Values.sidecar.image.sha }} + image: "{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}@sha256:{{ .Values.sidecar.image.sha }}" + {{- else }} + image: "{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}" + {{- end }} + imagePullPolicy: {{ .Values.sidecar.imagePullPolicy }} + env: + {{- range $key, $value := .Values.sidecar.alerts.env }} + - name: "{{ $key }}" + value: "{{ $value }}" + {{- end }} + {{- if .Values.sidecar.alerts.ignoreAlreadyProcessed }} + - name: IGNORE_ALREADY_PROCESSED + value: "true" + {{- end }} + - name: METHOD + value: {{ .Values.sidecar.alerts.watchMethod }} + - name: LABEL + value: "{{ .Values.sidecar.alerts.label }}" + {{- with .Values.sidecar.alerts.labelValue }} + - name: LABEL_VALUE + value: {{ quote . }} + {{- end }} + {{- if or .Values.sidecar.logLevel .Values.sidecar.alerts.logLevel }} + - name: LOG_LEVEL + value: {{ default .Values.sidecar.logLevel .Values.sidecar.alerts.logLevel }} + {{- end }} + - name: FOLDER + value: "/etc/grafana/provisioning/alerting" + - name: RESOURCE + value: {{ quote .Values.sidecar.alerts.resource }} + {{- with .Values.sidecar.enableUniqueFilenames }} + - name: UNIQUE_FILENAMES + value: "{{ . }}" + {{- end }} + {{- with .Values.sidecar.alerts.searchNamespace }} + - name: NAMESPACE + value: {{ . | join "," | quote }} + {{- end }} + {{- with .Values.sidecar.alerts.skipTlsVerify }} + - name: SKIP_TLS_VERIFY + value: {{ quote . }} + {{- end }} + {{- with .Values.sidecar.alerts.script }} + - name: SCRIPT + value: {{ quote . }} + {{- end }} + {{- if and (not .Values.env.GF_SECURITY_ADMIN_USER) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) }} + - name: REQ_USERNAME + valueFrom: + secretKeyRef: + name: {{ (tpl .Values.admin.existingSecret .) | default (include "grafana.fullname" .) }} + key: {{ .Values.admin.userKey | default "admin-user" }} + {{- end }} + {{- if and (not .Values.env.GF_SECURITY_ADMIN_PASSWORD) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD__FILE) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) }} + - name: REQ_PASSWORD + valueFrom: + secretKeyRef: + name: {{ (tpl .Values.admin.existingSecret .) | default (include "grafana.fullname" .) }} + key: {{ .Values.admin.passwordKey | default "admin-password" }} + {{- end }} + {{- if not .Values.sidecar.alerts.skipReload }} + - name: REQ_URL + value: {{ .Values.sidecar.alerts.reloadURL }} + - name: REQ_METHOD + value: POST + {{- end }} + {{- if .Values.sidecar.alerts.watchServerTimeout }} + {{- if ne .Values.sidecar.alerts.watchMethod "WATCH" }} + {{- fail (printf "Cannot use .Values.sidecar.alerts.watchServerTimeout with .Values.sidecar.alerts.watchMethod %s" .Values.sidecar.alerts.watchMethod) }} + {{- end }} + - name: WATCH_SERVER_TIMEOUT + value: "{{ .Values.sidecar.alerts.watchServerTimeout }}" + {{- end }} + {{- if .Values.sidecar.alerts.watchClientTimeout }} + {{- if ne .Values.sidecar.alerts.watchMethod "WATCH" }} + {{- fail (printf "Cannot use .Values.sidecar.alerts.watchClientTimeout with .Values.sidecar.alerts.watchMethod %s" .Values.sidecar.alerts.watchMethod) }} + {{- end }} + - name: WATCH_CLIENT_TIMEOUT + value: "{{ .Values.sidecar.alerts.watchClientTimeout }}" + {{- end }} + {{- with .Values.sidecar.livenessProbe }} + livenessProbe: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.sidecar.readinessProbe }} + readinessProbe: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.sidecar.resources }} + resources: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.sidecar.securityContext }} + securityContext: + {{- toYaml . | nindent 6 }} + {{- end }} + volumeMounts: + - name: sc-alerts-volume + mountPath: "/etc/grafana/provisioning/alerting" +{{- end}} +{{- if .Values.sidecar.dashboards.enabled }} + - name: {{ include "grafana.name" . }}-sc-dashboard + {{- if .Values.sidecar.image.sha }} + image: "{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}@sha256:{{ .Values.sidecar.image.sha }}" + {{- else }} + image: "{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}" + {{- end }} + imagePullPolicy: {{ .Values.sidecar.imagePullPolicy }} + env: + {{- range $key, $value := .Values.sidecar.dashboards.env }} + - name: "{{ $key }}" + value: "{{ $value }}" + {{- end }} + {{- if .Values.sidecar.dashboards.ignoreAlreadyProcessed }} + - name: IGNORE_ALREADY_PROCESSED + value: "true" + {{- end }} + - name: METHOD + value: {{ .Values.sidecar.dashboards.watchMethod }} + - name: LABEL + value: "{{ .Values.sidecar.dashboards.label }}" + {{- with .Values.sidecar.dashboards.labelValue }} + - name: LABEL_VALUE + value: {{ quote . }} + {{- end }} + {{- if or .Values.sidecar.logLevel .Values.sidecar.dashboards.logLevel }} + - name: LOG_LEVEL + value: {{ default .Values.sidecar.logLevel .Values.sidecar.dashboards.logLevel }} + {{- end }} + - name: FOLDER + value: "{{ .Values.sidecar.dashboards.folder }}{{- with .Values.sidecar.dashboards.defaultFolderName }}/{{ . }}{{- end }}" + - name: RESOURCE + value: {{ quote .Values.sidecar.dashboards.resource }} + {{- with .Values.sidecar.enableUniqueFilenames }} + - name: UNIQUE_FILENAMES + value: "{{ . }}" + {{- end }} + {{- with .Values.sidecar.dashboards.searchNamespace }} + - name: NAMESPACE + value: "{{ tpl (. | join ",") $root }}" + {{- end }} + {{- with .Values.sidecar.skipTlsVerify }} + - name: SKIP_TLS_VERIFY + value: "{{ . }}" + {{- end }} + {{- with .Values.sidecar.dashboards.folderAnnotation }} + - name: FOLDER_ANNOTATION + value: "{{ . }}" + {{- end }} + {{- with .Values.sidecar.dashboards.script }} + - name: SCRIPT + value: "{{ . }}" + {{- end }} + {{- if and (not .Values.env.GF_SECURITY_ADMIN_USER) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) }} + - name: REQ_USERNAME + valueFrom: + secretKeyRef: + name: {{ (tpl .Values.admin.existingSecret .) | default (include "grafana.fullname" .) }} + key: {{ .Values.admin.userKey | default "admin-user" }} + {{- end }} + {{- if and (not .Values.env.GF_SECURITY_ADMIN_PASSWORD) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD__FILE) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) }} + - name: REQ_PASSWORD + valueFrom: + secretKeyRef: + name: {{ (tpl .Values.admin.existingSecret .) | default (include "grafana.fullname" .) }} + key: {{ .Values.admin.passwordKey | default "admin-password" }} + {{- end }} + {{- if not .Values.sidecar.dashboards.skipReload }} + - name: REQ_URL + value: {{ .Values.sidecar.dashboards.reloadURL }} + - name: REQ_METHOD + value: POST + {{- end }} + {{- if .Values.sidecar.dashboards.watchServerTimeout }} + {{- if ne .Values.sidecar.dashboards.watchMethod "WATCH" }} + {{- fail (printf "Cannot use .Values.sidecar.dashboards.watchServerTimeout with .Values.sidecar.dashboards.watchMethod %s" .Values.sidecar.dashboards.watchMethod) }} + {{- end }} + - name: WATCH_SERVER_TIMEOUT + value: "{{ .Values.sidecar.dashboards.watchServerTimeout }}" + {{- end }} + {{- if .Values.sidecar.dashboards.watchClientTimeout }} + {{- if ne .Values.sidecar.dashboards.watchMethod "WATCH" }} + {{- fail (printf "Cannot use .Values.sidecar.dashboards.watchClientTimeout with .Values.sidecar.dashboards.watchMethod %s" .Values.sidecar.dashboards.watchMethod) }} + {{- end }} + - name: WATCH_CLIENT_TIMEOUT + value: {{ .Values.sidecar.dashboards.watchClientTimeout | quote }} + {{- end }} + {{- with .Values.sidecar.livenessProbe }} + livenessProbe: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.sidecar.readinessProbe }} + readinessProbe: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.sidecar.resources }} + resources: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.sidecar.securityContext }} + securityContext: + {{- toYaml . | nindent 6 }} + {{- end }} + volumeMounts: + - name: sc-dashboard-volume + mountPath: {{ .Values.sidecar.dashboards.folder | quote }} + {{- with .Values.sidecar.dashboards.extraMounts }} + {{- toYaml . | trim | nindent 6 }} + {{- end }} +{{- end}} +{{- if .Values.sidecar.datasources.enabled }} + - name: {{ include "grafana.name" . }}-sc-datasources + {{- if .Values.sidecar.image.sha }} + image: "{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}@sha256:{{ .Values.sidecar.image.sha }}" + {{- else }} + image: "{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}" + {{- end }} + imagePullPolicy: {{ .Values.sidecar.imagePullPolicy }} + env: + {{- range $key, $value := .Values.sidecar.datasources.env }} + - name: "{{ $key }}" + value: "{{ $value }}" + {{- end }} + {{- if .Values.sidecar.datasources.ignoreAlreadyProcessed }} + - name: IGNORE_ALREADY_PROCESSED + value: "true" + {{- end }} + - name: METHOD + value: {{ .Values.sidecar.datasources.watchMethod }} + - name: LABEL + value: "{{ .Values.sidecar.datasources.label }}" + {{- with .Values.sidecar.datasources.labelValue }} + - name: LABEL_VALUE + value: {{ quote . }} + {{- end }} + {{- if or .Values.sidecar.logLevel .Values.sidecar.datasources.logLevel }} + - name: LOG_LEVEL + value: {{ default .Values.sidecar.logLevel .Values.sidecar.datasources.logLevel }} + {{- end }} + - name: FOLDER + value: "/etc/grafana/provisioning/datasources" + - name: RESOURCE + value: {{ quote .Values.sidecar.datasources.resource }} + {{- with .Values.sidecar.enableUniqueFilenames }} + - name: UNIQUE_FILENAMES + value: "{{ . }}" + {{- end }} + {{- with .Values.sidecar.datasources.searchNamespace }} + - name: NAMESPACE + value: "{{ tpl (. | join ",") $root }}" + {{- end }} + {{- if .Values.sidecar.skipTlsVerify }} + - name: SKIP_TLS_VERIFY + value: "{{ .Values.sidecar.skipTlsVerify }}" + {{- end }} + {{- if .Values.sidecar.datasources.script }} + - name: SCRIPT + value: "{{ .Values.sidecar.datasources.script }}" + {{- end }} + {{- if and (not .Values.env.GF_SECURITY_ADMIN_USER) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) }} + - name: REQ_USERNAME + valueFrom: + secretKeyRef: + name: {{ (tpl .Values.admin.existingSecret .) | default (include "grafana.fullname" .) }} + key: {{ .Values.admin.userKey | default "admin-user" }} + {{- end }} + {{- if and (not .Values.env.GF_SECURITY_ADMIN_PASSWORD) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD__FILE) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) }} + - name: REQ_PASSWORD + valueFrom: + secretKeyRef: + name: {{ (tpl .Values.admin.existingSecret .) | default (include "grafana.fullname" .) }} + key: {{ .Values.admin.passwordKey | default "admin-password" }} + {{- end }} + {{- if not .Values.sidecar.datasources.skipReload }} + - name: REQ_URL + value: {{ .Values.sidecar.datasources.reloadURL }} + - name: REQ_METHOD + value: POST + {{- end }} + {{- if .Values.sidecar.datasources.watchServerTimeout }} + {{- if ne .Values.sidecar.datasources.watchMethod "WATCH" }} + {{- fail (printf "Cannot use .Values.sidecar.datasources.watchServerTimeout with .Values.sidecar.datasources.watchMethod %s" .Values.sidecar.datasources.watchMethod) }} + {{- end }} + - name: WATCH_SERVER_TIMEOUT + value: "{{ .Values.sidecar.datasources.watchServerTimeout }}" + {{- end }} + {{- if .Values.sidecar.datasources.watchClientTimeout }} + {{- if ne .Values.sidecar.datasources.watchMethod "WATCH" }} + {{- fail (printf "Cannot use .Values.sidecar.datasources.watchClientTimeout with .Values.sidecar.datasources.watchMethod %s" .Values.sidecar.datasources.watchMethod) }} + {{- end }} + - name: WATCH_CLIENT_TIMEOUT + value: "{{ .Values.sidecar.datasources.watchClientTimeout }}" + {{- end }} + {{- with .Values.sidecar.livenessProbe }} + livenessProbe: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.sidecar.readinessProbe }} + readinessProbe: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.sidecar.resources }} + resources: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.sidecar.securityContext }} + securityContext: + {{- toYaml . | nindent 6 }} + {{- end }} + volumeMounts: + - name: sc-datasources-volume + mountPath: "/etc/grafana/provisioning/datasources" +{{- end}} +{{- if .Values.sidecar.notifiers.enabled }} + - name: {{ include "grafana.name" . }}-sc-notifiers + {{- if .Values.sidecar.image.sha }} + image: "{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}@sha256:{{ .Values.sidecar.image.sha }}" + {{- else }} + image: "{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}" + {{- end }} + imagePullPolicy: {{ .Values.sidecar.imagePullPolicy }} + env: + {{- range $key, $value := .Values.sidecar.notifiers.env }} + - name: "{{ $key }}" + value: "{{ $value }}" + {{- end }} + {{- if .Values.sidecar.notifiers.ignoreAlreadyProcessed }} + - name: IGNORE_ALREADY_PROCESSED + value: "true" + {{- end }} + - name: METHOD + value: {{ .Values.sidecar.notifiers.watchMethod }} + - name: LABEL + value: "{{ .Values.sidecar.notifiers.label }}" + {{- with .Values.sidecar.notifiers.labelValue }} + - name: LABEL_VALUE + value: {{ quote . }} + {{- end }} + {{- if or .Values.sidecar.logLevel .Values.sidecar.notifiers.logLevel }} + - name: LOG_LEVEL + value: {{ default .Values.sidecar.logLevel .Values.sidecar.notifiers.logLevel }} + {{- end }} + - name: FOLDER + value: "/etc/grafana/provisioning/notifiers" + - name: RESOURCE + value: {{ quote .Values.sidecar.notifiers.resource }} + {{- if .Values.sidecar.enableUniqueFilenames }} + - name: UNIQUE_FILENAMES + value: "{{ .Values.sidecar.enableUniqueFilenames }}" + {{- end }} + {{- with .Values.sidecar.notifiers.searchNamespace }} + - name: NAMESPACE + value: "{{ tpl (. | join ",") $root }}" + {{- end }} + {{- with .Values.sidecar.skipTlsVerify }} + - name: SKIP_TLS_VERIFY + value: "{{ . }}" + {{- end }} + {{- if .Values.sidecar.notifiers.script }} + - name: SCRIPT + value: "{{ .Values.sidecar.notifiers.script }}" + {{- end }} + {{- if and (not .Values.env.GF_SECURITY_ADMIN_USER) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) }} + - name: REQ_USERNAME + valueFrom: + secretKeyRef: + name: {{ (tpl .Values.admin.existingSecret .) | default (include "grafana.fullname" .) }} + key: {{ .Values.admin.userKey | default "admin-user" }} + {{- end }} + {{- if and (not .Values.env.GF_SECURITY_ADMIN_PASSWORD) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD__FILE) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) }} + - name: REQ_PASSWORD + valueFrom: + secretKeyRef: + name: {{ (tpl .Values.admin.existingSecret .) | default (include "grafana.fullname" .) }} + key: {{ .Values.admin.passwordKey | default "admin-password" }} + {{- end }} + {{- if not .Values.sidecar.notifiers.skipReload }} + - name: REQ_URL + value: {{ .Values.sidecar.notifiers.reloadURL }} + - name: REQ_METHOD + value: POST + {{- end }} + {{- if .Values.sidecar.notifiers.watchServerTimeout }} + {{- if ne .Values.sidecar.notifiers.watchMethod "WATCH" }} + {{- fail (printf "Cannot use .Values.sidecar.notifiers.watchServerTimeout with .Values.sidecar.notifiers.watchMethod %s" .Values.sidecar.notifiers.watchMethod) }} + {{- end }} + - name: WATCH_SERVER_TIMEOUT + value: "{{ .Values.sidecar.notifiers.watchServerTimeout }}" + {{- end }} + {{- if .Values.sidecar.notifiers.watchClientTimeout }} + {{- if ne .Values.sidecar.notifiers.watchMethod "WATCH" }} + {{- fail (printf "Cannot use .Values.sidecar.notifiers.watchClientTimeout with .Values.sidecar.notifiers.watchMethod %s" .Values.sidecar.notifiers.watchMethod) }} + {{- end }} + - name: WATCH_CLIENT_TIMEOUT + value: "{{ .Values.sidecar.notifiers.watchClientTimeout }}" + {{- end }} + {{- with .Values.sidecar.livenessProbe }} + livenessProbe: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.sidecar.readinessProbe }} + readinessProbe: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.sidecar.resources }} + resources: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.sidecar.securityContext }} + securityContext: + {{- toYaml . | nindent 6 }} + {{- end }} + volumeMounts: + - name: sc-notifiers-volume + mountPath: "/etc/grafana/provisioning/notifiers" +{{- end}} +{{- if .Values.sidecar.plugins.enabled }} + - name: {{ include "grafana.name" . }}-sc-plugins + {{- if .Values.sidecar.image.sha }} + image: "{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}@sha256:{{ .Values.sidecar.image.sha }}" + {{- else }} + image: "{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}" + {{- end }} + imagePullPolicy: {{ .Values.sidecar.imagePullPolicy }} + env: + {{- range $key, $value := .Values.sidecar.plugins.env }} + - name: "{{ $key }}" + value: "{{ $value }}" + {{- end }} + {{- if .Values.sidecar.plugins.ignoreAlreadyProcessed }} + - name: IGNORE_ALREADY_PROCESSED + value: "true" + {{- end }} + - name: METHOD + value: {{ .Values.sidecar.plugins.watchMethod }} + - name: LABEL + value: "{{ .Values.sidecar.plugins.label }}" + {{- if .Values.sidecar.plugins.labelValue }} + - name: LABEL_VALUE + value: {{ quote .Values.sidecar.plugins.labelValue }} + {{- end }} + {{- if or .Values.sidecar.logLevel .Values.sidecar.plugins.logLevel }} + - name: LOG_LEVEL + value: {{ default .Values.sidecar.logLevel .Values.sidecar.plugins.logLevel }} + {{- end }} + - name: FOLDER + value: "/etc/grafana/provisioning/plugins" + - name: RESOURCE + value: {{ quote .Values.sidecar.plugins.resource }} + {{- with .Values.sidecar.enableUniqueFilenames }} + - name: UNIQUE_FILENAMES + value: "{{ . }}" + {{- end }} + {{- with .Values.sidecar.plugins.searchNamespace }} + - name: NAMESPACE + value: "{{ tpl (. | join ",") $root }}" + {{- end }} + {{- with .Values.sidecar.plugins.script }} + - name: SCRIPT + value: "{{ . }}" + {{- end }} + {{- with .Values.sidecar.skipTlsVerify }} + - name: SKIP_TLS_VERIFY + value: "{{ . }}" + {{- end }} + {{- if and (not .Values.env.GF_SECURITY_ADMIN_USER) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) }} + - name: REQ_USERNAME + valueFrom: + secretKeyRef: + name: {{ (tpl .Values.admin.existingSecret .) | default (include "grafana.fullname" .) }} + key: {{ .Values.admin.userKey | default "admin-user" }} + {{- end }} + {{- if and (not .Values.env.GF_SECURITY_ADMIN_PASSWORD) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD__FILE) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) }} + - name: REQ_PASSWORD + valueFrom: + secretKeyRef: + name: {{ (tpl .Values.admin.existingSecret .) | default (include "grafana.fullname" .) }} + key: {{ .Values.admin.passwordKey | default "admin-password" }} + {{- end }} + {{- if not .Values.sidecar.plugins.skipReload }} + - name: REQ_URL + value: {{ .Values.sidecar.plugins.reloadURL }} + - name: REQ_METHOD + value: POST + {{- end }} + {{- if .Values.sidecar.plugins.watchServerTimeout }} + {{- if ne .Values.sidecar.plugins.watchMethod "WATCH" }} + {{- fail (printf "Cannot use .Values.sidecar.plugins.watchServerTimeout with .Values.sidecar.plugins.watchMethod %s" .Values.sidecar.plugins.watchMethod) }} + {{- end }} + - name: WATCH_SERVER_TIMEOUT + value: "{{ .Values.sidecar.plugins.watchServerTimeout }}" + {{- end }} + {{- if .Values.sidecar.plugins.watchClientTimeout }} + {{- if ne .Values.sidecar.plugins.watchMethod "WATCH" }} + {{- fail (printf "Cannot use .Values.sidecar.plugins.watchClientTimeout with .Values.sidecar.plugins.watchMethod %s" .Values.sidecar.plugins.watchMethod) }} + {{- end }} + - name: WATCH_CLIENT_TIMEOUT + value: "{{ .Values.sidecar.plugins.watchClientTimeout }}" + {{- end }} + {{- with .Values.sidecar.livenessProbe }} + livenessProbe: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.sidecar.readinessProbe }} + readinessProbe: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.sidecar.resources }} + resources: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.sidecar.securityContext }} + securityContext: + {{- toYaml . | nindent 6 }} + {{- end }} + volumeMounts: + - name: sc-plugins-volume + mountPath: "/etc/grafana/provisioning/plugins" +{{- end}} + - name: {{ .Chart.Name }} + {{- if .Values.image.sha }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}@sha256:{{ .Values.image.sha }}" + {{- else }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + {{- end }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + {{- if .Values.command }} + command: + {{- range .Values.command }} + - {{ . | quote }} + {{- end }} + {{- end }} + {{- if .Values.args }} + args: + {{- range .Values.args }} + - {{ . | quote }} + {{- end }} + {{- end }} + {{- with .Values.containerSecurityContext }} + securityContext: + {{- toYaml . | nindent 6 }} + {{- end }} + volumeMounts: + - name: config + mountPath: "/etc/grafana/grafana.ini" + subPath: grafana.ini + {{- if .Values.ldap.enabled }} + - name: ldap + mountPath: "/etc/grafana/ldap.toml" + subPath: ldap.toml + {{- end }} + {{- range .Values.extraConfigmapMounts }} + - name: {{ tpl .name $root }} + mountPath: {{ tpl .mountPath $root }} + subPath: {{ (tpl .subPath $root) | default "" }} + readOnly: {{ .readOnly }} + {{- end }} + - name: storage + mountPath: "/var/lib/grafana" + {{- with .Values.persistence.subPath }} + subPath: {{ tpl . $root }} + {{- end }} + {{- with .Values.dashboards }} + {{- range $provider, $dashboards := . }} + {{- range $key, $value := $dashboards }} + {{- if (or (hasKey $value "json") (hasKey $value "file")) }} + - name: dashboards-{{ $provider }} + mountPath: "/var/lib/grafana/dashboards/{{ $provider }}/{{ $key }}.json" + subPath: "{{ $key }}.json" + {{- end }} + {{- end }} + {{- end }} + {{- end }} + {{- with .Values.dashboardsConfigMaps }} + {{- range (keys . | sortAlpha) }} + - name: dashboards-{{ . }} + mountPath: "/var/lib/grafana/dashboards/{{ . }}" + {{- end }} + {{- end }} + {{- with .Values.datasources }} + {{- range (keys . | sortAlpha) }} + - name: config + mountPath: "/etc/grafana/provisioning/datasources/{{ . }}" + subPath: {{ . | quote }} + {{- end }} + {{- end }} + {{- with .Values.notifiers }} + {{- range (keys . | sortAlpha) }} + - name: config + mountPath: "/etc/grafana/provisioning/notifiers/{{ . }}" + subPath: {{ . | quote }} + {{- end }} + {{- end }} + {{- with .Values.alerting }} + {{- range (keys . | sortAlpha) }} + - name: config + mountPath: "/etc/grafana/provisioning/alerting/{{ . }}" + subPath: {{ . | quote }} + {{- end }} + {{- end }} + {{- with .Values.dashboardProviders }} + {{- range (keys . | sortAlpha) }} + - name: config + mountPath: "/etc/grafana/provisioning/dashboards/{{ . }}" + subPath: {{ . | quote }} + {{- end }} + {{- end }} + {{- with .Values.sidecar.alerts.enabled }} + - name: sc-alerts-volume + mountPath: "/etc/grafana/provisioning/alerting" + {{- end}} + {{- if .Values.sidecar.dashboards.enabled }} + - name: sc-dashboard-volume + mountPath: {{ .Values.sidecar.dashboards.folder | quote }} + {{- if .Values.sidecar.dashboards.SCProvider }} + - name: sc-dashboard-provider + mountPath: "/etc/grafana/provisioning/dashboards/sc-dashboardproviders.yaml" + subPath: provider.yaml + {{- end}} + {{- end}} + {{- if .Values.sidecar.datasources.enabled }} + - name: sc-datasources-volume + mountPath: "/etc/grafana/provisioning/datasources" + {{- end}} + {{- if .Values.sidecar.plugins.enabled }} + - name: sc-plugins-volume + mountPath: "/etc/grafana/provisioning/plugins" + {{- end}} + {{- if .Values.sidecar.notifiers.enabled }} + - name: sc-notifiers-volume + mountPath: "/etc/grafana/provisioning/notifiers" + {{- end}} + {{- range .Values.extraSecretMounts }} + - name: {{ .name }} + mountPath: {{ .mountPath }} + readOnly: {{ .readOnly }} + subPath: {{ .subPath | default "" }} + {{- end }} + {{- range .Values.extraVolumeMounts }} + - name: {{ .name }} + mountPath: {{ .mountPath }} + subPath: {{ .subPath | default "" }} + readOnly: {{ .readOnly }} + {{- end }} + {{- range .Values.extraEmptyDirMounts }} + - name: {{ .name }} + mountPath: {{ .mountPath }} + {{- end }} + ports: + - name: {{ .Values.podPortName }} + containerPort: {{ .Values.service.targetPort }} + protocol: TCP + - name: {{ .Values.gossipPortName }}-tcp + containerPort: 9094 + protocol: TCP + - name: {{ .Values.gossipPortName }}-udp + containerPort: 9094 + protocol: UDP + env: + - name: POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + {{- if and (not .Values.env.GF_SECURITY_ADMIN_USER) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) }} + - name: GF_SECURITY_ADMIN_USER + valueFrom: + secretKeyRef: + name: {{ (tpl .Values.admin.existingSecret .) | default (include "grafana.fullname" .) }} + key: {{ .Values.admin.userKey | default "admin-user" }} + {{- end }} + {{- if and (not .Values.env.GF_SECURITY_ADMIN_PASSWORD) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD__FILE) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) }} + - name: GF_SECURITY_ADMIN_PASSWORD + valueFrom: + secretKeyRef: + name: {{ (tpl .Values.admin.existingSecret .) | default (include "grafana.fullname" .) }} + key: {{ .Values.admin.passwordKey | default "admin-password" }} + {{- end }} + {{- if .Values.plugins }} + - name: GF_INSTALL_PLUGINS + valueFrom: + configMapKeyRef: + name: {{ include "grafana.fullname" . }} + key: plugins + {{- end }} + {{- if .Values.smtp.existingSecret }} + - name: GF_SMTP_USER + valueFrom: + secretKeyRef: + name: {{ .Values.smtp.existingSecret }} + key: {{ .Values.smtp.userKey | default "user" }} + - name: GF_SMTP_PASSWORD + valueFrom: + secretKeyRef: + name: {{ .Values.smtp.existingSecret }} + key: {{ .Values.smtp.passwordKey | default "password" }} + {{- end }} + {{- if .Values.imageRenderer.enabled }} + - name: GF_RENDERING_SERVER_URL + value: http://{{ include "grafana.fullname" . }}-image-renderer.{{ include "grafana.namespace" . }}:{{ .Values.imageRenderer.service.port }}/render + - name: GF_RENDERING_CALLBACK_URL + value: {{ .Values.imageRenderer.grafanaProtocol }}://{{ include "grafana.fullname" . }}.{{ include "grafana.namespace" . }}:{{ .Values.service.port }}/{{ .Values.imageRenderer.grafanaSubPath }} + {{- end }} + - name: GF_PATHS_DATA + value: {{ (get .Values "grafana.ini").paths.data }} + - name: GF_PATHS_LOGS + value: {{ (get .Values "grafana.ini").paths.logs }} + - name: GF_PATHS_PLUGINS + value: {{ (get .Values "grafana.ini").paths.plugins }} + - name: GF_PATHS_PROVISIONING + value: {{ (get .Values "grafana.ini").paths.provisioning }} + {{- range $key, $value := .Values.envValueFrom }} + - name: {{ $key | quote }} + valueFrom: + {{- tpl (toYaml $value) $ | nindent 10 }} + {{- end }} + {{- range $key, $value := .Values.env }} + - name: "{{ tpl $key $ }}" + value: "{{ tpl (print $value) $ }}" + {{- end }} + {{- if or .Values.envFromSecret (or .Values.envRenderSecret .Values.envFromSecrets) .Values.envFromConfigMaps }} + envFrom: + {{- if .Values.envFromSecret }} + - secretRef: + name: {{ tpl .Values.envFromSecret . }} + {{- end }} + {{- if .Values.envRenderSecret }} + - secretRef: + name: {{ include "grafana.fullname" . }}-env + {{- end }} + {{- range .Values.envFromSecrets }} + - secretRef: + name: {{ tpl .name $ }} + optional: {{ .optional | default false }} + {{- end }} + {{- range .Values.envFromConfigMaps }} + - configMapRef: + name: {{ tpl .name $ }} + optional: {{ .optional | default false }} + {{- end }} + {{- end }} + {{- with .Values.livenessProbe }} + livenessProbe: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.readinessProbe }} + readinessProbe: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.lifecycleHooks }} + lifecycle: + {{- tpl (toYaml .) $root | nindent 6 }} + {{- end }} + {{- with .Values.resources }} + resources: + {{- toYaml . | nindent 6 }} + {{- end }} +{{- with .Values.extraContainers }} + {{- tpl . $ | nindent 2 }} +{{- end }} +{{- with .Values.nodeSelector }} +nodeSelector: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- with .Values.affinity }} +affinity: + {{- tpl (toYaml .) $root | nindent 2 }} +{{- end }} +{{- with .Values.topologySpreadConstraints }} +topologySpreadConstraints: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- with .Values.tolerations }} +tolerations: + {{- toYaml . | nindent 2 }} +{{- end }} +volumes: + - name: config + configMap: + name: {{ include "grafana.fullname" . }} + {{- range .Values.extraConfigmapMounts }} + - name: {{ tpl .name $root }} + configMap: + name: {{ tpl .configMap $root }} + {{- with .items }} + items: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- end }} + {{- if .Values.dashboards }} + {{- range (keys .Values.dashboards | sortAlpha) }} + - name: dashboards-{{ . }} + configMap: + name: {{ include "grafana.fullname" $ }}-dashboards-{{ . }} + {{- end }} + {{- end }} + {{- if .Values.dashboardsConfigMaps }} + {{- range $provider, $name := .Values.dashboardsConfigMaps }} + - name: dashboards-{{ $provider }} + configMap: + name: {{ tpl $name $root }} + {{- end }} + {{- end }} + {{- if .Values.ldap.enabled }} + - name: ldap + secret: + {{- if .Values.ldap.existingSecret }} + secretName: {{ .Values.ldap.existingSecret }} + {{- else }} + secretName: {{ include "grafana.fullname" . }} + {{- end }} + items: + - key: ldap-toml + path: ldap.toml + {{- end }} + {{- if and .Values.persistence.enabled (eq .Values.persistence.type "pvc") }} + - name: storage + persistentVolumeClaim: + claimName: {{ tpl (.Values.persistence.existingClaim | default (include "grafana.fullname" .)) . }} + {{- else if and .Values.persistence.enabled (has .Values.persistence.type $sts) }} + {{/* nothing */}} + {{- else }} + - name: storage + {{- if .Values.persistence.inMemory.enabled }} + emptyDir: + medium: Memory + {{- with .Values.persistence.inMemory.sizeLimit }} + sizeLimit: {{ . }} + {{- end }} + {{- else }} + emptyDir: {} + {{- end }} + {{- end }} + {{- if .Values.sidecar.alerts.enabled }} + - name: sc-alerts-volume + emptyDir: + {{- with .Values.sidecar.alerts.sizeLimit }} + sizeLimit: {{ . }} + {{- else }} + {} + {{- end }} + {{- end }} + {{- if .Values.sidecar.dashboards.enabled }} + - name: sc-dashboard-volume + emptyDir: + {{- with .Values.sidecar.dashboards.sizeLimit }} + sizeLimit: {{ . }} + {{- else }} + {} + {{- end }} + {{- if .Values.sidecar.dashboards.SCProvider }} + - name: sc-dashboard-provider + configMap: + name: {{ include "grafana.fullname" . }}-config-dashboards + {{- end }} + {{- end }} + {{- if .Values.sidecar.datasources.enabled }} + - name: sc-datasources-volume + emptyDir: + {{- with .Values.sidecar.datasources.sizeLimit }} + sizeLimit: {{ . }} + {{- else }} + {} + {{- end }} + {{- end }} + {{- if .Values.sidecar.plugins.enabled }} + - name: sc-plugins-volume + emptyDir: + {{- with .Values.sidecar.plugins.sizeLimit }} + sizeLimit: {{ . }} + {{- else }} + {} + {{- end }} + {{- end }} + {{- if .Values.sidecar.notifiers.enabled }} + - name: sc-notifiers-volume + emptyDir: + {{- with .Values.sidecar.notifiers.sizeLimit }} + sizeLimit: {{ . }} + {{- else }} + {} + {{- end }} + {{- end }} + {{- range .Values.extraSecretMounts }} + {{- if .secretName }} + - name: {{ .name }} + secret: + secretName: {{ .secretName }} + defaultMode: {{ .defaultMode }} + {{- with .items }} + items: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- else if .projected }} + - name: {{ .name }} + projected: + {{- toYaml .projected | nindent 6 }} + {{- else if .csi }} + - name: {{ .name }} + csi: + {{- toYaml .csi | nindent 6 }} + {{- end }} + {{- end }} + {{- range .Values.extraVolumeMounts }} + - name: {{ .name }} + {{- if .existingClaim }} + persistentVolumeClaim: + claimName: {{ .existingClaim }} + {{- else if .hostPath }} + hostPath: + path: {{ .hostPath }} + {{- else if .csi }} + csi: + {{- toYaml .data | nindent 6 }} + {{- else }} + emptyDir: {} + {{- end }} + {{- end }} + {{- range .Values.extraEmptyDirMounts }} + - name: {{ .name }} + emptyDir: {} + {{- end }} + {{- with .Values.extraContainerVolumes }} + {{- tpl (toYaml .) $root | nindent 2 }} + {{- end }} +{{- end }} diff --git a/helm/grafana/templates/clusterrole.yaml b/helm/grafana/templates/clusterrole.yaml new file mode 100644 index 0000000..3396713 --- /dev/null +++ b/helm/grafana/templates/clusterrole.yaml @@ -0,0 +1,25 @@ +{{- if and .Values.rbac.create (not .Values.rbac.namespaced) (not .Values.rbac.useExistingRole) }} +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + labels: + {{- include "grafana.labels" . | nindent 4 }} + {{- with .Values.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ include "grafana.fullname" . }}-clusterrole +{{- if or .Values.sidecar.dashboards.enabled (or .Values.rbac.extraClusterRoleRules (or .Values.sidecar.datasources.enabled .Values.sidecar.plugins.enabled)) }} +rules: + {{- if or .Values.sidecar.dashboards.enabled (or .Values.sidecar.datasources.enabled .Values.sidecar.plugins.enabled) }} + - apiGroups: [""] # "" indicates the core API group + resources: ["configmaps", "secrets"] + verbs: ["get", "watch", "list"] + {{- end}} + {{- with .Values.rbac.extraClusterRoleRules }} + {{- toYaml . | nindent 2 }} + {{- end}} +{{- else }} +rules: [] +{{- end}} +{{- end}} diff --git a/helm/grafana/templates/clusterrolebinding.yaml b/helm/grafana/templates/clusterrolebinding.yaml new file mode 100644 index 0000000..48411fe --- /dev/null +++ b/helm/grafana/templates/clusterrolebinding.yaml @@ -0,0 +1,24 @@ +{{- if and .Values.rbac.create (not .Values.rbac.namespaced) }} +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ include "grafana.fullname" . }}-clusterrolebinding + labels: + {{- include "grafana.labels" . | nindent 4 }} + {{- with .Values.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +subjects: + - kind: ServiceAccount + name: {{ include "grafana.serviceAccountName" . }} + namespace: {{ include "grafana.namespace" . }} +roleRef: + kind: ClusterRole + {{- if .Values.rbac.useExistingRole }} + name: {{ .Values.rbac.useExistingRole }} + {{- else }} + name: {{ include "grafana.fullname" . }}-clusterrole + {{- end }} + apiGroup: rbac.authorization.k8s.io +{{- end }} diff --git a/helm/grafana/templates/configmap-dashboard-provider.yaml b/helm/grafana/templates/configmap-dashboard-provider.yaml new file mode 100644 index 0000000..1f706a8 --- /dev/null +++ b/helm/grafana/templates/configmap-dashboard-provider.yaml @@ -0,0 +1,29 @@ +{{- if and .Values.sidecar.dashboards.enabled .Values.sidecar.dashboards.SCProvider }} +apiVersion: v1 +kind: ConfigMap +metadata: + labels: + {{- include "grafana.labels" . | nindent 4 }} + {{- with .Values.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ include "grafana.fullname" . }}-config-dashboards + namespace: {{ include "grafana.namespace" . }} +data: + provider.yaml: |- + apiVersion: 1 + providers: + - name: '{{ .Values.sidecar.dashboards.provider.name }}' + orgId: {{ .Values.sidecar.dashboards.provider.orgid }} + {{- if not .Values.sidecar.dashboards.provider.foldersFromFilesStructure }} + folder: '{{ .Values.sidecar.dashboards.provider.folder }}' + {{- end }} + type: {{ .Values.sidecar.dashboards.provider.type }} + disableDeletion: {{ .Values.sidecar.dashboards.provider.disableDelete }} + allowUiUpdates: {{ .Values.sidecar.dashboards.provider.allowUiUpdates }} + updateIntervalSeconds: {{ .Values.sidecar.dashboards.provider.updateIntervalSeconds | default 30 }} + options: + foldersFromFilesStructure: {{ .Values.sidecar.dashboards.provider.foldersFromFilesStructure }} + path: {{ .Values.sidecar.dashboards.folder }}{{- with .Values.sidecar.dashboards.defaultFolderName }}/{{ . }}{{- end }} +{{- end }} diff --git a/helm/grafana/templates/configmap.yaml b/helm/grafana/templates/configmap.yaml new file mode 100644 index 0000000..00ab74e --- /dev/null +++ b/helm/grafana/templates/configmap.yaml @@ -0,0 +1,134 @@ +{{- if .Values.createConfigmap }} +{{- $files := .Files }} +{{- $root := . -}} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "grafana.fullname" . }} + namespace: {{ include "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} + {{- with .Values.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +data: + {{- with .Values.plugins }} + plugins: {{ join "," . }} + {{- end }} + grafana.ini: | + {{- range $elem, $elemVal := index .Values "grafana.ini" }} + {{- if not (kindIs "map" $elemVal) }} + {{- if kindIs "invalid" $elemVal }} + {{ $elem }} = + {{- else if kindIs "string" $elemVal }} + {{ $elem }} = {{ tpl $elemVal $ }} + {{- else }} + {{ $elem }} = {{ $elemVal }} + {{- end }} + {{- end }} + {{- end }} + {{- range $key, $value := index .Values "grafana.ini" }} + {{- if kindIs "map" $value }} + [{{ $key }}] + {{- range $elem, $elemVal := $value }} + {{- if kindIs "invalid" $elemVal }} + {{ $elem }} = + {{- else if kindIs "string" $elemVal }} + {{ $elem }} = {{ tpl $elemVal $ }} + {{- else }} + {{ $elem }} = {{ $elemVal }} + {{- end }} + {{- end }} + {{- end }} + {{- end }} + + {{- range $key, $value := .Values.datasources }} + {{- $key | nindent 2 }}: | + {{- tpl (toYaml $value | nindent 4) $root }} + {{- end }} + + {{- range $key, $value := .Values.notifiers }} + {{- $key | nindent 2 }}: | + {{- toYaml $value | nindent 4 }} + {{- end }} + + {{- range $key, $value := .Values.alerting }} + {{- if (hasKey $value "file") }} + {{- $key | nindent 2 }}: + {{- toYaml ( $files.Get $value.file ) | nindent 4}} + {{- else }} + {{- $key | nindent 2 }}: | + {{- tpl (toYaml $value | nindent 4) $root }} + {{- end }} + {{- end }} + + {{- range $key, $value := .Values.dashboardProviders }} + {{- $key | nindent 2 }}: | + {{- toYaml $value | nindent 4 }} + {{- end }} + +{{- if .Values.dashboards }} + download_dashboards.sh: | + #!/usr/bin/env sh + set -euf + {{- if .Values.dashboardProviders }} + {{- range $key, $value := .Values.dashboardProviders }} + {{- range $value.providers }} + mkdir -p {{ .options.path }} + {{- end }} + {{- end }} + {{- end }} + {{ $dashboardProviders := .Values.dashboardProviders }} + {{- range $provider, $dashboards := .Values.dashboards }} + {{- range $key, $value := $dashboards }} + {{- if (or (hasKey $value "gnetId") (hasKey $value "url")) }} + curl -skf \ + --connect-timeout 60 \ + --max-time 60 \ + {{- if not $value.b64content }} + -H "Accept: application/json" \ + {{- if $value.token }} + -H "Authorization: token {{ $value.token }}" \ + {{- end }} + {{- if $value.bearerToken }} + -H "Authorization: Bearer {{ $value.bearerToken }}" \ + {{- end }} + {{- if $value.basic }} + -H "Basic: {{ $value.basic }}" \ + {{- end }} + {{- if $value.gitlabToken }} + -H "PRIVATE-TOKEN: {{ $value.gitlabToken }}" \ + {{- end }} + -H "Content-Type: application/json;charset=UTF-8" \ + {{- end }} + {{- $dpPath := "" -}} + {{- range $kd := (index $dashboardProviders "dashboardproviders.yaml").providers }} + {{- if eq $kd.name $provider }} + {{- $dpPath = $kd.options.path }} + {{- end }} + {{- end }} + {{- if $value.url }} + "{{ $value.url }}" \ + {{- else }} + "https://grafana.com/api/dashboards/{{ $value.gnetId }}/revisions/{{- if $value.revision -}}{{ $value.revision }}{{- else -}}1{{- end -}}/download" \ + {{- end }} + {{- if $value.datasource }} + {{- if kindIs "string" $value.datasource }} + | sed '/-- .* --/! s/"datasource":.*,/"datasource": "{{ $value.datasource }}",/g' \ + {{- end }} + {{- if kindIs "slice" $value.datasource }} + {{- range $value.datasource }} + | sed '/-- .* --/! s/${{"{"}}{{ .name }}}/{{ .value }}/g' \ + {{- end }} + {{- end }} + {{- end }} + {{- if $value.b64content }} + | base64 -d \ + {{- end }} + > "{{- if $dpPath -}}{{ $dpPath }}{{- else -}}/var/lib/grafana/dashboards/{{ $provider }}{{- end -}}/{{ $key }}.json" + {{ end }} + {{- end }} + {{- end }} +{{- end }} +{{- end }} diff --git a/helm/grafana/templates/dashboards-json-configmap.yaml b/helm/grafana/templates/dashboards-json-configmap.yaml new file mode 100644 index 0000000..df0ed0d --- /dev/null +++ b/helm/grafana/templates/dashboards-json-configmap.yaml @@ -0,0 +1,35 @@ +{{- if .Values.dashboards }} +{{ $files := .Files }} +{{- range $provider, $dashboards := .Values.dashboards }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "grafana.fullname" $ }}-dashboards-{{ $provider }} + namespace: {{ include "grafana.namespace" $ }} + labels: + {{- include "grafana.labels" $ | nindent 4 }} + dashboard-provider: {{ $provider }} +{{- if $dashboards }} +data: +{{- $dashboardFound := false }} +{{- range $key, $value := $dashboards }} +{{- if (or (hasKey $value "json") (hasKey $value "file")) }} +{{- $dashboardFound = true }} + {{- print $key | nindent 2 }}.json: + {{- if hasKey $value "json" }} + |- + {{- $value.json | nindent 6 }} + {{- end }} + {{- if hasKey $value "file" }} + {{- toYaml ( $files.Get $value.file ) | nindent 4}} + {{- end }} +{{- end }} +{{- end }} +{{- if not $dashboardFound }} + {} +{{- end }} +{{- end }} +--- +{{- end }} + +{{- end }} diff --git a/helm/grafana/templates/deployment.yaml b/helm/grafana/templates/deployment.yaml new file mode 100644 index 0000000..96eac4d --- /dev/null +++ b/helm/grafana/templates/deployment.yaml @@ -0,0 +1,50 @@ +{{- if (and (not .Values.useStatefulSet) (or (not .Values.persistence.enabled) (eq .Values.persistence.type "pvc"))) }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "grafana.fullname" . }} + namespace: {{ include "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if and (not .Values.autoscaling.enabled) (.Values.replicas) }} + replicas: {{ .Values.replicas }} + {{- end }} + revisionHistoryLimit: {{ .Values.revisionHistoryLimit }} + selector: + matchLabels: + {{- include "grafana.selectorLabels" . | nindent 6 }} + {{- with .Values.deploymentStrategy }} + strategy: + {{- toYaml . | trim | nindent 4 }} + {{- end }} + template: + metadata: + labels: + {{- include "grafana.selectorLabels" . | nindent 8 }} + {{- with .Values.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + annotations: + checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} + checksum/dashboards-json-config: {{ include (print $.Template.BasePath "/dashboards-json-configmap.yaml") . | sha256sum }} + checksum/sc-dashboard-provider-config: {{ include (print $.Template.BasePath "/configmap-dashboard-provider.yaml") . | sha256sum }} + {{- if and (or (and (not .Values.admin.existingSecret) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD__FILE) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD)) (and .Values.ldap.enabled (not .Values.ldap.existingSecret))) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) }} + checksum/secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }} + {{- end }} + {{- if .Values.envRenderSecret }} + checksum/secret-env: {{ include (print $.Template.BasePath "/secret-env.yaml") . | sha256sum }} + {{- end }} + {{- with .Values.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- include "grafana.pod" . | nindent 6 }} +{{- end }} diff --git a/helm/grafana/templates/extra-manifests.yaml b/helm/grafana/templates/extra-manifests.yaml new file mode 100644 index 0000000..a9bb3b6 --- /dev/null +++ b/helm/grafana/templates/extra-manifests.yaml @@ -0,0 +1,4 @@ +{{ range .Values.extraObjects }} +--- +{{ tpl (toYaml .) $ }} +{{ end }} diff --git a/helm/grafana/templates/headless-service.yaml b/helm/grafana/templates/headless-service.yaml new file mode 100644 index 0000000..3028589 --- /dev/null +++ b/helm/grafana/templates/headless-service.yaml @@ -0,0 +1,22 @@ +{{- $sts := list "sts" "StatefulSet" "statefulset" -}} +{{- if or .Values.headlessService (and .Values.persistence.enabled (not .Values.persistence.existingClaim) (has .Values.persistence.type $sts)) }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "grafana.fullname" . }}-headless + namespace: {{ include "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} + {{- with .Values.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + clusterIP: None + selector: + {{- include "grafana.selectorLabels" . | nindent 4 }} + type: ClusterIP + ports: + - name: {{ .Values.gossipPortName }}-tcp + port: 9094 +{{- end }} diff --git a/helm/grafana/templates/hpa.yaml b/helm/grafana/templates/hpa.yaml new file mode 100644 index 0000000..46bbcb4 --- /dev/null +++ b/helm/grafana/templates/hpa.yaml @@ -0,0 +1,52 @@ +{{- $sts := list "sts" "StatefulSet" "statefulset" -}} +{{- if .Values.autoscaling.enabled }} +apiVersion: {{ include "grafana.hpa.apiVersion" . }} +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "grafana.fullname" . }} + namespace: {{ include "grafana.namespace" . }} + labels: + app.kubernetes.io/name: {{ include "grafana.name" . }} + helm.sh/chart: {{ include "grafana.chart" . }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + {{- if has .Values.persistence.type $sts }} + kind: StatefulSet + {{- else }} + kind: Deployment + {{- end }} + name: {{ include "grafana.fullname" . }} + minReplicas: {{ .Values.autoscaling.minReplicas }} + maxReplicas: {{ .Values.autoscaling.maxReplicas }} + metrics: + {{- if .Values.autoscaling.targetMemory }} + - type: Resource + resource: + name: memory + {{- if eq (include "grafana.hpa.apiVersion" .) "autoscaling/v2beta1" }} + targetAverageUtilization: {{ .Values.autoscaling.targetMemory }} + {{- else }} + target: + type: Utilization + averageUtilization: {{ .Values.autoscaling.targetMemory }} + {{- end }} + {{- end }} + {{- if .Values.autoscaling.targetCPU }} + - type: Resource + resource: + name: cpu + {{- if eq (include "grafana.hpa.apiVersion" .) "autoscaling/v2beta1" }} + targetAverageUtilization: {{ .Values.autoscaling.targetCPU }} + {{- else }} + target: + type: Utilization + averageUtilization: {{ .Values.autoscaling.targetCPU }} + {{- end }} + {{- end }} + {{- if .Values.autoscaling.behavior }} + behavior: {{ toYaml .Values.autoscaling.behavior | nindent 4 }} + {{- end }} +{{- end }} diff --git a/helm/grafana/templates/image-renderer-deployment.yaml b/helm/grafana/templates/image-renderer-deployment.yaml new file mode 100644 index 0000000..0c3d30c --- /dev/null +++ b/helm/grafana/templates/image-renderer-deployment.yaml @@ -0,0 +1,125 @@ +{{ if .Values.imageRenderer.enabled }} +{{- $root := . -}} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "grafana.fullname" . }}-image-renderer + namespace: {{ include "grafana.namespace" . }} + labels: + {{- include "grafana.imageRenderer.labels" . | nindent 4 }} + {{- with .Values.imageRenderer.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.imageRenderer.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if and (not .Values.imageRenderer.autoscaling.enabled) (.Values.imageRenderer.replicas) }} + replicas: {{ .Values.imageRenderer.replicas }} + {{- end }} + revisionHistoryLimit: {{ .Values.imageRenderer.revisionHistoryLimit }} + selector: + matchLabels: + {{- include "grafana.imageRenderer.selectorLabels" . | nindent 6 }} + + {{- with .Values.imageRenderer.deploymentStrategy }} + strategy: + {{- toYaml . | trim | nindent 4 }} + {{- end }} + template: + metadata: + labels: + {{- include "grafana.imageRenderer.selectorLabels" . | nindent 8 }} + {{- with .Values.imageRenderer.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + annotations: + checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} + {{- with .Values.imageRenderer.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- with .Values.imageRenderer.schedulerName }} + schedulerName: "{{ . }}" + {{- end }} + {{- with .Values.imageRenderer.serviceAccountName }} + serviceAccountName: "{{ . }}" + {{- end }} + {{- with .Values.imageRenderer.securityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.imageRenderer.hostAliases }} + hostAliases: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.imageRenderer.priorityClassName }} + priorityClassName: {{ . }} + {{- end }} + {{- with .Values.imageRenderer.image.pullSecrets }} + imagePullSecrets: + {{- range . }} + - name: {{ tpl . $root }} + {{- end}} + {{- end }} + containers: + - name: {{ .Chart.Name }}-image-renderer + {{- if .Values.imageRenderer.image.sha }} + image: "{{ .Values.imageRenderer.image.repository }}:{{ .Values.imageRenderer.image.tag }}@sha256:{{ .Values.imageRenderer.image.sha }}" + {{- else }} + image: "{{ .Values.imageRenderer.image.repository }}:{{ .Values.imageRenderer.image.tag }}" + {{- end }} + imagePullPolicy: {{ .Values.imageRenderer.image.pullPolicy }} + {{- if .Values.imageRenderer.command }} + command: + {{- range .Values.imageRenderer.command }} + - {{ . }} + {{- end }} + {{- end}} + ports: + - name: {{ .Values.imageRenderer.service.portName }} + containerPort: {{ .Values.imageRenderer.service.targetPort }} + protocol: TCP + livenessProbe: + httpGet: + path: / + port: {{ .Values.imageRenderer.service.portName }} + env: + - name: HTTP_PORT + value: {{ .Values.imageRenderer.service.targetPort | quote }} + {{- if .Values.imageRenderer.serviceMonitor.enabled }} + - name: ENABLE_METRICS + value: "true" + {{- end }} + {{- range $key, $value := .Values.imageRenderer.env }} + - name: {{ $key | quote }} + value: {{ $value | quote }} + {{- end }} + {{- with .Values.imageRenderer.containerSecurityContext }} + securityContext: + {{- toYaml . | nindent 12 }} + {{- end }} + volumeMounts: + - mountPath: /tmp + name: image-renderer-tmpfs + {{- with .Values.imageRenderer.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.imageRenderer.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.imageRenderer.affinity }} + affinity: + {{- tpl (toYaml .) $root | nindent 8 }} + {{- end }} + {{- with .Values.imageRenderer.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: image-renderer-tmpfs + emptyDir: {} +{{- end }} diff --git a/helm/grafana/templates/image-renderer-hpa.yaml b/helm/grafana/templates/image-renderer-hpa.yaml new file mode 100644 index 0000000..b0f0059 --- /dev/null +++ b/helm/grafana/templates/image-renderer-hpa.yaml @@ -0,0 +1,47 @@ +{{- if and .Values.imageRenderer.enabled .Values.imageRenderer.autoscaling.enabled }} +apiVersion: {{ include "grafana.hpa.apiVersion" . }} +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "grafana.fullname" . }}-image-renderer + namespace: {{ include "grafana.namespace" . }} + labels: + app.kubernetes.io/name: {{ include "grafana.name" . }}-image-renderer + helm.sh/chart: {{ include "grafana.chart" . }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "grafana.fullname" . }}-image-renderer + minReplicas: {{ .Values.imageRenderer.autoscaling.minReplicas }} + maxReplicas: {{ .Values.imageRenderer.autoscaling.maxReplicas }} + metrics: + {{- if .Values.imageRenderer.autoscaling.targetMemory }} + - type: Resource + resource: + name: memory + {{- if eq (include "grafana.hpa.apiVersion" .) "autoscaling/v2beta1" }} + targetAverageUtilization: {{ .Values.imageRenderer.autoscaling.targetMemory }} + {{- else }} + target: + type: Utilization + averageUtilization: {{ .Values.imageRenderer.autoscaling.targetMemory }} + {{- end }} + {{- end }} + {{- if .Values.imageRenderer.autoscaling.targetCPU }} + - type: Resource + resource: + name: cpu + {{- if eq (include "grafana.hpa.apiVersion" .) "autoscaling/v2beta1" }} + targetAverageUtilization: {{ .Values.imageRenderer.autoscaling.targetCPU }} + {{- else }} + target: + type: Utilization + averageUtilization: {{ .Values.imageRenderer.autoscaling.targetCPU }} + {{- end }} + {{- end }} + {{- if .Values.imageRenderer.autoscaling.behavior }} + behavior: {{ toYaml .Values.imageRenderer.autoscaling.behavior | nindent 4 }} + {{- end }} +{{- end }} diff --git a/helm/grafana/templates/image-renderer-network-policy.yaml b/helm/grafana/templates/image-renderer-network-policy.yaml new file mode 100644 index 0000000..d1a0eb3 --- /dev/null +++ b/helm/grafana/templates/image-renderer-network-policy.yaml @@ -0,0 +1,79 @@ +{{- if and .Values.imageRenderer.enabled .Values.imageRenderer.networkPolicy.limitIngress }} +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "grafana.fullname" . }}-image-renderer-ingress + namespace: {{ include "grafana.namespace" . }} + annotations: + comment: Limit image-renderer ingress traffic from grafana +spec: + podSelector: + matchLabels: + {{- include "grafana.imageRenderer.selectorLabels" . | nindent 6 }} + {{- with .Values.imageRenderer.podLabels }} + {{- toYaml . | nindent 6 }} + {{- end }} + + policyTypes: + - Ingress + ingress: + - ports: + - port: {{ .Values.imageRenderer.service.targetPort }} + protocol: TCP + from: + - namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: {{ include "grafana.namespace" . }} + podSelector: + matchLabels: + {{- include "grafana.selectorLabels" . | nindent 14 }} + {{- with .Values.podLabels }} + {{- toYaml . | nindent 14 }} + {{- end }} + {{- with .Values.imageRenderer.networkPolicy.extraIngressSelectors -}} + {{ toYaml . | nindent 8 }} + {{- end }} +{{- end }} + +{{- if and .Values.imageRenderer.enabled .Values.imageRenderer.networkPolicy.limitEgress }} +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "grafana.fullname" . }}-image-renderer-egress + namespace: {{ include "grafana.namespace" . }} + annotations: + comment: Limit image-renderer egress traffic to grafana +spec: + podSelector: + matchLabels: + {{- include "grafana.imageRenderer.selectorLabels" . | nindent 6 }} + {{- with .Values.imageRenderer.podLabels }} + {{- toYaml . | nindent 6 }} + {{- end }} + + policyTypes: + - Egress + egress: + # allow dns resolution + - ports: + - port: 53 + protocol: UDP + - port: 53 + protocol: TCP + # talk only to grafana + - ports: + - port: {{ .Values.service.targetPort }} + protocol: TCP + to: + - namespaceSelector: + matchLabels: + name: {{ include "grafana.namespace" . }} + podSelector: + matchLabels: + {{- include "grafana.selectorLabels" . | nindent 14 }} + {{- with .Values.podLabels }} + {{- toYaml . | nindent 14 }} + {{- end }} +{{- end }} diff --git a/helm/grafana/templates/image-renderer-service.yaml b/helm/grafana/templates/image-renderer-service.yaml new file mode 100644 index 0000000..f8da127 --- /dev/null +++ b/helm/grafana/templates/image-renderer-service.yaml @@ -0,0 +1,31 @@ +{{- if and .Values.imageRenderer.enabled .Values.imageRenderer.service.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "grafana.fullname" . }}-image-renderer + namespace: {{ include "grafana.namespace" . }} + labels: + {{- include "grafana.imageRenderer.labels" . | nindent 4 }} + {{- with .Values.imageRenderer.service.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.imageRenderer.service.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + type: ClusterIP + {{- with .Values.imageRenderer.service.clusterIP }} + clusterIP: {{ . }} + {{- end }} + ports: + - name: {{ .Values.imageRenderer.service.portName }} + port: {{ .Values.imageRenderer.service.port }} + protocol: TCP + targetPort: {{ .Values.imageRenderer.service.targetPort }} + {{- with .Values.imageRenderer.appProtocol }} + appProtocol: {{ . }} + {{- end }} + selector: + {{- include "grafana.imageRenderer.selectorLabels" . | nindent 4 }} +{{- end }} diff --git a/helm/grafana/templates/image-renderer-servicemonitor.yaml b/helm/grafana/templates/image-renderer-servicemonitor.yaml new file mode 100644 index 0000000..5d9f09d --- /dev/null +++ b/helm/grafana/templates/image-renderer-servicemonitor.yaml @@ -0,0 +1,48 @@ +{{- if .Values.imageRenderer.serviceMonitor.enabled }} +--- +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ include "grafana.fullname" . }}-image-renderer + {{- if .Values.imageRenderer.serviceMonitor.namespace }} + namespace: {{ tpl .Values.imageRenderer.serviceMonitor.namespace . }} + {{- else }} + namespace: {{ include "grafana.namespace" . }} + {{- end }} + labels: + {{- include "grafana.imageRenderer.labels" . | nindent 4 }} + {{- with .Values.imageRenderer.serviceMonitor.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + endpoints: + - port: {{ .Values.imageRenderer.service.portName }} + {{- with .Values.imageRenderer.serviceMonitor.interval }} + interval: {{ . }} + {{- end }} + {{- with .Values.imageRenderer.serviceMonitor.scrapeTimeout }} + scrapeTimeout: {{ . }} + {{- end }} + honorLabels: true + path: {{ .Values.imageRenderer.serviceMonitor.path }} + scheme: {{ .Values.imageRenderer.serviceMonitor.scheme }} + {{- with .Values.imageRenderer.serviceMonitor.tlsConfig }} + tlsConfig: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.imageRenderer.serviceMonitor.relabelings }} + relabelings: + {{- toYaml . | nindent 6 }} + {{- end }} + jobLabel: "{{ .Release.Name }}-image-renderer" + selector: + matchLabels: + {{- include "grafana.imageRenderer.selectorLabels" . | nindent 6 }} + namespaceSelector: + matchNames: + - {{ include "grafana.namespace" . }} + {{- with .Values.imageRenderer.serviceMonitor.targetLabels }} + targetLabels: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/helm/grafana/templates/ingress.yaml b/helm/grafana/templates/ingress.yaml new file mode 100644 index 0000000..063cdfa --- /dev/null +++ b/helm/grafana/templates/ingress.yaml @@ -0,0 +1,78 @@ +{{- if .Values.ingress.enabled -}} +{{- $ingressApiIsStable := eq (include "grafana.ingress.isStable" .) "true" -}} +{{- $ingressSupportsIngressClassName := eq (include "grafana.ingress.supportsIngressClassName" .) "true" -}} +{{- $ingressSupportsPathType := eq (include "grafana.ingress.supportsPathType" .) "true" -}} +{{- $fullName := include "grafana.fullname" . -}} +{{- $servicePort := .Values.service.port -}} +{{- $ingressPath := .Values.ingress.path -}} +{{- $ingressPathType := .Values.ingress.pathType -}} +{{- $extraPaths := .Values.ingress.extraPaths -}} +apiVersion: {{ include "grafana.ingress.apiVersion" . }} +kind: Ingress +metadata: + name: {{ $fullName }} + namespace: {{ include "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} + {{- with .Values.ingress.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.ingress.annotations }} + annotations: + {{- range $key, $value := . }} + {{ $key }}: {{ tpl $value $ | quote }} + {{- end }} + {{- end }} +spec: + {{- if and $ingressSupportsIngressClassName .Values.ingress.ingressClassName }} + ingressClassName: {{ .Values.ingress.ingressClassName }} + {{- end -}} + {{- with .Values.ingress.tls }} + tls: + {{- tpl (toYaml .) $ | nindent 4 }} + {{- end }} + rules: + {{- if .Values.ingress.hosts }} + {{- range .Values.ingress.hosts }} + - host: {{ tpl . $ }} + http: + paths: + {{- with $extraPaths }} + {{- toYaml . | nindent 10 }} + {{- end }} + - path: {{ $ingressPath }} + {{- if $ingressSupportsPathType }} + pathType: {{ $ingressPathType }} + {{- end }} + backend: + {{- if $ingressApiIsStable }} + service: + name: {{ $fullName }} + port: + number: {{ $servicePort }} + {{- else }} + serviceName: {{ $fullName }} + servicePort: {{ $servicePort }} + {{- end }} + {{- end }} + {{- else }} + - http: + paths: + - backend: + {{- if $ingressApiIsStable }} + service: + name: {{ $fullName }} + port: + number: {{ $servicePort }} + {{- else }} + serviceName: {{ $fullName }} + servicePort: {{ $servicePort }} + {{- end }} + {{- with $ingressPath }} + path: {{ . }} + {{- end }} + {{- if $ingressSupportsPathType }} + pathType: {{ $ingressPathType }} + {{- end }} + {{- end -}} +{{- end }} diff --git a/helm/grafana/templates/networkpolicy.yaml b/helm/grafana/templates/networkpolicy.yaml new file mode 100644 index 0000000..ea4578b --- /dev/null +++ b/helm/grafana/templates/networkpolicy.yaml @@ -0,0 +1,52 @@ +{{- if .Values.networkPolicy.enabled }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "grafana.fullname" . }} + namespace: {{ include "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + policyTypes: + {{- if .Values.networkPolicy.ingress }} + - Ingress + {{- end }} + {{- if .Values.networkPolicy.egress.enabled }} + - Egress + {{- end }} + podSelector: + matchLabels: + {{- include "grafana.selectorLabels" . | nindent 6 }} + + {{- if .Values.networkPolicy.egress.enabled }} + egress: + - ports: + {{ .Values.networkPolicy.egress.ports | toJson }} + {{- end }} + {{- if .Values.networkPolicy.ingress }} + ingress: + - ports: + - port: {{ .Values.service.targetPort }} + {{- if not .Values.networkPolicy.allowExternal }} + from: + - podSelector: + matchLabels: + {{ include "grafana.fullname" . }}-client: "true" + {{- with .Values.networkPolicy.explicitNamespacesSelector }} + - namespaceSelector: + {{- toYaml . | nindent 12 }} + {{- end }} + - podSelector: + matchLabels: + {{- include "grafana.labels" . | nindent 14 }} + role: read + {{- end }} + {{- end }} +{{- end }} diff --git a/helm/grafana/templates/poddisruptionbudget.yaml b/helm/grafana/templates/poddisruptionbudget.yaml new file mode 100644 index 0000000..0525121 --- /dev/null +++ b/helm/grafana/templates/poddisruptionbudget.yaml @@ -0,0 +1,22 @@ +{{- if .Values.podDisruptionBudget }} +apiVersion: {{ include "grafana.podDisruptionBudget.apiVersion" . }} +kind: PodDisruptionBudget +metadata: + name: {{ include "grafana.fullname" . }} + namespace: {{ include "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} + {{- with .Values.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- with .Values.podDisruptionBudget.minAvailable }} + minAvailable: {{ . }} + {{- end }} + {{- with .Values.podDisruptionBudget.maxUnavailable }} + maxUnavailable: {{ . }} + {{- end }} + selector: + matchLabels: + {{- include "grafana.selectorLabels" . | nindent 6 }} +{{- end }} diff --git a/helm/grafana/templates/podsecuritypolicy.yaml b/helm/grafana/templates/podsecuritypolicy.yaml new file mode 100644 index 0000000..eed7af9 --- /dev/null +++ b/helm/grafana/templates/podsecuritypolicy.yaml @@ -0,0 +1,49 @@ +{{- if and .Values.rbac.pspEnabled (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ include "grafana.fullname" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} + annotations: + seccomp.security.alpha.kubernetes.io/allowedProfileNames: 'docker/default,runtime/default' + seccomp.security.alpha.kubernetes.io/defaultProfileName: 'docker/default' + {{- if .Values.rbac.pspUseAppArmor }} + apparmor.security.beta.kubernetes.io/allowedProfileNames: 'runtime/default' + apparmor.security.beta.kubernetes.io/defaultProfileName: 'runtime/default' + {{- end }} +spec: + privileged: false + allowPrivilegeEscalation: false + requiredDropCapabilities: + # Default set from Docker, with DAC_OVERRIDE and CHOWN + - ALL + volumes: + - 'configMap' + - 'emptyDir' + - 'projected' + - 'csi' + - 'secret' + - 'downwardAPI' + - 'persistentVolumeClaim' + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'MustRunAs' + ranges: + # Forbid adding the root group. + - min: 1 + max: 65535 + fsGroup: + rule: 'MustRunAs' + ranges: + # Forbid adding the root group. + - min: 1 + max: 65535 + readOnlyRootFilesystem: false +{{- end }} diff --git a/helm/grafana/templates/pvc.yaml b/helm/grafana/templates/pvc.yaml new file mode 100644 index 0000000..eb8f87f --- /dev/null +++ b/helm/grafana/templates/pvc.yaml @@ -0,0 +1,36 @@ +{{- if and .Values.persistence.enabled (not .Values.persistence.existingClaim) (eq .Values.persistence.type "pvc")}} +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ include "grafana.fullname" . }} + namespace: {{ include "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} + {{- with .Values.persistence.extraPvcLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.persistence.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.persistence.finalizers }} + finalizers: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + accessModes: + {{- range .Values.persistence.accessModes }} + - {{ . | quote }} + {{- end }} + resources: + requests: + storage: {{ .Values.persistence.size | quote }} + {{- with .Values.persistence.storageClassName }} + storageClassName: {{ . }} + {{- end }} + {{- with .Values.persistence.selectorLabels }} + selector: + matchLabels: + {{- toYaml . | nindent 6 }} + {{- end }} +{{- end }} diff --git a/helm/grafana/templates/role.yaml b/helm/grafana/templates/role.yaml new file mode 100644 index 0000000..ffdb16f --- /dev/null +++ b/helm/grafana/templates/role.yaml @@ -0,0 +1,32 @@ +{{- if and .Values.rbac.create (not .Values.rbac.useExistingRole) -}} +apiVersion: {{ include "grafana.rbac.apiVersion" . }} +kind: Role +metadata: + name: {{ include "grafana.fullname" . }} + namespace: {{ include "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} + {{- with .Values.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- if or .Values.rbac.pspEnabled (and .Values.rbac.namespaced (or .Values.sidecar.dashboards.enabled .Values.sidecar.datasources.enabled .Values.sidecar.plugins.enabled .Values.rbac.extraRoleRules)) }} +rules: + {{- if .Values.rbac.pspEnabled }} + - apiGroups: ['extensions'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: [{{ include "grafana.fullname" . }}] + {{- end }} + {{- if and .Values.rbac.namespaced (or .Values.sidecar.dashboards.enabled .Values.sidecar.datasources.enabled .Values.sidecar.plugins.enabled) }} + - apiGroups: [""] # "" indicates the core API group + resources: ["configmaps", "secrets"] + verbs: ["get", "watch", "list"] + {{- end }} + {{- with .Values.rbac.extraRoleRules }} + {{- toYaml . | nindent 2 }} + {{- end}} +{{- else }} +rules: [] +{{- end }} +{{- end }} diff --git a/helm/grafana/templates/rolebinding.yaml b/helm/grafana/templates/rolebinding.yaml new file mode 100644 index 0000000..cc07bd9 --- /dev/null +++ b/helm/grafana/templates/rolebinding.yaml @@ -0,0 +1,25 @@ +{{- if .Values.rbac.create }} +apiVersion: {{ include "grafana.rbac.apiVersion" . }} +kind: RoleBinding +metadata: + name: {{ include "grafana.fullname" . }} + namespace: {{ include "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} + {{- with .Values.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + {{- if .Values.rbac.useExistingRole }} + name: {{ .Values.rbac.useExistingRole }} + {{- else }} + name: {{ include "grafana.fullname" . }} + {{- end }} +subjects: +- kind: ServiceAccount + name: {{ include "grafana.serviceAccountName" . }} + namespace: {{ include "grafana.namespace" . }} +{{- end }} diff --git a/helm/grafana/templates/secret-env.yaml b/helm/grafana/templates/secret-env.yaml new file mode 100644 index 0000000..c765567 --- /dev/null +++ b/helm/grafana/templates/secret-env.yaml @@ -0,0 +1,14 @@ +{{- if .Values.envRenderSecret }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "grafana.fullname" . }}-env + namespace: {{ include "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} +type: Opaque +data: +{{- range $key, $val := .Values.envRenderSecret }} + {{ $key }}: {{ $val | b64enc | quote }} +{{- end }} +{{- end }} diff --git a/helm/grafana/templates/secret.yaml b/helm/grafana/templates/secret.yaml new file mode 100644 index 0000000..5cbd527 --- /dev/null +++ b/helm/grafana/templates/secret.yaml @@ -0,0 +1,26 @@ +{{- if or (and (not .Values.admin.existingSecret) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD__FILE) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION)) (and .Values.ldap.enabled (not .Values.ldap.existingSecret)) }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "grafana.fullname" . }} + namespace: {{ include "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} + {{- with .Values.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +type: Opaque +data: + {{- if and (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) (not .Values.admin.existingSecret) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD__FILE) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD) }} + admin-user: {{ .Values.adminUser | b64enc | quote }} + {{- if .Values.adminPassword }} + admin-password: {{ .Values.adminPassword | b64enc | quote }} + {{- else }} + admin-password: {{ include "grafana.password" . }} + {{- end }} + {{- end }} + {{- if not .Values.ldap.existingSecret }} + ldap-toml: {{ tpl .Values.ldap.config $ | b64enc | quote }} + {{- end }} +{{- end }} diff --git a/helm/grafana/templates/service.yaml b/helm/grafana/templates/service.yaml new file mode 100644 index 0000000..ca95d1d --- /dev/null +++ b/helm/grafana/templates/service.yaml @@ -0,0 +1,60 @@ +{{- if .Values.service.enabled }} +{{- $root := . }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "grafana.fullname" . }} + namespace: {{ include "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} + {{- with .Values.service.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.service.annotations }} + annotations: + {{- tpl (toYaml . | nindent 4) $root }} + {{- end }} +spec: + {{- if (or (eq .Values.service.type "ClusterIP") (empty .Values.service.type)) }} + type: ClusterIP + {{- with .Values.service.clusterIP }} + clusterIP: {{ . }} + {{- end }} + {{- else if eq .Values.service.type "LoadBalancer" }} + type: {{ .Values.service.type }} + {{- with .Values.service.loadBalancerIP }} + loadBalancerIP: {{ . }} + {{- end }} + {{- with .Values.service.loadBalancerSourceRanges }} + loadBalancerSourceRanges: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- else if eq .Values.service.type "NodePort" }} + type: {{ .Values.service.type }} + {{- with .Values.service.nodePort }} + nodePort: {{ . }} + {{- end }} + {{- else }} + type: {{ .Values.service.type }} + {{- end }} + {{- with .Values.service.externalIPs }} + externalIPs: + {{- toYaml . | nindent 4 }} + {{- end }} + ports: + - name: {{ .Values.service.portName }} + port: {{ .Values.service.port }} + protocol: TCP + targetPort: {{ .Values.service.targetPort }} + {{- with .Values.service.appProtocol }} + appProtocol: {{ . }} + {{- end }} + {{- if (and (eq .Values.service.type "NodePort") (not (empty .Values.service.nodePort))) }} + nodePort: {{ .Values.service.nodePort }} + {{- end }} + {{- with .Values.extraExposePorts }} + {{- tpl (toYaml . | nindent 4) $root }} + {{- end }} + selector: + {{- include "grafana.selectorLabels" . | nindent 4 }} +{{- end }} diff --git a/helm/grafana/templates/serviceaccount.yaml b/helm/grafana/templates/serviceaccount.yaml new file mode 100644 index 0000000..784e71b --- /dev/null +++ b/helm/grafana/templates/serviceaccount.yaml @@ -0,0 +1,17 @@ +{{- if .Values.serviceAccount.create }} +{{- $root := . -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + {{- include "grafana.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- tpl (toYaml . | nindent 4) $root }} + {{- end }} + name: {{ include "grafana.serviceAccountName" . }} + namespace: {{ include "grafana.namespace" . }} +{{- end }} diff --git a/helm/grafana/templates/servicemonitor.yaml b/helm/grafana/templates/servicemonitor.yaml new file mode 100644 index 0000000..a4e9f00 --- /dev/null +++ b/helm/grafana/templates/servicemonitor.yaml @@ -0,0 +1,48 @@ +{{- if .Values.serviceMonitor.enabled }} +--- +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ include "grafana.fullname" . }} + {{- if .Values.serviceMonitor.namespace }} + namespace: {{ tpl .Values.serviceMonitor.namespace . }} + {{- else }} + namespace: {{ include "grafana.namespace" . }} + {{- end }} + labels: + {{- include "grafana.labels" . | nindent 4 }} + {{- with .Values.serviceMonitor.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + endpoints: + - port: {{ .Values.service.portName }} + {{- with .Values.serviceMonitor.interval }} + interval: {{ . }} + {{- end }} + {{- with .Values.serviceMonitor.scrapeTimeout }} + scrapeTimeout: {{ . }} + {{- end }} + honorLabels: true + path: {{ .Values.serviceMonitor.path }} + scheme: {{ .Values.serviceMonitor.scheme }} + {{- with .Values.serviceMonitor.tlsConfig }} + tlsConfig: + {{- toYaml . | nindent 6 }} + {{- end }} + {{- with .Values.serviceMonitor.relabelings }} + relabelings: + {{- toYaml . | nindent 6 }} + {{- end }} + jobLabel: "{{ .Release.Name }}" + selector: + matchLabels: + {{- include "grafana.selectorLabels" . | nindent 6 }} + namespaceSelector: + matchNames: + - {{ include "grafana.namespace" . }} + {{- with .Values.serviceMonitor.targetLabels }} + targetLabels: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/helm/grafana/templates/statefulset.yaml b/helm/grafana/templates/statefulset.yaml new file mode 100644 index 0000000..acfab4d --- /dev/null +++ b/helm/grafana/templates/statefulset.yaml @@ -0,0 +1,55 @@ +{{- $sts := list "sts" "StatefulSet" "statefulset" -}} +{{- if (or (.Values.useStatefulSet) (and .Values.persistence.enabled (not .Values.persistence.existingClaim) (has .Values.persistence.type $sts)))}} +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ include "grafana.fullname" . }} + namespace: {{ include "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} + {{- with .Values.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + replicas: {{ .Values.replicas }} + selector: + matchLabels: + {{- include "grafana.selectorLabels" . | nindent 6 }} + serviceName: {{ include "grafana.fullname" . }}-headless + template: + metadata: + labels: + {{- include "grafana.selectorLabels" . | nindent 8 }} + {{- with .Values.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + annotations: + checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} + checksum/dashboards-json-config: {{ include (print $.Template.BasePath "/dashboards-json-configmap.yaml") . | sha256sum }} + checksum/sc-dashboard-provider-config: {{ include (print $.Template.BasePath "/configmap-dashboard-provider.yaml") . | sha256sum }} + {{- if and (or (and (not .Values.admin.existingSecret) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD__FILE) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD)) (and .Values.ldap.enabled (not .Values.ldap.existingSecret))) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) }} + checksum/secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }} + {{- end }} + {{- with .Values.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- include "grafana.pod" . | nindent 6 }} + {{- if .Values.persistence.enabled}} + volumeClaimTemplates: + - metadata: + name: storage + spec: + accessModes: {{ .Values.persistence.accessModes }} + storageClassName: {{ .Values.persistence.storageClassName }} + resources: + requests: + storage: {{ .Values.persistence.size }} + {{- with .Values.persistence.selectorLabels }} + selector: + matchLabels: + {{- toYaml . | nindent 10 }} + {{- end }} + {{- end }} +{{- end }} diff --git a/helm/grafana/templates/tests/test-configmap.yaml b/helm/grafana/templates/tests/test-configmap.yaml new file mode 100644 index 0000000..01c96c9 --- /dev/null +++ b/helm/grafana/templates/tests/test-configmap.yaml @@ -0,0 +1,20 @@ +{{- if .Values.testFramework.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "grafana.fullname" . }}-test + namespace: {{ include "grafana.namespace" . }} + annotations: + "helm.sh/hook": test-success + "helm.sh/hook-delete-policy": "before-hook-creation,hook-succeeded" + labels: + {{- include "grafana.labels" . | nindent 4 }} +data: + run.sh: |- + @test "Test Health" { + url="http://{{ include "grafana.fullname" . }}/api/health" + + code=$(wget --server-response --spider --timeout 90 --tries 10 ${url} 2>&1 | awk '/^ HTTP/{print $2}') + [ "$code" == "200" ] + } +{{- end }} diff --git a/helm/grafana/templates/tests/test-podsecuritypolicy.yaml b/helm/grafana/templates/tests/test-podsecuritypolicy.yaml new file mode 100644 index 0000000..1821772 --- /dev/null +++ b/helm/grafana/templates/tests/test-podsecuritypolicy.yaml @@ -0,0 +1,32 @@ +{{- if and (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") .Values.testFramework.enabled .Values.rbac.pspEnabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ include "grafana.fullname" . }}-test + annotations: + "helm.sh/hook": test-success + "helm.sh/hook-delete-policy": "before-hook-creation,hook-succeeded" + labels: + {{- include "grafana.labels" . | nindent 4 }} +spec: + allowPrivilegeEscalation: true + privileged: false + hostNetwork: false + hostIPC: false + hostPID: false + fsGroup: + rule: RunAsAny + seLinux: + rule: RunAsAny + supplementalGroups: + rule: RunAsAny + runAsUser: + rule: RunAsAny + volumes: + - configMap + - downwardAPI + - emptyDir + - projected + - csi + - secret +{{- end }} diff --git a/helm/grafana/templates/tests/test-role.yaml b/helm/grafana/templates/tests/test-role.yaml new file mode 100644 index 0000000..cb4c782 --- /dev/null +++ b/helm/grafana/templates/tests/test-role.yaml @@ -0,0 +1,17 @@ +{{- if and (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") .Values.testFramework.enabled .Values.rbac.pspEnabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ include "grafana.fullname" . }}-test + namespace: {{ include "grafana.namespace" . }} + annotations: + "helm.sh/hook": test-success + "helm.sh/hook-delete-policy": "before-hook-creation,hook-succeeded" + labels: + {{- include "grafana.labels" . | nindent 4 }} +rules: + - apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: [{{ include "grafana.fullname" . }}-test] +{{- end }} diff --git a/helm/grafana/templates/tests/test-rolebinding.yaml b/helm/grafana/templates/tests/test-rolebinding.yaml new file mode 100644 index 0000000..f40d791 --- /dev/null +++ b/helm/grafana/templates/tests/test-rolebinding.yaml @@ -0,0 +1,20 @@ +{{- if and (.Capabilities.APIVersions.Has "policy/v1beta1/PodSecurityPolicy") .Values.testFramework.enabled .Values.rbac.pspEnabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ include "grafana.fullname" . }}-test + namespace: {{ include "grafana.namespace" . }} + annotations: + "helm.sh/hook": test-success + "helm.sh/hook-delete-policy": "before-hook-creation,hook-succeeded" + labels: + {{- include "grafana.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ include "grafana.fullname" . }}-test +subjects: + - kind: ServiceAccount + name: {{ include "grafana.serviceAccountNameTest" . }} + namespace: {{ include "grafana.namespace" . }} +{{- end }} diff --git a/helm/grafana/templates/tests/test-serviceaccount.yaml b/helm/grafana/templates/tests/test-serviceaccount.yaml new file mode 100644 index 0000000..38fba35 --- /dev/null +++ b/helm/grafana/templates/tests/test-serviceaccount.yaml @@ -0,0 +1,12 @@ +{{- if and .Values.testFramework.enabled .Values.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + {{- include "grafana.labels" . | nindent 4 }} + name: {{ include "grafana.serviceAccountNameTest" . }} + namespace: {{ include "grafana.namespace" . }} + annotations: + "helm.sh/hook": test-success + "helm.sh/hook-delete-policy": "before-hook-creation,hook-succeeded" +{{- end }} diff --git a/helm/grafana/templates/tests/test.yaml b/helm/grafana/templates/tests/test.yaml new file mode 100644 index 0000000..9fb8842 --- /dev/null +++ b/helm/grafana/templates/tests/test.yaml @@ -0,0 +1,49 @@ +{{- if .Values.testFramework.enabled }} +{{- $root := . }} +apiVersion: v1 +kind: Pod +metadata: + name: {{ include "grafana.fullname" . }}-test + labels: + {{- include "grafana.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test-success + "helm.sh/hook-delete-policy": "before-hook-creation,hook-succeeded" + namespace: {{ include "grafana.namespace" . }} +spec: + serviceAccountName: {{ include "grafana.serviceAccountNameTest" . }} + {{- with .Values.testFramework.securityContext }} + securityContext: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if or .Values.image.pullSecrets .Values.global.imagePullSecrets }} + imagePullSecrets: + {{- include "grafana.imagePullSecrets" (dict "root" $root "imagePullSecrets" .Values.image.pullSecrets) | nindent 4 }} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- tpl (toYaml .) $root | nindent 4 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 4 }} + {{- end }} + containers: + - name: {{ .Release.Name }}-test + image: "{{ .Values.testFramework.image}}:{{ .Values.testFramework.tag }}" + imagePullPolicy: "{{ .Values.testFramework.imagePullPolicy}}" + command: ["/opt/bats/bin/bats", "-t", "/tests/run.sh"] + volumeMounts: + - mountPath: /tests + name: tests + readOnly: true + volumes: + - name: tests + configMap: + name: {{ include "grafana.fullname" . }}-test + restartPolicy: Never +{{- end }} diff --git a/helm/grafana/values.yaml b/helm/grafana/values.yaml new file mode 100644 index 0000000..89b1a33 --- /dev/null +++ b/helm/grafana/values.yaml @@ -0,0 +1,1223 @@ +global: + # To help compatibility with other charts which use global.imagePullSecrets. + # Allow either an array of {name: pullSecret} maps (k8s-style), or an array of strings (more common helm-style). + # Can be tempalted. + # global: + # imagePullSecrets: + # - name: pullSecret1 + # - name: pullSecret2 + # or + # global: + # imagePullSecrets: + # - pullSecret1 + # - pullSecret2 + imagePullSecrets: [] + +rbac: + create: true + ## Use an existing ClusterRole/Role (depending on rbac.namespaced false/true) + # useExistingRole: name-of-some-(cluster)role + pspEnabled: true + pspUseAppArmor: true + namespaced: false + extraRoleRules: [] + # - apiGroups: [] + # resources: [] + # verbs: [] + extraClusterRoleRules: [] + # - apiGroups: [] + # resources: [] + # verbs: [] +serviceAccount: + create: true + name: + nameTest: + ## ServiceAccount labels. + labels: {} +## Service account annotations. Can be templated. +# annotations: +# eks.amazonaws.com/role-arn: arn:aws:iam::123456789000:role/iam-role-name-here + autoMount: true + +replicas: 1 + +## Create a headless service for the deployment +headlessService: false + +## Create HorizontalPodAutoscaler object for deployment type +# +autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 5 + targetCPU: "60" + targetMemory: "" + behavior: {} + +## See `kubectl explain poddisruptionbudget.spec` for more +## ref: https://kubernetes.io/docs/tasks/run-application/configure-pdb/ +podDisruptionBudget: {} +# minAvailable: 1 +# maxUnavailable: 1 + +## See `kubectl explain deployment.spec.strategy` for more +## ref: https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#strategy +deploymentStrategy: + type: RollingUpdate + +readinessProbe: + httpGet: + path: /api/health + port: 3000 + +livenessProbe: + httpGet: + path: /api/health + port: 3000 + initialDelaySeconds: 60 + timeoutSeconds: 30 + failureThreshold: 10 + +## Use an alternate scheduler, e.g. "stork". +## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ +## +# schedulerName: "default-scheduler" + +image: + repository: nexus.exem-oss.org/library/grafana + # Overrides the Grafana image tag whose default is the chart appVersion + tag: "9.4.7" + sha: "" + pullPolicy: IfNotPresent + + ## Optionally specify an array of imagePullSecrets. + ## Secrets must be manually created in the namespace. + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ + ## Can be templated. + ## + pullSecrets: [] + # - myRegistrKeySecretName + +testFramework: + enabled: true + image: "bats/bats" + tag: "v1.4.1" + imagePullPolicy: IfNotPresent + securityContext: {} + +securityContext: + runAsUser: 472 + runAsGroup: 472 + fsGroup: 472 + +containerSecurityContext: {} + +# Enable creating the grafana configmap +createConfigmap: true + +# Extra configmaps to mount in grafana pods +# Values are templated. +extraConfigmapMounts: [] + # - name: certs-configmap + # mountPath: /etc/grafana/ssl/ + # subPath: certificates.crt # (optional) + # configMap: certs-configmap + # readOnly: true + + +extraEmptyDirMounts: [] + # - name: provisioning-notifiers + # mountPath: /etc/grafana/provisioning/notifiers + + +# Apply extra labels to common labels. +extraLabels: {} + +## Assign a PriorityClassName to pods if set +# priorityClassName: + +downloadDashboardsImage: + repository: curlimages/curl + tag: 7.85.0 + sha: "" + pullPolicy: IfNotPresent + +downloadDashboards: + env: {} + envFromSecret: "" + resources: {} + securityContext: {} + envValueFrom: {} + # ENV_NAME: + # configMapKeyRef: + # name: configmap-name + # key: value_key + +## Pod Annotations +# podAnnotations: {} + +## Pod Labels +# podLabels: {} + +podPortName: grafana +gossipPortName: gossip +## Deployment annotations +# annotations: {} + +## Expose the grafana service to be accessed from outside the cluster (LoadBalancer service). +## or access it from within the cluster (ClusterIP service). Set the service type and the port to serve it. +## ref: http://kubernetes.io/docs/user-guide/services/ +## +service: + enabled: true + type: NodePort + port: 3000 + targetPort: 3000 + nodePort: 32665 + # targetPort: 4181 To be used with a proxy extraContainer + ## Service annotations. Can be templated. + annotations: {} + labels: {} + portName: service + # Adds the appProtocol field to the service. This allows to work with istio protocol selection. Ex: "http" or "tcp" + appProtocol: "" + +serviceMonitor: + ## If true, a ServiceMonitor CRD is created for a prometheus operator + ## https://github.com/coreos/prometheus-operator + ## + enabled: false + path: /metrics + # namespace: monitoring (defaults to use the namespace this chart is deployed to) + labels: {} + interval: 1m + scheme: http + tlsConfig: {} + scrapeTimeout: 30s + relabelings: [] + targetLabels: [] + +extraExposePorts: [] + # - name: keycloak + # port: 8080 + # targetPort: 8080 + # type: ClusterIP + +# overrides pod.spec.hostAliases in the grafana deployment's pods +hostAliases: [] + # - ip: "1.2.3.4" + # hostnames: + # - "my.host.com" + +ingress: + enabled: false + # For Kubernetes >= 1.18 you should specify the ingress-controller via the field ingressClassName + # See https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/#specifying-the-class-of-an-ingress + # ingressClassName: nginx + # Values can be templated + annotations: {} + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: "true" + labels: {} + path: / + + # pathType is only for k8s >= 1.1= + pathType: Prefix + + hosts: + - chart-example.local + ## Extra paths to prepend to every host configuration. This is useful when working with annotation based services. + extraPaths: [] + # - path: /* + # backend: + # serviceName: ssl-redirect + # servicePort: use-annotation + ## Or for k8s > 1.19 + # - path: /* + # pathType: Prefix + # backend: + # service: + # name: ssl-redirect + # port: + # name: use-annotation + + + tls: [] + # - secretName: chart-example-tls + # hosts: + # - chart-example.local + +resources: {} +# limits: +# cpu: 100m +# memory: 128Mi +# requests: +# cpu: 100m +# memory: 128Mi + +## Node labels for pod assignment +## ref: https://kubernetes.io/docs/user-guide/node-selection/ +# +nodeSelector: {} + +## Tolerations for pod assignment +## ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ +## +tolerations: [] + +## Affinity for pod assignment (evaluated as template) +## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity +## +affinity: {} + +## Topology Spread Constraints +## ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ +## +topologySpreadConstraints: [] + +## Additional init containers (evaluated as template) +## ref: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/ +## +extraInitContainers: [] + +## Enable an Specify container in extraContainers. This is meant to allow adding an authentication proxy to a grafana pod +extraContainers: "" +# extraContainers: | +# - name: proxy +# image: quay.io/gambol99/keycloak-proxy:latest +# args: +# - -provider=github +# - -client-id= +# - -client-secret= +# - -github-org= +# - -email-domain=* +# - -cookie-secret= +# - -http-address=http://0.0.0.0:4181 +# - -upstream-url=http://127.0.0.1:3000 +# ports: +# - name: proxy-web +# containerPort: 4181 + +## Volumes that can be used in init containers that will not be mounted to deployment pods +extraContainerVolumes: [] +# - name: volume-from-secret +# secret: +# secretName: secret-to-mount +# - name: empty-dir-volume +# emptyDir: {} + +## Enable persistence using Persistent Volume Claims +## ref: http://kubernetes.io/docs/user-guide/persistent-volumes/ +## +persistence: + type: pvc + enabled: true + storageClassName: "" + accessModes: + - ReadWriteOnce + size: 10Gi + # annotations: {} + finalizers: + - kubernetes.io/pvc-protection + # selectorLabels: {} + ## Sub-directory of the PV to mount. Can be templated. + # subPath: "" + ## Name of an existing PVC. Can be templated. + # existingClaim: + ## Extra labels to apply to a PVC. + extraPvcLabels: {} + + ## If persistence is not enabled, this allows to mount the + ## local storage in-memory to improve performance + ## + inMemory: + enabled: false + ## The maximum usage on memory medium EmptyDir would be + ## the minimum value between the SizeLimit specified + ## here and the sum of memory limits of all containers in a pod + ## + # sizeLimit: 300Mi + +initChownData: + ## If false, data ownership will not be reset at startup + ## This allows the grafana-server to be run with an arbitrary user + ## + enabled: true + + ## initChownData container image + ## + image: + repository: nexus.exem-oss.org/library/busybox + tag: "1.31.1" + sha: "" + pullPolicy: IfNotPresent + + ## initChownData resource requests and limits + ## Ref: http://kubernetes.io/docs/user-guide/compute-resources/ + ## + resources: {} + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + securityContext: + runAsNonRoot: false + runAsUser: 0 + + +# Administrator credentials when not using an existing secret (see below) +adminUser: admin +# adminPassword: strongpassword + +# Use an existing secret for the admin user. +admin: + ## Name of the secret. Can be templated. + existingSecret: "" + userKey: admin-user + passwordKey: admin-password + +## Define command to be executed at startup by grafana container +## Needed if using `vault-env` to manage secrets (ref: https://banzaicloud.com/blog/inject-secrets-into-pods-vault/) +## Default is "run.sh" as defined in grafana's Dockerfile +# command: +# - "sh" +# - "/run.sh" + +## Optionally define args if command is used +## Needed if using `hashicorp/envconsul` to manage secrets +## By default no arguments are set +# args: +# - "-secret" +# - "secret/grafana" +# - "./grafana" + +## Extra environment variables that will be pass onto deployment pods +## +## to provide grafana with access to CloudWatch on AWS EKS: +## 1. create an iam role of type "Web identity" with provider oidc.eks.* (note the provider for later) +## 2. edit the "Trust relationships" of the role, add a line inside the StringEquals clause using the +## same oidc eks provider as noted before (same as the existing line) +## also, replace NAMESPACE and prometheus-operator-grafana with the service account namespace and name +## +## "oidc.eks.us-east-1.amazonaws.com/id/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:sub": "system:serviceaccount:NAMESPACE:prometheus-operator-grafana", +## +## 3. attach a policy to the role, you can use a built in policy called CloudWatchReadOnlyAccess +## 4. use the following env: (replace 123456789000 and iam-role-name-here with your aws account number and role name) +## +## env: +## AWS_ROLE_ARN: arn:aws:iam::123456789000:role/iam-role-name-here +## AWS_WEB_IDENTITY_TOKEN_FILE: /var/run/secrets/eks.amazonaws.com/serviceaccount/token +## AWS_REGION: us-east-1 +## +## 5. uncomment the EKS section in extraSecretMounts: below +## 6. uncomment the annotation section in the serviceAccount: above +## make sure to replace arn:aws:iam::123456789000:role/iam-role-name-here with your role arn + +env: {} + +## "valueFrom" environment variable references that will be added to deployment pods. Name is templated. +## ref: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#envvarsource-v1-core +## Renders in container spec as: +## env: +## ... +## - name: +## valueFrom: +## +envValueFrom: {} + # ENV_NAME: + # configMapKeyRef: + # name: configmap-name + # key: value_key + +## The name of a secret in the same kubernetes namespace which contain values to be added to the environment +## This can be useful for auth tokens, etc. Value is templated. +envFromSecret: "" + +## Sensible environment variables that will be rendered as new secret object +## This can be useful for auth tokens, etc +envRenderSecret: {} + +## The names of secrets in the same kubernetes namespace which contain values to be added to the environment +## Each entry should contain a name key, and can optionally specify whether the secret must be defined with an optional key. +## Name is templated. +envFromSecrets: [] +## - name: secret-name +## optional: true + +## The names of conifgmaps in the same kubernetes namespace which contain values to be added to the environment +## Each entry should contain a name key, and can optionally specify whether the configmap must be defined with an optional key. +## Name is templated. +## ref: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.23/#configmapenvsource-v1-core +envFromConfigMaps: [] +## - name: configmap-name +## optional: true + +# Inject Kubernetes services as environment variables. +# See https://kubernetes.io/docs/concepts/services-networking/connect-applications-service/#environment-variables +enableServiceLinks: true + +## Additional grafana server secret mounts +# Defines additional mounts with secrets. Secrets must be manually created in the namespace. +extraSecretMounts: [] + # - name: secret-files + # mountPath: /etc/secrets + # secretName: grafana-secret-files + # readOnly: true + # subPath: "" + # + # for AWS EKS (cloudwatch) use the following (see also instruction in env: above) + # - name: aws-iam-token + # mountPath: /var/run/secrets/eks.amazonaws.com/serviceaccount + # readOnly: true + # projected: + # defaultMode: 420 + # sources: + # - serviceAccountToken: + # audience: sts.amazonaws.com + # expirationSeconds: 86400 + # path: token + # + # for CSI e.g. Azure Key Vault use the following + # - name: secrets-store-inline + # mountPath: /run/secrets + # readOnly: true + # csi: + # driver: secrets-store.csi.k8s.io + # readOnly: true + # volumeAttributes: + # secretProviderClass: "akv-grafana-spc" + # nodePublishSecretRef: # Only required when using service principal mode + # name: grafana-akv-creds # Only required when using service principal mode + +## Additional grafana server volume mounts +# Defines additional volume mounts. +extraVolumeMounts: [] + # - name: extra-volume-0 + # mountPath: /mnt/volume0 + # readOnly: true + # existingClaim: volume-claim + # - name: extra-volume-1 + # mountPath: /mnt/volume1 + # readOnly: true + # hostPath: /usr/shared/ + # - name: grafana-secrets + # csi: true + # data: + # driver: secrets-store.csi.k8s.io + # readOnly: true + # volumeAttributes: + # secretProviderClass: "grafana-env-spc" + +## Container Lifecycle Hooks. Execute a specific bash command or make an HTTP request +lifecycleHooks: {} + # postStart: + # exec: + # command: [] + +## Pass the plugins you want installed as a list. +## +plugins: [] + # - digrich-bubblechart-panel + # - grafana-clock-panel + +## Configure grafana datasources +## ref: http://docs.grafana.org/administration/provisioning/#datasources +## +datasources: {} +# datasources.yaml: +# apiVersion: 1 +# datasources: +# - name: Prometheus +# type: prometheus +# url: http://prometheus-prometheus-server +# access: proxy +# isDefault: true +# - name: CloudWatch +# type: cloudwatch +# access: proxy +# uid: cloudwatch +# editable: false +# jsonData: +# authType: default +# defaultRegion: us-east-1 + +## Configure grafana alerting (can be templated) +## ref: http://docs.grafana.org/administration/provisioning/#alerting +## +alerting: {} + # rules.yaml: + # apiVersion: 1 + # groups: + # - orgId: 1 + # name: '{{ .Chart.Name }}_my_rule_group' + # folder: my_first_folder + # interval: 60s + # rules: + # - uid: my_id_1 + # title: my_first_rule + # condition: A + # data: + # - refId: A + # datasourceUid: '-100' + # model: + # conditions: + # - evaluator: + # params: + # - 3 + # type: gt + # operator: + # type: and + # query: + # params: + # - A + # reducer: + # type: last + # type: query + # datasource: + # type: __expr__ + # uid: '-100' + # expression: 1==0 + # intervalMs: 1000 + # maxDataPoints: 43200 + # refId: A + # type: math + # dashboardUid: my_dashboard + # panelId: 123 + # noDataState: Alerting + # for: 60s + # annotations: + # some_key: some_value + # labels: + # team: sre_team_1 + # contactpoints.yaml: + # apiVersion: 1 + # contactPoints: + # - orgId: 1 + # name: cp_1 + # receivers: + # - uid: first_uid + # type: pagerduty + # settings: + # integrationKey: XXX + # severity: critical + # class: ping failure + # component: Grafana + # group: app-stack + # summary: | + # {{ `{{ include "default.message" . }}` }} + +## Configure notifiers +## ref: http://docs.grafana.org/administration/provisioning/#alert-notification-channels +## +notifiers: {} +# notifiers.yaml: +# notifiers: +# - name: email-notifier +# type: email +# uid: email1 +# # either: +# org_id: 1 +# # or +# org_name: Main Org. +# is_default: true +# settings: +# addresses: an_email_address@example.com +# delete_notifiers: + +## Configure grafana dashboard providers +## ref: http://docs.grafana.org/administration/provisioning/#dashboards +## +## `path` must be /var/lib/grafana/dashboards/ +## +dashboardProviders: {} +# dashboardproviders.yaml: +# apiVersion: 1 +# providers: +# - name: 'default' +# orgId: 1 +# folder: '' +# type: file +# disableDeletion: false +# editable: true +# options: +# path: /var/lib/grafana/dashboards/default + +## Configure grafana dashboard to import +## NOTE: To use dashboards you must also enable/configure dashboardProviders +## ref: https://grafana.com/dashboards +## +## dashboards per provider, use provider name as key. +## +dashboards: {} + # default: + # some-dashboard: + # json: | + # $RAW_JSON + # custom-dashboard: + # file: dashboards/custom-dashboard.json + # prometheus-stats: + # gnetId: 2 + # revision: 2 + # datasource: Prometheus + # local-dashboard: + # url: https://example.com/repository/test.json + # token: '' + # local-dashboard-base64: + # url: https://example.com/repository/test-b64.json + # token: '' + # b64content: true + # local-dashboard-gitlab: + # url: https://example.com/repository/test-gitlab.json + # gitlabToken: '' + # local-dashboard-bitbucket: + # url: https://example.com/repository/test-bitbucket.json + # bearerToken: '' + # local-dashboard-azure: + # url: https://example.com/repository/test-azure.json + # basic: '' + +## Reference to external ConfigMap per provider. Use provider name as key and ConfigMap name as value. +## A provider dashboards must be defined either by external ConfigMaps or in values.yaml, not in both. +## ConfigMap data example: +## +## data: +## example-dashboard.json: | +## RAW_JSON +## +dashboardsConfigMaps: {} +# default: "" + +## Grafana's primary configuration +## NOTE: values in map will be converted to ini format +## ref: http://docs.grafana.org/installation/configuration/ +## +grafana.ini: + paths: + data: /var/lib/grafana/ + logs: /var/log/grafana + plugins: /var/lib/grafana/plugins + provisioning: /etc/grafana/provisioning + analytics: + check_for_updates: true + log: + mode: console + grafana_net: + url: https://grafana.net + server: + #domain: "{{ if (and .Values.ingress.enabled .Values.ingress.hosts) }}{{ .Values.ingress.hosts | first }}{{ else }}''{{ end }}" + root_url: http://10.10.43.240:32665 + users: + auto_assign_org_role: Admin + auth.basic: + enabled: false + auth: + oauth_auto_login: true + disable_login_form: true + signout_redirect_url: http://10.10.43.111:31130/auth/realms/dsk-dev-mgmt/protocol/openid-connect/logout?redirect_uri=http%3A%2F%2F10.10.43.240%3A32665%2Flogin + auth.generic_oauth: + enabled: true + name: dsk-dev-keycloak + allow_sign_up: true + client_id: grafana + client_secret: PrBssg99XVlAClhqSlnhefErXiZqJFbI + scopes: openid email profile roles + email_attribute_path: email + email_attribute_name: email + login_attribute_path: email + name_attribute_path: full_name + auth_url: http://10.10.43.111:31130/auth/realms/dsk-dev-mgmt/protocol/openid-connect/auth + token_url: http://10.10.43.111:31130/auth/realms/dsk-dev-mgmt/protocol/openid-connect/token + api_url: http://10.10.43.111:31130/auth/realms/dsk-dev-mgmt/protocol/openid-connect/userinfo + introspect_url: http://10.10.43.111:31130/auth/realms/dsk-dev-mgmt/protocol/openid-connect/token/introspect + role_attribute_path: contains(roles[*], 'admin') && 'Admin' || contains(roles[*], 'editor') && 'Editor' || 'Viewer' + allow_assign_grafana_admin: true +## grafana Authentication can be enabled with the following values on grafana.ini + # server: + # The full public facing url you use in browser, used for redirects and emails + # root_url: + # https://grafana.com/docs/grafana/latest/auth/github/#enable-github-in-grafana + # auth.github: + # enabled: false + # allow_sign_up: false + # scopes: user:email,read:org + # auth_url: https://github.com/login/oauth/authorize + # token_url: https://github.com/login/oauth/access_token + # api_url: https://api.github.com/user + # team_ids: + # allowed_organizations: + # client_id: + # client_secret: +## LDAP Authentication can be enabled with the following values on grafana.ini +## NOTE: Grafana will fail to start if the value for ldap.toml is invalid + # auth.ldap: + # enabled: true + # allow_sign_up: true + # config_file: /etc/grafana/ldap.toml + +## Grafana's LDAP configuration +## Templated by the template in _helpers.tpl +## NOTE: To enable the grafana.ini must be configured with auth.ldap.enabled +## ref: http://docs.grafana.org/installation/configuration/#auth-ldap +## ref: http://docs.grafana.org/installation/ldap/#configuration +ldap: + enabled: false + # `existingSecret` is a reference to an existing secret containing the ldap configuration + # for Grafana in a key `ldap-toml`. + existingSecret: "" + # `config` is the content of `ldap.toml` that will be stored in the created secret + config: "" + # config: |- + # verbose_logging = true + + # [[servers]] + # host = "my-ldap-server" + # port = 636 + # use_ssl = true + # start_tls = false + # ssl_skip_verify = false + # bind_dn = "uid=%s,ou=users,dc=myorg,dc=com" + +## Grafana's SMTP configuration +## NOTE: To enable, grafana.ini must be configured with smtp.enabled +## ref: http://docs.grafana.org/installation/configuration/#smtp +smtp: + # `existingSecret` is a reference to an existing secret containing the smtp configuration + # for Grafana. + existingSecret: "" + userKey: "user" + passwordKey: "password" + +## Sidecars that collect the configmaps with specified label and stores the included files them into the respective folders +## Requires at least Grafana 5 to work and can't be used together with parameters dashboardProviders, datasources and dashboards +sidecar: + image: + repository: quay.io/kiwigrid/k8s-sidecar + tag: 1.22.0 + sha: "" + imagePullPolicy: IfNotPresent + resources: {} +# limits: +# cpu: 100m +# memory: 100Mi +# requests: +# cpu: 50m +# memory: 50Mi + securityContext: {} + # skipTlsVerify Set to true to skip tls verification for kube api calls + # skipTlsVerify: true + enableUniqueFilenames: false + readinessProbe: {} + livenessProbe: {} + # Log level default for all sidecars. Can be one of: DEBUG, INFO, WARN, ERROR, CRITICAL. Defaults to INFO + # logLevel: INFO + alerts: + enabled: false + # Additional environment variables for the alerts sidecar + env: {} + # Do not reprocess already processed unchanged resources on k8s API reconnect. + # ignoreAlreadyProcessed: true + # label that the configmaps with alert are marked with + label: grafana_alert + # value of label that the configmaps with alert are set to + labelValue: "" + # Log level. Can be one of: DEBUG, INFO, WARN, ERROR, CRITICAL. + # logLevel: INFO + # If specified, the sidecar will search for alert config-maps inside this namespace. + # Otherwise the namespace in which the sidecar is running will be used. + # It's also possible to specify ALL to search in all namespaces + searchNamespace: null + # Method to use to detect ConfigMap changes. With WATCH the sidecar will do a WATCH requests, with SLEEP it will list all ConfigMaps, then sleep for 60 seconds. + watchMethod: WATCH + # search in configmap, secret or both + resource: both + # watchServerTimeout: request to the server, asking it to cleanly close the connection after that. + # defaults to 60sec; much higher values like 3600 seconds (1h) are feasible for non-Azure K8S + # watchServerTimeout: 3600 + # + # watchClientTimeout: is a client-side timeout, configuring your local socket. + # If you have a network outage dropping all packets with no RST/FIN, + # this is how long your client waits before realizing & dropping the connection. + # defaults to 66sec (sic!) + # watchClientTimeout: 60 + # + # Endpoint to send request to reload alerts + reloadURL: "http://localhost:3000/api/admin/provisioning/alerting/reload" + # Absolute path to shell script to execute after a alert got reloaded + script: null + skipReload: false + # Deploy the alert sidecar as an initContainer in addition to a container. + # Sets the size limit of the alert sidecar emptyDir volume + sizeLimit: {} + dashboards: + enabled: false + # Additional environment variables for the dashboards sidecar + env: {} + # Do not reprocess already processed unchanged resources on k8s API reconnect. + # ignoreAlreadyProcessed: true + SCProvider: true + # label that the configmaps with dashboards are marked with + label: grafana_dashboard + # value of label that the configmaps with dashboards are set to + labelValue: "" + # Log level. Can be one of: DEBUG, INFO, WARN, ERROR, CRITICAL. + # logLevel: INFO + # folder in the pod that should hold the collected dashboards (unless `defaultFolderName` is set) + folder: /tmp/dashboards + # The default folder name, it will create a subfolder under the `folder` and put dashboards in there instead + defaultFolderName: null + # Namespaces list. If specified, the sidecar will search for config-maps/secrets inside these namespaces. + # Otherwise the namespace in which the sidecar is running will be used. + # It's also possible to specify ALL to search in all namespaces. + searchNamespace: null + # Method to use to detect ConfigMap changes. With WATCH the sidecar will do a WATCH requests, with SLEEP it will list all ConfigMaps, then sleep for 60 seconds. + watchMethod: WATCH + # search in configmap, secret or both + resource: both + # If specified, the sidecar will look for annotation with this name to create folder and put graph here. + # You can use this parameter together with `provider.foldersFromFilesStructure`to annotate configmaps and create folder structure. + folderAnnotation: null + # Endpoint to send request to reload alerts + reloadURL: "http://localhost:3000/api/admin/provisioning/dashboards/reload" + # Absolute path to shell script to execute after a configmap got reloaded + script: null + skipReload: false + # watchServerTimeout: request to the server, asking it to cleanly close the connection after that. + # defaults to 60sec; much higher values like 3600 seconds (1h) are feasible for non-Azure K8S + # watchServerTimeout: 3600 + # + # watchClientTimeout: is a client-side timeout, configuring your local socket. + # If you have a network outage dropping all packets with no RST/FIN, + # this is how long your client waits before realizing & dropping the connection. + # defaults to 66sec (sic!) + # watchClientTimeout: 60 + # + # provider configuration that lets grafana manage the dashboards + provider: + # name of the provider, should be unique + name: sidecarProvider + # orgid as configured in grafana + orgid: 1 + # folder in which the dashboards should be imported in grafana + folder: '' + # type of the provider + type: file + # disableDelete to activate a import-only behaviour + disableDelete: false + # allow updating provisioned dashboards from the UI + allowUiUpdates: false + # allow Grafana to replicate dashboard structure from filesystem + foldersFromFilesStructure: false + # Additional dashboard sidecar volume mounts + extraMounts: [] + # Sets the size limit of the dashboard sidecar emptyDir volume + sizeLimit: {} + datasources: + enabled: false + # Additional environment variables for the datasourcessidecar + env: {} + # Do not reprocess already processed unchanged resources on k8s API reconnect. + # ignoreAlreadyProcessed: true + # label that the configmaps with datasources are marked with + label: grafana_datasource + # value of label that the configmaps with datasources are set to + labelValue: "" + # Log level. Can be one of: DEBUG, INFO, WARN, ERROR, CRITICAL. + # logLevel: INFO + # If specified, the sidecar will search for datasource config-maps inside this namespace. + # Otherwise the namespace in which the sidecar is running will be used. + # It's also possible to specify ALL to search in all namespaces + searchNamespace: null + # Method to use to detect ConfigMap changes. With WATCH the sidecar will do a WATCH requests, with SLEEP it will list all ConfigMaps, then sleep for 60 seconds. + watchMethod: WATCH + # search in configmap, secret or both + resource: both + # watchServerTimeout: request to the server, asking it to cleanly close the connection after that. + # defaults to 60sec; much higher values like 3600 seconds (1h) are feasible for non-Azure K8S + # watchServerTimeout: 3600 + # + # watchClientTimeout: is a client-side timeout, configuring your local socket. + # If you have a network outage dropping all packets with no RST/FIN, + # this is how long your client waits before realizing & dropping the connection. + # defaults to 66sec (sic!) + # watchClientTimeout: 60 + # + # Endpoint to send request to reload datasources + reloadURL: "http://localhost:3000/api/admin/provisioning/datasources/reload" + # Absolute path to shell script to execute after a datasource got reloaded + script: null + skipReload: false + # Deploy the datasource sidecar as an initContainer in addition to a container. + # This is needed if skipReload is true, to load any datasources defined at startup time. + initDatasources: false + # Sets the size limit of the datasource sidecar emptyDir volume + sizeLimit: {} + plugins: + enabled: false + # Additional environment variables for the plugins sidecar + env: {} + # Do not reprocess already processed unchanged resources on k8s API reconnect. + # ignoreAlreadyProcessed: true + # label that the configmaps with plugins are marked with + label: grafana_plugin + # value of label that the configmaps with plugins are set to + labelValue: "" + # Log level. Can be one of: DEBUG, INFO, WARN, ERROR, CRITICAL. + # logLevel: INFO + # If specified, the sidecar will search for plugin config-maps inside this namespace. + # Otherwise the namespace in which the sidecar is running will be used. + # It's also possible to specify ALL to search in all namespaces + searchNamespace: null + # Method to use to detect ConfigMap changes. With WATCH the sidecar will do a WATCH requests, with SLEEP it will list all ConfigMaps, then sleep for 60 seconds. + watchMethod: WATCH + # search in configmap, secret or both + resource: both + # watchServerTimeout: request to the server, asking it to cleanly close the connection after that. + # defaults to 60sec; much higher values like 3600 seconds (1h) are feasible for non-Azure K8S + # watchServerTimeout: 3600 + # + # watchClientTimeout: is a client-side timeout, configuring your local socket. + # If you have a network outage dropping all packets with no RST/FIN, + # this is how long your client waits before realizing & dropping the connection. + # defaults to 66sec (sic!) + # watchClientTimeout: 60 + # + # Endpoint to send request to reload plugins + reloadURL: "http://localhost:3000/api/admin/provisioning/plugins/reload" + # Absolute path to shell script to execute after a plugin got reloaded + script: null + skipReload: false + # Deploy the datasource sidecar as an initContainer in addition to a container. + # This is needed if skipReload is true, to load any plugins defined at startup time. + initPlugins: false + # Sets the size limit of the plugin sidecar emptyDir volume + sizeLimit: {} + notifiers: + enabled: false + # Additional environment variables for the notifierssidecar + env: {} + # Do not reprocess already processed unchanged resources on k8s API reconnect. + # ignoreAlreadyProcessed: true + # label that the configmaps with notifiers are marked with + label: grafana_notifier + # value of label that the configmaps with notifiers are set to + labelValue: "" + # Log level. Can be one of: DEBUG, INFO, WARN, ERROR, CRITICAL. + # logLevel: INFO + # If specified, the sidecar will search for notifier config-maps inside this namespace. + # Otherwise the namespace in which the sidecar is running will be used. + # It's also possible to specify ALL to search in all namespaces + searchNamespace: null + # Method to use to detect ConfigMap changes. With WATCH the sidecar will do a WATCH requests, with SLEEP it will list all ConfigMaps, then sleep for 60 seconds. + watchMethod: WATCH + # search in configmap, secret or both + resource: both + # watchServerTimeout: request to the server, asking it to cleanly close the connection after that. + # defaults to 60sec; much higher values like 3600 seconds (1h) are feasible for non-Azure K8S + # watchServerTimeout: 3600 + # + # watchClientTimeout: is a client-side timeout, configuring your local socket. + # If you have a network outage dropping all packets with no RST/FIN, + # this is how long your client waits before realizing & dropping the connection. + # defaults to 66sec (sic!) + # watchClientTimeout: 60 + # + # Endpoint to send request to reload notifiers + reloadURL: "http://localhost:3000/api/admin/provisioning/notifications/reload" + # Absolute path to shell script to execute after a notifier got reloaded + script: null + skipReload: false + # Deploy the notifier sidecar as an initContainer in addition to a container. + # This is needed if skipReload is true, to load any notifiers defined at startup time. + initNotifiers: false + # Sets the size limit of the notifier sidecar emptyDir volume + sizeLimit: {} + +## Override the deployment namespace +## +namespaceOverride: "" + +## Number of old ReplicaSets to retain +## +revisionHistoryLimit: 10 + +## Add a seperate remote image renderer deployment/service +imageRenderer: + deploymentStrategy: {} + # Enable the image-renderer deployment & service + enabled: false + replicas: 1 + autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 5 + targetCPU: "60" + targetMemory: "" + behavior: {} + image: + # image-renderer Image repository + repository: grafana/grafana-image-renderer + # image-renderer Image tag + tag: latest + # image-renderer Image sha (optional) + sha: "" + # image-renderer ImagePullPolicy + pullPolicy: Always + # extra environment variables + env: + HTTP_HOST: "0.0.0.0" + # RENDERING_ARGS: --no-sandbox,--disable-gpu,--window-size=1280x758 + # RENDERING_MODE: clustered + # IGNORE_HTTPS_ERRORS: true + # image-renderer deployment serviceAccount + serviceAccountName: "" + # image-renderer deployment securityContext + securityContext: {} + # image-renderer deployment container securityContext + containerSecurityContext: + capabilities: + drop: ['ALL'] + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + # image-renderer deployment Host Aliases + hostAliases: [] + # image-renderer deployment priority class + priorityClassName: '' + service: + # Enable the image-renderer service + enabled: true + # image-renderer service port name + portName: 'http' + # image-renderer service port used by both service and deployment + port: 8081 + targetPort: 8081 + # Adds the appProtocol field to the image-renderer service. This allows to work with istio protocol selection. Ex: "http" or "tcp" + appProtocol: "" + serviceMonitor: + ## If true, a ServiceMonitor CRD is created for a prometheus operator + ## https://github.com/coreos/prometheus-operator + ## + enabled: false + path: /metrics + # namespace: monitoring (defaults to use the namespace this chart is deployed to) + labels: {} + interval: 1m + scheme: http + tlsConfig: {} + scrapeTimeout: 30s + relabelings: [] + # See: https://doc.crds.dev/github.com/prometheus-operator/kube-prometheus/monitoring.coreos.com/ServiceMonitor/v1@v0.11.0#spec-targetLabels + targetLabels: [] + # - targetLabel1 + # - targetLabel2 + # If https is enabled in Grafana, this needs to be set as 'https' to correctly configure the callback used in Grafana + grafanaProtocol: http + # In case a sub_path is used this needs to be added to the image renderer callback + grafanaSubPath: "" + # name of the image-renderer port on the pod + podPortName: http + # number of image-renderer replica sets to keep + revisionHistoryLimit: 10 + networkPolicy: + # Enable a NetworkPolicy to limit inbound traffic to only the created grafana pods + limitIngress: true + # Enable a NetworkPolicy to limit outbound traffic to only the created grafana pods + limitEgress: false + # Allow additional services to access image-renderer (eg. Prometheus operator when ServiceMonitor is enabled) + extraIngressSelectors: [] + resources: {} +# limits: +# cpu: 100m +# memory: 100Mi +# requests: +# cpu: 50m +# memory: 50Mi + ## Node labels for pod assignment + ## ref: https://kubernetes.io/docs/user-guide/node-selection/ + # + nodeSelector: {} + + ## Tolerations for pod assignment + ## ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ + ## + tolerations: [] + + ## Affinity for pod assignment (evaluated as template) + ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity + ## + affinity: {} + + ## Use an alternate scheduler, e.g. "stork". + ## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ + ## + # schedulerName: "default-scheduler" + +networkPolicy: + ## @param networkPolicy.enabled Enable creation of NetworkPolicy resources. Only Ingress traffic is filtered for now. + ## + enabled: false + ## @param networkPolicy.allowExternal Don't require client label for connections + ## The Policy model to apply. When set to false, only pods with the correct + ## client label will have network access to grafana port defined. + ## When true, grafana will accept connections from any source + ## (with the correct destination port). + ## + ingress: true + ## @param networkPolicy.ingress When true enables the creation + ## an ingress network policy + ## + allowExternal: true + ## @param networkPolicy.explicitNamespacesSelector A Kubernetes LabelSelector to explicitly select namespaces from which traffic could be allowed + ## If explicitNamespacesSelector is missing or set to {}, only client Pods that are in the networkPolicy's namespace + ## and that match other criteria, the ones that have the good label, can reach the grafana. + ## But sometimes, we want the grafana to be accessible to clients from other namespaces, in this case, we can use this + ## LabelSelector to select these namespaces, note that the networkPolicy's namespace should also be explicitly added. + ## + ## Example: + ## explicitNamespacesSelector: + ## matchLabels: + ## role: frontend + ## matchExpressions: + ## - {key: role, operator: In, values: [frontend]} + ## + explicitNamespacesSelector: {} + ## + ## + ## + ## + ## + ## + egress: + ## @param networkPolicy.egress.enabled When enabled, an egress network policy will be + ## created allowing grafana to connect to external data sources from kubernetes cluster. + enabled: false + ## + ## @param networkPolicy.egress.ports Add individual ports to be allowed by the egress + ports: [] + ## Add ports to the egress by specifying - port: + ## E.X. + ## ports: + ## - port: 80 + ## - port: 443 + ## + ## + ## + ## + ## + ## + +# Enable backward compatibility of kubernetes where version below 1.13 doesn't have the enableServiceLinks option +enableKubeBackwardCompatibility: false +useStatefulSet: false +# Create a dynamic manifests via values: +extraObjects: [] + # - apiVersion: "kubernetes-client.io/v1" + # kind: ExternalSecret + # metadata: + # name: grafana-secrets + # spec: + # backendType: gcpSecretsManager + # data: + # - key: grafana-admin-password + # name: adminPassword diff --git a/helm/jenkins/.helmignore b/helm/jenkins/.helmignore new file mode 100644 index 0000000..701e6bc --- /dev/null +++ b/helm/jenkins/.helmignore @@ -0,0 +1,26 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*~ +# Various IDEs +.project +.idea/ +*.tmproj +ci/ +# do not package unittests +unittests/ +Tiltfile +.helmignore diff --git a/helm/jenkins/CHANGELOG.md b/helm/jenkins/CHANGELOG.md new file mode 100644 index 0000000..4abe216 --- /dev/null +++ b/helm/jenkins/CHANGELOG.md @@ -0,0 +1,2451 @@ +# Change Log + +This file documents all notable changes to the Jenkins Helm Chart. +The release numbering uses [semantic versioning](http://semver.org). + +Use the following links to reference issues, PRs, and commits prior to v2.6.0. + +* Issue: `https://github.com/helm/charts/issues/[issue#]` +* PR: `https://github.com/helm/charts/pull/[pr#]` +* Commit: `https://github.com/helm/charts/commit/[commit]/stable/jenkins` + +The change log until v1.5.7 was auto-generated based on git commits. +Those entries include a reference to the git commit to be able to get more details. + +## 4.2.18 + +Added option to set secretEnvVars. + +## 4.2.17 + +Update Jenkins image and appVersion to jenkins lts release version 2.375.1 + + +## 4.2.16 + +Fixed chart notes not rendering Jenkins URL with prefix when `controller.jenkinsUriPrefix` is set. +Fixed chart notes not rendering Jenkins URL with `https` when `controller.ingress.tls` or `controller.controller.httpsKeyStore.enable` is set. +Fixed chart notes rendering wrong JCasC URL when not using `controller.ingress`. + +## 4.2.15 + +Update Jenkins image and appVersion to jenkins lts release version 2.361.4 + +## 4.2.14 + +Added option to mount all keys from an existing k8s secret + +## 4.2.13 + +Adding `tpl` to `controller.additionalExistingSecrets` + +## 4.2.12 + +Update Jenkins image and appVersion to jenkins lts release version 2.361.3 + + +## 4.2.11 + +Update default plugin versions + +| plugin | old version | new version | +|-----------------------|-----------------------|------------------------| +| kubernetes | 3706.vdfb_d599579f3 | 3734.v562b_b_a_627ea_c | +| git | 4.11.5 | 4.13.0 | +| configuration-as-code | 1512.vb_79d418d5fc8 | 1569.vb_72405b_80249 | + +## 4.2.10 +Fix grammar and typos + +## 4.2.9 +Update Jenkins image and appVersion to jenkins lts release version 2.361.2 + +## 4.2.8 +Modify the condition to trigger copying jenkins_config files when configAutoReload option is disabled during Jenkins initialization + +## 4.2.7 +Support for remote url for configuration + +## 4.2.6 +Add option to set hostnetwork for agents + +## 4.2.5 +Add an extra optional argument to extraPorts in order to specify targetPort + +## 4.2.4 +Remove k8s capibility requirements when setting priority class for controller + +## 4.2.3 Update plugin versions + +| plugin | old version | new version | +| --------------------- | --------------------- | --------------------- | +| kubernetes | 3600.v144b_cd192ca_a_ | 3706.vdfb_d599579f3 | +| workflow-aggregator | 581.v0c46fa_697ffd | 590.v6a_d052e5a_a_b_5 | +| configuration-as-code | 1429.v09b_044a_c93de | 1512.vb_79d418d5fc8 | +| git | 4.11.3 | 4.11.5 | + +Resolve version conflict between default install of plugins. + +## 4.2.2 + +Support Google Managed Prometheus + +## 4.2.1 + +Remove option to provide command and args of agent as YAML. This feature was never supported by the Jenkins Kubernetes +plugin. + +## 4.2.0 + +Add option to provide additional containers to agents + +## 4.1.18 + +Update Jenkins image and appVersion to jenkins lts release version 2.361.1 + + +## 4.1.17 + +Update Jenkins casc default settings to allow `security` configs to be provided + + +## 4.1.16 + +Update Jenkins image and appVersion to jenkins lts release version 2.346.3 + + +## 4.1.15 + +`projectNamingStrategy` is configurable in default config. + +## 4.1.14 + +If `installPlugins` is disabled, don't create unused plugins volume. + +## 4.1.13 + +Update Jenkins image and appVersion to jenkins lts release version 2.346.2 + + +## 4.1.12 + +If keystore is defined, it is now also made available in the initContainer. + +## 4.1.11 + +JCasC ConfigMaps now generate their name from the `jenkins.casc.configName` helper + +## 4.1.10 + +Update Jenkins image and appVersion to jenkins lts release version 2.346.1 + + +## 4.1.9 + +Allow setting `imagePullSecret` for backup job via `backup.imagePullSecretName` + +## 4.1.8 + +Fix path of projected secrets from `additionalExistingSecrets`. + +## 4.1.7 + +Update README with explanation on the required environmental variable `AWS_REGION` in case of using an S3 bucket. + +## 4.1.6 + +project adminSecret, additionalSecrets and additionalExistingSecrets instead of mount with subPath + +## 4.1.5 + +Update README to fix `JAVA_OPTS` name. + +## 4.1.4 +Update plugins + +## 4.1.3 +Update jenkins-controller-statefulset projected volumes definition + +## 4.1.1 +Added 'controller.prometheus.metricRelabelings' to allow relabling and dropping unused prometheus metrics + +## 4.1.0 + +Added `controller.sidecars.configAutoReload.envFrom`, `controller.initContainerEnvFrom`, `controller.containerEnvFrom` + +## 4.0.1 + +No code changes - CI updated to run unit tests using Helm 3.8.2. + +## 4.0.0 + +Removes automatic `remotingSecurity` setting when using a container tag older than `2.326` (introduced in [`3.11.7`](#3117)). If you're using a version older than `2.326`, you should explicitly set `.controller.legacyRemotingSecurityEnabled` to `true`. + +## 3.12.2 + +Update Jenkins image and appVersion to jenkins lts release version 2.332.3 + +## 3.12.1 + +Make namespace configurable for agents and additional agents. + +## 3.12.0 + +Added a flag for disabling the default Jenkins Agent configuration. + +## 3.11.10 + +Update Jenkins image and appVersion to jenkins lts release version 2.332.2 + +## 3.11.9 Bump configuration-as-code plugin version + +| plugin | old version | new version | +| --------------------- | ----------- | ----------- | +| configuration-as-code | 1.51 | 1414.v878271fc496f | + +## 3.11.8 + +Make [externalTrafficPolicy](https://kubernetes.io/docs/concepts/services-networking/service/#traffic-policies) and `loadBalancerSourceRanges` fields customizable for Agent listener service via `controller.agentListenerExternalTrafficPolicy` and `controller.loadBalancerSourceRanges`. + +## 3.11.7 + +Removed Configuration as Code `remotingSecurity` section for Jenkins 2.326 or newer. See [Documentation](https://www.jenkins.io/redirect/AdminWhitelistRule) to learn more. + +## 3.11.6 + +Update Jenkins image and appVersion to jenkins lts release version 2.332.1 + + +## 3.11.5 + +Change Backup Role name function call to match the RoleDef function call in the Backup RoleBinding + +## 3.11.4 + +Update Jenkins image and appVersion to jenkins lts release version 2.319.3 + + +## 3.11.3 + +Update kiwigrid/k8s-sidecar:1.15.0 +Update jenkins/inbound-agent:4.11.2-4 + +## 3.11.2 + +Improve example for workspaceVolume. Clarify that this is not a list. + +## 3.11.1 + +Update configuration-as-code plugin to 1.55.1 + + +## 3.11.0 + +Update default plugin versions + +| plugin | old version | new version | +| --------------------- | ----------- | ----------- | +| kubernetes | 1.31.1 | 1.31.3 | +| git | 4.10.1 | 4.10.2 | + +## 3.10.3 + +Update Jenkins image and appVersion to jenkins lts release version 2.319.2 + + +## 3.10.2 + +Fix definition of startupProbe when deploying on a Kubernetes cluster < 1.16 + +## 3.10.1 + +correct VALUES_SUMMARY.md for installLatestPlugins + +## 3.10.0 + +Update default plugin versions + +| plugin | old version | new version | +| --------------------- | ----------- | ----------- | +| kubernetes | 1.30.11 | 1.31.1 | +| git | 4.10.0 | 4.10.1 | +| configuration-as-code | 1.54 | 1.55 | + +## 3.9.4 + +Add JAVA_OPTIONS to the README so proxy settings get picked by jenkins-plugin-cli + +## 3.9.3 + +Fix config reload request url when httpsKeystore in use + +## 3.9.2 + +Update Jenkins image and appVersion to jenkins lts release version 2.319.1 +Update following plugins: + +* kubernetes:1.30.11 +* git:4.10.0 +* configuration-as-code:1.54 + +## 3.9.1 + +Adding `tpl` to `controller.overrideArgs` + +## 3.9.0 + +Added containerSecurityContext + +## 3.8.9 + +Fix mounting of https keystore secret when httpsKeyStore is enabled + +## 3.8.8 + +Update Jenkins image and appVersion to jenkins lts release version 2.303.3 + +## 3.8.7 + +Adding `tpl` to `initScripts` + +## 3.8.6 + +Add `controller.tagLabel` to specify the label for the image tag, for example `jdk11` or `alpine` + +## 3.8.5 + +Move jenkins web root outside of home dir + +## 3.8.4 + +Add `controller.initConfigMap` to pass pre-existing `init.groovy.d` ConfigMaps to the controller + +## 3.8.3 + +Update missed reference to jenkins/inbound-agent:4.11-1 + +## 3.8.2 + +Update jenkins/inbound-agent:4.11-1 + +## 3.8.1 + +Update jenkins/inbound-agent:4.10-3 + +## 3.8.0 + +Update kiwigrid/k8s-sidecar:1.14.2 + +## 3.7.1 + +Update git and casc plugins versions + +## 3.7.0 + +Added the option to create AWS SecurityGroupPolicy resources + +## 3.6.2 + +Fix httpsKeyStore mount when `controller.httpsKeyStore.enable` is `true` + +## 3.6.1 + +Update Jenkins image and appVersion to jenkins lts release version 2.303.2 + + +## 3.6.0 +Support custom agent pod labels + +## 3.5.20 +Disallow ingress on port 50000 when agent listener is disabled + +## 3.5.19 +Add support for specifying termination-log behaviour for Jenkins controller + +## 3.5.18 +Add support for creating a Pod Disruption Budget for Jenkins controller + +## 3.5.17 +Update workdingDir to `/home/jenkins/agent` + +## 3.5.16 +Update location of icon (wiki.jenkins.io is down) + +## 3.5.15 +Add support for adding labels to the Jenkins home Persistent Volume Claim (pvc) + +## 3.5.14 + +* Updated versions of default plugins +* Use verbose logging during plugin installation +* download the latest version of all plugin dependencies (Fixes #442) + +## 3.5.13 + +Update Jenkins image and appVersion to jenkins lts release version 2.303.1 + +## 3.5.12 + +Added extended documentation for Backup and Restore. + +## 3.5.11 + +Sanitized the Jenkins Label + +## 3.5.10 + +Fixed `controller.customJenkinsLabels` not getting templated into the controller `labelString:` field in JCasC + +## 3.5.9 + +Update Jenkins image and appVersion to jenkins lts release version 2.289.3 + + +## 3.5.8 + +Add parameter `backup.serviceAccount.create` to disable service account creation for backup service and `backup.serviceAccount.name` to allow change of the SA name. +`backup.annotations` was moved to `backup.serviceAccount.annotations` + +## 3.5.7 + +Enable setting `controller.serviceExternalTrafficPolicy` to set [the standard Service option](https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#preserving-the-client-source-ip). `externalTrafficPolicy` denotes if this Service desires to route external traffic to node-local or cluster-wide endpoints. + +## 3.5.6 + +Add optional `controller.initContainerResources`, if set, it will change resources allocation for init controller, overwise the `controller.resources` will be used + +## 3.5.5 + +Allow to configure nodeUsageMode via `agent.nodeUsageMode` + +## 3.5.4 + +Update tests to work with unittest 0.2.6 + +## 3.5.3 + +Update Jenkins image and appVersion to jenkins lts release version 2.289.2 + +## 3.5.2 + +Enable setting `controller.installLatestSpecifiedPlugins` to set whether to download the latest dependencies of any plugin that is requested to have the latest version. + +## 3.5.1 +Fix activeDeadlineSeconds wrong type bug in jenkins-backup-cronjob template + +## 3.5.0 + +Allow `controller.podAnnotations` to be render as a template + +## 3.4.1 + +Allow showRawYaml for the default agent's pod template to be customized. + +## 3.4.0 + +configAutoReload container updated from `kiwigrid/k8s-sidecar:0.1.275` to `kiwigrid/k8s-sidecar:1.12.2` + +## 3.3.23 + +Make `controller.ingress.resourceRootUrl` compatible with api version networking.k8s.io/v1 on k8s >= 1.19.x + +## 3.3.22 + +Update Jenkins image and appVersion to jenkins lts release version 2.289.1 + +## 3.3.21 +`persistence.mounts` additionally mount to init container to allow custom CA certificate keystore + +## 3.3.18 +Added `controller.overrideArgs` so any cli argument can be passed to the WAR. + +## 3.3.17 +Correct docs on disabling plugin installation + +## 3.3.16 +Support generating `SecretClaim` resources in order to read secrets from HashiCorp Vault into Kubernetes using `kube-vault-controller`. + +## 3.3.15 +Prevent `controller.httpsKeyStore` from improperly being quoted, leading to an invalid location on disk + +## 3.3.14 +Correct docs on disabling plugin installation + +## 3.3.13 +Update plugins + +## 3.3.12 +Add `controller.additionalExistingSecrets` property + +## 3.3.11 +Add support for disabling the Agent listener service via `controller.agentListenerEnabled`. + +## 3.3.10 +Update Jenkins image and appVersion to jenkins lts release version 2.277.4 + +## 3.3.9 +* Change helper template so user defined `agent.jenkinsUrl` value will always be used, if set +* Simplify logic for `jenkinsUrl` and `jenkinsTunnel` generation: always use fully qualified address + +## 3.3.8 +Update Jenkins image and appVersion to jenkins lts release version 2.277.3 + +## 3.3.7 +fix controller-ingress line feed bug + +## 3.3.6 + +Update Git plugin version to v4.7.1 +Update ldap plugin version to v2.5 + +## 3.3.5 + +Use tpl function for environment vars. Fixes [https://github.com/jenkinsci/helm-charts/issues/324] + +## 3.3.4 + +Update Jenkins image and appVersion to jenkins lts release version 2.277.2 + + +## 3.3.3 + +Enable setting `controller.installLatestPlugins` to set whether to download the minimum required version of all dependencies. + +## 3.3.2 + +Add `controller.additionalSecrets` documentation + +## 3.3.1 + +Add `controller.additionalSecrets` property + +## 3.3.0 + +Change default Jenkins image to `jdk11` variant + +## 3.2.6 + +Add missing `controller.jenkinsUrlProtocol` property + +## 3.2.5 + +Add additional metadata `artifacthub.io/images` for artifacthub + +## 3.2.4 +Update Jenkins image and appVersion to jenkins lts release version 2.277.1 +Update Git plugin version to v4.6.0 +Update kubernetes plugin version to v1.29.2 + +## 3.2.3 + +Fix rendering `controller.ingress.path` + +## 3.2.2 + +Added description for `controller.jenkinsUrl` value + +## 3.2.1 + +Enable setting ImagePullSecrets to controller and agent service accounts. + +## 3.2.0 + +Calculate consistent unique agent IDs to be used in pod templates. Fixes [https://github.com/jenkinsci/helm-charts/issues/270] + +## 3.1.15 + +Fix documentation for the kubernetes probes + +## 3.1.14 + +Typo in documentation + +## 3.1.13 + +Update Jenkins image and appVersion to jenkins lts release version 2.263.4 + +## 3.1.12 + +Added GitHub action to automate the updating of LTS releases. + +## 3.1.11 + +Enable setting controller.updateStrategy to change the update strategy for StatefulSet + +## 3.1.10 + +Fixed issue for the AgentListener where it was not possible to attribute a NodePort + +## 3.1.9 + +Upgrade kubernetes plugin to 1.29.0 and CasC plugin to 1.47 + +## 3.1.8 + +Fix init scripts config map name + +## 3.1.7 + +Fix missing newline when `httpsKeyStore` is enabled + +## 3.1.6 + +Mount controller init scripts from ConfigMap + +## 3.1.5 + +Fix `namespaceOverride` not applied when loading JCasC + +## 3.1.4 + +Update Git plugin version to v4.5.2 + +## 3.1.3 + +Update Jenkins image and appVersion to jenkins lts release version 2.263.3 + +## 3.1.2 + +Enable setting maxRequestsPerHostStr to change the max concurrent connections to Kubernetes API + +## 3.1.1 + +Update Jenkins image and appVersion to jenkins lts release version 2.263.2 + +## 3.1.0 + +* Added `.Values.controller.podSecurityContextOverride` and `.Values.backup.podSecurityContextOverride`. +* Added simple default values tests for `jenkins-backup-cronjob.yaml`. + +## 3.0.14 + +Enable to only backup job folder instead of whole jenkins + +## 3.0.13 + +Improve Documentation around JCasc and Custom Image + +## 3.0.12 + +Added GitHub Action testing on Kind 1.16, 1.17, 1.18, 1.19 & 1.20 + +## 3.0.11 + +Fixes & unit tests for Ingress resources on Kubernetes 1.19 and above + +## 3.0.10 + +Ingress resources on Kubernetes 1.19 (or above) are created with the version `networking.k8s.io/v1` + +## 3.0.9 + +Added support for backing up to Azure Blob Storage. + +## 3.0.8 + +* Typo in documentation + +## 3.0.7 + +* Add support for setting default agent workspaceVolume + +## 3.0.6 + +Use 2.263.1 image + +## 3.0.5 + +* Update appVersion to reflect new jenkins lts release version 2.263.1 + +## 3.0.4 + +* Fix documentation for additional secret mounts + +## 3.0.3 + +* Update `README.md` with explanation on how to mount additional secrets + +## 3.0.2 + +* Fix `.Values.controller.tolerations` and `.Values.controller.nodeSelector` variable names in templates\jenkins-backup-cronjob.yaml + +## 3.0.1 + +* added 'runAsNonroot' to security context + +## 3.0.0 + +* Chart uses StatefulSet instead of Deployment +* XML configuration was removed in favor of JCasC +* chart migrated to helm 3.0.0 (apiVersion v2) +* offending terms have been removed +* values have been renamed and re-ordered to make it easier to use +* already deprecated items have been removed +* componentName for the controller is now `jenkins-controller` +* componentName for the agent is now `jenkins-agent` +* container names are now + * `init` for the init container which downloads Jenkins plugins + * `jenkins` for the Jenkins controller + * `config-reload` for the sidecar container which automatically reloads JCasC +* Updated UI tests to use official `bats/bats` image instead of `dduportal/bats` + +For migration instructions from previous versions and additional information check README.md. + +## 2.19.0 + +* Use lts version 2.249.3 +* Update kubernetes, workflow-aggregator, git and configuration-as-code plugins. +* Fail apply_config.sh script if an error occurs. + +## 2.18.2 + +Fix: `master.javaOpts` issue with quoted values + +## 2.18.1 + +Recommend installing plugins in custom image + +## 2.18.0 + +Removed /tmp volume. Making /tmp a volume causes permission issues with jmap/jstack on certain Kubernetes clusters + +## 2.17.1 + +Fix location of jenkins.war file. +It is located in `/usr/share/jenkins/jenkins.war` and can be fonfigured via `master.jenkinsWar`. + +## 2.17.0 + +Add support for plugin-installation-manager-tool + +## 2.16.0 + +Added Startup probe for Jenkins pod when Kubernetes cluster is 1.16 or newer + +## 2.15.5 + +scriptApproval is taken into account when enableXmlConfig is false. + +## 2.15.4 + +Add Tilt support for easier helm chart development. + +## 2.15.3 + +Fix error on missing `ingress.paths` value + +## 2.15.2 + +Added documentation for ingress and jenkins url + +## 2.15.1 + +Fix priorityClassName entry in values.yaml file + +## 2.15.0 + +Added support for disabling the helm.sh/chart annotation + +## 2.14.0 + +Added support for annotations in podTemplates + +## 2.13.2 + +Add nodeSelector in the backup pod +Fix tolerations in the backup pod + +## 2.13.1 + +Update list of maintainers + +## 2.13.0 + +Added Support for websockets in the default Jcasc config +Added trailing slash to JENKINS_URL env var + +## 2.12.2 + +Added unit tests for most resources in the Helm chart. + +## 2.12.1 + +Helm chart README update + +## 2.12.0 + +Add option to configure securityContext capabilities + +## 2.11.0 + +Added configurable security context for jenkins backup CronJob and annotations to its serviceaccount. + +## 2.10.0 + +Make activeDeadlineSeconds for backup job configurable + +## 2.9.0 + +Make namespace of PrometheusRule configurable + +## 2.8.2 + +Bumped configuration-as-code plugin version from 1.41 to 1.43. +See [configuration-as-code plugin issue #1478](https://github.com/jenkinsci/configuration-as-code-plugin/issues/1478) + +## 2.8.1 + +Fix indentation of JAVA_OPTS + +## 2.8.0 + +Add support for helm unittest and include first tests + +## 2.7.2 + +Target port of container `jenkins-sc-config` taken the value from values.yaml. + +## 2.7.0 + +Add a secondary ingress template for those who want a second ingress with different labels or annotations or whatever else. + +Example: You want /github-webhook to be on a public ingress, while the main Jenkins intance to be on a private locked down ingress. + +## 2.6.5 + +Update configScripts example + +## 2.6.4 + +Add timja as a maintainer + +## 2.6.3 + +Update k8s-sidecar image to 0.1.193 + +## 2.6.2 + +Only mount empty dir secrets-dir if either `master.enableXmlConfig` or `master.secretsFilesSecret` is set +Fixes #19 + +## 2.6.1 Do not render empty JCasC templates + +## 2.6.0 First release in jenkinsci GitHub org + +Updated README for new location + +## 2.5.2 + +Fix as per JENKINS-47112 + +## 2.5.1 + +Support Jenkins Resource Root URL + +## 2.5.0 + +Add an option to specify that Jenkins master should be initialized only once, during first install. + +## 2.4.1 + +Reorder README parameters into sections to facilitate chart usage and maintenance + +## 2.4.0 Update default agent image + +`jenkins/jnlp-slave` is deprected and `jenkins/inbound-agent` should be used instead. +Also updated it to newest version (4.3-4). + +## 2.3.3 correct templating of master.slaveJenkinsUrl + +Fixes #22708 + +## 2.3.2 Fix wrong value for overwritePluginsFromImage + +Fixes #23003 +Fixes #22633 + +Also fixes indentation for #23114 + +## 2.3.1 + +Always mount {{ .Values.master.jenkinsRef }}/secrets/ directory. Previous it +was mounted only when `master.enableXmlConfig` was enabled. + +## 2.3.0 + +Add an option to specify pod based on labels that can connect to master if NetworkPolicy is enabled + +## 2.2.0 increase retry for config auto reload + +Configure `REQ_RETRY_CONNECT` to `10` to give Jenkins more time to start up. + + +Value can be configured via `master.sidecars.configAutoReload.reqRetryConnect` + +## 2.1.2 updated README + +## 2.1.1 update credentials-binding plugin to 1.23 + +## 2.1.0 + +Add support to set `runAsUser` and `runAsGroup` for `agent`. + +## 2.0.1 + +Only render authorizationStrategy and securityRealm when values are set. + +## 2.0.0 Configuration as Code now default + container does not run as root anymore + +The README contains more details for this update. +Please note that the updated values contain breaking changes. + +## 1.27.0 Update plugin versions & sidecar container + +| plugin | old version | new version | +| --------------------- | ----------- | ----------- | +| kubernetes | 1.25.3 | 1.25.7 | +| workflow-job | 2.38 | 2.39 | +| credentials-binding | 1.21 | 1.22 | +| configuration-as-code | 1.39 | 1.41 | + +configAutoReload container updated from `kiwigrid/k8s-sidecar:0.1.132` to `kiwigrid/k8s-sidecar:0.1.144` + +## 1.26.0 + +Add support to override `workingDir` for default pod template + +## 1.25.0 + +Add support for installing plugins in addition to the chart's default plugins via `master.additionalPlugins` + +## 1.24.0 + +Allow configuration of yamlMergeStrategy via `agent.yamlMergeStrategy` + +## 1.23.2 + +In the `jenkins.xml.podTemplate` helper function, allow templating of all string values under `agent.volumes` except `type` by rendering them with the `tpl` function + +## 1.23.1 + +Added auto detection for Ingress API version + +## 1.23.0 + +Allow to use an existing secret for the jenkins admin credentials + +## 1.22.0 + +Add support for UI security in the default JCasC via `master.JCasC.securityRealm` and `master.JCasC.authorizationStrategy` which deny anonymous access by default + +## 1.21.3 + +Render `agent.envVars` in kubernetes pod template JCasC + +## 1.21.2 + +Cleanup `agent.yamlTemplate` rendering in kubernetes pod template XML configuration + +## 1.21.1 + +Render `agent.nodeSelector` in the kubernetes pod template JCasC + +## 1.21.0 + +Add support for overriding Ingress paths via `master.ingress.paths` + +## 1.20.0 + +Add the following options for configuring the Kubernetes plugin. + +- master.slaveDefaultsProviderTemplate +- master.slaveJenkinsUrl +- master.slaveJenkinsTunnel +- master.slaveConnectTimeout +- master.slaveReadTimeout + +## 1.19.0 + +Add support for disabling remember me via `master.disableRememberMe` +Add support for using a different markup formatter via `master.markupFormatter` + +## 1.18.1 + +Add support for executor mode configuraton with `master.executorMode`. + +## 1.18.0 Make installation of configuration-as-code plugin explicit + +Instead of configuring the configuration-as-code plugin version via +`master.JCasC.pluginVersion` it is now installed via `master.installPlugins` + +## 1.17.2 + +Allow templating of `serviceAccount.annotations` and `serviceAccountAgent.annotations` by rendering them with the `tpl` function + +## 1.17.1 + +Add support for Persistent Volume Claim (PVC) in `agent.volumes` + +## 1.17.0 + +Render `agent.volumes` in kubernetes pod template JCasC + +## 1.16.2 + +Reverts 1.16.1 as it introduced an error #22047 + +## 1.16.1 + +Fixed a bug with master.runAsUser variable due to use wrong type for comparison. + +## 1.16.0 + +Add `master.overwritePluginsFromImage` to allow support for jenkins plugins installed in the master image to persist. + +## 1.15.0 Update plugin versions & sidecar container + +| plugin | old version | new version | +| --------------------- | ----------- | ----------- | +| kubernetes | 1.25.1 | 1.25.3 | +| workflow-job | 2.36 | 2.38 | +| git | 4.2.0 | 4.2.2 | +| configuration-as-code | 1.36 | 1.39 | + +configAutoReload container updated from `kiwigrid/k8s-sidecar:0.1.20` to `kiwigrid/k8s-sidecar:0.1.132` + +## 1.14.0 + +support auto-reload container environment variables configuration + +## 1.13.3 + +Fix wrong indent in tolerations + +## 1.13.2 + +Add support for custom ClusterIP + +## 1.13.1 + +Fix `agent.yamlTemplate` rendering in kubernetes pod template JCasC + +## 1.13.0 + +Add `master.networkPolicy.internalAgents` and `master.networkPolicy.externalAgents` stanzas to fine grained controls over where internal/external agents can connect from. Internal ones are allowed based on pod labels and (optionally) namespaces, and external ones are allowed based on IP ranges. + +## 1.12.0 Support additional agents + +Add support for easy configuration of additional agents which inherit values from `agent`. + +## 1.11.3 + +Update the kubernetes plugin from 1.24.1 to 1.25.1 and grant 'watch' permission to 'events' which is required since this plugin version. + +## 1.11.2 Configure agent.args in values.yaml + +## 1.11.1 Support for master.additionalConfig + +Fixed a bug with jenkinsHome variable in range block when master.additionalConfig is set - Helm cannot evaluate field Values in type interface {}. + +## 1.11.0 Add support for configuring custom pod templates + +Add `agent.podTemplates` option for declaring custom pod templates in the default configured kubernetes cloud. + +## 1.10.1 Only copy JCasC files if there are any + +The chart always tried to copy Configuration as Code configs even if there are none. That resulted in an error which is resolved with this. + +## 1.10.0 Remove configuration-as-code-support plugins + +In recent version of configuration-as-code-plugin this is no longer necessary. + +## 1.9.24 + +Update JCasC auto-reload docs and remove stale ssh key references from version "1.8.0 JCasC auto reload works without ssh keys" + +## 1.9.23 Support jenkinsUriPrefix when JCasC is enabled + +Fixed a bug in the configuration as code reload url, where it wouldn't work with a jenkinsUriPrefix set. + +## 1.9.22 + +Add `master.jenkinsHome` and `master.jenkinsRef` options to use docker images derivates from Jenkins + +## 1.9.21 + +Add `master.terminationGracePeriodSeconds` option + +## 1.9.20 + +Update default plugins + +- kubernetes:1.24.1 +- workflow-job:2.36 +- workflow-aggregator:2.6 +- credentials-binding:1.21 +- git:4.2.0 +- configuration-as-code:1.36 + +## 1.9.19 + +Update docs for Helm 3 + +## 1.9.18 + +Make `jenkins-home` attachable to Azure Disks without pvc + +```yaml + volumes: + - name: jenkins-home + azureDisk: + kind: Managed + diskName: myAKSDisk + diskURI: /subscriptions//resourceGroups/MC_myAKSCluster_myAKSCluster_eastus/providers/Microsoft.Compute/disks/myAKSDisk +``` + +## 1.9.16 + +Fix PodLabel for NetworkPolicy to work if enabled + +## 1.9.14 + +Properly fix case sense in `Values.master.overwriteConfig` in `config.yaml` + +## 1.9.13 + +Fix case sense in `Values.master.overwriteConfig` in `config.yaml` + +## 1.9.12 + +Scriptapprovals are overwritten when overwriteConfig is enabled + +## 1.9.10 + +Added documentation for `persistence.storageClass`. + +## 1.9.9 +Make `master.deploymentAnnotation` configurable. + +## 1.9.8 + +Make `agent.slaveConnectTimeout` configurable: by increasing this value Jenkins will not cancel&ask k8s for a pod again, while it's on `ContainerCreating`. Useful when you have big images or autoscaling takes some time. + +## 1.9.7 Update plugin versions + +plugin | old version | new version +--------------------- | ----------- | ---------- +kubernetes | 1.18.2 | 1.21.2 +workflow-job | 2.33 | 2.36 +credentials-binding | 1.19 | 1.20 +git | 3.11.0 | 4.0.0 +configuration-as-code | 1.27 | 1.32 + +## 1.9.6 + +Enables jenkins to use keystore inorder to have native ssl support #17790 + +## 1.9.5 Enable remoting security + +`Manage Jenkins` -> `Configure Global Security` -> `Enable Agent → Master Access Control` is now enabled via configuration as code plugin + +## 1.9.4 Option to set existing secret with Google Application Default Credentials + +Google application credentials are kept in a file, which has to be mounted to a pod. You can set `gcpcredentials` in `existingSecret` as follows: + +```yaml + existingSecret: + jenkins-service-account: + gcpcredentials: application_default_credentials.json +``` + +Helm template then creates the necessary volume mounts and `GOOGLE_APPLICATION_CREDENTIALS` environmental variable. + +## 1.9.3 Fix `JAVA_OPTS` when config auto-reload is enabled + +## 1.9.2 Add support for kubernetes-credentials-provider-plugin + +[kubernetes-credentials-provider-plugin](https://jenkinsci.github.io/kubernetes-credentials-provider-plugin/) needs permissions to get/watch/list kubernetes secrets in the namespaces where Jenkins is running. + +The necessary role binding can be created using `rbac.readSecrets` when `rbac.create` is `true`. + +To quote from the plugin documentation: + +> Because granting these permissions for secrets is not something that should be done lightly it is highly advised for security reasons that you both create a unique service account to run Jenkins as, and run Jenkins in a unique namespace. + +Therefor this is disabled by default. + +## 1.9.1 Update kubernetes plugin URL + +## 1.9.0 Change default serviceType to ClusterIP + +## 1.8.2 + +Revert fix in `1.7.10` since direct connection is now disabled by default. + +## 1.8.1 + +Add `master.schedulerName` to allow setting a Kubernetes custom scheduler + +## 1.8.0 JCasC auto reload works without ssh keys + +We make use of the fact that the Jenkins Configuration as Code Plugin can be triggered via http `POST` to `JENKINS_URL/configuration-as-code/reload`and a pre-shared key. +The sidecar container responsible for reloading config changes is now `kiwigrid/k8s-sidecar:0.1.20` instead of it's fork `shadwell/k8s-sidecar`. + +References: + +- [Triggering Configuration Reload](https://github.com/jenkinsci/configuration-as-code-plugin/blob/master/docs/features/configurationReload.md) +- [kiwigrid/k8s-sidecar](https://hub.docker.com/r/kiwigrid/k8s-sidecar) + +`master.sidecars.configAutoReload.enabled` now works using `casc.reload.token` + +## 1.7.10 + +Disable direct connection in default configuration (when kubernetes plugin version >= 1.20.2). +Note: In case direct connection is going to be used `jenkins/jnlp-slave` needs to be version `3.35-5` or newer. + +## 1.7.9 + +Prevented Jenkins Setup Wizard on new installations + +## 1.7.8 + +Extend extraPorts to be opened on the Service object, not just the container. + +## 1.7.7 + +Add persistentvolumeclaim permission to the role to support new dynamic pvc workspaces. + +## 1.7.6 + +Updated `master.slaveKubernetesNamespace` to parse helm templates. +Defined an sensible empty value to the following variables, to silence invalid warnings: + +- master.extraPorts +- master.scriptApproval +- master.initScripts +- master.JCasC.configScripts +- master.sidecars.other +- agent.envVars +- agent.volumes + +## 1.7.5 + +Fixed an issue where the JCasC won't run if JCasC auto-reload is enabled [issue #17135](https://github.com/helm/charts/issues/17135) + +## 1.7.4 + +Comments out JCasC example of jenkins.systemMessage so that it can be used by end users. Previously, an attempt to set systemMessage causes Jenkins to startup, citing duplicate JCasC settings for systemMessage [issue #13333](https://github.com/helm/charts/issues/13333) + +## 1.7.2 + +Update kubernetes-plugin to version 1.18.2 which fixes frequently encountered [JENKINS-59000](https://issues.jenkins-ci.org/plugins/servlet/mobile#issue/JENKINS-59000) + +## 1.7.1 + +Update the default requirements for jenkins-agent to 512Mi which fixes frequently encountered [issue #3723](https://github.com/helm/charts/issues/3723) + +## 1.7.0 + +[Jenkins Configuration as Code Plugin](https://github.com/jenkinsci/configuration-as-code-plugin) default configuration can now be enabled via `master.JCasC.defaultConfig`. + +JCasC default configuration includes: + +- Jenkins url +- Admin email `master.jenkinsAdminEmail` +- crumbIssuer +- disableRememberMe: false +- mode: NORMAL +- numExecutors: {{ .Values.master.numExecutors }} +- projectNamingStrategy: "standard" +- kubernetes plugin + - containerCapStr via `agent.containerCap` + - jenkinsTunnel + - jenkinsUrl + - maxRequestsPerHostStr: "32" + - name: "kubernetes" + - namespace + - serverUrl: "https://kubernetes.default" + - template + - containers + - alwaysPullImage: `agent.alwaysPullImage` + - args + - command + - envVars + - image: `agent.image:agent.imageTag` + - name: `.agent.sideContainerName` + - privileged: `.agent.privileged` + - resourceLimitCpu: `agent.resources.limits.cpu` + - resourceLimitMemory: `agent.resources.limits.memory` + - resourceRequestCpu: `agent.resources.requests.cpu` + - resourceRequestMemory: `agent.resources.requests.memory` + - ttyEnabled: `agent.TTYEnabled` + - workingDir: "/home/jenkins" + - idleMinutes: `agent.idleMinutes` + - instanceCap: 2147483647 + - imagePullSecrets: + - name: `.agent.imagePullSecretName` + - label + - name + - nodeUsageMode: "NORMAL" + - podRetention: `agent.podRetention` + - serviceAccount + - showRawYaml: true + - slaveConnectTimeoutStr: "100" + - yaml: `agent.yamlTemplate` + - yamlMergeStrategy: "override" +- security: + - apiToken: + - creationOfLegacyTokenEnabled: false + - tokenGenerationOnCreationEnabled: false + - usageStatisticsEnabled: true + +Example `values.yaml` which enables JCasC, it's default config and configAutoReload: + +```yaml +master: + JCasC: + enabled: true + defaultConfig: true + sidecars: + configAutoReload: + enabled: true +``` + +add master.JCasC.defaultConfig and configure location + +- JCasC configuration is stored in template `jenkins.casc.defaults` + so that it can be used in `config.yaml` and `jcasc-config.yaml` + depending on if configAutoReload is enabled or not + +- Jenkins Location (URL) is configured to provide a startin point + for the config + +## 1.6.1 + +Print error message when `master.sidecars.configAutoReload.enabled` is `true`, but the admin user can't be found to configure the SSH key. + +## 1.6.0 + +Add support for Google Cloud Storage for backup CronJob (migrating from nuvo/kube-tasks to maorfr/kube-tasks) + +## 1.5.9 + +Fixed a warning when sidecar resources are provided through a parent chart or override values + +## 1.5.8 + +Fixed an issue when master.enableXmlConfig is set to false: Always mount jenkins-secrets volume if secretsFilesSecret is set (#16512) + +## 1.5.7 + +added initial changelog (#16324) +commit: cee2ebf98 + +## 1.5.6 + +enable xml config misspelling (#16477) +commit: a125b99f9 + +## 1.5.5 + +Jenkins master label (#16469) +commit: 4802d14c9 + +## 1.5.4 + +add option enableXmlConfig (#16346) +commit: 387d97a4c + +## 1.5.3 + +extracted "jenkins.url" into template (#16347) +commit: f2fdf5332 + +## 1.5.2 + +Fix backups when deployment has custom name (#16279) +commit: 16b89bfff + +## 1.5.1 + +Ability to set custom namespace for ServiceMonitor (#16145) +commit: 18ee6cf01 + +## 1.5.0 + +update Jenkins plugins to fix security issue (#16069) +commit: 603cf2d2b + +## 1.4.3 + +Use fixed container name (#16068) +commit: b3e4b4a49 + +## 1.4.2 + +Provide default job value (#15963) +commit: c462e2017 + +## 1.4.1 + +Add Jenkins backendconfig values (#15471) +commit: 7cc9b54c7 + +## 1.4.0 + +Change the value name for docker image tags - standartise to helm preferred value name - tag; this also allows auto-deployments using weaveworks flux (#15565) +commit: 5c3d920e7 + +## 1.3.6 + +jenkins deployment port should be target port (#15503) +commit: 83909ebe3 + +## 1.3.5 + +Add support for namespace specification (#15202) +commit: e773201a6 + +## 1.3.4 + +Adding sub-path option for scraping (#14833) +commit: e04021154 + +## 1.3.3 + +Add existingSecret to Jenkins backup AWS credentials (#13392) +commit: d9374f57d + +## 1.3.2 + +Fix JCasC version (#14992) +commit: 26a6d2b99 + +## 1.3.1 + +Update affinity for a backup cronjob (#14886) +commit: c21ed8331 + +## 1.3.0 + +only install casc support plugin when needed (#14862) +commit: a56fc0540 + +## 1.2.2 + +DNS Zone customization (#14775) +commit: da2910073 + +## 1.2.1 + +only render comment if configAutoReload is enabled (#14754) +commit: e07ead283 + +## 1.2.0 + +update plugins to latest version (#14744) +commit: 84336558e + +## 1.1.24 + +add example for EmptyDir volume (#14499) +commit: cafb60209 + +## 1.1.23 + +check if installPlugins is set before using it (#14168) +commit: 1218f0359 + +## 1.1.22 + +Support servicemonitor and alerting rules (#14124) +commit: e15a27f48 + +## 1.1.21 + +Fix: healthProbe timeouts mapping to initial delay (#13875) +commit: 825b32ece + +## 1.1.20 + +Properly handle overwrite config for additional configs (#13915) +commit: 18ce9b558 + +## 1.1.18 + +update maintainer (#13897) +commit: 223002b27 + +## 1.1.17 + +add apiVersion (#13795) +commit: cd1e5c35a + +## 1.1.16 + +allow changing of the target port to support TLS termination sidecar (#13576) +commit: a34d3bbcc + +## 1.1.15 + +fix wrong pod selector in jenkins-backup (#13542) +commit: b5df4fd7e + +## 1.1.14 + +allow templating of customInitContainers (#13536) +commit: d1e1421f4 + +## 1.1.13 + +fix #13467 (wrong deprecation message) (#13511) +commit: fbe28fa1c + +## 1.1.12 + +Correct customInitContainers Name example. (#13405) +commit: 6c6e40405 + +## 1.1.11 + +fix master.runAsUser, master.fsGroup examples (#13389) +commit: 2d7e5bf72 + +## 1.1.10 + +Ability to specify raw yaml template (#13319) +commit: 77aaa9a5f + +## 1.1.9 + +correct NOTES.txt - use master.ingress.hostname (#13318) +commit: b08ef6280 + +## 1.1.8 + +explain how to upgrade major versions (#13273) +commit: e7617a97e + +## 1.1.7 + +Add support for idleMinutes and serviceAccount (#13263) +commit: 4595ee033 + +## 1.1.6 + +Use same JENKINS_URL no matter if slaves use different namespace (#12564) +commit: 94c90339f + +## 1.1.5 + +fix deprecation checks (#13224) +commit: c7d2f8105 + +## 1.1.4 + +Fix issue introduced in #13136 (#13232) +commit: 0dbcded2e + +## 1.1.3 + +fix chart errors (#13197) +commit: 692a1e3da + +## 1.1.2 + +correct selector for jenkins pod (#13200) +commit: 4537e7fda + +## 1.1.1 + +Fix rendering of customInitContainers and lifecycle for Jenkins helm chart (#13189) +commit: e8f6b0ada + +## 1.1.0 + +Add support for openshift route in jenkins (#12973) +commit: 48c58a430 + +## 1.0.0 + +helm chart best practices (#13136) +commit: b02ae3f48 + +### Breaking changes + +- values have been renamed to follow helm chart best practices for naming conventions so + that all variables start with a lowercase letter and words are separated with camelcase + +- all resources are now using recommended standard labels + + +As a result of the label changes also the selectors of the deployment have been updated. +Those are immutable so trying an updated will cause an error like: + +```text +Error: Deployment.apps "jenkins" is invalid: spec.selector: Invalid value: v1.LabelSelector{MatchLabels:map[string]string{"app.kubernetes.io/component":"jenkins-master", "app.kubernetes.io/instance":"jenkins"}, MatchExpressions:[]v1.LabelSelectorRequirement(nil)}: field is immutable +``` + +In order to upgrade, delete the Jenkins Deployment before upgrading: + +```console +kubectl delete deploy jenkins +``` + +## 0.40.0 + +Allow to override jenkins location protocol (#12257) +commit: 18a830626 + +## 0.39.0 + +Add possibility to add custom init-container and lifecycle for master-container (#13062) +commit: 14d043593 + +## 0.38.0 + +Support `priorityClassName` on Master Deployment (#13069) +commit: e896c62bc + +## 0.37.3 + +Add support for service account annotations in jenkins (#12969) +commit: b22774e2f + +## 0.37.2 + +fix: add hostName to ingress in values.yaml (#12946) +commit: 041045e9b + +## 0.37.1 + +Update to match actual defaults in value.yaml (#12904) +commit: 73b6d37eb + +## 0.37.0 + +Support multiple Jenkins instances in same namespace (#12748) +commit: 32ff2f343 + +## 0.36.5 + +Fix wrong comment in values.yaml (#12761) +commit: 9db8ced23 + +## 0.36.4 + +Re-add value for Ingress API Version (#12753) +commit: ecb7791b5 + +## 0.36.3 + +allow templating of volumes (#12734) +commit: adbda2ca6 + +## 0.36.2 + +Fix self-introduced whitespace bug (#12528) +commit: eec1678eb + +## 0.36.1 + +Add flag to overwrite jobs definition from values.yaml (#12427) +commit: fd349b2fc + +## 0.36.0 + +Replace OwnSshKey with AdminSshKey (#12140) (#12466) +commit: 80a8c9eb6 + +## 0.35.2 + +add note for breaking changes (#12203) +commit: e779c5a54 + +## 0.35.1 + +Allow Jenkins to run with READONLYROOTFS psp (#12338) +commit: 7c419e191 + +## 0.35.0 + +Jenkins OverwriteConfig setting also overwrites init scripts (#9468) +commit: 501335b76 + +## 0.34.1 + +Fix typo on hostname variable (#12156) +commit: 3d337d8dd + +## 0.34.0 + +Allow ingress without host rule (#11960) +commit: ddc966d1e + +## 0.33.2 + +Improve documentation - clarify that rbac is needed for autoreload (#11739) +commit: 9d75a5c34 + +## 0.33.1 + +use object for rollingUpdate (#11909) +commit: cb9cf21e8 + +## 0.33.0 + +Add hostAliases (#11701) +commit: 0b89e1094 + +## 0.32.10 + +Fix slave jnlp port always being reset when container is restarted (#11685) +commit: d7d51797b + +## 0.32.9 + +add ingress Hostname an ApiVersion to docs (#11576) +commit: 4d3e77137 + +## 0.32.8 + +Support custom master pod labels in deployment (#9714) (#11511) +commit: 9de96faa0 + +## 0.32.7 + +Fix markdown syntax in README (#11496) +commit: a32221a95 + +## 0.32.6 + +Added custom labels on jenkins ingress (#11466) +commit: c875d2b9b + +## 0.32.5 + +fix typo in default jenkins agent image fixes #11356 (#11463) +commit: 30adb9a91 + +## 0.32.4 + +fix incorrect Deployment when using sidecars (#11413) +commit: 362b4cef8 + +## 0.32.3 + +[]: #10131 (#11411) +commit: 49cb72055 + +## 0.32.2 + +Option to expose the slave listener port as host port (#11187) +commit: 2f85a9663 + +## 0.32.1 + +Updating Jenkins deployment fails appears rollingUpdate needs to be (#11166) +commit: 07fc9dbde + +## 0.32.0 + +Merge Sidecard configs (#11339) +commit: 3696090b9 + +## 0.31.0 + +Add option to overwrite plugins (#11231) +commit: 0e9aa00a5 + +## 0.30.0 + +Added slave Pod env vars (#8743) +commit: 1499f6608 + +## 0.29.3 + +revert indentation to previous working version (#11293) +commit: 61662f17a + +## 0.29.2 + +allow running sidecar containers for Jenkins master (#10950) +commit: 9084ce54a + +## 0.29.1 + +Indent lines related to EnableRawHtmlMarkupFormatter (#11252) +commit: 20b310c08 + +## 0.29.0 + +Jenkins Configuration as Code (#9057) +commit: c3e8c0b17 + +## 0.28.11 + +Allow to enable OWASP Markup Formatter Plugin (#10851) +commit: 9486e5ddf + +## 0.28.10 + +Fixes #1341 -- update Jenkins chart documentation (#10290) +commit: 411c81cd0 + +## 0.28.9 + +Quoted JavaOpts values (#10671) +commit: 926a843a8 + +## 0.28.8 + +Support custom labels in deployment (#9714) (#10533) +commit: 3e00b47fa + +## 0.28.7 + +separate test resources (#10597) +commit: 7b7ae2d11 + +## 0.28.6 + +allow customizing livenessProbe periodSeconds (#10534) +commit: 3c94d250d + +## 0.28.5 + +Add role kind option (#8498) +commit: e791ad124 + +## 0.28.4 + +workaround for busybox's cp (Closes: #10471) (#10497) +commit: 0d51a4187 + +## 0.28.3 + +fix parsing java options (#10140) +commit: 9448d0293 + +## 0.28.2 + +Fix job definitions in standard values.yaml (#10184) +commit: 6b6355ae7 + +## 0.28.1 + +add numExecutors as a variable in values file (#10236) +commit: d5ea2050f + +## 0.28.0 + +various (#10223) +commit: e17d2a65d + +## 0.27.0 + +add backup cronjob (#10095) +commit: 863ead8db + +## 0.26.2 + +add namespace flag for port-forwarding in jenkins notes (#10399) +commit: 846b589a9 + +## 0.26.1 + +- fixes #10267 when executed with helm template - otherwise produces an invalid template. (#10403) + commit: 266f9d839 + +## 0.26.0 + +Add subPath for jenkins-home mount (#9671) +commit: a9c76ac9b + +## 0.25.1 + +update readme to indicate the correct image that is used by default (#9915) +commit: 6aba9631c + +## 0.25.0 + +Add ability to manually set Jenkins URL (#7405) +commit: a0178fcb4 + +## 0.24.0 + +Make AuthorizationStrategy configurable (#9567) +commit: 06545b226 + +## 0.23.0 + +Update Jenkins public chart (#9296) +commit: 4e5f5918b + +## 0.22.0 + +allow to override jobs (#9004) +commit: dca9f9ab9 + +## 0.21.0 + +Simple implementation of the option to define the ingress path to the jenkins service (#8101) +commit: 013159609 + +## 0.20.2 + +Cosmetic change to remove necessity of changing "appVersion" for every new LTS release (#8866) +commit: f52af042a + +## 0.20.1 + +Added ExtraPorts to open in the master pod (#7759) +commit: 78858a2fb + +## 0.19.1 + +Fix component label in NOTES.txt ... (#8300) +commit: c5494dbfe + +## 0.19.0 + +Kubernetes 1.9 support as well as automatic apiVersion detection (#7988) +commit: 6853ad364 + +## 0.18.1 + +Respect SlaveListenerPort value in config.xml (#7220) +commit: 0a5ddac35 + +## 0.18.0 + +Allow replacement of Jenkins config with configMap. (#7450) +commit: c766da3de + +## 0.17.0 + +Add option to allow host networking (#7530) +commit: dc2eeff32 + +## 0.16.25 + +add custom jenkins labels to the build agent (#7167) +commit: 3ecde5dbf + +## 0.16.24 + +Move kubernetes and job plugins to latest versions (#7438) +commit: 019e39456 + +## 0.16.23 + +Add different Deployment Strategies based on persistence (#6132) +commit: e0a20b0b9 + +## 0.16.22 + +avoid lint errors when adding Values.Ingress.Annotations (#7425) +commit: 99eacc854 + +## 0.16.21 + +bump appVersion to reflect new jenkins lts release version 2.121.3 (#7217) +commit: 296df165d + +## 0.16.20 + +Configure kubernetes plugin for including namespace value (#7164) +commit: c0dc6cc48 + +## 0.16.19 + +make pod retention policy setting configurable (#6962) +commit: e614c1033 + +## 0.16.18 + +Update plugins version (#6988) +commit: bf8180018 + +## 0.16.17 + +Add Master.AdminPassword in README (#6987) +commit: 13e754ad7 + +## 0.16.16 + +Added jenkins location configuration (#6573) +commit: 79de7026c + +## 0.16.15 + +use generic env var, not oracle specific env var (#6116) +commit: 6084ab4a4 + +## 0.16.14 + +Allow to specify resource requests and limits on initContainers (#6723) +commit: 942a33b1a + +## 0.16.13 + +Added support for NodePort service type for jenkens agent svc (#6571) +commit: 89a213c2b + +## 0.16.12 + +Added ability to configure multiple LoadBalancerSourceRanges (#6243) +commit: 01604ddbc + +## 0.16.11 + +Removing ContainerPort configuration as at the moment it does not work when you change this setting (#6411) +commit: e1c0468bd + +## 0.16.9 + +Fix jobs parsing for configmap by adding toYaml to jobs.yaml template (#3747) +commit: b2542a123 + +## 0.16.8 + +add jenkinsuriprefix in healthprobes (#5737) +commit: 435d7a7b9 + +## 0.16.7 + +Added the ability to switch from ClusterRoleBinding to RoleBinding. (#6190) +commit: dde03ede0 + +## 0.16.6 + +Make jenkins master pod security context optional (#6122) +commit: 63653fd59 + +## 0.16.5 + +Rework resources requests and limits (#6077) (#6077) +commit: e738f99d0 + +## 0.16.4 + +Add jenkins master pod annotations (#6313) +commit: 5e7325721 + +## 0.16.3 + +Split Jenkins readiness and liveness probe periods (#5704) +commit: fc6100c38 + +## 0.16.1 + +fix typo in jenkins README (#5228) +commit: 3cd3f4b8b + +## 0.16.0 + +Inherit existing plugins from Jenkins image (#5409) +commit: fd93bff82 + +## 0.15.1 + +Allow NetworkPolicy.ApiVersion and Master.Ingress.ApiVersion to Differ (#5103) +commit: 78ee4ba15 + +## 0.15.0 + +Secure Defaults (#5026) +commit: 0fe90b520 + +## 0.14.6 + +Wait for up to 2 minutes before failing liveness check (#5161) +commit: 2cd3fc481 + +## 0.14.5 + +correct ImageTag setting (#4371) +commit: 8ea04174d + +## 0.14.4 + +Update jenkins/README.md (#4559) +commit: d4e6352dd + +## 0.14.3 + +Bump appVersion (#4177) +commit: 605d3d441 + +## 0.14.2 + +Master.InitContainerEnv: Init Container Env Vars (#3495) +commit: c64abe27d + +## 0.14.1 + +Allow more configuration of Jenkins agent service (#4028) +commit: fc82f39b2 + +## 0.14.0 + +Add affinity settings (#3839) +commit: 64e82fa6a + +## 0.13.5 + +bump test timeouts (#3886) +commit: cd05dd99c + +## 0.13.4 + +Add OWNERS to jenkins chart (#3881) +commit: 1c106b9c8 + +## 0.13.3 + +Add fullnameOverride support (#3705) +commit: ec8080839 + +## 0.13.2 + +Update README.md (#3638) +commit: f6d274c37 + +## 0.13.1 + +Lower initial healthcheck delay (#3463) +commit: 9b99db67c + +## 0.13.0 + +Provision credentials.xml, secrets files and jobs (#3316) +commit: d305c5961 + +## 0.12.1 + +fix the default value for nodeUsageMode. (#3299) +commit: b68d19516 + +## 0.12.0 + +Recreate pods when CustomConfigMap is true and there are changes to the ConfigMap (which is how the vanilla chart works) (#3181) +commit: 86d29f804 + +## 0.11.1 + +Optionally adds liveness and readiness probes to jenkins (#3245) +commit: 8b9aa73ee + +## 0.11.0 + +Feature/run jenkins as non root user (#2899) +commit: 8918f4175 + +## 0.10.3 + +template the version to keep them synced (#3084) +commit: 35e7fa49a + +## 0.10.2 + +Update Chart.yaml +commit: e3e617a0b + +## 0.10.1 + +Merge branch 'master' into jenkins-test-timeout +commit: 9a230a6b1 + +Double retry count for Jenkins test +commit: 129c8e824 + +Jenkins: Update README | Master.ServiceAnnotations (#2757) +commit: 6571810bc + +## 0.10.0 + +Update Jenkins images and plugins (#2496) +commit: 2e2622682 + +## 0.9.4 + +Updating to remove the `.lock` directory as well (#2747) +commit: 6e676808f + +## 0.9.3 + +Use variable for service port when testing (#2666) +commit: d044f99be + +## 0.9.2 + +Review jenkins networkpolicy docs (#2618) +commit: 49911e458 + +Add image pull secrets to jenkins templates (#1389) +commit: 4dfae21fd + +## 0.9.1 + +Added persistent volume claim annotations (#2619) +commit: ac9e5306e + +Fix failing CI lint (#2758) +commit: 26f709f0e + +## 0.9.0 + +namespace defined templates with chart name (#2140) +commit: 408ae0b3f + +## 0.8.9 + +added useSecurity and adminUser to params (#1903) +commit: 39d2a03cd + +Use storageClassName for jenkins. (#1997) +commit: 802f6449b + +## 0.8.8 + +Remove old plugin locks before installing plugins (#1746) +commit: 6cd7b8ff4 + +promote initContainrs to podspec (#1740) +commit: fecc804fc + +## 0.8.7 + +add optional LoadBalancerIP option. (#1568) +commit: d39f11408 + +## 0.8.6 + +Fix bad key in values.yaml (#1633) +commit: dc27e5af3 + +## 0.8.5 + +Update Jenkins to support node selectors for agents. (#1532) +commit: 4af5810ff + +## 0.8.4 + +Add support for supplying JENKINS_OPTS and/or uri prefix (#1405) +commit: 6a331901a + +## 0.8.3 + +Add serviceAccountName to deployment (#1477) +commit: 0dc349b44 + +## 0.8.2 + +Remove path from ingress specification to allow other paths (#1599) +commit: e727f6b32 + +Update git plugin to 3.4.0 for CVE-2017-1000084 (#1505) +commit: 03482f995 + +## 0.8.1 + +Use consistent whitespace in template placeholders (#1437) +commit: 912f50c71 + +add configurable service annotations #1234 (#1244) +commit: 286861ca8 + +## 0.8.0 + +Jenkins v0.8.0 (#1385) +commit: 0009a2393 + +## 0.7.4 + +Use imageTag as version in config map (#1333) +commit: e8bb6ebb4 + +## 0.7.3 + +Add NetworkPolicy to Jenkins (#1228) +commit: 572b36c6d + +## 0.7.2 + +- Workflow plugin pin (#1178) + commit: ac3a0c7bc + +## 0.7.1 + +copy over plugins.txt in case of update (#1222) +commit: 75b5b1174 + +## 0.7.0 + +add jmx option (#964) +commit: 6ae8d1945 + +## 0.6.4 + +update jenkins to latest LTS 2.46.3 (#1182) +commit: ad90b4c27 + +## 0.6.3 + +Update chart maints to gh u/n (#1107) +commit: f357b77ed + +## 0.6.2 + +Add Agent.Privileged option (#957) +commit: 2cf4aced2 + +## 0.6.1 + +Upgrade jenkins to 2.46.2 (#971) +commit: 41bd742b4 + +## 0.6.0 + +Smoke test for Jenkins Chart (#944) +commit: 110441054 + +## 0.5.1 + +removed extra space from hardcoded password (#925) +commit: 85a9b9123 + +## 0.5.0 + +move config to init-container allowing use of upstream containers (#921) +commit: 1803c3d33 + +## 0.4.1 + +add ability to toggle jnlp-agent podTemplate generation (#918) +commit: accd53203 + +## 0.4.0 + +Jenkins add script approval (#916) +commit: c1746656e + +## 0.3.1 + +Update Jenkins to Latest LTS fixes #731 (#733) +commit: e9a3aed8b + +## 0.3.0 + +Added option to add Jenkins init scripts (#617) +commit: b889623d0 + +## 0.2.0 + +Add existing PVC (#716) +commit: 05271f145 + +## 0.1.15 + +use Master.ServicePort in config.xml (#769) +commit: f351f4b16 + +## 0.1.14 + +Added option to disable security on master node (#403) +commit: 3a6113d18 + +## 0.1.13 + +Added: extra mount points support for jenkins master (#474) +commit: fab0f7eb1 + +## 0.1.12 + +fix storageclass config typo (#548) +commit: 6fc0ff242 + +## 0.1.10 + +Changed default value of Kubernetes Cloud name to match one in kubernetes plugin (#404) +commit: 68351304a + +Add support for overriding the Jenkins ConfigMap (#524) +commit: f97ca53b1 + +## 0.1.9 + +Added jenkins-master ingress support (#402) +commit: d76a09588 + +## 0.1.8 + +Change description (#553) +commit: 91f5c24e1 + +Removed default Persistence.StorageClass: generic (#530) +commit: c87494c10 + +Update to the recommended pvc patterns. (#448) +commit: a7fc595aa + +Remove helm.sh/created annotations (#505) +commit: f380da2fb + +## 0.1.7 + +add support for explicit NodePort on jenkins chart (#342) +commit: f63c188da + +Add configurable loadBalancerSourceRanges for jenkins chart (#360) +commit: 44007c50e + +Update Jenkins version to current LTS (2.19.4) and Kubernetes Plugin to 0.10 (#341) +commit: 6c8678167 + +## 0.1.6 + +Add imagePullPolicy to init container (#295) +commit: 103ee1952 + +## 0.1.5 + +bump chart version with PVC metadata label additions +commit: 4aa9cf5b1 + +## 0.1.4 + +removed `*` from `jenkins/templates/NOTES.txt` +commit: 76212230b + +apply standard metadata labels to PVC's +commit: 58b730836 + +specify namespace in `kubectl get svc` commands in NOTES.txt +commit: 7d3287e81 + +Update Jenkins version to current LTS (#194) +commit: 2c0404049 + +## 0.1.1 + +escape fixed +commit: 2026e1d15 + +.status.loadBalancer.ingress[0].ip is empty in AWS +commit: 1810e37f4 + +.status.loadBalancer.ingress[0].ip is empty in AWS +commit: 3cbd3ced6 + +Remove 'Getting Started:' from various NOTES.txt. (#181) +commit: 2f63fd524 + +docs(\*): update READMEs to reference chart repos (#119) +commit: c7d1bff05 + +## 0.1.0 + +Move first batch of PVC charts to stable +commit: d745f4879 diff --git a/helm/jenkins/Chart.yaml b/helm/jenkins/Chart.yaml new file mode 100644 index 0000000..e8108e6 --- /dev/null +++ b/helm/jenkins/Chart.yaml @@ -0,0 +1,38 @@ +apiVersion: v2 +name: jenkins +home: https://jenkins.io/ +version: 4.2.18 +appVersion: 2.375.1 +description: Jenkins - Build great things at any scale! The leading open source automation server, Jenkins provides hundreds of plugins to support building, deploying and automating any project. +sources: + - https://github.com/jenkinsci/jenkins + - https://github.com/jenkinsci/docker-inbound-agent + - https://github.com/maorfr/kube-tasks + - https://github.com/jenkinsci/configuration-as-code-plugin +maintainers: + - name: maorfr + email: maor.friedman@redhat.com + - name: torstenwalter + email: mail@torstenwalter.de + - name: mogaal + email: garridomota@gmail.com + - name: wmcdona89 + email: wmcdona89@gmail.com + - name: timja + email: timjacomb1@gmail.com +icon: https://get.jenkins.io/art/jenkins-logo/logo.svg +annotations: + artifacthub.io/links: | + - name: Chart Source + url: https://github.com/jenkinsci/helm-charts/tree/main/charts/jenkins + - name: Jenkins + url: https://www.jenkins.io/ + artifacthub.io/images: | + - name: jenkins + image: jenkins/jenkins:2.375.1-jdk11 + - name: k8s-sidecar + image: kiwigrid/k8s-sidecar:1.15.0 + - name: inbound-agent + image: jenkins/inbound-agent:4.11.2-4 + - name: backup + image: maorfr/kube-tasks:0.2.0 diff --git a/helm/jenkins/README.md b/helm/jenkins/README.md new file mode 100644 index 0000000..359eca8 --- /dev/null +++ b/helm/jenkins/README.md @@ -0,0 +1,1044 @@ +# Jenkins + +[Jenkins](https://www.jenkins.io/) is the leading open source automation server, Jenkins provides hundreds of plugins to support building, deploying and automating any project. + +This chart installs a Jenkins server which spawns agents on [Kubernetes](http://kubernetes.io) utilizing the [Jenkins Kubernetes plugin](https://plugins.jenkins.io/kubernetes/). + +Inspired by the awesome work of [Carlos Sanchez](https://github.com/carlossg). + +## Get Repo Info + +```console +helm repo add jenkins https://charts.jenkins.io +helm repo update +``` + +_See [helm repo](https://helm.sh/docs/helm/helm_repo/) for command documentation._ + +## Install Chart + +```console +# Helm 3 +$ helm install [RELEASE_NAME] jenkins/jenkins [flags] +``` + +_See [configuration](#configuration) below._ + +_See [helm install](https://helm.sh/docs/helm/helm_install/) for command documentation._ + +## Uninstall Chart + +```console +# Helm 3 +$ helm uninstall [RELEASE_NAME] +``` + +This removes all the Kubernetes components associated with the chart and deletes the release. + +_See [helm uninstall](https://helm.sh/docs/helm/helm_uninstall/) for command documentation._ + +## Upgrade Chart + +```console +# Helm 3 +$ helm upgrade [RELEASE_NAME] jenkins/jenkins [flags] +``` + +_See [helm upgrade](https://helm.sh/docs/helm/helm_upgrade/) for command documentation._ + +Visit the chart's [CHANGELOG](./CHANGELOG.md) to view the chart's release history. +For migration between major version check [migration guide](#migration-guide). + +## Configuration + +See [Customizing the Chart Before Installing](https://helm.sh/docs/intro/using_helm/#customizing-the-chart-before-installing). +To see all configurable options with detailed comments, visit the chart's [values.yaml](./values.yaml), or run these configuration commands: + +```console +# Helm 3 +$ helm show values jenkins/jenkins +``` + +For a summary of all configurable options, see [VALUES_SUMMARY.md](./VALUES_SUMMARY.md) + +### Configure Security Realm and Authorization Strategy + +This chart configured a `securityRealm` and `authorizationStrategy` as shown below: + +```yaml +controller: + JCasC: + securityRealm: |- + local: + allowsSignup: false + enableCaptcha: false + users: + - id: "${chart-admin-username}" + name: "Jenkins Admin" + password: "${chart-admin-password}" + authorizationStrategy: |- + loggedInUsersCanDoAnything: + allowAnonymousRead: false +``` + +With the configuration above there is only a single user. +This is ok for getting started quickly, but it needs to be adjusted for any serious environment. + +So you should adjust this to suite your needs. +That could be using LDAP / OIDC / .. as authorization strategy and use globalMatrix as authorization strategy to configure more fine-grained permissions. + +### Consider using a custom image + +This chart allows the user to specify plugins which should be installed. However, for production use cases one should consider to build a custom Jenkins image which has all required plugins pre-installed. +This way you can be sure which plugins Jenkins is using when starting up and you avoid trouble in case of connectivity issues to the Jenkins update site. + +The [docker repository](https://github.com/jenkinsci/docker) for the Jenkins image contains [documentation](https://github.com/jenkinsci/docker#preinstalling-plugins) how to do it. + +Here is an example how that can be done: + +```Dockerfile +FROM jenkins/jenkins:lts +RUN jenkins-plugin-cli --plugins kubernetes workflow-aggregator git configuration-as-code +``` + +NOTE: If you want a reproducible build then you should specify a non-floating tag for the image `jenkins/jenkins:2.249.3` and specify plugin versions. + +Once you built the image and pushed it to your registry you can specify it in your values file like this: + +```yaml +controller: + image: "registry/my-jenkins" + tag: "v1.2.3" + installPlugins: false +``` + +Notice: `installPlugins` is set to false to disable plugin download. In this case, the image `registry/my-jenkins:v1.2.3` must have the plugins specified as default value for [the `controller.installPlugins` directive](https://github.com/jenkinsci/helm-charts/blob/main/charts/jenkins/VALUES_SUMMARY.md#jenkins-plugins) to ensure that the configuration side-car system works as expected. + +In case you are using a private registry you can use 'imagePullSecretName' to specify the name of the secret to use when pulling the image: + +```yaml +controller: + image: "registry/my-jenkins" + tag: "v1.2.3" + imagePullSecretName: registry-secret + installPlugins: false +``` + +### External URL Configuration + +If you are using the ingress definitions provided by this chart via the `controller.ingress` block the configured hostname will be the ingress hostname starting with `https://` or `http://` depending on the `tls` configuration. +The Protocol can be overwritten by specifying `controller.jenkinsUrlProtocol`. + +If you are not using the provided ingress you can specify `controller.jenkinsUrl` to change the url definition. + +### Configuration as Code + +Jenkins Configuration as Code (JCasC) is now a standard component in the Jenkins project. +To allow JCasC's configuration from the helm values, the plugin [`configuration-as-code`](https://plugins.jenkins.io/configuration-as-code/) must be installed in the Jenkins Controller's Docker image (which is the case by default as specified by the [default value of the directive `controller.installPlugins`](https://github.com/jenkinsci/helm-charts/blob/main/charts/jenkins/VALUES_SUMMARY.md#jenkins-plugins)). + +JCasc configuration is passed through Helm values under the key `controller.JCasC`. +The section ["Jenkins Configuration as Code (JCasC)" of the page "VALUES_SUMMARY.md"](https://github.com/jenkinsci/helm-charts/blob/main/charts/jenkins/VALUES_SUMMARY.md#jenkins-configuration-as-code-jcasc) lists all the possible directives. + +In particular, you may specify custom JCasC scripts by adding sub-key under the `controller.JCasC.configScripts` for each configuration area where each corresponds to a plugin or section of the UI. + +The sub-keys (prior to `|` character) are only labels used to give the section a meaningful name. +The only restriction is they must conform to RFC 1123 definition of a DNS label, so they may only contain lowercase letters, numbers, and hyphens. + +Each key will become the name of a configuration yaml file on the controller in `/var/jenkins_home/casc_configs` (by default) and will be processed by the Configuration as Code Plugin during Jenkins startup. + +The lines after each `|` become the content of the configuration yaml file. + +The first line after this is a JCasC root element, e.g. jenkins, credentials, etc. + +Best reference is the Documentation link here: `https:///configuration-as-code`. + +The example below sets custom systemMessage: + +```yaml +controller: + JCasC: + configScripts: + welcome-message: | + jenkins: + systemMessage: Welcome to our CI\CD server. +``` + +More complex example that creates ldap settings: + +```yaml +controller: + JCasC: + configScripts: + ldap-settings: | + jenkins: + securityRealm: + ldap: + configurations: + - server: ldap.acme.com + rootDN: dc=acme,dc=uk + managerPasswordSecret: ${LDAP_PASSWORD} + groupMembershipStrategy: + fromUserRecord: + attributeName: "memberOf" +``` + +Keep in mind that default configuration file already contains some values that you won't be able to override under configScripts section. + +For example, you can not configure Jenkins URL and System Admin e-mail address like this because of conflicting configuration error. + +Incorrect: + +```yaml +controller: + JCasC: + configScripts: + jenkins-url: | + unclassified: + location: + url: https://example.com/jenkins + adminAddress: example@mail.com +``` + +Correct: + +```yaml +controller: + jenkinsUrl: https://example.com/jenkins + jenkinsAdminEmail: example@mail.com +``` + +Further JCasC examples can be found [here](https://github.com/jenkinsci/configuration-as-code-plugin/tree/master/demos). + +#### Config as Code With or Without Auto-Reload + +Config as Code changes (to `controller.JCasC.configScripts`) can either force a new pod to be created and only be applied at next startup, or can be auto-reloaded on-the-fly. +If you set `controller.sidecars.configAutoReload.enabled` to `true`, a second, auxiliary container will be installed into the Jenkins controller pod, known as a "sidecar". +This watches for changes to configScripts, copies the content onto the Jenkins file-system and issues a POST to `http:///reload-configuration-as-code` with a pre-shared key. +You can monitor this sidecar's logs using command `kubectl logs -c config-reload -f`. +If you want to enable auto-reload then you also need to configure rbac as the container which triggers the reload needs to watch the config maps: + +```yaml +controller: + sidecars: + configAutoReload: + enabled: true +rbac: + create: true +``` + +### Allow Limited HTML Markup in User-Submitted Text + +Some third-party systems (e.g. GitHub) use HTML-formatted data in their payload sent to a Jenkins webhook (e.g. URL of a pull-request being built). +To display such data as processed HTML instead of raw text set `controller.enableRawHtmlMarkupFormatter` to true. +This option requires installation of the [OWASP Markup Formatter Plugin (antisamy-markup-formatter)](https://plugins.jenkins.io/antisamy-markup-formatter/). +This plugin is **not** installed by default but may be added to `controller.additionalPlugins`. + +### Change max connections to Kubernetes API +When using agents with containers other than JNLP, The kubernetes plugin will communicate with those containers using the Kubernetes API. this changes the maximum concurrent connections +```yaml +agent: + maxRequestsPerHostStr: "32" +``` +This will change the configuration of the kubernetes "cloud" (as called by jenkins) that is created automatically as part of this helm chart. + +### Mounting Volumes into Agent Pods + +Your Jenkins Agents will run as pods, and it's possible to inject volumes where needed: + +```yaml +agent: + volumes: + - type: Secret + secretName: jenkins-mysecrets + mountPath: /var/run/secrets/jenkins-mysecrets +``` + +The supported volume types are: `ConfigMap`, `EmptyDir`, `HostPath`, `Nfs`, `PVC`, `Secret`. +Each type supports a different set of configurable attributes, defined by [the corresponding Java class](https://github.com/jenkinsci/kubernetes-plugin/tree/master/src/main/java/org/csanchez/jenkins/plugins/kubernetes/volumes). + +### NetworkPolicy + +To make use of the NetworkPolicy resources created by default, install [a networking plugin that implements the Kubernetes NetworkPolicy spec](https://kubernetes.io/docs/tasks/administer-cluster/declare-network-policy#before-you-begin). + +[Install](#install-chart) helm chart with network policy enabled by setting `networkPolicy.enabled` to `true`. + +You can use `controller.networkPolicy.internalAgents` and `controller.networkPolicy.externalAgents` stanzas for fine-grained controls over where internal/external agents can connect from. +Internal ones are allowed based on pod labels and (optionally) namespaces, and external ones are allowed based on IP ranges. + +### Script approval list + +`controller.scriptApproval` allows to pass function signatures that will be allowed in pipelines. +Example: + +```yaml +controller: + scriptApproval: + - "method java.util.Base64$Decoder decode java.lang.String" + - "new java.lang.String byte[]" + - "staticMethod java.util.Base64 getDecoder" +``` + +### Custom Labels + +`controller.serviceLabels` can be used to add custom labels in `jenkins-controller-svc.yaml`. +For example: + +```yaml +ServiceLabels: + expose: true +``` + +### Persistence + +The Jenkins image stores persistence under `/var/jenkins_home` path of the container. +A dynamically managed Persistent Volume Claim is used to keep the data across deployments, by default. +This is known to work in GCE, AWS, and minikube. Alternatively, a previously configured Persistent Volume Claim can be used. + +It is possible to mount several volumes using `persistence.volumes` and `persistence.mounts` parameters. +See additional `persistence` values using [configuration commands](#configuration). + +#### Existing PersistentVolumeClaim + +1. Create the PersistentVolume +2. Create the PersistentVolumeClaim +3. [Install](#install-chart) the chart, setting `persistence.existingClaim` to `PVC_NAME` + +#### Long Volume Attach/Mount Times + +Certain volume type and filesystem format combinations may experience long +attach/mount times, [10 or more minutes][K8S_VOLUME_TIMEOUT], when using +`fsGroup`. This issue may result in the following entries in the pod's event +history: + +```console +Warning FailedMount 38m kubelet, aks-default-41587790-2 Unable to attach or mount volumes: unmounted volumes=[jenkins-home], unattached volumes=[plugins plugin-dir jenkins-token-rmq2g sc-config-volume tmp jenkins-home jenkins-config secrets-dir]: timed out waiting for the condition +``` + +In these cases, experiment with replacing `fsGroup` with +`supplementalGroups` in the pod's `securityContext`. This can be achieved by +setting the `controller.podSecurityContextOverride` Helm chart value to +something like: + +```yaml +controller: + podSecurityContextOverride: + runAsNonRoot: true + runAsUser: 1000 + supplementalGroups: [1000] +``` + +This issue has been reported on [azureDisk with ext4][K8S_VOLUME_TIMEOUT] and +on [Alibaba cloud][K8S_VOLUME_TIMEOUT_ALIBABA]. + +[K8S_VOLUME_TIMEOUT]: https://github.com/kubernetes/kubernetes/issues/67014 +[K8S_VOLUME_TIMEOUT_ALIBABA]: https://github.com/kubernetes/kubernetes/issues/67014#issuecomment-698770511 + +#### Storage Class + +It is possible to define which storage class to use, by setting `persistence.storageClass` to `[customStorageClass]`. +If set to a dash (`-`), dynamic provisioning is disabled. +If the storage class is set to null or left undefined (`""`), the default provisioner is used (gp2 on AWS, standard on GKE, AWS & OpenStack). + +### Additional Secrets + +Additional secrets and Additional Existing Secrets, +can be mounted into the Jenkins controller through the chart or created using `controller.additionalSecrets` or `controller.additionalExistingSecrets`. +A common use case might be identity provider credentials if using an external LDAP or OIDC-based identity provider. +The secret may then be referenced in JCasC configuration (see [JCasC configuration](#configuration-as-code)). + +`values.yaml` controller section, referencing mounted secrets: +```yaml +controller: + # the 'name' and 'keyName' are concatenated with a '-' in between, so for example: + # an existing secret "secret-credentials" and a key inside it named "github-password" should be used in Jcasc as ${secret-credentials-github-password} + # 'name' and 'keyName' must be lowercase RFC 1123 label must consist of lower case alphanumeric characters or '-', + # and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc') + # existingSecret existing secret "secret-credentials" and a key inside it named "github-username" should be used in Jcasc as ${github-username} + # When using existingSecret no need to specify the keyName under additionalExistingSecrets. + existingSecret: secret-credentials + + additionalExistingSecrets: + - name: secret-credentials + keyName: github-username + - name: secret-credentials + keyName: github-password + - name: secret-credentials + keyName: token + + additionalSecrets: + - name: client_id + value: abc123 + - name: client_secret + value: xyz999 + JCasC: + securityRealm: | + oic: + clientId: ${client_id} + clientSecret: ${client_secret} + ... + configScripts: + jenkins-casc-configs: | + credentials: + system: + domainCredentials: + - credentials: + - string: + description: "github access token" + id: "github_app_token" + scope: GLOBAL + secret: ${secret-credentials-token} + - usernamePassword: + description: "github access username password" + id: "github_username_pass" + password: ${secret-credentials-github-password} + scope: GLOBAL + username: ${secret-credentials-github-username} +``` + +For more information, see [JCasC documentation](https://github.com/jenkinsci/configuration-as-code-plugin/blob/master/docs/features/secrets.adoc#kubernetes-secrets). + +### Secret Claims from HashiCorp Vault + +It's possible for this chart to generate `SecretClaim` resources in order to automatically create and maintain Kubernetes `Secrets` from HashiCorp [Vault](https://www.vaultproject.io/) via [`kube-vault-controller`](https://github.com/roboll/kube-vault-controller) + +These `Secrets` can then be referenced in the same manner as Additional Secrets above. + +This can be achieved by defining required Secret Claims within `controller.secretClaims`, as follows: +```yaml +controller: + secretClaims: + - name: jenkins-secret + path: secret/path + - name: jenkins-short-ttl + path: secret/short-ttl-path + renew: 60 +``` + +### RBAC + +RBAC is enabled by default. If you want to disable it you will need to set `rbac.create` to `false`. + +### Backup + +Adds a backup CronJob for jenkins, along with required RBAC resources. See additional `backup` values using [configuration commands](#configuration). + +#### Example: Backup to Google Cloud Storage Bucket + +Let's look at a quick example. Let's pretend we are backing up Jenkins to a **Google Cloud Storage (GCS) Bucket**. Here is what the process would look like: + +##### 1. Create a Google Cloud Platform Account + +If you don't have a GCP account, you can create a Free Account with the link below: + +- + +##### 2. Create a GCS bucket with a unique name + +You need to create a GCS bucket with a unique name, which you can do by following the guide below: + +- + +##### 3. Create a GCP Service Account + +In order for the backup job to upload Jenkins data to the GCS bucket, you need to provide it with a Google Service Account, which you can create by following the guide below: + +- + +##### 4. Bind `roles/storage.admin` role to Service Account + +Now you need to provide your GCP Service Account with the `roles/storage.admin` role, which has permissions to read/write content to a GCS bucket. You can do this by following the guide below: + +- + +##### 5. Create a Service Account Key + +Now that you have a Service Account (SA), you need to create a Service Account Key, which is a file that represents the GCP Service Account that will get passed to the Backup Job (and later on to the Recovery Job). You can create it by following the guide below: + +- + +##### 6. Create a Kubernetes Secret from the Service Account key + +In order for the Backup Job to access the GCP Service Account Key you need to create Kubernetes Secret, which you can create using the command below: + +```bash +# Replace with the path to the SA Key +kubectl -n jenkins create secret generic jenkinsgcp --from-file=sa-credentials.json=/path/to/sa_key.json +``` + +**NOTE**: This assumes that you will deploy the Jenkins chart in the `jenkins` namespace. + +##### 7. Deploy the Jenkins Helm Chart using a modified values file + +Rather than using a long command to pass on all the new Chart values, create a values file called `values.yaml`, then put the following content on it, then save it: + +```yaml +backup: + enabled: true + schedule: "0 2 * * *" # Runs every day at 2 am, change it to whatever interval works for you + existingSecret: + jenkinsgcp: # This is the secret name + gcpcredentials: sa-credentials.json # The service account file in the secret + destination: "gcs://BUCKET_NAME/jenkins-k8s-backup" # Replace with Bucket Name from previous step +controller: + initializeOnce: true # Installs latest plugins as soon as Jenkins starts + installLatestPlugins: true +persistence: + enabled: true # So that we have a PVC that we can backup +``` + +**NOTE**: The [`gcpcredentials`](https://github.com/fabiogomezdiaz/helm-charts-1/blob/main/charts/jenkins/values.yaml#L829) key in the [`jenkinsgcp`](https://github.com/fabiogomezdiaz/helm-charts-1/blob/main/charts/jenkins/values.yaml#L827) field tells the Helm chart that we will be using a GCS bucket as our backup. + +##### 8. Deploy Jenkins Chart with new values + +Now that we have everything in place, let's deploy the Jenkins Chart with the new values file: + +```bash +helm upgrade --install jenkins --namespace jenkins \ + -f values.yaml \ + jenkinsci/jenkins; +``` + +**NOTE**: Save the password from this installation as it will be needed in the [Restore from Backup in Google Cloud Storage Bucket](#example-restore-from-backup-in-google-cloud-storage-bucket) section. + +##### 9. Create resources to backup in Jenkins + +Once Jenkins is available, go to Jenkins and create jobs, download plugins, and create credentials so that we have something to backup other than the default Jenkins installation. + +##### 10. Trigger the backup job + +The values file we used to deploy Jenkins runs the backup job every day at 2 AM. + +If you don't want to wait that long for the job to start running, then patch the CronJob to run in the next minute with the following commands: + +```bash +# Update CronJob to run every minute +kubectl -n jenkins patch cronjob.batch/jenkins-backup --patch '{"spec": {"schedule": "* * * * *"}}' + +# Run this command until the "jenkins-backup-*" container is running +kubectl get pods | grep backup; + +# To prevent multiple jobs from spanning every minute, change the CronJob back to original schedule +kubectl -n jenkins patch cronjob.batch/jenkins-backup --patch '{"spec": {"schedule": "0 2 * * *"}}' +``` + +##### 11. Verify that the backup job completed successfully + +Once the job is running, then query the backup pod logs to monitor progress as follows: + +```bash +# Get backup container name +BACKUP_CONTAINER=$(kubectl get pods | grep backup | awk '{print $1}'); + +# Stream logs of backup container until job is finished +kubectl logs -f ${BACKUP_CONTAINER}; +``` + +**NOTE**: The backup job will create a time-stamped folder in the GCS bucket each time the backup job runs. + +If you can see a success message from the backup job and can see the contents of the backup on your GCS bucket, then the backup was successful! + +A similar process would work for AWS S3. See additional `backup` values using [configuration commands](#configuration). + +**NOTE**: If an environmental variable `AWS_REGION` is not provided, the region of the AWS S3 bucket will be assumed to be `eu-central-1`. If you want to use an S3 bucket in another region, you need to provide the bucket's region as an environmental variable as below: + +```yaml +backup: + env: # The region of your S3 bucket. + - name: AWS_REGION + value: us-east-1 +``` + +### Restore From Backup + +To restore a backup, you can use the `kube-tasks` underlying tool called [skbn](https://github.com/maorfr/skbn), which copies files from cloud storage to Kubernetes. +The best way to do it would be using a `Job` to copy files from the desired backup tag to the Jenkins pod. + +See the following example for more details. + +#### Example: Restore from Backup in Google Cloud Storage Bucket + +**NOTE**: This section assumes that you ran the steps in [Example: Backup to Google Cloud Storage Bucket](#example-backup-to-google-cloud-storage-bucket) beforehand and that you **saved the password** for that Jenkins installation, which you will need at the end of this section. + +Let's pretend you are restoring a backup from a Google Cloud Storage Bucket because you completely lost your Jenkins installation and you are starting from scratch. + +In the following steps, we will explain what this process would look like: + +##### 1. Reinstall the Jenkins Helm Chart + +First, we need to remove the old Jenkins installation that we backed up previously, then we can install a clean Jenkins instance to restore from GCS backup. + +To do so, run the following commands: + +```bash +# Delete old Jenkins installation +helm delete jenkins + +# Install Jenkins Chart +helm upgrade --install jenkins --namespace jenkins \ + -f values.yaml \ + jenkinsci/jenkins; +``` + +**NOTE**: This Command uses the same values file that was created in the [7. Deploy the Jenkins Helm Chart using a modified values file](#7-deploy-the-jenkins-helm-chart-using-a-modified-values-file) section. + +Now verify that Jenkins is up and running and it DOES NOT have any of the resources you created earlier. + +##### 2. Create a Kubernetes Service Account for the Restore Job + +In order for the Restore job to pull backup data from the GCS bucket and put it in the jenkins `/var/jenkins_home` folder in the Jenkins pod, you need to create the following: + +- A [Kubernetes Service Account](https://kubernetes.io/docs/reference/access-authn-authz/service-accounts-admin/) (not to be confused with a GCP Service Account) for the Restore job. +- A [Kubernetes ClusterRole](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#role-and-clusterrole) that lists the necessary permissions to update the data in the volumes of other pods. +- A [Kubernetes ClusterRoleBinding](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#rolebinding-and-clusterrolebinding) that binds the above ClusterRole to the Service Account. + +To do so, create a file called `restore-rbac.yaml` and enter the following content, then save it: + +```yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app: skbn + name: skbn + namespace: jenkins +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app: skbn + name: skbn +rules: +- apiGroups: [""] + resources: ["pods", "pods/log"] + verbs: ["get", "list"] +- apiGroups: [""] + resources: ["pods/exec"] + verbs: ["create"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app: skbn + name: skbn +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: skbn +subjects: +- kind: ServiceAccount + name: skbn + namespace: jenkins +``` + +To apply the above manifest, run the following command: + +```bash +kubectl apply -f restore-rbac.yaml +``` + +##### 3. Create a Kubernetes Job to restore Jenkins + +The logic that will execute the Jenkins restoration from a GCS backup will be done through a +[Kubernetes Job](https://kubernetes.io/docs/concepts/workloads/controllers/job/), which will run only once as needed. + +To create the job, create a manifest file called `restore.yaml` with the following content, then save it: + +```yaml +apiVersion: batch/v1 +kind: Job +metadata: + labels: + app: skbn + name: skbn + namespace: jenkins +spec: + template: + metadata: + labels: + app: skbn + spec: + restartPolicy: OnFailure + serviceAccountName: skbn + containers: + - name: skbn + image: maorfr/skbn + command: ["skbn"] + args: + - "cp" + - "--src" + - "gcs://BUCKET_NAME/jenkins-k8s-backup/BACKUP_NAME" + - "--dst" + - "k8s://jenkins/jenkins-0/jenkins/var/jenkins_home" + imagePullPolicy: IfNotPresent + env: + - name: GOOGLE_APPLICATION_CREDENTIALS + value: /var/run/secrets/jenkinsgcp/sa-credentials.json + volumeMounts: + - mountPath: /var/run/secrets/jenkinsgcp + name: jenkinsgcp + volumes: + - name: jenkinsgcp + secret: + secretName: jenkinsgcp +``` + +While the above Job manifest is mostly complete, you need to replace a couple of things, as follows: + +- Replace `BUCKET_NAME` with the GCS Bucket name created in [Create a GCS bucket with a unique name](#2-create-a-gcs-bucket-with-a-unique-name). +- Go to your GCS bucket and find the name of the latest timestamped folder (i.e. `20210717154947`), then replace `BACKUP_NAME` with it, then save the file. + +Notice that we are using the `jenkinsgcp` Kubernetes Secret that holds the `sa-credentials.json` key file for the GCP Service Account that we created in [Create a Service Account Key](#5-create-a-service-account-key). + +Having the Kubernetes Secret provide the GCP Service Account Key to the Restore Kubernetes Job is what will allow the Job to download the contents of the backup from the GCS bucket and put it into the `/var/jenkins_home` folder in the Persistent Volume Claim of the `jenkins-0` pod. + +##### 4. Deploy the Restore Job + +Deploy the Restore Job using the following command: + +```bash +kubectl apply -f restore.yaml +``` + +Wait about a minute for the Job to start, then query the logs using the following commands: + +```bash +# Get restore container name +RESTORE_CONTAINER=$(kubectl get pods | grep skbn | awk '{print $1}'); + +# Stream logs of restore container until job is finished +kubectl logs -f ${RESTORE_CONTAINER}; +``` + +Watch the logs until the job is done. This usually takes a few minutes. + +##### 5. Verify that Jenkins was restored from GCS Backup + +Login to Jenkins, then click on `Manage Jenkins-> Reload Configuration from Disk`, then press `OK`. + +Jenkins is now going to reload the backup content from disk and restart. Now, if you performed this on a new Jenkins installation, you will **not be able to login** using the password for the new installation of Jenkins. + +Because we are restoring from the backup of a previous installation, we need to login using the password for the old Jenkins installation. + +So, refresh your browser and login to Jenkins using the password from the backup. + +Now, verify that all your jobs, plugins, and credentials from that backup are showing up, and if they are, then CONGRATULATIONS on successfully restoring Jenkins from a GCS Backup! + +A similar process would work for AWS S3. See additional `backup` values using [configuration commands](#configuration) to figure out how what fields to put in the Restore Job manifest. + +### Adding Custom Pod Templates + +It is possible to add custom pod templates for the default configured kubernetes cloud. +Add a key under `agent.podTemplates` for each pod template. Each key (prior to `|` character) is just a label, and can be any value. +Keys are only used to give the pod template a meaningful name. The only restriction is they may only contain RFC 1123 \ DNS label characters: lowercase letters, numbers, and hyphens. Each pod template can contain multiple containers. +There's no need to add the *jnlp* container since the kubernetes plugin will automatically inject it into the pod. +For this pod templates configuration to be loaded the following values must be set: + +```yaml +controller.JCasC.defaultConfig: true +``` + +The example below creates a python pod template in the kubernetes cloud: + +```yaml +agent: + podTemplates: + python: | + - name: python + label: jenkins-python + serviceAccount: jenkins + containers: + - name: python + image: python:3 + command: "/bin/sh -c" + args: "cat" + ttyEnabled: true + privileged: true + resourceRequestCpu: "400m" + resourceRequestMemory: "512Mi" + resourceLimitCpu: "1" + resourceLimitMemory: "1024Mi" +``` + +Best reference is `https:///configuration-as-code/reference#Cloud-kubernetes`. + +### Adding Pod Templates Using additionalAgents + +`additionalAgents` may be used to configure additional kubernetes pod templates. +Each additional agent corresponds to `agent` in terms of the configurable values and inherits all values from `agent` so you only need to specify values which differ. +For example: + +```yaml +agent: + podName: default + customJenkinsLabels: default + # set resources for additional agents to inherit + resources: + limits: + cpu: "1" + memory: "2048Mi" + +additionalAgents: + maven: + podName: maven + customJenkinsLabels: maven + # An example of overriding the jnlp container + # sideContainerName: jnlp + image: jenkins/jnlp-agent-maven + tag: latest + python: + podName: python + customJenkinsLabels: python + sideContainerName: python + image: python + tag: "3" + command: "/bin/sh -c" + args: "cat" + TTYEnabled: true +``` + +### Ingress Configuration + +This chart provides ingress resources configurable via the `controller.ingress` block. + +The simplest configuration looks like the following: + +```yaml +controller: + ingress: + enabled: true + paths: [] + apiVersion: "extensions/v1beta1" + hostName: jenkins.example.com +``` + +This snippet configures an ingress rule for exposing jenkins at `jenkins.example.com` + +You can define labels and annotations via `controller.ingress.labels` and `controller.ingress.annotations` respectively. +Additionally, you can configure the ingress tls via `controller.ingress.tls`. +By default, this ingress rule exposes all paths. +If needed this can be overwritten by specifying the wanted paths in `controller.ingress.paths` + +If you want to configure a secondary ingress e.g. you don't want the jenkins instance exposed but still want to receive webhooks you can configure `controller.secondaryingress`. +The secondaryingress doesn't expose anything by default and has to be configured via `controller.secondaryingress.paths`: + +```yaml +controller: + ingress: + enabled: true + apiVersion: "extensions/v1beta1" + hostName: "jenkins.internal.example.com" + annotations: + kubernetes.io/ingress.class: "internal" + secondaryingress: + enabled: true + apiVersion: "extensions/v1beta1" + hostName: "jenkins-scm.example.com" + annotations: + kubernetes.io/ingress.class: "public" + paths: + - /github-webhook +``` + +## Prometheus Metrics + +If you want to expose Prometheus metrics you need to install the [Jenkins Prometheus Metrics Plugin](https://github.com/jenkinsci/prometheus-plugin). +It will expose an endpoint (default `/prometheus`) with metrics where a Prometheus Server can scrape. + +If you have implemented [Prometheus Operator](https://github.com/prometheus-operator/prometheus-operator), you can set `master.prometheus.enabled` to `true` to configure a `ServiceMonitor` and `PrometheusRule`. +If you want to further adjust alerting rules you can do so by configuring `master.prometheus.alertingrules` + +If you have implemented Prometheus without using the operator, you can leave `master.prometheus.enabled` set to `false`. + +### Running Behind a Forward Proxy + +The controller pod uses an Init Container to install plugins etc. If you are behind a corporate proxy it may be useful to set `controller.initContainerEnv` to add environment variables such as `http_proxy`, so that these can be downloaded. + +Additionally, you may want to add env vars for the init container, the Jenkins container, and the JVM (`controller.javaOpts`): + +```yaml +controller: + initContainerEnv: + - name: http_proxy + value: "http://192.168.64.1:3128" + - name: https_proxy + value: "http://192.168.64.1:3128" + - name: no_proxy + value: "" + - name: JAVA_OPTS + value: "-Dhttps.proxyHost=proxy_host_name_without_protocol -Dhttps.proxyPort=3128" + containerEnv: + - name: http_proxy + value: "http://192.168.64.1:3128" + - name: https_proxy + value: "http://192.168.64.1:3128" + javaOpts: >- + -Dhttp.proxyHost=192.168.64.1 + -Dhttp.proxyPort=3128 + -Dhttps.proxyHost=192.168.64.1 + -Dhttps.proxyPort=3128 +``` + +### HTTPS Keystore Configuration + +[This configuration](https://wiki.jenkins.io/pages/viewpage.action?pageId=135468777) enables jenkins to use keystore in order to serve https. +Here is the [value file section](https://wiki.jenkins.io/pages/viewpage.action?pageId=135468777#RunningJenkinswithnativeSSL/HTTPS-ConfigureJenkinstouseHTTPSandtheJKSkeystore) related to keystore configuration. +Keystore itself should be placed in front of `jenkinsKeyStoreBase64Encoded` key and in base64 encoded format. To achieve that after having `keystore.jks` file simply do this: `cat keystore.jks | base64` and paste the output in front of `jenkinsKeyStoreBase64Encoded`. +After enabling `httpsKeyStore.enable` make sure that `httpPort` and `targetPort` are not the same, as `targetPort` will serve https. +Do not set `controller.httpsKeyStore.httpPort` to `-1` because it will cause readiness and liveliness prob to fail. +If you already have a kubernetes secret that has keystore and its password you can specify its' name in front of `jenkinsHttpsJksSecretName`, You need to remember that your secret should have proper data key names `jenkins-jks-file` and `https-jks-password`. Example: + +```yaml +controller: + httpsKeyStore: + enable: true + jenkinsHttpsJksSecretName: '' + httpPort: 8081 + path: "/var/jenkins_keystore" + fileName: "keystore.jks" + password: "changeit" + jenkinsKeyStoreBase64Encoded: '' +``` +### AWS Security Group Policies + +To create SecurityGroupPolicies set `awsSecurityGroupPolicies.enabled` to true and add your policies. Each policy requires a `name`, array of `securityGroupIds` and a `podSelector`. Example: + +```yaml +awsSecurityGroupPolicies: + enabled: true + policies: + - name: "jenkins-controller" + securityGroupIds: + - sg-123456789 + podSelector: + matchExpressions: + - key: app.kubernetes.io/component + operator: In + values: + - jenkins-controller +``` + +## Migration Guide + +### From stable repo + +Upgrade an existing release from `stable/jenkins` to `jenkins/jenkins` seamlessly by ensuring you have the latest [repo info](#get-repo-info) and running the [upgrade commands](#upgrade-chart) specifying the `jenkins/jenkins` chart. + +### Major Version Upgrades + +Chart release versions follow [semver](../../CONTRIBUTING.md#versioning), where a MAJOR version change (example `1.0.0` -> `2.0.0`) indicates an incompatible breaking change needing manual actions. + +### To 3.0.0 + +* Check `securityRealm` and `authorizationStrategy` and adjust it. + Otherwise, your configured users and permissions will be overridden. +* You need to use helm version 3 as the `Chart.yaml` uses `apiVersion: v2`. +* All XML configuration options have been removed. + In case those are still in use you need to migrate to configuration as code. + Upgrade guide to 2.0.0 contains pointers how to do that. +* Jenkins is now using a `StatefulSet` instead of a `Deployment` +* terminology has been adjusted that's also reflected in values.yaml + The following values from `values.yaml` have been renamed: + + * `master` => `controller` + * `master.useSecurity` => `controller.adminSecret` + * `master.slaveListenerPort` => `controller.agentListenerPort` + * `master.slaveHostPort` => `controller.agentListenerHostPort` + * `master.slaveKubernetesNamespace` => `agent.namespace` + * `master.slaveDefaultsProviderTemplate` => `agent.defaultsProviderTemplate` + * `master.slaveJenkinsUrl` => `agent.jenkinsUrl` + * `master.slaveJenkinsTunnel` => `agent.jenkinsTunnel` + * `master.slaveConnectTimeout` => `agent.kubernetesConnectTimeout` + * `master.slaveReadTimeout` => `agent.kubernetesReadTimeout` + * `master.slaveListenerServiceAnnotations` => `controller.agentListenerServiceAnnotations` + * `master.slaveListenerServiceType` => `controller.agentListenerServiceType` + * `master.slaveListenerLoadBalancerIP` => `controller.agentListenerLoadBalancerIP` + * `agent.slaveConnectTimeout` => `agent.connectTimeout` +* Removed values: + + * `master.imageTag`: use `controller.image` and `controller.tag` instead + * `slave.imageTag`: use `agent.image` and `agent.tag` instead + +### To 2.0.0 + +Configuration as Code is now default + container does not run as root anymore. + +#### Configuration as Code new default + +Configuration is done via [Jenkins Configuration as Code Plugin](https://github.com/jenkinsci/configuration-as-code-plugin) by default. +That means that changes in values which result in a configuration change are always applied. +In contrast, the XML configuration was only applied during the first start and never altered. + +:exclamation::exclamation::exclamation: +Attention: +This also means if you manually altered configuration then this will most likely be reset to what was configured by default. +It also applies to `securityRealm` and `authorizationStrategy` as they are also configured using configuration as code. +:exclamation::exclamation::exclamation: + +#### Image does not run as root anymore + +It's not recommended to run containers in Kubernetes as `root`. + +:exclamation: Attention: If you had not configured a different user before then you need to ensure that your image supports the user and group id configured and also manually change permissions of all files so that Jenkins is still able to use them. + +#### Summary of updated values + +As version 2.0.0 only updates default values and nothing else it's still possible to migrate to this version and opt out of some or all new defaults. +All you have to do is ensure the old values are set in your installation. + +Here we show which values have changed and the previous default values: + +```yaml +controller: + runAsUser: 1000 # was unset before + fsGroup: 1000 # was unset before + JCasC: + enabled: true # was false + defaultConfig: true # was false + sidecars: + configAutoReload: + enabled: true # was false +``` + +#### Migration steps + +Migration instructions heavily depend on your current setup. +So think of the list below more as a general guideline of what should be done. + +- Ensure that the Jenkins image you are using contains a user with id 1000 and a group with the same id. + That's the case for `jenkins/jenkins:lts` image, which the chart uses by default +- Make a backup of your existing installation especially the persistent volume +- Ensure that you have the configuration as code plugin installed +- Export your current settings via the plugin: + `Manage Jenkins` -> `Configuration as Code` -> `Download Configuration` +- prepare your values file for the update e.g. add additional configuration as code setting that you need. + The export taken from above might be a good starting point for this. + In addition, the [demos](https://github.com/jenkinsci/configuration-as-code-plugin/tree/master/demos) from the plugin itself are quite useful. +- Test drive those setting on a separate installation +- Put Jenkins to Quiet Down mode so that it does not accept new jobs + `/quietDown` +- Change permissions of all files and folders to the new user and group id: + + ```console + kubectl exec -it -c jenkins /bin/bash + chown -R 1000:1000 /var/jenkins_home + ``` + +- Update Jenkins + +### To 1.0.0 + +Breaking changes: + +- Values have been renamed to follow [helm recommended naming conventions](https://helm.sh/docs/chart_best_practices/#naming-conventions) so that all variables start with a lowercase letter and words are separated with camelcase +- All resources are now using [helm recommended standard labels](https://helm.sh/docs/chart_best_practices/#standard-labels) + +As a result of the label changes also the selectors of the deployment have been updated. +Those are immutable so trying an updated will cause an error like: + +```console +Error: Deployment.apps "jenkins" is invalid: spec.selector: Invalid value: v1.LabelSelector{MatchLabels:map[string]string{"app.kubernetes.io/component":"jenkins-controller", "app.kubernetes.io/instance":"jenkins"}, MatchExpressions:[]v1.LabelSelectorRequirement(nil)}: field is immutable +``` + +In order to upgrade, [uninstall](#uninstall-chart) the Jenkins Deployment before upgrading: diff --git a/helm/jenkins/Tiltfile b/helm/jenkins/Tiltfile new file mode 100644 index 0000000..4537cfe --- /dev/null +++ b/helm/jenkins/Tiltfile @@ -0,0 +1,5 @@ + +# If not using a standard local dev name, specify your k8s context here +#allow_k8s_contexts('jenkins-dev') +k8s_yaml(helm('.', values='values.yaml', set=['controller.adminPassword=asdf'])) +watch_file('.') diff --git a/helm/jenkins/VALUES_SUMMARY.md b/helm/jenkins/VALUES_SUMMARY.md new file mode 100644 index 0000000..cbcea3f --- /dev/null +++ b/helm/jenkins/VALUES_SUMMARY.md @@ -0,0 +1,400 @@ +# Jenkins + +## Configuration + +The following tables list the configurable parameters of the Jenkins chart and their default values. + +### Jenkins Controller + +| Parameter | Description | Default | +|---------------------------------------------|--------------------------------------------------------------------------|----------------------------------------------------------------------| +| `checkDeprecation` | Checks for deprecated values used | `true` | +| `clusterZone` | Override the cluster name for FQDN resolving | `cluster.local` | +| `nameOverride` | Override the resource name prefix | `jenkins` | +| `renderHelmLabels` | Enables rendering of the helm.sh/chart label to the annotations | `true` | +| `fullnameOverride` | Override the full resource names | `jenkins-{release-name}` (or `jenkins` if release-name is `jenkins`) | +| `namespaceOverride` | Override the deployment namespace | Not set (`Release.Namespace`) | +| `controller.componentName` | Jenkins controller name | `jenkins-controller` | +| `controller.testEnabled` | Can be used to disable rendering test resources when using helm template | `true` | +| `controller.cloudName` | Name of default cloud configuration | `kubernetes` | +| `controller.legacyRemotingSecurityEnabled` | Is remoting security enabled? | Not set (i.e. not enabled) | + +#### Jenkins Configuration as Code (JCasC) + +| Parameter | Description | Default | +| --------------------------------- | ------------------------------------ | ----------------------------------------- | +| `controller.JCasC.defaultConfig` | Enables default Jenkins configuration via configuration as code plugin | `true` | +| `controller.JCasC.configScripts` | List of Jenkins Config as Code scripts | `{}` | +| `controller.JCasC.security` | Jenkins Config as Code for Security section | `legacy` | +| `controller.JCasC.securityRealm` | Jenkins Config as Code for Security Realm | `legacy` | +| `controller.JCasC.authorizationStrategy` | Jenkins Config as Code for Authorization Strategy | `loggedInUsersCanDoAnything` | +| `controller.sidecars.configAutoReload` | Jenkins Config as Code auto-reload settings | | +| `controller.sidecars.configAutoReload.enabled` | Jenkins Config as Code auto-reload settings (Attention: rbac needs to be enabled otherwise the sidecar can't read the config map) | `true` | +| `controller.sidecars.configAutoReload.image` | Image which triggers the reload | `kiwigrid/k8s-sidecar:0.1.144` | +| `controller.sidecars.configAutoReload.reqRetryConnect` | How many connection-related errors to retry on | `10` | +| `controller.sidecars.configAutoReload.envFrom` | Environment variable sources for the Jenkins Config as Code auto-reload container | Not set | +| `controller.sidecars.configAutoReload.env` | Environment variables for the Jenkins Config as Code auto-reload container | Not set | +| `controller.sidecars.configAutoReload.containerSecurityContext` | Enable container security context | `{readOnlyRootFilesystem: true, allowPrivilegeEscalation: false}` | + +#### Jenkins Configuration Files & Scripts + +| Parameter | Description | Default | +| --------------------------------- | ------------------------------------ | ----------------------------------------- | +| `controller.initScripts` | List of Jenkins init scripts | `[]` | +| `controller.initConfigMap` | Pre-existing init scripts | Not set | + +#### Jenkins Global Security + +| Parameter | Description | Default | +| --------------------------------- | ---------------------------------------- | ----------------------------------------- | +| `controller.adminSecret` | Create secret for admin user | `true` | +| `controller.disableRememberMe` | Disable use of remember me | `false` | +| `controller.enableRawHtmlMarkupFormatter` | Enable HTML parsing using | false | +| `controller.markupFormatter` | Yaml of the markup formatter to use | `plainText` | +| `controller.disabledAgentProtocols` | Disabled agent protocols | `JNLP-connect JNLP2-connect` | +| `controller.csrf.defaultCrumbIssuer.enabled` | Enable the default CSRF Crumb issuer | `true` | +| `controller.csrf.defaultCrumbIssuer.proxyCompatability` | Enable proxy compatibility | `true` | + +#### Jenkins Global Settings + +| Parameter | Description | Default | +| --------------------------------- | ------------------------------------ | ----------------------------------------- | +| `controller.numExecutors` | Set Number of executors | 0 | +| `controller.executorMode` | Set executor mode of the Jenkins node. Possible values are: NORMAL or EXCLUSIVE | NORMAL | +| `controller.customJenkinsLabels` | Append Jenkins labels to the controller | `[]` | +| `controller.jenkinsHome` | Custom Jenkins home path | `/var/jenkins_home` | +| `controller.jenkinsRef` | Custom Jenkins reference path | `/usr/share/jenkins/ref` | +| `controller.jenkinsAdminEmail` | Email address for the administrator of the Jenkins instance | Not set | +| `controller.jenkinsUrl` | Set Jenkins URL if you are not using the ingress definitions provided by the chart | Not set | +| `controller.jenkinsUrlProtocol` | Set protocol for Jenkins URL | Set to `https` if `controller.ingress.tls`, `http` otherwise | +| `controller.jenkinsUriPrefix` | Root Uri Jenkins will be served on | Not set | + +#### Jenkins In-Process Script Approval + +| Parameter | Description | Default | +| --------------------------------- | ------------------------------------ | ----------------------------------------- | +| `controller.scriptApproval` | List of groovy functions to approve | `[]` | + +#### Jenkins Plugins + +| Parameter | Description | Default | +| --------------------------------- | ------------------------------------ | ----------------------------------------- | +| `controller.installPlugins` | List of Jenkins plugins to install. If you don't want to install plugins set it to `false` | `kubernetes:1.31.3 workflow-aggregator:2.6 git:4.10.2 configuration-as-code:1414.v878271fc496f` | +| `controller.additionalPlugins` | List of Jenkins plugins to install in addition to those listed in controller.installPlugins | `[]` | +| `controller.initializeOnce` | Initialize only on first install. Ensures plugins do not get updated inadvertently. Requires `persistence.enabled` to be set to `true`. | `false` | +| `controller.overwritePlugins` | Overwrite installed plugins on start.| `false` | +| `controller.overwritePluginsFromImage` | Keep plugins that are already installed in the controller image.| `true` | +| `controller.installLatestPlugins` | Set to false to download the minimum required version of all dependencies. | `true` | +| `controller.installLatestSpecifiedPlugins` | Set to true to download latest dependencies of any plugin that is requested to have the latest version. | `false` | + +#### Jenkins Agent Listener + +| Parameter | Description | Default | +| -------------------------------------------- | ----------------------------------------------- | ------------ | +| `controller.agentListenerEnabled` | Create Agent listener service | `true` | +| `controller.agentListenerPort` | Listening port for agents | `50000` | +| `controller.agentListenerHostPort` | Host port to listen for agents | Not set | +| `controller.agentListenerNodePort` | Node port to listen for agents | Not set | +| `controller.agentListenerServiceType` | Defines how to expose the agentListener service | `ClusterIP` | +| `controller.agentListenerServiceAnnotations` | Annotations for the agentListener service | `{}` | +| `controller.agentListenerLoadBalancerIP` | Static IP for the agentListener LoadBalancer | Not set | +| `controller.agentListenerExternalTrafficPolicy` | [Traffic Policy](https://kubernetes.io/docs/concepts/services-networking/service/#traffic-policies) of for the agentListener service | Not set | +| `controller.agentListenerLoadBalancerSourceRanges` | Allowed inbound IP for the agentListener service | `0.0.0.0/0` | + +#### Kubernetes StatefulSet & Service + +| Parameter | Description | Default | +| --------------------------------- | ------------------------------------ | ----------------------------------------- | +| `controller.image` | Controller image name | `jenkins/jenkins` | +| `controller.tagLabel` | Controller image tag label | `jdk11` | +| `controller.tag` | Controller image tag override | Not set | +| `controller.imagePullPolicy` | Controller image pull policy | `Always` | +| `controller.imagePullSecretName` | Controller image pull secret | Not set | +| `controller.resources` | Resources allocation (Requests and Limits) | `{requests: {cpu: 50m, memory: 256Mi}, limits: {cpu: 2000m, memory: 4096Mi}}`| +| `controller.initContainerResources` | Resources allocation (Requests and Limits) for Init Container | Not set | +| `controller.initContainerEnvFrom` | Environment variable sources for Init Container | Not set | +| `controller.initContainerEnv` | Environment variables for Init Container | Not set | +| `controller.containerEnvFrom` | Environment variable sources for Jenkins Container | Not set | +| `controller.containerEnv` | Environment variables for Jenkins Container | Not set | +| `controller.usePodSecurityContext` | Enable pod security context (must be `true` if `runAsUser`, `fsGroup`, or `podSecurityContextOverride` are set) | `true` | +| `controller.runAsUser` | Deprecated in favor of `controller.podSecurityContextOverride`. uid that jenkins runs with. | `1000` | +| `controller.fsGroup` | Deprecated in favor of `controller.podSecurityContextOverride`. uid that will be used for persistent volume. | `1000` | +| `controller.podSecurityContextOverride` | Completely overwrites the contents of the pod security context, ignoring the values provided for `runAsUser`, and `fsGroup`. | Not set | +| `controller.containerSecurityContext` | Allow to control securityContext for the jenkins container. | `{runAsUser: 1000, runAsGroup: 1000, readOnlyRootFilesystem: true, allowPrivilegeEscalation: false}` | +| `controller.hostAliases` | Aliases for IPs in `/etc/hosts` | `[]` | +| `controller.serviceAnnotations` | Service annotations | `{}` | +| `controller.serviceType` | k8s service type | `ClusterIP` | +| `controller.clusterIP` | k8s service clusterIP | Not set | +| `controller.servicePort` | k8s service port | `8080` | +| `controller.targetPort` | k8s target port | `8080` | +| `controller.nodePort` | k8s node port | Not set | +| `controller.jmxPort` | Open a port, for JMX stats | Not set | +| `controller.extraPorts` | Open extra ports, for other uses | `[]` | +| `controller.loadBalancerSourceRanges` | Allowed inbound IP addresses | `0.0.0.0/0` | +| `controller.loadBalancerIP` | Optional fixed external IP | Not set | +| `controller.statefulSetLabels` | Custom StatefulSet labels | Not set | +| `controller.serviceLabels` | Custom Service labels | Not set | +| `controller.podLabels` | Custom Pod labels (an object with `label-key: label-value` pairs) | Not set | +| `controller.nodeSelector` | Node labels for pod assignment | `{}` | +| `controller.affinity` | Affinity settings | `{}` | +| `controller.schedulerName` | Kubernetes scheduler name | Not set | +| `controller.terminationGracePeriodSeconds` | Set TerminationGracePeriodSeconds | Not set | +| `controller.terminationMessagePath` | Set the termination message path | Not set | +| `controller.terminationMessagePolicy` | Set the termination message policy | Not set | +| `controller.tolerations` | Toleration labels for pod assignment | `[]` | +| `controller.podAnnotations` | Annotations for controller pod | `{}` | +| `controller.statefulSetAnnotations` | Annotations for controller StatefulSet | `{}` | +| `controller.updateStrategy` | Update strategy for StatefulSet | `{}` | +| `controller.lifecycle` | Lifecycle specification for controller-container | Not set | +| `controller.priorityClassName` | The name of a `priorityClass` to apply to the controller pod | Not set | +| `controller.admin.existingSecret` | The name of an existing secret containing the admin credentials. | `""`| +| `controller.admin.userKey` | The key in the existing admin secret containing the username. | `jenkins-admin-user` | +| `controller.admin.passwordKey` | The key in the existing admin secret containing the password. | `jenkins-admin-password` | +| `controller.customInitContainers` | Custom init-container specification in raw-yaml format | Not set | +| `controller.sidecars.other` | Configures additional sidecar container(s) for Jenkins controller | `[]` | + +#### Kubernetes Pod Disruption Budget + +| Parameter | Description | Default | +| --------------------------------- | ------------------------------------ | ----------------------------------------- | +| `controller.podDisruptionBudget.enabled` | Enable [Kubernetes Pod Disruption Budget](https://kubernetes.io/docs/tasks/run-application/configure-pdb/) configuration from `controller.podDisruptionBudget` (see below) | `false` | +| `controller.podDisruptionBudget.apiVersion` | Policy API version | `policy/v1beta1` | +| `controller.podDisruptionBudget.maxUnavailable` | Number of pods that can be unavailable. Either an absolute number or a percentage. | Not set | + +#### Kubernetes Health Probes + +| Parameter | Description | Default | +| --------------------------------- | ------------------------------------ | ----------------------------------------- | +| `controller.healthProbes` | Enable [Kubernetes Probes](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes) configuration from `controller.probes` (see below) | `true` | +| `controller.probes.livenessProbe.timeoutSeconds` | Set the timeout for the liveness probe in seconds | `5` | +| `controller.probes.livenessProbe.periodSeconds` | Set the time interval (in seconds) between two liveness probes executions | `10` | +| `controller.probes.livenessProbe.failureThreshold` | Set the failure threshold for the liveness probe | `5` | +| `controller.probes.livenessProbe.initialDelaySeconds` | Set the initial delay for the liveness probe | Not set | +| `controller.probes.livenessProbe.httpGet.port` | Set the Pod's HTTP port to use for the liveness probe | `http` | +| `controller.probes.livenessProbe.httpGet.path` | Set the HTTP's path for the liveness probe | `/login'` (or `${controller.jenkinsUriPrefix}/login` if `controller.jenkinsUriPrefix` is defined) | +| `controller.probes.readinessProbe.timeoutSeconds` | Set the timeout for the readiness probe in seconds | `5` | +| `controller.probes.readinessProbe.periodSeconds` | Set the time interval (in seconds) between two readiness probes executions | `10` | +| `controller.probes.readinessProbe.failureThreshold` | Set the failure threshold for the readiness probe | `3` | +| `controller.probes.readinessProbe.initialDelaySeconds` | Set the initial delay for the readiness probe | Not set | +| `controller.probes.readinessProbe.httpGet.port` | Set the Pod's HTTP port to use for the readiness probe | `http` | +| `controller.probes.readinessProbe.httpGet.path` | Set the HTTP's path for the readiness probe | `/login'` (or `${controller.jenkinsUriPrefix}/login` if `controller.jenkinsUriPrefix` is defined) | +| `controller.probes.startupProbe.timeoutSeconds` | Set the timeout for the startup probe in seconds | `5` | +| `controller.probes.startupProbe.periodSeconds` | Set the time interval (in seconds) between two startup probes executions | `10` | +| `controller.probes.startupProbe.failureThreshold` | Set the failure threshold for the startup probe | `12` | +| `controller.probes.startupProbe.initialDelaySeconds` | Set the initial delay for the startup probe | Not set | +| `controller.probes.startupProbe.httpGet.port` | Set the Pod's HTTP port to use for the startup probe | `http` | +| `controller.probes.startupProbe.httpGet.path` | Set the HTTP's path for the startup probe | `/login'` (or `${controller.jenkinsUriPrefix}/login` if `controller.jenkinsUriPrefix` is defined) | + +#### Kubernetes Ingress + +| Parameter | Description | Default | +| --------------------------------- | ------------------------------------ | ----------------------------------------- | +| `controller.ingress.enabled` | Enables ingress | `false` | +| `controller.ingress.apiVersion` | Ingress API version | `extensions/v1beta1` | +| `controller.ingress.hostName` | Ingress host name | Not set | +| `controller.ingress.resourceRootUrl` | Hostname to serve assets from | Not set | +| `controller.ingress.annotations` | Ingress annotations | `{}` | +| `controller.ingress.labels` | Ingress labels | `{}` | +| `controller.ingress.path` | Ingress path | Not set | +| `controller.ingress.paths` | Override for the default Ingress paths | `[]` | +| `controller.ingress.tls` | Ingress TLS configuration | `[]` | + +#### GKE BackendConfig + +| Parameter | Description | Default | +| --------------------------------- | ------------------------------------ | ----------------------------------------- | +| `controller.backendconfig.enabled` | Enables backendconfig | `false` | +| `controller.backendconfig.apiVersion` | backendconfig API version | `extensions/v1beta1` | +| `controller.backendconfig.name` | backendconfig name | Not set | +| `controller.backendconfig.annotations` | backendconfig annotations | `{}` | +| `controller.backendconfig.labels` | backendconfig labels | `{}` | +| `controller.backendconfig.spec` | backendconfig spec | `{}` | + +#### OpenShift Route + +| Parameter | Description | Default | +| --------------------------------- | ------------------------------------ | ----------------------------------------- | +| `controller.route.enabled` | Enables openshift route | `false` | +| `controller.route.annotations` | Route annotations | `{}` | +| `controller.route.labels` | Route labels | `{}` | +| `controller.route.path` | Route path | Not set | + +#### Prometheus + +| Parameter | Description | Default | +| --------------------------------- | ------------------------------------ | ----------------------------------------- | +| `controller.prometheus.enabled` | Enables prometheus service monitor | `false` | +| `controller.prometheus.serviceMonitorAdditionalLabels` | Additional labels to add to the service monitor object | `{}` | +| `controller.prometheus.serviceMonitorNamespace` | Custom namespace for serviceMonitor | Not set (same ns where is Jenkins being deployed) | +| `controller.prometheus.scrapeInterval` | How often prometheus should scrape metrics | `60s` | +| `controller.prometheus.scrapeEndpoint` | The endpoint prometheus should get metrics from | `/prometheus` | +| `controller.prometheus.alertingrules` | Array of prometheus alerting rules | `[]` | +| `controller.prometheus.alertingRulesAdditionalLabels` | Additional labels to add to the prometheus rule object | `{}` | +| `controller.prometheus.prometheusRuleNamespace` | Custom namespace for PrometheusRule | `""` (same ns where Jenkins being deployed) | + +#### HTTPS Keystore + +| Parameter | Description | Default | +| --------------------------------- | ------------------------------------ | ----------------------------------------- | +| `controller.httpsKeyStore.enable` | Enables https keystore on jenkins controller | `false` | +| `controller.httpsKeyStore.jenkinsHttpsJksSecretName` | Name of the secret that already has ssl keystore | `` | +| `controller.httpsKeyStore.httpPort` | Http Port that Jenkins should listen on along with https, it also serves liveness and readiness probs port. When https keystore is enabled servicePort and targetPort will be used as https port | `8081` | +| `controller.httpsKeyStore.path` | Path of https keystore file | `/var/jenkins_keystore` | +| `controller.httpsKeyStore.fileName` | Jenkins keystore filename which will appear under controller.httpsKeyStore.path | `keystore.jks` | +| `controller.httpsKeyStore.password` | Jenkins keystore password | `password` | +| `controller.httpsKeyStore.jenkinsKeyStoreBase64Encoded` | Base64 encoded Keystore content. Keystore must be converted to base64 then being pasted here | a self signed cert | + +#### Kubernetes Secret + +| Parameter | Description | Default | +|----------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| ----------------------------------------- | +| `controller.adminUser` | Admin username (and password) created as a secret if adminSecret is true | `admin` | +| `controller.adminPassword` | Admin password (and user) created as a secret if adminSecret is true | Random value | +| `controller.existingSecret` | The name of an existing secret containing keys credentials. | `""`| +| `controller.additionalSecrets` | List of additional secrets to create and mount according to [JCasC docs](https://github.com/jenkinsci/configuration-as-code-plugin/blob/master/docs/features/secrets.adoc#kubernetes-secrets) | `[]` | +| `controller.additionalExistingSecrets` | List of additional existing secrets to mount according to [JCasC docs](https://github.com/jenkinsci/configuration-as-code-plugin/blob/master/docs/features/secrets.adoc#kubernetes-secrets) | `[]` | +| `controller.secretClaims` | List of `SecretClaim` resources to create | `[]` | + +#### Kubernetes NetworkPolicy + +| Parameter | Description | Default | +| --------------------------------- | ------------------------------------ | ----------------------------------------- | +| `networkPolicy.enabled` | Enable creation of NetworkPolicy resources. | `false` | +| `networkPolicy.apiVersion` | NetworkPolicy ApiVersion | `networking.k8s.io/v1` | +| `networkPolicy.internalAgents.allowed` | Allow internal agents (from the same cluster) to connect to controller. Agent pods would be filtered based on PodLabels. | `false` | +| `networkPolicy.internalAgents.podLabels` | A map of labels (keys/values) that agents pods must have to be able to connect to controller. | `{}` | +| `networkPolicy.internalAgents.namespaceLabels` | A map of labels (keys/values) that agents namespaces must have to be able to connect to controller. | `{}` | +| `networkPolicy.externalAgents.ipCIDR` | The IP range from which external agents are allowed to connect to controller. | `` | +| `networkPolicy.externalAgents.except` | A list of IP sub-ranges to be excluded from the whitelisted IP range. | `[]` | + +#### Kubernetes RBAC + +| Parameter | Description | Default | +| --------------------------------- | ------------------------------------ | ----------------------------------------- | +| `rbac.create` | Whether RBAC resources are created | `true` | +| `rbac.readSecrets` | Whether the Jenkins service account should be able to read Kubernetes secrets | `false` | + +#### Kubernetes ServiceAccount - Controller + +| Parameter | Description | Default | +| --------------------------------- | ------------------------------------ | ----------------------------------------- | +| `serviceAccount.name` | name of the ServiceAccount to be used by access-controlled resources | autogenerated | +| `serviceAccount.create` | Configures if a ServiceAccount with this name should be created | `true` | +| `serviceAccount.annotations` | Configures annotation for the ServiceAccount | `{}` | +| `serviceAccount.imagePullSecretName` | Controller ServiceAccount image pull secret | Not set | + +#### Kubernetes ServiceAccount - Agent + +| Parameter | Description | Default | +| --------------------------------- | ------------------------------------ | ----------------------------------------- | +| `serviceAccountAgent.name` | name of the agent ServiceAccount to be used by access-controlled resources | autogenerated | +| `serviceAccountAgent.create` | Configures if an agent ServiceAccount with this name should be created | `false` | +| `serviceAccountAgent.annotations` | Configures annotation for the agent ServiceAccount | `{}` | +| `serviceAccountAgent.imagePullSecretName` | Agent ServiceAccount image pull secret | Not set | + +### Jenkins Agent(s) + +| Parameter | Description | Default | +| -------------------------- | ----------------------------------------------- | ---------------------- | +| `agent.enabled` | Enable Kubernetes plugin jnlp-agent podTemplate | `true` | +| `agent.namespace` | Namespace in which the Kubernetes agents should be launched | Not set | +| `agent.containerCap` | Maximum number of agent | 10 | +| `agent.defaultsProviderTemplate` | The name of the pod template to use for providing default values | Not set | +| `agent.jenkinsUrl` | Overrides the Kubernetes Jenkins URL | Not set | +| `agent.jenkinsTunnel` | Overrides the Kubernetes Jenkins tunnel | Not set | +| `agent.kubernetesConnectTimeout` | The connection timeout in seconds for connections to Kubernetes API. Minimum value is 5. | 5 | +| `agent.kubernetesReadTimeout` | The read timeout in seconds for connections to Kubernetes API. Minimum value is 15. | 15 | +| `agent.maxRequestsPerHostStr` | The maximum concurrent connections to Kubernetes API | 32 | +| `agent.podLabels` | Custom Pod labels (an object with `label-key: label-value` pairs) | Not set | + +#### Pod Configuration + +| Parameter | Description | Default | +| -------------------------- | ----------------------------------------------- | ---------------------- | +| `agent.websocket` | Enables agent communication via websockets | false | +| `agent.podName` | Agent Pod base name | Not set | +| `agent.customJenkinsLabels`| Append Jenkins labels to the agent | `[]` | +| `agent.envVars` | Environment variables for the agent Pod | `[]` | +| `agent.idleMinutes` | Allows the Pod to remain active for reuse | 0 | +| `agent.imagePullSecretName` | Agent image pull secret | Not set | +| `agent.hostNetworking` | Enabled agent to use hostnetwork | false | +| `agent.nodeSelector` | Node labels for pod assignment | `{}` | +| `agent.connectTimeout` | Timeout in seconds for an agent to be online | 100 | +| `agent.volumes` | Additional volumes | `[]` | +| `agent.workspaceVolume` | Workspace volume (defaults to EmptyDir) | `{}` | +| `agent.yamlTemplate` | The raw yaml of a Pod API Object to merge into the agent spec | Not set | +| `agent.yamlMergeStrategy` | Defines how the raw yaml field gets merged with yaml definitions from inherited pod templates | `override` | +| `agent.annotations` | Annotations to apply to the pod | `{}` | +| `agent.additionalContainers` | Add additional containers to the agents. | `[]` | + +#### Side Container Configuration + +| Parameter | Description | Default | +| -------------------------- | ----------------------------------------------- | ---------------------- | +| `agent.sideContainerName` | Side container name in agent | jnlp | +| `agent.image` | Agent image name | `jenkins/inbound-agent`| +| `agent.tag` | Agent image tag | `4.11.2-4` | +| `agent.alwaysPullImage` | Always pull agent container image before build | `false` | +| `agent.privileged` | Agent privileged container | `false` | +| `agent.resources` | Resources allocation (Requests and Limits) | `{requests: {cpu: 512m, memory: 512Mi}, limits: {cpu: 512m, memory: 512Mi}}` | +| `agent.runAsUser` | Configure container user | Not set | +| `agent.runAsGroup` | Configure container group | Not set | +| `agent.command` | Executed command when side container starts | Not set | +| `agent.args` | Arguments passed to executed command | `${computer.jnlpmac} ${computer.name}` | +| `agent.TTYEnabled` | Allocate pseudo tty to the side container | false | +| `agent.workingDir` | Configure working directory for default agent | `/home/jenkins/agent` | + +#### Other + +| Parameter | Description | Default | +| -------------------------- | ----------------------------------------------- | ---------------------- | +| `agent.disableDefaultAgent` | Ignore the default Jenkins Agent configuration | false | +| `agent.podTemplates` | Configures extra pod templates for the default kubernetes cloud | `{}` | +| `additionalAgents` | Configure additional agents which inherit values from `agent` | `{}` | + +### Persistence + +| Parameter | Description | Default | +| --------------------------- | ------------------------------- | --------------- | +| `persistence.enabled` | Enable the use of a Jenkins PVC | `true` | +| `persistence.existingClaim` | Provide the name of a PVC | `nil` | +| `persistence.storageClass` | Storage class for the PVC | `nil` | +| `persistence.annotations` | Annotations for the PVC | `{}` | +| `persistence.labels` | Labels for the PVC | `{}` | +| `persistence.accessMode` | The PVC access mode | `ReadWriteOnce` | +| `persistence.size` | The size of the PVC | `8Gi` | +| `persistence.subPath` | SubPath for jenkins-home mount | `nil` | +| `persistence.volumes` | Additional volumes | `nil` | +| `persistence.mounts` | Additional mounts | `nil` | + +### Backup + +| Parameter | Description | Default | +| ---------------------------------------- | ----------------------------------------------------------------- | --------------------------------- | +| `backup.enabled` | Enable the use of a backup CronJob | `false` | +| `backup.schedule` | Schedule to run jobs | `0 2 * * *` | +| `backup.labels` | Backup pod labels | `{}` | +| `backup.serviceAccount.create` | Specifies whether a ServiceAccount should be created | `true` | +| `backup.serviceAccount.name` | name of the backup ServiceAccount | autogenerated | +| `backup.serviceAccount.annotations` | Backup pod annotations | `{}` | +| `backup.image.repo` | Backup image repository | `maorfr/kube-tasks` | +| `backup.image.tag` | Backup image tag | `0.2.0` | +| `backup.image.imagePullSecretName` | Backup image pull secret | Not set | +| `backup.extraArgs` | Additional arguments for kube-tasks | `[]` | +| `backup.existingSecret` | Environment variables to add to the cronjob container | `{}` | +| `backup.existingSecret.*` | Specify the secret name containing the AWS or GCP credentials | `jenkinsaws` | +| `backup.existingSecret.*.awsaccesskey` | `secretKeyRef.key` used for `AWS_ACCESS_KEY_ID` | `jenkins_aws_access_key` | +| `backup.existingSecret.*.awssecretkey` | `secretKeyRef.key` used for `AWS_SECRET_ACCESS_KEY` | `jenkins_aws_secret_key` | +| `backup.existingSecret.*.azstorageaccount`| `secretKeyRef.key` used for `AZURE_STORAGE_ACCOUNT` | `""` | +| `backup.existingSecret.*.azstoragekey` | `secretKeyRef.key` used for `AZURE_STORAGE_ACCESS_KEY` | `""` | +| `backup.existingSecret.*.gcpcredentials` | Mounts secret as volume and sets `GOOGLE_APPLICATION_CREDENTIALS` | `credentials.json` | +| `backup.env` | Backup environment variables | `[]` | +| `backup.resources` | Backup CPU/Memory resource requests/limits | Memory: `1Gi`, CPU: `1` | +| `backup.destination` | Destination to store backup artifacts | `s3://jenkins-data/backup` | +| `backup.onlyJobs` | Only backup the job folder | `false` | +| `backup.usePodSecurityContext` | Enable backup pod's security context (must be `true` if `runAsUser`, `fsGroup`, or `podSecurityContextOverride` are set) | `true` | +| `backup.runAsUser` | Deprecated in favor of `backup.podSecurityContextOverride`. uid that jenkins runs with. | `1000` | +| `backup.fsGroup` | Deprecated in favor of `backup.podSecurityContextOverride`. uid that will be used for persistent volume. | `1000` | +| `backup.podSecurityContextOverride` | Completely overwrites the contents of the backup pod's security context, ignoring the values provided for `runAsUser`, and `fsGroup`. | Not set | +| `awsSecurityGroupPolicies.enabled` | Enable the creation of SecurityGroupPolicy resources | `false` | +| `awsSecurityGroupPolicies.policies` | Security Group Policy definitions. `awsSecurityGroupPolicies.enabled` must be `true` | Not set | \ No newline at end of file diff --git a/helm/jenkins/ci/default-values.yaml b/helm/jenkins/ci/default-values.yaml new file mode 100644 index 0000000..37c37f4 --- /dev/null +++ b/helm/jenkins/ci/default-values.yaml @@ -0,0 +1,5 @@ +# this file is empty to check if defaults within values.yaml work as expected +controller: + JCasC: + configScripts: + empty: "" diff --git a/helm/jenkins/ci/other-values.yaml b/helm/jenkins/ci/other-values.yaml new file mode 100644 index 0000000..f00e5a7 --- /dev/null +++ b/helm/jenkins/ci/other-values.yaml @@ -0,0 +1,95 @@ +--- +controller: + overwritePluginsFromImage: false + containerSecurityContext: "" + runAsUser: 0 + fsGroup: 1000 + JCasC: + authorizationStrategy: |- + loggedInUsersCanDoAnything: + allowAnonymousRead: true + securityRealm: |- + ldap: + configurations: + - server: ldap.acme.com + rootDN: dc=acme,dc=uk + managerPasswordSecret: ${LDAP_PASSWORD} + groupMembershipStrategy: + fromUserRecord: + attributeName: "memberOf" + additionalPlugins: + - ldap:2.5 + scriptApproval: + - "method groovy.json.JsonSlurperClassic parseText java.lang.String" + - "new groovy.json.JsonSlurperClassic" + + ingress: + enabled: true + +persistence: + enabled: false + +agent: + resources: + limits: + cpu: "1" + memory: "2048Mi" + envVars: + - name: HOME + value: /home/jenkins/agent + - name: PATH + value: /usr/local/bin + nodeSelector: + "app.kubernetes.io/component": "{{ .Values.agent.componentName }}" + yamlTemplate: |- + apiVersion: v1 + kind: Pod + spec: + tolerations: + - key: "app.kubernetes.io/component" + operator: "Equal" + value: "{{ .Values.agent.componentName }}" + effect: "NoSchedule" + additionalAgents: + maven: + podName: maven + customJenkinsLabels: maven + # An example of overriding the jnlp container + # sideContainerName: jnlp + image: jenkins/jnlp-agent-maven + tag: latest + python: + podName: python + customJenkinsLabels: python + sideContainerName: python + image: python + tag: "3" + command: "/bin/sh -c" + args: "cat" + TTYEnabled: true + podTemplates: + python: | + - name: python + label: jenkins-python + containers: + - name: python + image: python:3 + command: "/bin/sh -c" + args: "cat" + ttyEnabled: true + privileged: true + resourceRequestCpu: "400m" + resourceRequestMemory: "512Mi" + resourceLimitCpu: "1" + resourceLimitMemory: "1024Mi" + volumes: + - type: EmptyDir + mountPath: /var/myapp/myemptydir + memory: false +serviceAccount: + annotations: + description: "Used by release {{ .Release.Name }} for role-based access control" +serviceAccountAgent: + create: true + annotations: + description: "Used by release {{ .Release.Name }} for role-based access control" diff --git a/helm/jenkins/ci/with-secrets-values.yaml b/helm/jenkins/ci/with-secrets-values.yaml new file mode 100644 index 0000000..a1b8169 --- /dev/null +++ b/helm/jenkins/ci/with-secrets-values.yaml @@ -0,0 +1,4 @@ +controller: + additionalSecrets: + - name: nameOfSecret + value: secretText diff --git a/helm/jenkins/override_values.yaml b/helm/jenkins/override_values.yaml new file mode 100644 index 0000000..78b277f --- /dev/null +++ b/helm/jenkins/override_values.yaml @@ -0,0 +1,132 @@ +controller: + tag: "2.375.1-jdk11" + numExecutors: 20 + installPlugins: [] + jenkinsUrlProtocol: "https" + serviceType: NodePort + nodePort: 31080 + resources: + requests: + cpu: "500m" + memory: "2Gi" + limits: + cpu: 1 + memory: "4Gi" + jenkinsUrl: "https://jenkins.exem-oss.org/" +agent: + podName: "jenkins-agent" + defaultsProviderTemplate: "jenkins-agent" + websocket: true + workingDir: "/var/jenkins_home" + imagePullSecretName: "dsk-cred" + resources: + requests: + cpu: "500m" + memory: "512Mi" + limits: + cpu: 2 + memory: "2Gi" + podTemplates: + default-jenkins-agent: | + - name: "default-jenkins-agent" + label: "default-jenkins-agent" + containers: + - name: kaniko + image: "gcr.io/kaniko-project/executor:v1.9.0-debug" + command: "/busybox/cat" + ttyEnabled: true + maven-jenkins-agent: | + - name: "maven-jenkins-agent" + label: "maven-jenkins-agent" + containers: + - name: kaniko + image: "gcr.io/kaniko-project/executor:v1.9.0-debug" + command: "/busybox/cat" + ttyEnabled: true + - name: maven + image: "maven:3.8.5" + command: "/bin/sh -c" + args: "cat" + ttyEnabled: true + volumes: + - persistentVolumeClaim: + claimName: jenkins + mountPath: "/root/.m2/repository" + ui-jenkins-agent: | + - name: "ui-jenkins-agent" + label: "ui-jenkins-agent" + containers: + - name: kaniko + image: "gcr.io/kaniko-project/executor:v1.9.0-debug" + command: "/busybox/cat" + ttyEnabled: true + - name: node + image: "datasaker/node:16" + command: "/bin/sh -c" + args: "cat" + ttyEnabled: true + - name: node18 + image: "datasaker/node:18-pnpm" + command: "/bin/sh -c" + args: "cat" + ttyEnabled: true + go-jenkins-agent: | + - name: "go-jenkins-agent" + label: "go-jenkins-agent" + containers: + - name: kaniko + image: "gcr.io/kaniko-project/executor:v1.9.0-debug" + command: "/busybox/cat" + ttyEnabled: true + - name: go-builder + image: "datasaker/golang:1.21" + command: "/bin/sh -c" + args: "cat" + ttyEnabled: true + - name: podman + image: "datasaker/podman:latest" + command: "/bin/sh -c" + args: "cat" + alwaysPullImage: true + ttyEnabled: true + privileged: true + volumes: + - emptyDirVolume: + mountPath: "/tmp" + - persistentVolumeClaim: + claimName: jenkins + mountPath: "/go" + host-jenkins-agent: | + - name: "host-jenkins-agent" + label: "host-jenkins-agent" + containers: + - name: go-builder + image: "datasaker/golang:1.19.1" + command: "/bin/sh -c" + args: "cat" + ttyEnabled: true + - name: ubuntu-22-04 + image: "datasaker/dsk-host-ubuntu-22.04:latest" + command: "/bin/sh -c" + args: "cat" + ttyEnabled: true + - name: ubuntu-18-04 + image: "datasaker/dsk-host-ubuntu-18.04:latest" + command: "/bin/sh -c" + args: "cat" + ttyEnabled: true + - name: centos-7 + image: "datasaker/dsk-host-centos-7:latest" + command: "/bin/sh -c" + args: "cat" + ttyEnabled: true + volumes: + - emptyDirVolume: + mountPath: "/tmp" + - persistentVolumeClaim: + claimName: jenkins + mountPath: "/go" +persistence: + storageClass: "nfs-provisioner-mgmt-nas" + accessMode: "ReadWriteMany" + size: "200Gi" \ No newline at end of file diff --git a/helm/jenkins/templates/NOTES.txt b/helm/jenkins/templates/NOTES.txt new file mode 100644 index 0000000..0d2df0b --- /dev/null +++ b/helm/jenkins/templates/NOTES.txt @@ -0,0 +1,68 @@ +{{- $prefix := .Values.controller.jenkinsUriPrefix | default "" -}} +{{- $url := "" -}} +1. Get your '{{ .Values.controller.adminUser }}' user password by running: + kubectl exec --namespace {{ template "jenkins.namespace" . }} -it svc/{{ template "jenkins.fullname" . }} -c jenkins -- /bin/cat /run/secrets/additional/chart-admin-password && echo +{{- if .Values.controller.ingress.hostName -}} +{{- if .Values.controller.ingress.tls -}} +{{- $url = print "https://" .Values.controller.ingress.hostName $prefix -}} +{{- else -}} +{{- $url = print "http://" .Values.controller.ingress.hostName $prefix -}} +{{- end }} +2. Visit {{ $url }} +{{- else }} +2. Get the Jenkins URL to visit by running these commands in the same shell: +{{- if contains "NodePort" .Values.controller.serviceType }} + export NODE_PORT=$(kubectl get --namespace {{ template "jenkins.namespace" . }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "jenkins.fullname" . }}) + export NODE_IP=$(kubectl get nodes --namespace {{ template "jenkins.namespace" . }} -o jsonpath="{.items[0].status.addresses[0].address}") +{{- if .Values.controller.httpsKeyStore.enable -}} +{{- $url = print "https://$NODE_IP:$NODE_PORT" $prefix -}} +{{- else -}} +{{- $url = print "http://$NODE_IP:$NODE_PORT" $prefix -}} +{{- end }} + echo {{ $url }} + +{{- else if contains "LoadBalancer" .Values.controller.serviceType }} + NOTE: It may take a few minutes for the LoadBalancer IP to be available. + You can watch the status of by running 'kubectl get svc --namespace {{ template "jenkins.namespace" . }} -w {{ template "jenkins.fullname" . }}' + export SERVICE_IP=$(kubectl get svc --namespace {{ template "jenkins.namespace" . }} {{ template "jenkins.fullname" . }} --template "{{ "{{ range (index .status.loadBalancer.ingress 0) }}{{ . }}{{ end }}" }}") +{{- if .Values.controller.httpsKeyStore.enable -}} +{{- $url = print "https://$SERVICE_IP:" .Values.controller.servicePort $prefix -}} +{{- else -}} +{{- $url = print "http://$SERVICE_IP:" .Values.controller.servicePort $prefix -}} +{{- end }} + echo {{ $url }} + +{{- else if contains "ClusterIP" .Values.controller.serviceType -}} +{{- if .Values.controller.httpsKeyStore.enable -}} +{{- $url = print "https://127.0.0.1:" .Values.controller.servicePort $prefix -}} +{{- else -}} +{{- $url = print "http://127.0.0.1:" .Values.controller.servicePort $prefix -}} +{{- end }} + echo {{ $url }} + kubectl --namespace {{ template "jenkins.namespace" . }} port-forward svc/{{template "jenkins.fullname" . }} {{ .Values.controller.servicePort }}:{{ .Values.controller.servicePort }} +{{- end }} +{{- end }} + +3. Login with the password from step 1 and the username: {{ .Values.controller.adminUser }} +4. Configure security realm and authorization strategy +5. Use Jenkins Configuration as Code by specifying configScripts in your values.yaml file, see documentation: {{ $url }}/configuration-as-code and examples: https://github.com/jenkinsci/configuration-as-code-plugin/tree/master/demos + +For more information on running Jenkins on Kubernetes, visit: +https://cloud.google.com/solutions/jenkins-on-container-engine + +For more information about Jenkins Configuration as Code, visit: +https://jenkins.io/projects/jcasc/ + +{{ if (eq .Values.controller.image "jenkins/jenkins") }} +NOTE: Consider using a custom image with pre-installed plugins +{{- else if .Values.controller.installPlugins }} +NOTE: Consider disabling `installPlugins` if your image already contains plugins. +{{- end }} + +{{- if .Values.persistence.enabled }} +{{- else }} +################################################################################# +###### WARNING: Persistence is disabled!!! You will lose your data when ##### +###### the Jenkins pod is terminated. ##### +################################################################################# +{{- end }} diff --git a/helm/jenkins/templates/_helpers.tpl b/helm/jenkins/templates/_helpers.tpl new file mode 100644 index 0000000..617b4e0 --- /dev/null +++ b/helm/jenkins/templates/_helpers.tpl @@ -0,0 +1,448 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "jenkins.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Expand the label of the chart. +*/}} +{{- define "jenkins.label" -}} +{{- printf "%s-%s" (include "jenkins.name" .) .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + + +{{/* +Allow the release namespace to be overridden for multi-namespace deployments in combined charts. +*/}} +{{- define "jenkins.namespace" -}} + {{- if .Values.namespaceOverride -}} + {{- .Values.namespaceOverride -}} + {{- else -}} + {{- .Release.Namespace -}} + {{- end -}} +{{- end -}} + +{{- define "jenkins.agent.namespace" -}} + {{- if .Values.agent.namespace -}} + {{- tpl .Values.agent.namespace . -}} + {{- else -}} + {{- if .Values.namespaceOverride -}} + {{- .Values.namespaceOverride -}} + {{- else -}} + {{- .Release.Namespace -}} + {{- end -}} + {{- end -}} +{{- end -}} + + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "jenkins.fullname" -}} +{{- if .Values.fullnameOverride -}} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Returns the admin password +https://github.com/helm/charts/issues/5167#issuecomment-619137759 +*/}} +{{- define "jenkins.password" -}} + {{ if .Values.controller.adminPassword -}} + {{- .Values.controller.adminPassword | b64enc | quote }} + {{- else -}} + {{- $secret := (lookup "v1" "Secret" .Release.Namespace (include "jenkins.fullname" .)).data -}} + {{- if $secret -}} + {{/* + Reusing current password since secret exists + */}} + {{- index $secret ( .Values.controller.admin.passwordKey | default "jenkins-admin-password" ) -}} + {{- else -}} + {{/* + Generate new password + */}} + {{- randAlphaNum 22 | b64enc | quote }} + {{- end -}} + {{- end -}} +{{- end -}} + +{{/* +Returns the Jenkins URL +*/}} +{{- define "jenkins.url" -}} +{{- if .Values.controller.jenkinsUrl }} + {{- .Values.controller.jenkinsUrl }} +{{- else }} + {{- if .Values.controller.ingress.hostName }} + {{- if .Values.controller.ingress.tls }} + {{- default "https" .Values.controller.jenkinsUrlProtocol }}://{{ .Values.controller.ingress.hostName }}{{ default "" .Values.controller.jenkinsUriPrefix }} + {{- else }} + {{- default "http" .Values.controller.jenkinsUrlProtocol }}://{{ .Values.controller.ingress.hostName }}{{ default "" .Values.controller.jenkinsUriPrefix }} + {{- end }} + {{- else }} + {{- default "http" .Values.controller.jenkinsUrlProtocol }}://{{ template "jenkins.fullname" . }}:{{.Values.controller.servicePort}}{{ default "" .Values.controller.jenkinsUriPrefix }} + {{- end}} +{{- end}} +{{- end -}} + +{{/* +Returns configuration as code default config +*/}} +{{- define "jenkins.casc.defaults" -}} +jenkins: + {{- $configScripts := toYaml .Values.controller.JCasC.configScripts }} + {{- if and (.Values.controller.JCasC.authorizationStrategy) (not (contains "authorizationStrategy:" $configScripts)) }} + authorizationStrategy: + {{- tpl .Values.controller.JCasC.authorizationStrategy . | nindent 4 }} + {{- end }} + {{- if and (.Values.controller.JCasC.securityRealm) (not (contains "securityRealm:" $configScripts)) }} + securityRealm: + {{- tpl .Values.controller.JCasC.securityRealm . | nindent 4 }} + {{- end }} + disableRememberMe: {{ .Values.controller.disableRememberMe }} + {{- if .Values.controller.legacyRemotingSecurityEnabled }} + remotingSecurity: + enabled: true + {{- end }} + mode: {{ .Values.controller.executorMode }} + numExecutors: {{ .Values.controller.numExecutors }} + {{- if not (kindIs "invalid" .Values.controller.customJenkinsLabels) }} + labelString: "{{ join " " .Values.controller.customJenkinsLabels }}" + {{- end }} + {{- if .Values.controller.projectNamingStrategy }} + {{- if kindIs "string" .Values.controller.projectNamingStrategy }} + projectNamingStrategy: "{{ .Values.controller.projectNamingStrategy }}" + {{- else }} + projectNamingStrategy: + {{- toYaml .Values.controller.projectNamingStrategy | nindent 4 }} + {{- end }} + {{- end }} + markupFormatter: + {{- if .Values.controller.enableRawHtmlMarkupFormatter }} + rawHtml: + disableSyntaxHighlighting: true + {{- else }} + {{- toYaml .Values.controller.markupFormatter | nindent 4 }} + {{- end }} + clouds: + - kubernetes: + containerCapStr: "{{ .Values.agent.containerCap }}" + defaultsProviderTemplate: "{{ .Values.agent.defaultsProviderTemplate }}" + connectTimeout: "{{ .Values.agent.kubernetesConnectTimeout }}" + readTimeout: "{{ .Values.agent.kubernetesReadTimeout }}" + {{- if .Values.agent.jenkinsUrl }} + jenkinsUrl: "{{ tpl .Values.agent.jenkinsUrl . }}" + {{- else }} + jenkinsUrl: "http://{{ template "jenkins.fullname" . }}.{{ template "jenkins.namespace" . }}.svc.{{.Values.clusterZone}}:{{.Values.controller.servicePort}}{{ default "" .Values.controller.jenkinsUriPrefix }}" + {{- end }} + {{- if not .Values.agent.websocket }} + {{- if .Values.agent.jenkinsTunnel }} + jenkinsTunnel: "{{ tpl .Values.agent.jenkinsTunnel . }}" + {{- else }} + jenkinsTunnel: "{{ template "jenkins.fullname" . }}-agent.{{ template "jenkins.namespace" . }}.svc.{{.Values.clusterZone}}:{{ .Values.controller.agentListenerPort }}" + {{- end }} + {{- else }} + webSocket: true + {{- end }} + maxRequestsPerHostStr: {{ .Values.agent.maxRequestsPerHostStr | quote }} + name: "{{ .Values.controller.cloudName }}" + namespace: "{{ template "jenkins.agent.namespace" . }}" + serverUrl: "https://kubernetes.default" + {{- if .Values.agent.enabled }} + podLabels: + - key: "jenkins/{{ .Release.Name }}-{{ .Values.agent.componentName }}" + value: "true" + {{- range $key, $val := .Values.agent.podLabels }} + - key: {{ $key | quote }} + value: {{ $val | quote }} + {{- end }} + templates: + {{- if not .Values.agent.disableDefaultAgent }} + {{- include "jenkins.casc.podTemplate" . | nindent 8 }} + {{- end }} + {{- if .Values.additionalAgents }} + {{- /* save .Values.agent */}} + {{- $agent := .Values.agent }} + {{- range $name, $additionalAgent := .Values.additionalAgents }} + {{- $additionalContainersEmpty := and (hasKey $additionalAgent "additionalContainers") (empty $additionalAgent.additionalContainers) }} + {{- /* merge original .Values.agent into additional agent to ensure it at least has the default values */}} + {{- $additionalAgent := merge $additionalAgent $agent }} + {{- /* clear list of additional containers in case it is configured empty for this agent (merge might have overwritten that) */}} + {{- if $additionalContainersEmpty }} + {{- $_ := set $additionalAgent "additionalContainers" list }} + {{- end }} + {{- /* set .Values.agent to $additionalAgent */}} + {{- $_ := set $.Values "agent" $additionalAgent }} + {{- include "jenkins.casc.podTemplate" $ | nindent 8 }} + {{- end }} + {{- /* restore .Values.agent */}} + {{- $_ := set .Values "agent" $agent }} + {{- end }} + {{- if .Values.agent.podTemplates }} + {{- range $key, $val := .Values.agent.podTemplates }} + {{- tpl $val $ | nindent 8 }} + {{- end }} + {{- end }} + {{- end }} + {{- if .Values.controller.csrf.defaultCrumbIssuer.enabled }} + crumbIssuer: + standard: + excludeClientIPFromCrumb: {{ if .Values.controller.csrf.defaultCrumbIssuer.proxyCompatability }}true{{ else }}false{{- end }} + {{- end }} +{{- include "jenkins.casc.security" . }} +{{- if .Values.controller.scriptApproval }} + scriptApproval: + approvedSignatures: +{{- range $key, $val := .Values.controller.scriptApproval }} + - "{{ $val }}" +{{- end }} +{{- end }} +unclassified: + location: + adminAddress: {{ default "" .Values.controller.jenkinsAdminEmail }} + url: {{ template "jenkins.url" . }} +{{- end -}} + +{{/* +Returns a name template to be used for jcasc configmaps, using +suffix passed in at call as index 0 +*/}} +{{- define "jenkins.casc.configName" -}} +{{- $name := index . 0 -}} +{{- $root := index . 1 -}} +"{{- include "jenkins.fullname" $root -}}-jenkins-{{ $name }}" +{{- end -}} + +{{/* +Returns kubernetes pod template configuration as code +*/}} +{{- define "jenkins.casc.podTemplate" -}} +- name: "{{ .Values.agent.podName }}" + namespace: "{{ template "jenkins.agent.namespace" . }}" +{{- if .Values.agent.annotations }} + annotations: + {{- range $key, $value := .Values.agent.annotations }} + - key: {{ $key }} + value: {{ $value | quote }} + {{- end }} +{{- end }} + id: {{ sha256sum (toYaml .Values.agent) }} + containers: + - name: "{{ .Values.agent.sideContainerName }}" + alwaysPullImage: {{ .Values.agent.alwaysPullImage }} + args: "{{ .Values.agent.args | replace "$" "^$" }}" + command: {{ .Values.agent.command }} + envVars: + - envVar: + key: "JENKINS_URL" + {{- if .Values.agent.jenkinsUrl }} + value: {{ tpl .Values.agent.jenkinsUrl . }} + {{- else }} + value: "http://{{ template "jenkins.fullname" . }}.{{ template "jenkins.namespace" . }}.svc.{{.Values.clusterZone}}:{{.Values.controller.servicePort}}{{ default "/" .Values.controller.jenkinsUriPrefix }}" + {{- end }} + image: "{{ .Values.agent.image }}:{{ .Values.agent.tag }}" + privileged: "{{- if .Values.agent.privileged }}true{{- else }}false{{- end }}" + resourceLimitCpu: {{.Values.agent.resources.limits.cpu}} + resourceLimitMemory: {{.Values.agent.resources.limits.memory}} + resourceRequestCpu: {{.Values.agent.resources.requests.cpu}} + resourceRequestMemory: {{.Values.agent.resources.requests.memory}} + runAsUser: {{ .Values.agent.runAsUser }} + runAsGroup: {{ .Values.agent.runAsGroup }} + ttyEnabled: {{ .Values.agent.TTYEnabled }} + workingDir: {{ .Values.agent.workingDir }} +{{- range $additionalContainers := .Values.agent.additionalContainers }} + - name: "{{ $additionalContainers.sideContainerName }}" + alwaysPullImage: {{ $additionalContainers.alwaysPullImage | default $.Values.agent.alwaysPullImage }} + args: "{{ $additionalContainers.args | replace "$" "^$" }}" + command: {{ $additionalContainers.command }} + envVars: + - envVar: + key: "JENKINS_URL" + {{- if $additionalContainers.jenkinsUrl }} + value: {{ tpl ($additionalContainers.jenkinsUrl) . }} + {{- else }} + value: "http://{{ template "jenkins.fullname" $ }}.{{ template "jenkins.namespace" $ }}.svc.{{ $.Values.clusterZone }}:{{ $.Values.controller.servicePort }}{{ default "/" $.Values.controller.jenkinsUriPrefix }}" + {{- end }} + image: "{{ $additionalContainers.image }}:{{ $additionalContainers.tag }}" + privileged: "{{- if $additionalContainers.privileged }}true{{- else }}false{{- end }}" + resourceLimitCpu: {{ if $additionalContainers.resources }}{{ $additionalContainers.resources.limits.cpu }}{{ else }}{{ $.Values.agent.resources.limits.cpu }}{{ end }} + resourceLimitMemory: {{ if $additionalContainers.resources }}{{ $additionalContainers.resources.limits.memory }}{{ else }}{{ $.Values.agent.resources.limits.memory }}{{ end }} + resourceRequestCpu: {{ if $additionalContainers.resources }}{{ $additionalContainers.resources.requests.cpu }}{{ else }}{{ $.Values.agent.resources.requests.cpu }}{{ end }} + resourceRequestMemory: {{ if $additionalContainers.resources }}{{ $additionalContainers.resources.requests.memory }}{{ else }}{{ $.Values.agent.resources.requests.memory }}{{ end }} + runAsUser: {{ $additionalContainers.runAsUser | default $.Values.agent.runAsUser }} + runAsGroup: {{ $additionalContainers.runAsGroup | default $.Values.agent.runAsGroup }} + ttyEnabled: {{ $additionalContainers.TTYEnabled | default $.Values.agent.TTYEnabled }} + workingDir: {{ $additionalContainers.workingDir | default $.Values.agent.workingDir }} +{{- end }} +{{- if or .Values.agent.envVars .Values.agent.secretEnvVars }} + envVars: + {{- range $index, $var := .Values.agent.envVars }} + - envVar: + key: {{ $var.name }} + value: {{ tpl $var.value $ }} + {{- end }} + {{- range $index, $var := .Values.agent.secretEnvVars }} + - secretEnvVar: + key: {{ $var.key }} + secretName: {{ $var.secretName }} + secretKey: {{ $var.secretKey }} + optional: {{ $var.optional | default false }} + {{- end }} +{{- end }} + idleMinutes: {{ .Values.agent.idleMinutes }} + instanceCap: 2147483647 + {{- if .Values.agent.hostNetworking }} + hostNetwork: {{ .Values.agent.hostNetworking }} + {{- end }} + {{- if .Values.agent.imagePullSecretName }} + imagePullSecrets: + - name: {{ .Values.agent.imagePullSecretName }} + {{- end }} + label: "{{ .Release.Name }}-{{ .Values.agent.componentName }} {{ .Values.agent.customJenkinsLabels | join " " }}" +{{- if .Values.agent.nodeSelector }} + nodeSelector: + {{- $local := dict "first" true }} + {{- range $key, $value := .Values.agent.nodeSelector }} + {{- if $local.first }} {{ else }},{{ end }} + {{- $key }}={{ tpl $value $ }} + {{- $_ := set $local "first" false }} + {{- end }} +{{- end }} + nodeUsageMode: {{ quote .Values.agent.nodeUsageMode }} + podRetention: {{ .Values.agent.podRetention }} + showRawYaml: {{ .Values.agent.showRawYaml }} + serviceAccount: "{{ include "jenkins.serviceAccountAgentName" . }}" + slaveConnectTimeoutStr: "{{ .Values.agent.connectTimeout }}" +{{- if .Values.agent.volumes }} + volumes: + {{- range $index, $volume := .Values.agent.volumes }} + -{{- if (eq $volume.type "ConfigMap") }} configMapVolume: + {{- else if (eq $volume.type "EmptyDir") }} emptyDirVolume: + {{- else if (eq $volume.type "HostPath") }} hostPathVolume: + {{- else if (eq $volume.type "Nfs") }} nfsVolume: + {{- else if (eq $volume.type "PVC") }} persistentVolumeClaim: + {{- else if (eq $volume.type "Secret") }} secretVolume: + {{- else }} {{ $volume.type }}: + {{- end }} + {{- range $key, $value := $volume }} + {{- if not (eq $key "type") }} + {{ $key }}: {{ if kindIs "string" $value }}{{ tpl $value $ | quote }}{{ else }}{{ $value }}{{ end }} + {{- end }} + {{- end }} + {{- end }} +{{- end }} +{{- if .Values.agent.workspaceVolume }} + workspaceVolume: + {{- if (eq .Values.agent.workspaceVolume.type "DynamicPVC") }} + dynamicPVC: + {{- else if (eq .Values.agent.workspaceVolume.type "EmptyDir") }} + emptyDirWorkspaceVolume: + {{- else if (eq .Values.agent.workspaceVolume.type "HostPath") }} + hostPathWorkspaceVolume: + {{- else if (eq .Values.agent.workspaceVolume.type "Nfs") }} + nfsWorkspaceVolume: + {{- else if (eq .Values.agent.workspaceVolume.type "PVC") }} + persistentVolumeClaimWorkspaceVolume: + {{- else }} + {{ .Values.agent.workspaceVolume.type }}: + {{- end }} + {{- range $key, $value := .Values.agent.workspaceVolume }} + {{- if not (eq $key "type") }} + {{ $key }}: {{ if kindIs "string" $value }}{{ tpl $value $ | quote }}{{ else }}{{ $value }}{{ end }} + {{- end }} + {{- end }} +{{- end }} +{{- if .Values.agent.yamlTemplate }} + yaml: |- + {{- tpl (trim .Values.agent.yamlTemplate) . | nindent 4 }} +{{- end }} + yamlMergeStrategy: {{ .Values.agent.yamlMergeStrategy }} +{{- end -}} + +{{- define "jenkins.kubernetes-version" -}} + {{- if .Values.controller.installPlugins -}} + {{- range .Values.controller.installPlugins -}} + {{ if hasPrefix "kubernetes:" . }} + {{- $split := splitList ":" . }} + {{- printf "%s" (index $split 1 ) -}} + {{- end -}} + {{- end -}} + {{- end -}} +{{- end -}} + +{{- define "jenkins.casc.security" }} +security: +{{- with .Values.controller.JCasC }} +{{- if .security }} + {{- .security | toYaml | nindent 2 }} +{{- end }} +{{- end }} +{{- end -}} + +{{/* +Create the name of the service account to use +*/}} +{{- define "jenkins.serviceAccountName" -}} +{{- if .Values.serviceAccount.create -}} + {{ default (include "jenkins.fullname" .) .Values.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +Create the name of the service account for Jenkins agents to use +*/}} +{{- define "jenkins.serviceAccountAgentName" -}} +{{- if .Values.serviceAccountAgent.create -}} + {{ default (printf "%s-%s" (include "jenkins.fullname" .) "agent") .Values.serviceAccountAgent.name }} +{{- else -}} + {{ default "default" .Values.serviceAccountAgent.name }} +{{- end -}} +{{- end -}} + +{{/* +Create the name of the service account for Jenkins backup to use +*/}} +{{- define "backup.serviceAccountBackupName" -}} +{{- if .Values.backup.serviceAccount.create -}} + {{ default (printf "%s-%s" (include "jenkins.fullname" .) "backup") .Values.backup.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.backup.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +Create a full tag name for controller image +*/}} +{{- define "controller.tag" -}} +{{- if .Values.controller.tagLabel -}} + {{- default (printf "%s-%s" .Chart.AppVersion .Values.controller.tagLabel) .Values.controller.tag -}} +{{- else -}} + {{- default .Chart.AppVersion .Values.controller.tag -}} +{{- end -}} +{{- end -}} + +{{/* +Create the HTTP port for interacting with the controller +*/}} +{{- define "controller.httpPort" -}} +{{- if .Values.controller.httpsKeyStore.enable -}} + {{- .Values.controller.httpsKeyStore.httpPort -}} +{{- else -}} + {{- .Values.controller.targetPort -}} +{{- end -}} +{{- end -}} diff --git a/helm/jenkins/templates/config-init-scripts.yaml b/helm/jenkins/templates/config-init-scripts.yaml new file mode 100644 index 0000000..7dd253c --- /dev/null +++ b/helm/jenkins/templates/config-init-scripts.yaml @@ -0,0 +1,18 @@ +{{- if .Values.controller.initScripts -}} + +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "jenkins.fullname" . }}-init-scripts + namespace: {{ template "jenkins.namespace" . }} + labels: + "app.kubernetes.io/name": '{{ template "jenkins.name" .}}' + "app.kubernetes.io/managed-by": "{{ .Release.Service }}" + "app.kubernetes.io/instance": "{{ .Release.Name }}" + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" +data: +{{- range $key, $val := .Values.controller.initScripts }} + init{{ $key }}.groovy: |- +{{ tpl $val $ | indent 4 }} +{{- end }} +{{- end }} diff --git a/helm/jenkins/templates/config.yaml b/helm/jenkins/templates/config.yaml new file mode 100644 index 0000000..b94c79f --- /dev/null +++ b/helm/jenkins/templates/config.yaml @@ -0,0 +1,86 @@ +{{- $jenkinsHome := .Values.controller.jenkinsHome -}} + +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "jenkins.fullname" . }} + namespace: {{ template "jenkins.namespace" . }} + labels: + "app.kubernetes.io/name": '{{ template "jenkins.name" .}}' + "app.kubernetes.io/managed-by": "{{ .Release.Service }}" + "app.kubernetes.io/instance": "{{ .Release.Name }}" + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" +data: + apply_config.sh: |- + set -e +{{- if .Values.controller.initializeOnce }} + if [ -f {{ .Values.controller.jenkinsHome }}/initialization-completed ]; then + echo "controller was previously initialized, refusing to re-initialize" + exit 0 + fi +{{- end }} + echo "disable Setup Wizard" + # Prevent Setup Wizard when JCasC is enabled + echo $JENKINS_VERSION > {{ .Values.controller.jenkinsHome }}/jenkins.install.UpgradeWizard.state + echo $JENKINS_VERSION > {{ .Values.controller.jenkinsHome }}/jenkins.install.InstallUtil.lastExecVersion +{{- if .Values.controller.overwritePlugins }} + echo "remove all plugins from shared volume" + # remove all plugins from shared volume + rm -rf {{ .Values.controller.jenkinsHome }}/plugins/* +{{- end }} +{{- if .Values.controller.installPlugins }} + echo "download plugins" + # Install missing plugins + cp /var/jenkins_config/plugins.txt {{ .Values.controller.jenkinsHome }}; + rm -rf {{ .Values.controller.jenkinsRef }}/plugins/*.lock + version () { echo "$@" | awk -F. '{ printf("%d%03d%03d%03d\n", $1,$2,$3,$4); }'; } + if [ -f "{{ .Values.controller.jenkinsWar }}" ] && [ -n "$(command -v jenkins-plugin-cli)" 2>/dev/null ] && [ $(version $(jenkins-plugin-cli --version)) -ge $(version "2.1.1") ]; then + jenkins-plugin-cli --verbose --war "{{ .Values.controller.jenkinsWar }}" --plugin-file "{{ .Values.controller.jenkinsHome }}/plugins.txt" --latest {{ .Values.controller.installLatestPlugins }}{{- if .Values.controller.installLatestSpecifiedPlugins }} --latest-specified{{- end }}; + else + /usr/local/bin/install-plugins.sh `echo $(cat {{ .Values.controller.jenkinsHome }}/plugins.txt)`; + fi + echo "copy plugins to shared volume" + # Copy plugins to shared volume + yes n | cp -i {{ .Values.controller.jenkinsRef }}/plugins/* /var/jenkins_plugins/; +{{- end }} + {{- if not .Values.controller.sidecars.configAutoReload.enabled }} + echo "copy configuration as code files" + mkdir -p {{ .Values.controller.jenkinsHome }}/casc_configs; + rm -rf {{ .Values.controller.jenkinsHome }}/casc_configs/* + {{- if or .Values.controller.JCasC.defaultConfig .Values.controller.JCasC.configScripts }} + cp -v /var/jenkins_config/*.yaml {{ .Values.controller.jenkinsHome }}/casc_configs + {{- end }} + {{- end }} + echo "finished initialization" +{{- if .Values.controller.initializeOnce }} + touch {{ .Values.controller.jenkinsHome }}/initialization-completed +{{- end }} + {{- if not .Values.controller.sidecars.configAutoReload.enabled }} +# Only add config to this script if we aren't auto-reloading otherwise the pod will restart upon each config change: +{{- if .Values.controller.JCasC.defaultConfig }} + jcasc-default-config.yaml: |- + {{- include "jenkins.casc.defaults" . |nindent 4}} +{{- end }} +{{- range $key, $val := .Values.controller.JCasC.configScripts }} + {{ $key }}.yaml: |- +{{ tpl $val $| indent 4 }} +{{- end }} +{{- end }} + plugins.txt: |- +{{- if .Values.controller.installPlugins }} + {{- range $installPlugin := .Values.controller.installPlugins }} + {{- $installPlugin | nindent 4 }} + {{- end }} + {{- range $addlPlugin := .Values.controller.additionalPlugins }} + {{- /* duplicate plugin check */}} + {{- range $installPlugin := $.Values.controller.installPlugins }} + {{- if eq (splitList ":" $addlPlugin | first) (splitList ":" $installPlugin | first) }} + {{- $message := print "[PLUGIN CONFLICT] controller.additionalPlugins contains '" $addlPlugin "'" }} + {{- $message := print $message " but controller.installPlugins already contains '" $installPlugin "'." }} + {{- $message := print $message " Override controller.installPlugins to use '" $addlPlugin "' plugin." }} + {{- fail $message }} + {{- end }} + {{- end }} + {{- $addlPlugin | nindent 4 }} + {{- end }} +{{- end }} diff --git a/helm/jenkins/templates/deprecation.yaml b/helm/jenkins/templates/deprecation.yaml new file mode 100644 index 0000000..43a798d --- /dev/null +++ b/helm/jenkins/templates/deprecation.yaml @@ -0,0 +1,115 @@ +{{- if .Values.checkDeprecation }} + {{- if .Values.master }} + {{ fail "`master` does no longer exist. It has been renamed to `controller`" }} + {{- end }} + + {{- if .Values.controller.imageTag }} + {{ fail "`controller.imageTag` does no longer exist. Please use `controller.tag` instead" }} + {{- end }} + + {{- if .Values.controller.slaveListenerPort }} + {{ fail "`controller.slaveListenerPort` does no longer exist. It has been renamed to `controller.agentListenerPort`" }} + {{- end }} + + {{- if .Values.controller.slaveHostPort }} + {{ fail "`controller.slaveHostPort` does no longer exist. It has been renamed to `controller.agentListenerHostPort`" }} + {{- end }} + + {{- if .Values.controller.slaveKubernetesNamespace }} + {{ fail "`controller.slaveKubernetesNamespace` does no longer exist. It has been renamed to `agent.namespace`" }} + {{- end }} + + {{- if .Values.controller.slaveDefaultsProviderTemplate }} + {{ fail "`controller.slaveDefaultsProviderTemplate` does no longer exist. It has been renamed to `agent.defaultsProviderTemplate`" }} + {{- end }} + + {{- if .Values.controller.useSecurity }} + {{ fail "`controller.useSecurity` does no longer exist. It has been renamed to `controller.adminSecret`" }} + {{- end }} + + {{- if .Values.controller.slaveJenkinsUrl }} + {{ fail "`controller.slaveJenkinsUrl` does no longer exist. It has been renamed to `agent.jenkinsUrl`" }} + {{- end }} + + {{- if .Values.controller.slaveJenkinsTunnel }} + {{ fail "`controller.slaveJenkinsTunnel` does no longer exist. It has been renamed to `agent.jenkinsTunnel`" }} + {{- end }} + + {{- if .Values.controller.slaveConnectTimeout }} + {{ fail "`controller.slaveConnectTimeout` does no longer exist. It has been renamed to `agent.kubernetesConnectTimeout`" }} + {{- end }} + + {{- if .Values.controller.slaveReadTimeout }} + {{ fail "`controller.slaveReadTimeout` does no longer exist. It has been renamed to `agent.kubernetesReadTimeout`" }} + {{- end }} + + {{- if .Values.controller.slaveListenerServiceType }} + {{ fail "`controller.slaveListenerServiceType` does no longer exist. It has been renamed to `controller.agentListenerServiceType`" }} + {{- end }} + + {{- if .Values.controller.slaveListenerLoadBalancerIP }} + {{ fail "`controller.slaveListenerLoadBalancerIP` does no longer exist. It has been renamed to `controller.agentListenerLoadBalancerIP`" }} + {{- end }} + + {{- if .Values.controller.slaveListenerServiceAnnotations }} + {{ fail "`controller.slaveListenerServiceAnnotations` does no longer exist. It has been renamed to `controller.agentListenerServiceAnnotations`" }} + {{- end }} + + {{- if .Values.agent.slaveConnectTimeout }} + {{ fail "`agent.slaveConnectTimeout` does no longer exist. It has been renamed to `agent.connectTimeout`" }} + {{- end }} + + {{- if .Values.NetworkPolicy }} + + {{- if .Values.NetworkPolicy.Enabled }} + {{ fail "`NetworkPolicy.Enabled` does no longer exist. It has been renamed to `networkPolicy.enabled`" }} + {{- end }} + + {{- if .Values.NetworkPolicy.ApiVersion }} + {{ fail "`NetworkPolicy.ApiVersion` does no longer exist. It has been renamed to `networkPolicy.apiVersion`" }} + {{- end }} + + {{ fail "NetworkPolicy.* values have been renamed, please check the documentation" }} + {{- end }} + + + {{- if .Values.rbac.install }} + {{ fail "`rbac.install` does no longer exist. It has been renamed to `rbac.create` and is enabled by default!" }} + {{- end }} + + {{- if .Values.rbac.serviceAccountName }} + {{ fail "`rbac.serviceAccountName` does no longer exist. It has been renamed to `serviceAccount.name`" }} + {{- end }} + + {{- if .Values.rbac.serviceAccountAnnotations }} + {{ fail "`rbac.serviceAccountAnnotations` does no longer exist. It has been renamed to `serviceAccount.annotations`" }} + {{- end }} + + {{- if .Values.rbac.roleRef }} + {{ fail "`rbac.roleRef` does no longer exist. RBAC roles are now generated, please check the documentation" }} + {{- end }} + + {{- if .Values.rbac.roleKind }} + {{ fail "`rbac.roleKind` does no longer exist. RBAC roles are now generated, please check the documentation" }} + {{- end }} + + {{- if .Values.rbac.roleBindingKind }} + {{ fail "`rbac.roleBindingKind` does no longer exist. RBAC roles are now generated, please check the documentation" }} + {{- end }} + + {{- if .Values.controller.JCasC.pluginVersion }} + {{ fail "controller.JCasC.pluginVersion has been deprecated, please use controller.installPlugins instead" }} + {{- end }} + + {{- if .Values.controller.deploymentLabels }} + {{ fail "`controller.deploymentLabels` does no longer exist. It has been renamed to `controller.statefulSetLabels`" }} + {{- end }} + + {{- if .Values.controller.deploymentAnnotations }} + {{ fail "`controller.deploymentAnnotations` does no longer exist. It has been renamed to `controller.statefulSetAnnotations`" }} + {{- end }} + + {{- if .Values.controller.rollingUpdate }} + {{ fail "`controller.rollingUpdate` does no longer exist. It is no longer relevant, since a StatefulSet is used for the Jenkins controller" }} + {{- end }} +{{- end }} diff --git a/helm/jenkins/templates/home-pvc.yaml b/helm/jenkins/templates/home-pvc.yaml new file mode 100644 index 0000000..af17f7c --- /dev/null +++ b/helm/jenkins/templates/home-pvc.yaml @@ -0,0 +1,37 @@ +{{- if not (contains "jenkins-home" (quote .Values.persistence.volumes)) }} +{{- if and .Values.persistence.enabled (not .Values.persistence.existingClaim) -}} +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: +{{- if .Values.persistence.annotations }} + annotations: +{{ toYaml .Values.persistence.annotations | indent 4 }} +{{- end }} + name: {{ template "jenkins.fullname" . }} + namespace: {{ template "jenkins.namespace" . }} + labels: + "app.kubernetes.io/name": '{{ template "jenkins.name" .}}' + {{- if .Values.renderHelmLabels }} + "helm.sh/chart": "{{ template "jenkins.label" .}}" + {{- end }} + "app.kubernetes.io/managed-by": "{{ .Release.Service }}" + "app.kubernetes.io/instance": "{{ .Release.Name }}" + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" +{{- if .Values.persistence.labels }} +{{ toYaml .Values.persistence.labels | indent 4 }} +{{- end }} +spec: + accessModes: + - {{ .Values.persistence.accessMode | quote }} + resources: + requests: + storage: {{ .Values.persistence.size | quote }} +{{- if .Values.persistence.storageClass }} +{{- if (eq "-" .Values.persistence.storageClass) }} + storageClassName: "" +{{- else }} + storageClassName: "{{ .Values.persistence.storageClass }}" +{{- end }} +{{- end }} +{{- end }} +{{- end }} diff --git a/helm/jenkins/templates/jcasc-config.yaml b/helm/jenkins/templates/jcasc-config.yaml new file mode 100644 index 0000000..684c985 --- /dev/null +++ b/helm/jenkins/templates/jcasc-config.yaml @@ -0,0 +1,45 @@ +{{- $root := . }} +{{- if .Values.controller.sidecars.configAutoReload.enabled }} +{{- range $key, $val := .Values.controller.JCasC.configScripts }} +{{- if $val }} +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "jenkins.casc.configName" (list (printf "config-%s" $key) $ )}} + namespace: {{ template "jenkins.namespace" $root }} + labels: + "app.kubernetes.io/name": {{ template "jenkins.name" $root}} + {{- if $root.Values.renderHelmLabels }} + "helm.sh/chart": "{{ $root.Chart.Name }}-{{ $root.Chart.Version }}" + {{- end }} + "app.kubernetes.io/managed-by": "{{ $.Release.Service }}" + "app.kubernetes.io/instance": "{{ $.Release.Name }}" + "app.kubernetes.io/component": "{{ $.Values.controller.componentName }}" + {{ template "jenkins.fullname" $root }}-jenkins-config: "true" +data: + {{ $key }}.yaml: |- +{{ tpl $val $| indent 4 }} +{{- end }} +{{- end }} +{{- if .Values.controller.JCasC.defaultConfig }} +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "jenkins.casc.configName" (list "jcasc-config" $ )}} + namespace: {{ template "jenkins.namespace" $root }} + labels: + "app.kubernetes.io/name": {{ template "jenkins.name" $root}} + {{- if .Values.renderHelmLabels }} + "helm.sh/chart": "{{ $root.Chart.Name }}-{{ $root.Chart.Version }}" + {{- end }} + "app.kubernetes.io/managed-by": "{{ $.Release.Service }}" + "app.kubernetes.io/instance": "{{ $.Release.Name }}" + "app.kubernetes.io/component": "{{ $.Values.controller.componentName }}" + {{ template "jenkins.fullname" $root }}-jenkins-config: "true" +data: + jcasc-default-config.yaml: |- + {{- include "jenkins.casc.defaults" . |nindent 4 }} +{{- end}} +{{- end }} diff --git a/helm/jenkins/templates/jenkins-agent-svc.yaml b/helm/jenkins/templates/jenkins-agent-svc.yaml new file mode 100644 index 0000000..4440b91 --- /dev/null +++ b/helm/jenkins/templates/jenkins-agent-svc.yaml @@ -0,0 +1,43 @@ +{{- if .Values.controller.agentListenerEnabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "jenkins.fullname" . }}-agent + namespace: {{ template "jenkins.namespace" . }} + labels: + "app.kubernetes.io/name": '{{ template "jenkins.name" .}}' + {{- if .Values.renderHelmLabels }} + "helm.sh/chart": "{{ template "jenkins.label" .}}" + {{- end }} + "app.kubernetes.io/managed-by": "{{ .Release.Service }}" + "app.kubernetes.io/instance": "{{ .Release.Name }}" + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" + {{- if .Values.controller.agentListenerServiceAnnotations }} + annotations: + {{- toYaml .Values.controller.agentListenerServiceAnnotations | nindent 4 }} + {{- end }} +spec: + {{- if .Values.controller.agentListenerExternalTrafficPolicy }} + externalTrafficPolicy: {{.Values.controller.agentListenerExternalTrafficPolicy}} + {{- end }} + ports: + - port: {{ .Values.controller.agentListenerPort }} + targetPort: {{ .Values.controller.agentListenerPort }} + {{- if (and (eq .Values.controller.agentListenerServiceType "NodePort") (not (empty .Values.controller.agentListenerNodePort))) }} + nodePort: {{ .Values.controller.agentListenerNodePort }} + {{- end }} + name: agent-listener + selector: + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" + "app.kubernetes.io/instance": "{{ .Release.Name }}" + type: {{ .Values.controller.agentListenerServiceType }} + {{if eq .Values.controller.agentListenerServiceType "LoadBalancer"}} +{{- if .Values.controller.agentListenerLoadBalancerSourceRanges }} + loadBalancerSourceRanges: +{{ toYaml .Values.controller.agentListenerLoadBalancerSourceRanges | indent 4 }} +{{- end }} + {{- end }} + {{- if and (eq .Values.controller.agentListenerServiceType "LoadBalancer") (.Values.controller.agentListenerLoadBalancerIP) }} + loadBalancerIP: {{ .Values.controller.agentListenerLoadBalancerIP }} + {{- end }} + {{- end }} diff --git a/helm/jenkins/templates/jenkins-aws-security-group-policies.yaml b/helm/jenkins/templates/jenkins-aws-security-group-policies.yaml new file mode 100644 index 0000000..2f6e7a1 --- /dev/null +++ b/helm/jenkins/templates/jenkins-aws-security-group-policies.yaml @@ -0,0 +1,16 @@ +{{- if .Values.awsSecurityGroupPolicies.enabled -}} +{{- range .Values.awsSecurityGroupPolicies.policies -}} +apiVersion: vpcresources.k8s.aws/v1beta1 +kind: SecurityGroupPolicy +metadata: + name: {{ .name }} + namespace: {{ template "jenkins.namespace" $ }} +spec: + podSelector: + {{- toYaml .podSelector | nindent 6}} + securityGroups: + groupIds: + {{- toYaml .securityGroupIds | nindent 6}} +--- +{{- end -}} +{{- end -}} diff --git a/helm/jenkins/templates/jenkins-backup-cronjob.yaml b/helm/jenkins/templates/jenkins-backup-cronjob.yaml new file mode 100644 index 0000000..6c155ff --- /dev/null +++ b/helm/jenkins/templates/jenkins-backup-cronjob.yaml @@ -0,0 +1,168 @@ +{{- if .Values.backup.enabled }} +apiVersion: batch/v1beta1 +kind: CronJob +metadata: + name: {{ template "jenkins.fullname" . }}-backup + namespace: {{ template "jenkins.namespace" . }} + labels: + "app.kubernetes.io/name": '{{ template "jenkins.name" .}}' + {{- if .Values.renderHelmLabels }} + "helm.sh/chart": "{{ template "jenkins.label" .}}" + {{- end }} + "app.kubernetes.io/managed-by": "{{ .Release.Service }}" + "app.kubernetes.io/instance": "{{ .Release.Name }}" + "app.kubernetes.io/component": "{{ .Values.backup.componentName }}" +spec: + schedule: {{ .Values.backup.schedule | quote }} + concurrencyPolicy: Forbid + startingDeadlineSeconds: 120 + jobTemplate: + spec: +{{- if .Values.backup.activeDeadlineSeconds }} + activeDeadlineSeconds: {{ .Values.backup.activeDeadlineSeconds }} +{{- end }} + template: + metadata: + {{- if .Values.backup.labels }} + labels: + {{- toYaml .Values.backup.labels | trim | nindent 12 }} + {{- end }} + {{- if .Values.backup.annotations }} + annotations: + {{- toYaml .Values.backup.annotations | trim | nindent 12 }} + {{- end }} + spec: + restartPolicy: OnFailure + serviceAccountName: {{ include "backup.serviceAccountBackupName" . }} + {{- if .Values.backup.usePodSecurityContext }} + securityContext: + {{- if hasKey .Values.backup "podSecurityContextOverride" }} + {{- tpl (toYaml .Values.backup.podSecurityContextOverride | nindent 12) . }} + {{- else }} + runAsUser: {{ default 0 .Values.backup.runAsUser }} + {{- if and (.Values.backup.runAsUser) (.Values.backup.fsGroup) }} + {{- if not (eq (int .Values.backup.runAsUser) 0) }} + fsGroup: {{ .Values.backup.fsGroup }} + {{- end }} + {{- end }} + {{- if .Values.backup.securityContextCapabilities }} + capabilities: + {{- toYaml .Values.backup.securityContextCapabilities | nindent 12 }} + {{- end }} + {{- end }} + {{- end }} + containers: + - name: jenkins-backup + image: "{{ .Values.backup.image.repository }}:{{ .Values.backup.image.tag }}" + command: ["kube-tasks"] + args: + - simple-backup + - -n + - {{ template "jenkins.namespace" . }} + - -l + - app.kubernetes.io/instance={{ .Release.Name }} + - --container + - jenkins + - --path + {{- if .Values.backup.onlyJobs }} + - {{ .Values.controller.jenkinsHome }}/jobs + {{- else}} + - {{ .Values.controller.jenkinsHome }} + {{- end}} + - --dst + - {{ .Values.backup.destination }} + {{- with .Values.backup.extraArgs }} + {{- toYaml . | nindent 12 }} + {{- end }} + env: + {{- with .Values.backup.env }} + {{- toYaml . | trim | nindent 12 }} + {{- end }} + {{- if .Values.backup.existingSecret }} + {{- range $key,$value := .Values.backup.existingSecret }} + {{- if $value.awsaccesskey }} + - name: AWS_ACCESS_KEY_ID + valueFrom: + secretKeyRef: + name: {{ $key }} + key: {{ $value.awsaccesskey | quote }} + {{- end }} + {{- if $value.awssecretkey }} + - name: AWS_SECRET_ACCESS_KEY + valueFrom: + secretKeyRef: + name: {{ $key }} + key: {{ $value.awssecretkey | quote}} + {{- end }} + {{- if $value.azstorageaccount }} + - name: AZURE_STORAGE_ACCOUNT + valueFrom: + secretKeyRef: + name: {{ $key }} + key: {{ $value.azstorageaccount | quote}} + {{- end }} + {{- if $value.azstoragekey }} + - name: AZURE_STORAGE_ACCESS_KEY + valueFrom: + secretKeyRef: + name: {{ $key }} + key: {{ $value.azstoragekey | quote}} + {{- end }} + {{- if $value.gcpcredentials }} + - name: GOOGLE_APPLICATION_CREDENTIALS + value: "/var/run/secrets/{{ $key }}/{{ $value.gcpcredentials }}" + {{- end }} + {{- end }} + {{- end }} + {{- with .Values.backup.resources }} + resources: + {{- toYaml . | trim | nindent 14 }} + {{- end }} + volumeMounts: + {{- if .Values.backup.existingSecret }} + {{- range $key,$value := .Values.backup.existingSecret }} + {{- if $value.gcpcredentials }} + - mountPath: /var/run/secrets/{{ $key }} + name: {{ $key }} + {{- end }} + {{- end }} + {{- end }} + volumes: + {{- if .Values.backup.existingSecret }} + {{- range $key,$value := .Values.backup.existingSecret }} + {{- if $value.gcpcredentials }} + - name: {{ $key }} + secret: + secretName: {{ $key }} + {{- end }} + {{- end }} + {{- end }} + affinity: + podAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 100 + podAffinityTerm: + topologyKey: "kubernetes.io/hostname" + labelSelector: + matchExpressions: + - key: app + operator: In + values: + - {{ template "jenkins.fullname" . }} + - key: release + operator: In + values: + - {{ .Release.Name }} + {{- with .Values.controller.tolerations }} + tolerations: + {{- toYaml . | nindent 10 }} + {{- end }} + {{- with .Values.controller.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- if .Values.backup.imagePullSecretName }} + imagePullSecrets: + - name: {{ .Values.backup.imagePullSecretName }} + {{- end -}} +{{- end }} diff --git a/helm/jenkins/templates/jenkins-backup-rbac.yaml b/helm/jenkins/templates/jenkins-backup-rbac.yaml new file mode 100644 index 0000000..0f94fa8 --- /dev/null +++ b/helm/jenkins/templates/jenkins-backup-rbac.yaml @@ -0,0 +1,64 @@ +{{- if .Values.backup.enabled }} +{{- if .Values.backup.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "backup.serviceAccountBackupName" . }} + namespace: {{ template "jenkins.namespace" . }} + labels: + "app.kubernetes.io/name": '{{ template "jenkins.name" .}}' + {{- if .Values.renderHelmLabels }} + "helm.sh/chart": "{{ template "jenkins.label" .}}" + {{- end }} + "app.kubernetes.io/managed-by": "{{ .Release.Service }}" + "app.kubernetes.io/instance": "{{ .Release.Name }}" + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" + {{- if .Values.backup.serviceAccount.annotations }} + annotations: + {{- toYaml .Values.backup.serviceAccount.annotations | nindent 4 }} + {{- end }} +{{- end }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ template "jenkins.fullname" . }}-backup + namespace: {{ template "jenkins.namespace" . }} + labels: + "app.kubernetes.io/name": '{{ template "jenkins.name" .}}' + {{- if .Values.renderHelmLabels }} + "helm.sh/chart": "{{ template "jenkins.label" .}}" + {{- end }} + "app.kubernetes.io/managed-by": "{{ .Release.Service }}" + "app.kubernetes.io/instance": "{{ .Release.Name }}" + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" +rules: +- apiGroups: [""] + resources: ["pods", "pods/log"] + verbs: ["get", "list"] +- apiGroups: [""] + resources: ["pods/exec"] + verbs: ["create"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ template "jenkins.fullname" . }}-backup + namespace: {{ template "jenkins.namespace" . }} + labels: + "app.kubernetes.io/name": '{{ template "jenkins.name" .}}' + {{- if .Values.renderHelmLabels }} + "helm.sh/chart": "{{ template "jenkins.label" .}}" + {{- end }} + "app.kubernetes.io/managed-by": "{{ .Release.Service }}" + "app.kubernetes.io/instance": "{{ .Release.Name }}" + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "jenkins.fullname" . }}-backup +subjects: +- kind: ServiceAccount + name: {{ include "backup.serviceAccountBackupName" . }} + namespace: {{ template "jenkins.namespace" . }} +{{- end }} diff --git a/helm/jenkins/templates/jenkins-controller-alerting-rules.yaml b/helm/jenkins/templates/jenkins-controller-alerting-rules.yaml new file mode 100644 index 0000000..3fd8061 --- /dev/null +++ b/helm/jenkins/templates/jenkins-controller-alerting-rules.yaml @@ -0,0 +1,26 @@ +{{- if and .Values.controller.prometheus.enabled .Values.controller.prometheus.alertingrules }} +--- +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: {{ template "jenkins.fullname" . }} +{{- if .Values.controller.prometheus.prometheusRuleNamespace }} + namespace: {{ .Values.controller.prometheus.prometheusRuleNamespace }} +{{- else }} + namespace: {{ template "jenkins.namespace" . }} +{{- end }} + labels: + "app.kubernetes.io/name": '{{ template "jenkins.name" .}}' + {{- if .Values.renderHelmLabels }} + "helm.sh/chart": "{{ template "jenkins.label" .}}" + {{- end }} + "app.kubernetes.io/managed-by": "{{ .Release.Service }}" + "app.kubernetes.io/instance": "{{ .Release.Name }}" + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" + {{- range $key, $val := .Values.controller.prometheus.alertingRulesAdditionalLabels }} + {{ $key }}: {{ $val | quote }} + {{- end}} +spec: + groups: +{{ toYaml .Values.controller.prometheus.alertingrules | indent 2 }} +{{- end }} diff --git a/helm/jenkins/templates/jenkins-controller-backendconfig.yaml b/helm/jenkins/templates/jenkins-controller-backendconfig.yaml new file mode 100644 index 0000000..0e8a566 --- /dev/null +++ b/helm/jenkins/templates/jenkins-controller-backendconfig.yaml @@ -0,0 +1,24 @@ +{{- if .Values.controller.backendconfig.enabled }} +apiVersion: {{ .Values.controller.backendconfig.apiVersion }} +kind: BackendConfig +metadata: + name: {{ .Values.controller.backendconfig.name }} + namespace: {{ template "jenkins.namespace" . }} + labels: + "app.kubernetes.io/name": '{{ template "jenkins.name" .}}' + {{- if .Values.renderHelmLabels }} + "helm.sh/chart": "{{ template "jenkins.label" .}}" + {{- end }} + "app.kubernetes.io/managed-by": "{{ .Release.Service }}" + "app.kubernetes.io/instance": "{{ .Release.Name }}" + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" +{{- if .Values.controller.backendconfig.labels }} +{{ toYaml .Values.controller.backendconfig.labels | indent 4 }} +{{- end }} +{{- if .Values.controller.backendconfig.annotations }} + annotations: +{{ toYaml .Values.controller.backendconfig.annotations | indent 4 }} +{{- end }} +spec: +{{ toYaml .Values.controller.backendconfig.spec | indent 2 }} +{{- end }} diff --git a/helm/jenkins/templates/jenkins-controller-ingress.yaml b/helm/jenkins/templates/jenkins-controller-ingress.yaml new file mode 100644 index 0000000..e7b6c6f --- /dev/null +++ b/helm/jenkins/templates/jenkins-controller-ingress.yaml @@ -0,0 +1,77 @@ +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if .Values.controller.ingress.enabled }} +{{- if semverCompare ">=1.19-0" $kubeTargetVersion -}} +apiVersion: networking.k8s.io/v1 +{{- else if semverCompare ">=1.14-0" $kubeTargetVersion -}} +apiVersion: networking.k8s.io/v1beta1 +{{- else -}} +apiVersion: {{ .Values.controller.ingress.apiVersion }} +{{- end }} +kind: Ingress +metadata: + namespace: {{ template "jenkins.namespace" . }} + labels: + "app.kubernetes.io/name": '{{ template "jenkins.name" .}}' + {{- if .Values.renderHelmLabels }} + "helm.sh/chart": "{{ template "jenkins.label" .}}" + {{- end }} + "app.kubernetes.io/managed-by": "{{ .Release.Service }}" + "app.kubernetes.io/instance": "{{ .Release.Name }}" + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" +{{- if .Values.controller.ingress.labels }} +{{ toYaml .Values.controller.ingress.labels | indent 4 }} +{{- end }} +{{- if .Values.controller.ingress.annotations }} + annotations: +{{ toYaml .Values.controller.ingress.annotations | indent 4 }} +{{- end }} + name: {{ template "jenkins.fullname" . }} +spec: +{{- if .Values.controller.ingress.ingressClassName }} + ingressClassName: {{ .Values.controller.ingress.ingressClassName | quote }} +{{- end }} + rules: + - http: + paths: +{{- if empty (.Values.controller.ingress.paths) }} + - backend: +{{- if semverCompare ">=1.19-0" $kubeTargetVersion }} + service: + name: {{ template "jenkins.fullname" . }} + port: + number: {{ .Values.controller.servicePort }} + pathType: ImplementationSpecific +{{- else }} + serviceName: {{ template "jenkins.fullname" . }} + servicePort: {{ .Values.controller.servicePort }} +{{- end }} +{{- if .Values.controller.ingress.path }} + path: {{ .Values.controller.ingress.path }} +{{- end -}} +{{- else }} +{{ tpl (toYaml .Values.controller.ingress.paths | indent 6) . }} +{{- end -}} +{{- if .Values.controller.ingress.hostName }} + host: {{ .Values.controller.ingress.hostName | quote }} +{{- end }} +{{- if .Values.controller.ingress.resourceRootUrl }} + - http: + paths: + - backend: +{{- if semverCompare ">=1.19-0" $kubeTargetVersion }} + service: + name: {{ template "jenkins.fullname" . }} + port: + number: {{ .Values.controller.servicePort }} + pathType: ImplementationSpecific +{{- else }} + serviceName: {{ template "jenkins.fullname" . }} + servicePort: {{ .Values.controller.servicePort }} +{{- end }} + host: {{ .Values.controller.ingress.resourceRootUrl | quote }} +{{- end }} +{{- if .Values.controller.ingress.tls }} + tls: +{{ toYaml .Values.controller.ingress.tls | indent 4 }} +{{- end -}} +{{- end }} diff --git a/helm/jenkins/templates/jenkins-controller-networkpolicy.yaml b/helm/jenkins/templates/jenkins-controller-networkpolicy.yaml new file mode 100644 index 0000000..91cf6db --- /dev/null +++ b/helm/jenkins/templates/jenkins-controller-networkpolicy.yaml @@ -0,0 +1,76 @@ +{{- if .Values.networkPolicy.enabled }} +kind: NetworkPolicy +apiVersion: {{ .Values.networkPolicy.apiVersion }} +metadata: + name: "{{ .Release.Name }}-{{ .Values.controller.componentName }}" + namespace: {{ template "jenkins.namespace" . }} + labels: + "app.kubernetes.io/name": '{{ template "jenkins.name" .}}' + {{- if .Values.renderHelmLabels }} + "helm.sh/chart": "{{ template "jenkins.label" .}}" + {{- end }} + "app.kubernetes.io/managed-by": "{{ .Release.Service }}" + "app.kubernetes.io/instance": "{{ .Release.Name }}" + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" +spec: + podSelector: + matchLabels: + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" + "app.kubernetes.io/instance": "{{ .Release.Name }}" + ingress: + # Allow web access to the UI + - ports: + - port: {{ .Values.controller.targetPort }} + {{- if .Values.controller.agentListenerEnabled }} + # Allow inbound connections from agents + - from: + {{- if .Values.networkPolicy.internalAgents.allowed }} + - podSelector: + matchLabels: + "jenkins/{{ .Release.Name }}-{{ .Values.agent.componentName }}": "true" + {{- range $k,$v:= .Values.networkPolicy.internalAgents.podLabels }} + {{ $k }}: {{ $v }} + {{- end }} + {{- if .Values.networkPolicy.internalAgents.namespaceLabels }} + namespaceSelector: + matchLabels: + {{- range $k,$v:= .Values.networkPolicy.internalAgents.namespaceLabels }} + {{ $k }}: {{ $v }} + {{- end }} + {{- end }} + {{- end }} + {{- if .Values.networkPolicy.externalAgents }} + - ipBlock: + cidr: {{ required "ipCIDR is required if you wish to allow external agents to connect to Jenkins Controller." .Values.networkPolicy.externalAgents.ipCIDR }} + {{- if .Values.networkPolicy.externalAgents.except }} + except: + {{- range .Values.networkPolicy.externalAgents.except }} + - {{ . }} + {{- end }} + {{- end }} + {{- end }} + ports: + - port: {{ .Values.controller.agentListenerPort }} + {{- end }} +{{- if .Values.agent.enabled }} +--- +kind: NetworkPolicy +apiVersion: {{ .Values.networkPolicy.apiVersion }} +metadata: + name: "{{ .Release.Name }}-{{ .Values.agent.componentName }}" + namespace: {{ template "jenkins.namespace" . }} + labels: + "app.kubernetes.io/name": '{{ template "jenkins.name" .}}' + {{- if .Values.renderHelmLabels }} + "helm.sh/chart": "{{ template "jenkins.label" .}}" + {{- end }} + "app.kubernetes.io/managed-by": "{{ .Release.Service }}" + "app.kubernetes.io/instance": "{{ .Release.Name }}" + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" +spec: + podSelector: + matchLabels: + # DefaultDeny + "jenkins/{{ .Release.Name }}-{{ .Values.agent.componentName }}": "true" +{{- end }} +{{- end }} diff --git a/helm/jenkins/templates/jenkins-controller-pdb.yaml b/helm/jenkins/templates/jenkins-controller-pdb.yaml new file mode 100644 index 0000000..9dc1faf --- /dev/null +++ b/helm/jenkins/templates/jenkins-controller-pdb.yaml @@ -0,0 +1,34 @@ +{{- if .Values.controller.podDisruptionBudget.enabled }} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if semverCompare ">=1.21-0" $kubeTargetVersion -}} +apiVersion: policy/v1 +{{- else if semverCompare ">=1.5-0" $kubeTargetVersion -}} +apiVersion: policy/v1beta1 +{{- else -}} +apiVersion: {{ .Values.controller.podDisruptionBudget.apiVersion }} +{{- end }} +kind: PodDisruptionBudget +metadata: + name: {{ template "jenkins.fullname" . }}-pdb + namespace: {{ template "jenkins.namespace" . }} + labels: + "app.kubernetes.io/name": '{{ template "jenkins.name" .}}' + {{- if .Values.renderHelmLabels }} + "helm.sh/chart": "{{ template "jenkins.label" .}}" + {{- end }} + "app.kubernetes.io/managed-by": "{{ .Release.Service }}" + "app.kubernetes.io/instance": "{{ .Release.Name }}" + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" + {{- if .Values.controller.podDisruptionBudget.labels -}} + {{ toYaml .Values.controller.podDisruptionBudget.labels | nindent 4 }} + {{- end }} + {{- if .Values.controller.podDisruptionBudget.annotations }} + annotations: {{ toYaml .Values.controller.podDisruptionBudget.annotations | nindent 4 }} + {{- end }} +spec: + maxUnavailable: {{ .Values.controller.podDisruptionBudget.maxUnavailable }} + selector: + matchLabels: + "app.kubernetes.io/instance": "{{ .Release.Name }}" + "app.kubernetes.io/name": '{{ template "jenkins.name" .}}' +{{- end }} diff --git a/helm/jenkins/templates/jenkins-controller-podmonitor.yaml b/helm/jenkins/templates/jenkins-controller-podmonitor.yaml new file mode 100644 index 0000000..9a04019 --- /dev/null +++ b/helm/jenkins/templates/jenkins-controller-podmonitor.yaml @@ -0,0 +1,30 @@ +{{- if .Values.controller.googlePodMonitor.enabled }} +apiVersion: monitoring.googleapis.com/v1 +kind: PodMonitoring + +metadata: + name: {{ template "jenkins.fullname" . }} +{{- if .Values.controller.googlePodMonitor.serviceMonitorNamespace }} + namespace: {{ .Values.controller.googlePodMonitor.serviceMonitorNamespace }} +{{- else }} + namespace: {{ template "jenkins.namespace" . }} +{{- end }} + labels: + "app.kubernetes.io/name": '{{ template "jenkins.name" .}}' + {{- if .Values.renderHelmLabels }} + "helm.sh/chart": "{{ template "jenkins.label" .}}" + {{- end }} + "app.kubernetes.io/managed-by": "{{ .Release.Service }}" + "app.kubernetes.io/instance": "{{ .Release.Name }}" + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" + +spec: + endpoints: + - interval: {{ .Values.controller.googlePodMonitor.scrapeInterval }} + port: http + path: {{ .Values.controller.jenkinsUriPrefix }}{{ .Values.controller.googlePodMonitor.scrapeEndpoint }} + selector: + matchLabels: + "app.kubernetes.io/instance": "{{ .Release.Name }}" + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" +{{- end }} diff --git a/helm/jenkins/templates/jenkins-controller-route.yaml b/helm/jenkins/templates/jenkins-controller-route.yaml new file mode 100644 index 0000000..3550380 --- /dev/null +++ b/helm/jenkins/templates/jenkins-controller-route.yaml @@ -0,0 +1,34 @@ +{{- if .Values.controller.route.enabled }} +apiVersion: route.openshift.io/v1 +kind: Route +metadata: + namespace: {{ template "jenkins.namespace" . }} + labels: + app: {{ template "jenkins.fullname" . }} + {{- if .Values.renderHelmLabels }} + "helm.sh/chart": "{{ template "jenkins.label" .}}" + {{- end }} + release: "{{ .Release.Name }}" + heritage: "{{ .Release.Service }}" + component: "{{ .Release.Name }}-{{ .Values.controller.componentName }}" +{{- if .Values.controller.route.labels }} +{{ toYaml .Values.controller.route.labels | indent 4 }} +{{- end }} +{{- if .Values.controller.route.annotations }} + annotations: +{{ toYaml .Values.controller.route.annotations | indent 4 }} +{{- end }} + name: {{ template "jenkins.fullname" . }} +spec: + host: {{ .Values.controller.route.path }} + port: + targetPort: http + tls: + insecureEdgeTerminationPolicy: Redirect + termination: edge + to: + kind: Service + name: {{ template "jenkins.fullname" . }} + weight: 100 + wildcardPolicy: None +{{- end }} diff --git a/helm/jenkins/templates/jenkins-controller-secondary-ingress.yaml b/helm/jenkins/templates/jenkins-controller-secondary-ingress.yaml new file mode 100644 index 0000000..c63e482 --- /dev/null +++ b/helm/jenkins/templates/jenkins-controller-secondary-ingress.yaml @@ -0,0 +1,56 @@ +{{- if .Values.controller.secondaryingress.enabled }} +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- $serviceName := include "jenkins.fullname" . -}} +{{- $servicePort := .Values.controller.servicePort -}} +{{- if semverCompare ">=1.19-0" $kubeTargetVersion -}} +apiVersion: networking.k8s.io/v1 +{{- else if semverCompare ">=1.14-0" $kubeTargetVersion -}} +apiVersion: networking.k8s.io/v1beta1 +{{- else -}} +apiVersion: {{ .Values.controller.secondaryingress.apiVersion }} +{{- end }} +kind: Ingress +metadata: + namespace: {{ template "jenkins.namespace" . }} + labels: + "app.kubernetes.io/name": '{{ template "jenkins.name" .}}' + {{- if .Values.renderHelmLabels }} + "helm.sh/chart": "{{ template "jenkins.label" .}}" + {{- end }} + "app.kubernetes.io/managed-by": "{{ .Release.Service }}" + "app.kubernetes.io/instance": "{{ .Release.Name }}" + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" + {{- if .Values.controller.secondaryingress.labels -}} + {{ toYaml .Values.controller.secondaryingress.labels | nindent 4 }} + {{- end }} + {{- if .Values.controller.secondaryingress.annotations }} + annotations: {{ toYaml .Values.controller.secondaryingress.annotations | nindent 4 }} + {{- end }} + name: {{ template "jenkins.fullname" . }}-secondary +spec: +{{- if .Values.controller.secondaryingress.ingressClassName }} + ingressClassName: {{ .Values.controller.secondaryingress.ingressClassName | quote }} +{{- end }} + rules: + - host: {{ .Values.controller.secondaryingress.hostName }} + http: + paths: + {{- range .Values.controller.secondaryingress.paths }} + - path: {{ . | quote }} + backend: +{{ if semverCompare ">=1.19-0" $kubeTargetVersion }} + service: + name: {{ $serviceName }} + port: + number: {{ $servicePort }} + pathType: ImplementationSpecific +{{ else }} + serviceName: {{ $serviceName }} + servicePort: {{ $servicePort }} +{{ end }} + {{- end}} +{{- if .Values.controller.secondaryingress.tls }} + tls: +{{ toYaml .Values.controller.secondaryingress.tls | indent 4 }} +{{- end -}} +{{- end }} diff --git a/helm/jenkins/templates/jenkins-controller-servicemonitor.yaml b/helm/jenkins/templates/jenkins-controller-servicemonitor.yaml new file mode 100644 index 0000000..f7f4a7b --- /dev/null +++ b/helm/jenkins/templates/jenkins-controller-servicemonitor.yaml @@ -0,0 +1,40 @@ +{{- if and .Values.controller.prometheus.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor + +metadata: + name: {{ template "jenkins.fullname" . }} +{{- if .Values.controller.prometheus.serviceMonitorNamespace }} + namespace: {{ .Values.controller.prometheus.serviceMonitorNamespace }} +{{- else }} + namespace: {{ template "jenkins.namespace" . }} +{{- end }} + labels: + "app.kubernetes.io/name": '{{ template "jenkins.name" .}}' + {{- if .Values.renderHelmLabels }} + "helm.sh/chart": "{{ template "jenkins.label" .}}" + {{- end }} + "app.kubernetes.io/managed-by": "{{ .Release.Service }}" + "app.kubernetes.io/instance": "{{ .Release.Name }}" + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" + {{- range $key, $val := .Values.controller.prometheus.serviceMonitorAdditionalLabels }} + {{ $key }}: {{ $val | quote }} + {{- end}} + +spec: + endpoints: + - interval: {{ .Values.controller.prometheus.scrapeInterval }} + port: http + path: {{ .Values.controller.jenkinsUriPrefix }}{{ .Values.controller.prometheus.scrapeEndpoint }} + {{- if .Values.controller.prometheus.metricRelabelings }} + metricRelabelings: {{ .Values.controller.prometheus.metricRelabelings }} + {{- end }} + jobLabel: {{ template "jenkins.fullname" . }} + namespaceSelector: + matchNames: + - "{{ template "jenkins.namespace" $ }}" + selector: + matchLabels: + "app.kubernetes.io/instance": "{{ .Release.Name }}" + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" +{{- end }} diff --git a/helm/jenkins/templates/jenkins-controller-statefulset.yaml b/helm/jenkins/templates/jenkins-controller-statefulset.yaml new file mode 100644 index 0000000..d0110a6 --- /dev/null +++ b/helm/jenkins/templates/jenkins-controller-statefulset.yaml @@ -0,0 +1,436 @@ +{{- if .Capabilities.APIVersions.Has "apps/v1" }} +apiVersion: apps/v1 +{{- else }} +apiVersion: apps/v1beta1 +{{- end }} +kind: StatefulSet +metadata: + name: {{ template "jenkins.fullname" . }} + namespace: {{ template "jenkins.namespace" . }} + labels: + "app.kubernetes.io/name": '{{ template "jenkins.name" .}}' + {{- if .Values.renderHelmLabels }} + "helm.sh/chart": "{{ template "jenkins.label" .}}" + {{- end }} + "app.kubernetes.io/managed-by": "{{ .Release.Service }}" + "app.kubernetes.io/instance": "{{ .Release.Name }}" + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" + {{- range $key, $val := .Values.controller.statefulSetLabels }} + {{ $key }}: {{ $val | quote }} + {{- end}} + {{- if .Values.controller.statefulSetAnnotations }} + annotations: +{{ toYaml .Values.controller.statefulSetAnnotations | indent 4 }} + {{- end }} +spec: + serviceName: {{ template "jenkins.fullname" . }} + replicas: 1 + selector: + matchLabels: + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" + "app.kubernetes.io/instance": "{{ .Release.Name }}" + {{- if .Values.controller.updateStrategy }} + updateStrategy: +{{ toYaml .Values.controller.updateStrategy | indent 4 }} + {{- end }} + template: + metadata: + labels: + "app.kubernetes.io/name": '{{ template "jenkins.name" .}}' + "app.kubernetes.io/managed-by": "{{ .Release.Service }}" + "app.kubernetes.io/instance": "{{ .Release.Name }}" + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" + {{- range $key, $val := .Values.controller.podLabels }} + {{ $key }}: {{ $val | quote }} + {{- end}} + annotations: + checksum/config: {{ include (print $.Template.BasePath "/config.yaml") . | sha256sum }} + {{- if .Values.controller.podAnnotations }} +{{ tpl (toYaml .Values.controller.podAnnotations | indent 8) . }} + {{- end }} + spec: + {{- if .Values.controller.schedulerName }} + schedulerName: {{ .Values.controller.schedulerName }} + {{- end }} + {{- if .Values.controller.nodeSelector }} + nodeSelector: +{{ toYaml .Values.controller.nodeSelector | indent 8 }} + {{- end }} + {{- if .Values.controller.tolerations }} + tolerations: +{{ toYaml .Values.controller.tolerations | indent 8 }} + {{- end }} + {{- if .Values.controller.affinity }} + affinity: +{{ toYaml .Values.controller.affinity | indent 8 }} + {{- end }} + {{- if quote .Values.controller.terminationGracePeriodSeconds }} + terminationGracePeriodSeconds: {{ .Values.controller.terminationGracePeriodSeconds }} + {{- end }} + {{- if .Values.controller.priorityClassName }} + priorityClassName: {{ .Values.controller.priorityClassName }} + {{- end }} +{{- if .Values.controller.usePodSecurityContext }} + securityContext: + {{- if hasKey .Values.controller "podSecurityContextOverride" }} + {{- tpl (toYaml .Values.controller.podSecurityContextOverride | nindent 8) . -}} + {{- else }} + {{/* The rest of this section should be replaced with the contents of this comment one the runAsUser, fsGroup, and securityContextCapabilities Helm chart values have been removed: + runAsUser: 1000 + fsGroup: 1000 + runAsNonRoot: true + */}} + runAsUser: {{ default 0 .Values.controller.runAsUser }} + {{- if and (.Values.controller.runAsUser) (.Values.controller.fsGroup) }} + {{- if not (eq (int .Values.controller.runAsUser) 0) }} + fsGroup: {{ .Values.controller.fsGroup }} + runAsNonRoot: true + {{- end }} + {{- if .Values.controller.securityContextCapabilities }} + capabilities: + {{- toYaml .Values.controller.securityContextCapabilities | nindent 10 }} + {{- end }} + {{- end }} + {{- end }} +{{- end }} + serviceAccountName: "{{ template "jenkins.serviceAccountName" . }}" +{{- if .Values.controller.hostNetworking }} + hostNetwork: true + dnsPolicy: ClusterFirstWithHostNet +{{- end }} + {{- if .Values.controller.hostAliases }} + hostAliases: + {{- toYaml .Values.controller.hostAliases | nindent 8 }} + {{- end }} + initContainers: +{{- if .Values.controller.customInitContainers }} +{{ tpl (toYaml .Values.controller.customInitContainers) . | indent 8 }} +{{- end }} + - name: "init" + image: "{{ .Values.controller.image }}:{{- include "controller.tag" . -}}" + imagePullPolicy: "{{ .Values.controller.imagePullPolicy }}" + {{- if .Values.controller.containerSecurityContext }} + securityContext: {{- toYaml .Values.controller.containerSecurityContext | nindent 12 }} + {{- end }} + command: [ "sh", "/var/jenkins_config/apply_config.sh" ] + {{- if .Values.controller.initContainerEnvFrom }} + envFrom: +{{ (tpl (toYaml .Values.controller.initContainerEnvFrom) .) | indent 12 }} + {{- end }} + {{- if .Values.controller.initContainerEnv }} + env: +{{ (tpl (toYaml .Values.controller.initContainerEnv) .) | indent 12 }} + {{- end }} + resources: +{{- if .Values.controller.initContainerResources }} +{{ toYaml .Values.controller.initContainerResources | indent 12 }} +{{- else }} +{{ toYaml .Values.controller.resources | indent 12 }} +{{- end }} + volumeMounts: + {{- if .Values.persistence.mounts }} +{{ toYaml .Values.persistence.mounts | indent 12 }} + {{- end }} + - mountPath: {{ .Values.controller.jenkinsHome }} + name: jenkins-home + {{- if .Values.persistence.subPath }} + subPath: {{ .Values.persistence.subPath }} + {{- end }} + - mountPath: /var/jenkins_config + name: jenkins-config + {{- if .Values.controller.installPlugins }} + {{- if .Values.controller.overwritePluginsFromImage }} + - mountPath: {{ .Values.controller.jenkinsRef }}/plugins + name: plugins + {{- end }} + - mountPath: /var/jenkins_plugins + name: plugin-dir + - mountPath: /tmp + name: tmp-volume + {{- end }} + {{- if or .Values.controller.initScripts .Values.controller.initConfigMap }} + - mountPath: {{ .Values.controller.jenkinsHome }}/init.groovy.d + name: init-scripts + {{- end }} + {{- if .Values.controller.httpsKeyStore.enable }} + {{- $httpsJKSDirPath := printf "%s" .Values.controller.httpsKeyStore.path }} + - mountPath: {{ $httpsJKSDirPath }} + name: jenkins-https-keystore + {{- end }} + containers: + - name: jenkins + image: "{{ .Values.controller.image }}:{{- include "controller.tag" . -}}" + imagePullPolicy: "{{ .Values.controller.imagePullPolicy }}" + {{- if .Values.controller.containerSecurityContext }} + securityContext: {{- toYaml .Values.controller.containerSecurityContext | nindent 12 }} + {{- end }} + {{- if .Values.controller.overrideArgs }} + args: [ + {{- range $overrideArg := .Values.controller.overrideArgs }} + "{{- tpl $overrideArg $ }}", + {{- end }} + ] + {{- else if .Values.controller.httpsKeyStore.enable }} + {{- $httpsJKSFilePath := printf "%s/%s" .Values.controller.httpsKeyStore.path .Values.controller.httpsKeyStore.fileName }} + args: [ "--httpPort={{.Values.controller.httpsKeyStore.httpPort}}", "--httpsPort={{.Values.controller.targetPort}}", '--httpsKeyStore={{ $httpsJKSFilePath }}', "--httpsKeyStorePassword=$(JENKINS_HTTPS_KEYSTORE_PASSWORD)" ] + {{- else }} + args: [ "--httpPort={{.Values.controller.targetPort}}"] + {{- end }} + {{- if .Values.controller.lifecycle }} + lifecycle: +{{ toYaml .Values.controller.lifecycle | indent 12 }} + {{- end }} +{{- if .Values.controller.terminationMessagePath }} + terminationMessagePath: {{ .Values.controller.terminationMessagePath }} +{{- end }} +{{- if .Values.controller.terminationMessagePolicy }} + terminationMessagePolicy: {{ .Values.controller.terminationMessagePolicy }} +{{- end }} + {{- if .Values.controller.containerEnvFrom }} + envFrom: +{{ (tpl ( toYaml .Values.controller.containerEnvFrom) .) | indent 12 }} + {{- end }} + env: + {{- if or .Values.controller.additionalSecrets .Values.controller.existingSecret .Values.controller.additionalExistingSecrets .Values.controller.adminSecret }} + - name: SECRETS + value: /run/secrets/additional + {{- end }} + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: JAVA_OPTS + value: >- + {{ if .Values.controller.sidecars.configAutoReload.enabled }} -Dcasc.reload.token=$(POD_NAME) {{ end }}{{ default "" .Values.controller.javaOpts }} + - name: JENKINS_OPTS + value: >- + {{ if .Values.controller.jenkinsUriPrefix }}--prefix={{ .Values.controller.jenkinsUriPrefix }} {{ end }} --webroot=/var/jenkins_cache/war {{ default "" .Values.controller.jenkinsOpts}} + - name: JENKINS_SLAVE_AGENT_PORT + value: "{{ .Values.controller.agentListenerPort }}" + {{- if .Values.controller.httpsKeyStore.enable }} + - name: JENKINS_HTTPS_KEYSTORE_PASSWORD + valueFrom: + secretKeyRef: + name: {{ if .Values.controller.httpsKeyStore.jenkinsHttpsJksSecretName }} {{ .Values.controller.httpsKeyStore.jenkinsHttpsJksSecretName }} {{ else }} {{ template "jenkins.fullname" . }}-https-jks {{ end }} + key: {{ "https-jks-password" | quote }} + {{- end }} + + {{- if .Values.controller.containerEnv }} +{{ (tpl ( toYaml .Values.controller.containerEnv) .) | indent 12 }} + {{- end }} + - name: CASC_JENKINS_CONFIG + value: {{ .Values.controller.sidecars.configAutoReload.folder | default (printf "%s/casc_configs" (.Values.controller.jenkinsRef)) }}{{- if .Values.controller.JCasC.configUrls }},{{ join "," .Values.controller.JCasC.configUrls }}{{- end }} + ports: + {{- if .Values.controller.httpsKeyStore.enable }} + - containerPort: {{.Values.controller.httpsKeyStore.httpPort}} + {{- else }} + - containerPort: {{.Values.controller.targetPort}} + {{- end }} + name: http + - containerPort: {{ .Values.controller.agentListenerPort }} + name: agent-listener + {{- if .Values.controller.agentListenerHostPort }} + hostPort: {{ .Values.controller.agentListenerHostPort }} + {{- end }} + {{- if .Values.controller.jmxPort }} + - containerPort: {{ .Values.controller.jmxPort }} + name: jmx + {{- end }} +{{- range $index, $port := .Values.controller.extraPorts }} + - containerPort: {{ $port.port }} + name: {{ $port.name }} +{{- end }} +{{- if and .Values.controller.healthProbes .Values.controller.probes}} + {{- if semverCompare ">=1.16-0" .Capabilities.KubeVersion.GitVersion }} + startupProbe: +{{ tpl (toYaml .Values.controller.probes.startupProbe | indent 12) .}} + {{- end }} + livenessProbe: +{{ tpl (toYaml .Values.controller.probes.livenessProbe | indent 12) .}} + readinessProbe: +{{ tpl (toYaml .Values.controller.probes.readinessProbe | indent 12) .}} +{{- end }} + resources: +{{ toYaml .Values.controller.resources | indent 12 }} + volumeMounts: +{{- if .Values.persistence.mounts }} +{{ toYaml .Values.persistence.mounts | indent 12 }} +{{- end }} + {{- if .Values.controller.httpsKeyStore.enable }} + {{- $httpsJKSDirPath := printf "%s" .Values.controller.httpsKeyStore.path }} + - mountPath: {{ $httpsJKSDirPath }} + name: jenkins-https-keystore + {{- end }} + - mountPath: {{ .Values.controller.jenkinsHome }} + name: jenkins-home + readOnly: false + {{- if .Values.persistence.subPath }} + subPath: {{ .Values.persistence.subPath }} + {{- end }} + - mountPath: /var/jenkins_config + name: jenkins-config + readOnly: true + {{- if .Values.controller.installPlugins }} + - mountPath: {{ .Values.controller.jenkinsRef }}/plugins/ + name: plugin-dir + readOnly: false + {{- end }} + {{- if or .Values.controller.initScripts .Values.controller.initConfigMap }} + - mountPath: {{ .Values.controller.jenkinsHome }}/init.groovy.d + name: init-scripts + {{- end }} + {{- if .Values.controller.sidecars.configAutoReload.enabled }} + - name: sc-config-volume + mountPath: {{ .Values.controller.sidecars.configAutoReload.folder | default (printf "%s/casc_configs" (.Values.controller.jenkinsRef)) }} + {{- end }} + {{- if or .Values.controller.additionalSecrets .Values.controller.existingSecret .Values.controller.additionalExistingSecrets .Values.controller.adminSecret }} + - name: jenkins-secrets + mountPath: /run/secrets/additional + readOnly: true + {{- end }} + - name: jenkins-cache + mountPath: /var/jenkins_cache + - mountPath: /tmp + name: tmp-volume + +{{- if .Values.controller.sidecars.configAutoReload.enabled }} + - name: config-reload + image: "{{ .Values.controller.sidecars.configAutoReload.image }}" + imagePullPolicy: {{ .Values.controller.sidecars.configAutoReload.imagePullPolicy }} + {{- if .Values.controller.sidecars.configAutoReload.containerSecurityContext }} + securityContext: {{- toYaml .Values.controller.sidecars.configAutoReload.containerSecurityContext | nindent 12 }} + {{- end }} + {{- if .Values.controller.sidecars.configAutoReload.envFrom }} + envFrom: +{{ (tpl (toYaml .Values.controller.sidecars.configAutoReload.envFrom) .) | indent 12 }} + {{- end }} + env: + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: LABEL + value: "{{ template "jenkins.fullname" . }}-jenkins-config" + - name: FOLDER + value: "{{ .Values.controller.sidecars.configAutoReload.folder }}" + - name: NAMESPACE + value: '{{ .Values.controller.sidecars.configAutoReload.searchNamespace | default (include "jenkins.namespace" .) }}' + - name: REQ_URL + value: "http://localhost:{{- include "controller.httpPort" . -}}{{- .Values.controller.jenkinsUriPrefix -}}/reload-configuration-as-code/?casc-reload-token=$(POD_NAME)" + - name: REQ_METHOD + value: "POST" + - name: REQ_RETRY_CONNECT + value: "{{ .Values.controller.sidecars.configAutoReload.reqRetryConnect }}" + {{- if .Values.controller.sidecars.configAutoReload.env }} +{{ (tpl (toYaml .Values.controller.sidecars.configAutoReload.env) .) | indent 12 }} + {{- end }} + resources: +{{ toYaml .Values.controller.sidecars.configAutoReload.resources | indent 12 }} + volumeMounts: + - name: sc-config-volume + mountPath: {{ .Values.controller.sidecars.configAutoReload.folder | quote }} + - name: jenkins-home + mountPath: {{ .Values.controller.jenkinsHome }} + {{- if .Values.persistence.subPath }} + subPath: {{ .Values.persistence.subPath }} + {{- end }} +{{- end}} + + +{{- if .Values.controller.sidecars.other}} +{{ tpl (toYaml .Values.controller.sidecars.other | indent 8) .}} +{{- end }} + + volumes: +{{- if .Values.persistence.volumes }} +{{ tpl (toYaml .Values.persistence.volumes | indent 6) . }} +{{- end }} + {{- if .Values.controller.installPlugins }} + {{- if .Values.controller.overwritePluginsFromImage }} + - name: plugins + emptyDir: {} + {{- end }} + {{- end }} + {{- if and .Values.controller.initScripts .Values.controller.initConfigMap }} + - name: init-scripts + projected: + sources: + - configMap: + name: {{ template "jenkins.fullname" . }}-init-scripts + - configMap: + name: {{ .Values.controller.initConfigMap }} + {{- else if .Values.controller.initConfigMap }} + - name: init-scripts + configMap: + name: {{ .Values.controller.initConfigMap }} + {{- else if .Values.controller.initScripts }} + - name: init-scripts + configMap: + name: {{ template "jenkins.fullname" . }}-init-scripts + {{- end }} + - name: jenkins-config + configMap: + name: {{ template "jenkins.fullname" . }} + {{- if .Values.controller.installPlugins }} + - name: plugin-dir + emptyDir: {} + {{- end }} + {{- if or .Values.controller.additionalSecrets .Values.controller.existingSecret .Values.controller.additionalExistingSecrets .Values.controller.adminSecret }} + - name: jenkins-secrets + projected: + sources: + {{- if .Values.controller.additionalSecrets }} + - secret: + name: {{ template "jenkins.fullname" . }}-additional-secrets + {{- end }} + {{- if .Values.controller.additionalExistingSecrets }} + {{- range $key, $value := .Values.controller.additionalExistingSecrets }} + - secret: + name: {{ tpl $value.name $ }} + items: + - key: {{ tpl $value.keyName $ }} + path: {{ tpl $value.name $ }}-{{ tpl $value.keyName $ }} + {{- end }} + {{- end }} + {{- if .Values.controller.adminSecret }} + - secret: + name: {{ .Values.controller.admin.existingSecret | default (include "jenkins.fullname" .) }} + items: + - key: {{ .Values.controller.admin.userKey | default "jenkins-admin-user" }} + path: chart-admin-username + - key: {{ .Values.controller.admin.passwordKey | default "jenkins-admin-password" }} + path: chart-admin-password + {{- end }} + {{- if .Values.controller.existingSecret }} + - secret: + name: {{ .Values.controller.existingSecret }} + {{- end }} + {{- end }} + - name: jenkins-cache + emptyDir: {} + {{- if not (contains "jenkins-home" (quote .Values.persistence.volumes)) }} + - name: jenkins-home + {{- if .Values.persistence.enabled }} + persistentVolumeClaim: + claimName: {{ .Values.persistence.existingClaim | default (include "jenkins.fullname" .) }} + {{- else }} + emptyDir: {} + {{- end -}} + {{- end }} + - name: sc-config-volume + emptyDir: {} + - name: tmp-volume + emptyDir: {} + {{- if .Values.controller.httpsKeyStore.enable }} + - name: jenkins-https-keystore + secret: + secretName: {{ if .Values.controller.httpsKeyStore.jenkinsHttpsJksSecretName }} {{ .Values.controller.httpsKeyStore.jenkinsHttpsJksSecretName }} {{ else }} {{ template "jenkins.fullname" . }}-https-jks {{ end }} + items: + - key: jenkins-jks-file + path: {{ .Values.controller.httpsKeyStore.fileName }} + {{- end }} + +{{- if .Values.controller.imagePullSecretName }} + imagePullSecrets: + - name: {{ .Values.controller.imagePullSecretName }} +{{- end -}} diff --git a/helm/jenkins/templates/jenkins-controller-svc.yaml b/helm/jenkins/templates/jenkins-controller-svc.yaml new file mode 100644 index 0000000..a83466c --- /dev/null +++ b/helm/jenkins/templates/jenkins-controller-svc.yaml @@ -0,0 +1,56 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{template "jenkins.fullname" . }} + namespace: {{ template "jenkins.namespace" . }} + labels: + "app.kubernetes.io/name": '{{ template "jenkins.name" .}}' + {{- if .Values.renderHelmLabels }} + "helm.sh/chart": "{{ template "jenkins.label" .}}" + {{- end }} + "app.kubernetes.io/managed-by": "{{ .Release.Service }}" + "app.kubernetes.io/instance": "{{ .Release.Name }}" + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" + {{- if .Values.controller.serviceLabels }} +{{ toYaml .Values.controller.serviceLabels | indent 4 }} + {{- end }} +{{- if .Values.controller.serviceAnnotations }} + annotations: +{{ toYaml .Values.controller.serviceAnnotations | indent 4 }} +{{- end }} +spec: + {{- if .Values.controller.serviceExternalTrafficPolicy }} + externalTrafficPolicy: {{.Values.controller.serviceExternalTrafficPolicy}} + {{- end }} + {{- if (and (eq .Values.controller.serviceType "ClusterIP") (not (empty .Values.controller.clusterIP))) }} + clusterIP: {{.Values.controller.clusterIP}} + {{- end }} + ports: + - port: {{.Values.controller.servicePort}} + name: http + targetPort: {{ .Values.controller.targetPort }} + {{- if (and (eq .Values.controller.serviceType "NodePort") (not (empty .Values.controller.nodePort))) }} + nodePort: {{.Values.controller.nodePort}} + {{- end }} +{{- range $index, $port := .Values.controller.extraPorts }} + - port: {{ $port.port }} + name: {{ $port.name }} + {{- if $port.targetPort }} + targetPort: {{ $port.targetPort }} + {{- else }} + targetPort: {{ $port.port }} + {{- end -}} +{{- end }} + selector: + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" + "app.kubernetes.io/instance": "{{ .Release.Name }}" + type: {{.Values.controller.serviceType}} + {{if eq .Values.controller.serviceType "LoadBalancer"}} +{{- if .Values.controller.loadBalancerSourceRanges }} + loadBalancerSourceRanges: +{{ toYaml .Values.controller.loadBalancerSourceRanges | indent 4 }} +{{- end }} + {{if .Values.controller.loadBalancerIP}} + loadBalancerIP: {{.Values.controller.loadBalancerIP}} + {{end}} + {{end}} diff --git a/helm/jenkins/templates/rbac.yaml b/helm/jenkins/templates/rbac.yaml new file mode 100644 index 0000000..581cb8d --- /dev/null +++ b/helm/jenkins/templates/rbac.yaml @@ -0,0 +1,149 @@ +{{ if .Values.rbac.create }} +{{- $serviceName := include "jenkins.fullname" . -}} + +# This role is used to allow Jenkins scheduling of agents via Kubernetes plugin. +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ $serviceName }}-schedule-agents + namespace: {{ template "jenkins.agent.namespace" . }} + labels: + "app.kubernetes.io/name": '{{ template "jenkins.name" .}}' + {{- if .Values.renderHelmLabels }} + "helm.sh/chart": "{{ template "jenkins.label" .}}" + {{- end }} + "app.kubernetes.io/managed-by": "{{ .Release.Service }}" + "app.kubernetes.io/instance": "{{ .Release.Name }}" + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" +rules: +- apiGroups: [""] + resources: ["pods", "pods/exec", "pods/log", "persistentvolumeclaims", "events"] + verbs: ["get", "list", "watch"] +- apiGroups: [""] + resources: ["pods", "pods/exec", "persistentvolumeclaims"] + verbs: ["create", "delete", "deletecollection", "patch", "update"] + +--- + +# We bind the role to the Jenkins service account. The role binding is created in the namespace +# where the agents are supposed to run. +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ $serviceName }}-schedule-agents + namespace: {{ template "jenkins.agent.namespace" . }} + labels: + "app.kubernetes.io/name": '{{ template "jenkins.name" .}}' + {{- if .Values.renderHelmLabels }} + "helm.sh/chart": "{{ template "jenkins.label" .}}" + {{- end }} + "app.kubernetes.io/managed-by": "{{ .Release.Service }}" + "app.kubernetes.io/instance": "{{ .Release.Name }}" + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ $serviceName }}-schedule-agents +subjects: +- kind: ServiceAccount + name: {{ template "jenkins.serviceAccountName" .}} + namespace: {{ template "jenkins.namespace" . }} + +--- + +{{- if .Values.rbac.readSecrets }} +# This is needed if you want to use https://jenkinsci.github.io/kubernetes-credentials-provider-plugin/ +# as it needs permissions to get/watch/list Secrets +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ template "jenkins.fullname" . }}-read-secrets + namespace: {{ template "jenkins.namespace" . }} + labels: + "app.kubernetes.io/name": '{{ template "jenkins.name" .}}' + {{- if .Values.renderHelmLabels }} + "helm.sh/chart": "{{ template "jenkins.label" .}}" + {{- end }} + "app.kubernetes.io/managed-by": "{{ .Release.Service }}" + "app.kubernetes.io/instance": "{{ .Release.Name }}" + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" +rules: + - apiGroups: [""] + resources: ["secrets"] + verbs: ["get", "watch", "list"] + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ $serviceName }}-read-secrets + namespace: {{ template "jenkins.namespace" . }} + labels: + "app.kubernetes.io/name": '{{ template "jenkins.name" .}}' + {{- if .Values.renderHelmLabels }} + "helm.sh/chart": "{{ template "jenkins.label" .}}" + {{- end }} + "app.kubernetes.io/managed-by": "{{ .Release.Service }}" + "app.kubernetes.io/instance": "{{ .Release.Name }}" + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "jenkins.fullname" . }}-read-secrets +subjects: + - kind: ServiceAccount + name: {{ template "jenkins.serviceAccountName" . }} + namespace: {{ template "jenkins.namespace" . }} + +--- +{{- end}} + +{{- if .Values.controller.sidecars.configAutoReload.enabled }} +# The sidecar container which is responsible for reloading configuration changes +# needs permissions to watch ConfigMaps +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ template "jenkins.fullname" . }}-casc-reload + namespace: {{ template "jenkins.namespace" . }} + labels: + "app.kubernetes.io/name": '{{ template "jenkins.name" .}}' + {{- if .Values.renderHelmLabels }} + "helm.sh/chart": "{{ template "jenkins.label" .}}" + {{- end }} + "app.kubernetes.io/managed-by": "{{ .Release.Service }}" + "app.kubernetes.io/instance": "{{ .Release.Name }}" + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" +rules: +- apiGroups: [""] + resources: ["configmaps"] + verbs: ["get", "watch", "list"] + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ $serviceName }}-watch-configmaps + namespace: {{ template "jenkins.namespace" . }} + labels: + "app.kubernetes.io/name": '{{ template "jenkins.name" .}}' + {{- if .Values.renderHelmLabels }} + "helm.sh/chart": "{{ template "jenkins.label" .}}" + {{- end }} + "app.kubernetes.io/managed-by": "{{ .Release.Service }}" + "app.kubernetes.io/instance": "{{ .Release.Name }}" + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "jenkins.fullname" . }}-casc-reload +subjects: +- kind: ServiceAccount + name: {{ template "jenkins.serviceAccountName" . }} + namespace: {{ template "jenkins.namespace" . }} + +{{- end}} + +{{ end }} diff --git a/helm/jenkins/templates/secret-additional.yaml b/helm/jenkins/templates/secret-additional.yaml new file mode 100644 index 0000000..d1908aa --- /dev/null +++ b/helm/jenkins/templates/secret-additional.yaml @@ -0,0 +1,21 @@ +{{- if .Values.controller.additionalSecrets -}} +--- +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "jenkins.fullname" . }}-additional-secrets + namespace: {{ template "jenkins.namespace" . }} + labels: + "app.kubernetes.io/name": '{{ template "jenkins.name" .}}' + {{- if .Values.renderHelmLabels }} + "helm.sh/chart": "{{ template "jenkins.label" .}}" + {{- end }} + "app.kubernetes.io/managed-by": "{{ .Release.Service }}" + "app.kubernetes.io/instance": "{{ .Release.Name }}" + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" +type: Opaque +data: +{{- range .Values.controller.additionalSecrets }} + {{ .name }}: {{ .value | b64enc }} +{{- end }} +{{- end }} diff --git a/helm/jenkins/templates/secret-claims.yaml b/helm/jenkins/templates/secret-claims.yaml new file mode 100644 index 0000000..e8b6d6c --- /dev/null +++ b/helm/jenkins/templates/secret-claims.yaml @@ -0,0 +1,29 @@ +{{- if .Values.controller.secretClaims -}} +{{- $r := .Release -}} +{{- $v := .Values -}} +{{- $chart := printf "%s-%s" .Chart.Name .Chart.Version -}} +{{- $namespace := include "jenkins.namespace" . -}} +{{- $serviceName := include "jenkins.fullname" . -}} +{{ range .Values.controller.secretClaims }} +--- +kind: SecretClaim +apiVersion: vaultproject.io/v1 +metadata: + name: {{ $serviceName }}-{{ .name | default .path | lower }} + namespace: {{ $namespace }} + labels: + "app.kubernetes.io/name": '{{ $serviceName }}' + {{- if $v.renderHelmLabels }} + "helm.sh/chart": "{{ $chart }}" + {{- end }} + "app.kubernetes.io/managed-by": "{{ $r.Service }}" + "app.kubernetes.io/instance": "{{ $r.Name }}" + "app.kubernetes.io/component": "{{ $v.controller.componentName }}" +spec: + type: {{ .type | default "Opaque" }} + path: {{ .path }} +{{- if .renew }} + renew: {{ .renew }} +{{- end }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/helm/jenkins/templates/secret-https-jks.yaml b/helm/jenkins/templates/secret-https-jks.yaml new file mode 100644 index 0000000..98e2fad --- /dev/null +++ b/helm/jenkins/templates/secret-https-jks.yaml @@ -0,0 +1,20 @@ +{{- if and .Values.controller.httpsKeyStore.enable ( not .Values.controller.httpsKeyStore.jenkinsHttpsJksSecretName ) -}} +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "jenkins.fullname" . }}-https-jks + namespace: {{ template "jenkins.namespace" . }} + labels: + "app.kubernetes.io/name": '{{ template "jenkins.name" .}}' + {{- if .Values.renderHelmLabels }} + "helm.sh/chart": "{{ template "jenkins.label" .}}" + {{- end }} + "app.kubernetes.io/managed-by": "{{ .Release.Service }}" + "app.kubernetes.io/instance": "{{ .Release.Name }}" + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" +type: Opaque +data: + jenkins-jks-file: | +{{ .Values.controller.httpsKeyStore.jenkinsKeyStoreBase64Encoded | indent 4 }} + https-jks-password: {{ .Values.controller.httpsKeyStore.password | b64enc }} +{{- end }} diff --git a/helm/jenkins/templates/secret.yaml b/helm/jenkins/templates/secret.yaml new file mode 100644 index 0000000..4feb52f --- /dev/null +++ b/helm/jenkins/templates/secret.yaml @@ -0,0 +1,20 @@ +{{- if and (not .Values.controller.admin.existingSecret) (.Values.controller.adminSecret) -}} + +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "jenkins.fullname" . }} + namespace: {{ template "jenkins.namespace" . }} + labels: + "app.kubernetes.io/name": '{{ template "jenkins.name" .}}' + {{- if .Values.renderHelmLabels }} + "helm.sh/chart": "{{ template "jenkins.label" .}}" + {{- end }} + "app.kubernetes.io/managed-by": "{{ .Release.Service }}" + "app.kubernetes.io/instance": "{{ .Release.Name }}" + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" +type: Opaque +data: + jenkins-admin-password: {{ template "jenkins.password" . }} + jenkins-admin-user: {{ .Values.controller.adminUser | b64enc | quote }} +{{- end }} diff --git a/helm/jenkins/templates/service-account-agent.yaml b/helm/jenkins/templates/service-account-agent.yaml new file mode 100644 index 0000000..2cc05df --- /dev/null +++ b/helm/jenkins/templates/service-account-agent.yaml @@ -0,0 +1,23 @@ +{{ if .Values.serviceAccountAgent.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "jenkins.serviceAccountAgentName" . }} + namespace: {{ template "jenkins.agent.namespace" . }} +{{- if .Values.serviceAccountAgent.annotations }} + annotations: +{{ tpl (toYaml .Values.serviceAccountAgent.annotations) . | indent 4 }} +{{- end }} + labels: + "app.kubernetes.io/name": '{{ template "jenkins.name" .}}' + {{- if .Values.renderHelmLabels }} + "helm.sh/chart": "{{ template "jenkins.label" .}}" + {{- end }} + "app.kubernetes.io/managed-by": "{{ .Release.Service }}" + "app.kubernetes.io/instance": "{{ .Release.Name }}" + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" +{{- if .Values.serviceAccountAgent.imagePullSecretName }} +imagePullSecrets: + - name: {{ .Values.serviceAccountAgent.imagePullSecretName }} +{{- end -}} +{{ end }} diff --git a/helm/jenkins/templates/service-account.yaml b/helm/jenkins/templates/service-account.yaml new file mode 100644 index 0000000..db313d7 --- /dev/null +++ b/helm/jenkins/templates/service-account.yaml @@ -0,0 +1,23 @@ +{{ if .Values.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "jenkins.serviceAccountName" . }} + namespace: {{ template "jenkins.namespace" . }} +{{- if .Values.serviceAccount.annotations }} + annotations: +{{ tpl (toYaml .Values.serviceAccount.annotations) . | indent 4 }} +{{- end }} + labels: + "app.kubernetes.io/name": '{{ template "jenkins.name" .}}' + {{- if .Values.renderHelmLabels }} + "helm.sh/chart": "{{ template "jenkins.label" .}}" + {{- end }} + "app.kubernetes.io/managed-by": "{{ .Release.Service }}" + "app.kubernetes.io/instance": "{{ .Release.Name }}" + "app.kubernetes.io/component": "{{ .Values.controller.componentName }}" +{{- if .Values.serviceAccount.imagePullSecretName }} +imagePullSecrets: + - name: {{ .Values.serviceAccount.imagePullSecretName }} +{{- end -}} +{{ end }} diff --git a/helm/jenkins/templates/tests/jenkins-test.yaml b/helm/jenkins/templates/tests/jenkins-test.yaml new file mode 100644 index 0000000..e013e5e --- /dev/null +++ b/helm/jenkins/templates/tests/jenkins-test.yaml @@ -0,0 +1,49 @@ +{{- if .Values.controller.testEnabled }} +apiVersion: v1 +kind: Pod +metadata: + name: "{{ .Release.Name }}-ui-test-{{ randAlphaNum 5 | lower }}" + namespace: {{ template "jenkins.namespace" . }} + annotations: + "helm.sh/hook": test-success +spec: + {{- if .Values.controller.nodeSelector }} + nodeSelector: +{{ toYaml .Values.controller.nodeSelector | indent 4 }} + {{- end }} + {{- if .Values.controller.tolerations }} + tolerations: +{{ toYaml .Values.controller.tolerations | indent 4 }} + {{- end }} + initContainers: + - name: "test-framework" + image: "bats/bats:1.2.1" + command: + - "bash" + - "-c" + args: + - | + # copy bats to tools dir + set -ex + cp -R /opt/bats /tools/bats/ + volumeMounts: + - mountPath: /tools + name: tools + containers: + - name: {{ .Release.Name }}-ui-test + image: {{ .Values.controller.image }}:{{ .Chart.AppVersion }}-{{ .Values.controller.tagLabel }} + command: ["/tools/bats/bin/bats", "-t", "/tests/run.sh"] + volumeMounts: + - mountPath: /tests + name: tests + readOnly: true + - mountPath: /tools + name: tools + volumes: + - name: tests + configMap: + name: {{ template "jenkins.fullname" . }}-tests + - name: tools + emptyDir: {} + restartPolicy: Never +{{- end }} diff --git a/helm/jenkins/templates/tests/test-config.yaml b/helm/jenkins/templates/tests/test-config.yaml new file mode 100644 index 0000000..12c5b3a --- /dev/null +++ b/helm/jenkins/templates/tests/test-config.yaml @@ -0,0 +1,14 @@ +{{- if .Values.controller.testEnabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "jenkins.fullname" . }}-tests + namespace: {{ template "jenkins.namespace" . }} + annotations: + "helm.sh/hook": test +data: + run.sh: |- + @test "Testing Jenkins UI is accessible" { + curl --retry 48 --retry-delay 10 {{ template "jenkins.fullname" . }}:{{ .Values.controller.servicePort }}{{ default "" .Values.controller.jenkinsUriPrefix }}/login + } +{{- end }} diff --git a/helm/jenkins/unittests/__snapshot__/jenkins-controller-statefulset-test.yaml.snap b/helm/jenkins/unittests/__snapshot__/jenkins-controller-statefulset-test.yaml.snap new file mode 100644 index 0000000..1549081 --- /dev/null +++ b/helm/jenkins/unittests/__snapshot__/jenkins-controller-statefulset-test.yaml.snap @@ -0,0 +1,5 @@ +render pod annotations: + 1: | + checksum/config: d00c6603a9397bc202be5072a81644630af27fe47c7e542ea6b066073458af83 + fixed-annotation: some-fixed-annotation + templated-annotations: my-release diff --git a/helm/jenkins/unittests/config-init-scripts-test.yaml b/helm/jenkins/unittests/config-init-scripts-test.yaml new file mode 100644 index 0000000..b524460 --- /dev/null +++ b/helm/jenkins/unittests/config-init-scripts-test.yaml @@ -0,0 +1,19 @@ +suite: ConfigMap +templates: + - config-init-scripts.yaml +tests: + - it: config templates + set: + some.val: val here + controller.initScripts: + test: |- + my script here {{ .Values.some.val }} + asserts: + - isKind: + of: ConfigMap + - hasDocuments: + count: 1 + - equal: + path: data.inittest\.groovy + value: |- + my script here val here diff --git a/helm/jenkins/unittests/config-test.yaml b/helm/jenkins/unittests/config-test.yaml new file mode 100644 index 0000000..03931cb --- /dev/null +++ b/helm/jenkins/unittests/config-test.yaml @@ -0,0 +1,128 @@ +suite: ConfigMap +templates: + - config.yaml +tests: + - it: default config + asserts: + - isKind: + of: ConfigMap + - hasDocuments: + count: 1 + - equal: + path: metadata.labels + value: + app.kubernetes.io/component: jenkins-controller + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: jenkins + - equal: + path: data.apply_config\.sh + value: |- + set -e + echo "disable Setup Wizard" + # Prevent Setup Wizard when JCasC is enabled + echo $JENKINS_VERSION > /var/jenkins_home/jenkins.install.UpgradeWizard.state + echo $JENKINS_VERSION > /var/jenkins_home/jenkins.install.InstallUtil.lastExecVersion + echo "download plugins" + # Install missing plugins + cp /var/jenkins_config/plugins.txt /var/jenkins_home; + rm -rf /usr/share/jenkins/ref/plugins/*.lock + version () { echo "$@" | awk -F. '{ printf("%d%03d%03d%03d\n", $1,$2,$3,$4); }'; } + if [ -f "/usr/share/jenkins/jenkins.war" ] && [ -n "$(command -v jenkins-plugin-cli)" 2>/dev/null ] && [ $(version $(jenkins-plugin-cli --version)) -ge $(version "2.1.1") ]; then + jenkins-plugin-cli --verbose --war "/usr/share/jenkins/jenkins.war" --plugin-file "/var/jenkins_home/plugins.txt" --latest true; + else + /usr/local/bin/install-plugins.sh `echo $(cat /var/jenkins_home/plugins.txt)`; + fi + echo "copy plugins to shared volume" + # Copy plugins to shared volume + yes n | cp -i /usr/share/jenkins/ref/plugins/* /var/jenkins_plugins/; + echo "finished initialization" + - equal: + path: data.plugins\.txt + value: |- + kubernetes:3734.v562b_b_a_627ea_c + workflow-aggregator:590.v6a_d052e5a_a_b_5 + git:4.13.0 + configuration-as-code:1569.vb_72405b_80249 + - it: no plugins + set: + controller.installPlugins: [] + asserts: + - equal: + path: data.apply_config\.sh + value: |- + set -e + echo "disable Setup Wizard" + # Prevent Setup Wizard when JCasC is enabled + echo $JENKINS_VERSION > /var/jenkins_home/jenkins.install.UpgradeWizard.state + echo $JENKINS_VERSION > /var/jenkins_home/jenkins.install.InstallUtil.lastExecVersion + echo "finished initialization" + - equal: + path: data.plugins\.txt + value: "" + - it: additional plugins config + set: + controller: + additionalPlugins: + - kubernetes-credentials-provider + asserts: + - equal: + path: data.plugins\.txt + value: |- + kubernetes:3734.v562b_b_a_627ea_c + workflow-aggregator:590.v6a_d052e5a_a_b_5 + git:4.13.0 + configuration-as-code:1569.vb_72405b_80249 + kubernetes-credentials-provider + - it: install latest plugins + set: + controller.installLatestPlugins: false + asserts: + - equal: + path: data.apply_config\.sh + value: |- + set -e + echo "disable Setup Wizard" + # Prevent Setup Wizard when JCasC is enabled + echo $JENKINS_VERSION > /var/jenkins_home/jenkins.install.UpgradeWizard.state + echo $JENKINS_VERSION > /var/jenkins_home/jenkins.install.InstallUtil.lastExecVersion + echo "download plugins" + # Install missing plugins + cp /var/jenkins_config/plugins.txt /var/jenkins_home; + rm -rf /usr/share/jenkins/ref/plugins/*.lock + version () { echo "$@" | awk -F. '{ printf("%d%03d%03d%03d\n", $1,$2,$3,$4); }'; } + if [ -f "/usr/share/jenkins/jenkins.war" ] && [ -n "$(command -v jenkins-plugin-cli)" 2>/dev/null ] && [ $(version $(jenkins-plugin-cli --version)) -ge $(version "2.1.1") ]; then + jenkins-plugin-cli --verbose --war "/usr/share/jenkins/jenkins.war" --plugin-file "/var/jenkins_home/plugins.txt" --latest false; + else + /usr/local/bin/install-plugins.sh `echo $(cat /var/jenkins_home/plugins.txt)`; + fi + echo "copy plugins to shared volume" + # Copy plugins to shared volume + yes n | cp -i /usr/share/jenkins/ref/plugins/* /var/jenkins_plugins/; + echo "finished initialization" + - it: install latest specified plugins + set: + controller.installLatestSpecifiedPlugins: true + asserts: + - equal: + path: data.apply_config\.sh + value: |- + set -e + echo "disable Setup Wizard" + # Prevent Setup Wizard when JCasC is enabled + echo $JENKINS_VERSION > /var/jenkins_home/jenkins.install.UpgradeWizard.state + echo $JENKINS_VERSION > /var/jenkins_home/jenkins.install.InstallUtil.lastExecVersion + echo "download plugins" + # Install missing plugins + cp /var/jenkins_config/plugins.txt /var/jenkins_home; + rm -rf /usr/share/jenkins/ref/plugins/*.lock + version () { echo "$@" | awk -F. '{ printf("%d%03d%03d%03d\n", $1,$2,$3,$4); }'; } + if [ -f "/usr/share/jenkins/jenkins.war" ] && [ -n "$(command -v jenkins-plugin-cli)" 2>/dev/null ] && [ $(version $(jenkins-plugin-cli --version)) -ge $(version "2.1.1") ]; then + jenkins-plugin-cli --verbose --war "/usr/share/jenkins/jenkins.war" --plugin-file "/var/jenkins_home/plugins.txt" --latest true --latest-specified; + else + /usr/local/bin/install-plugins.sh `echo $(cat /var/jenkins_home/plugins.txt)`; + fi + echo "copy plugins to shared volume" + # Copy plugins to shared volume + yes n | cp -i /usr/share/jenkins/ref/plugins/* /var/jenkins_plugins/; + echo "finished initialization" diff --git a/helm/jenkins/unittests/home-pvc-test.yaml b/helm/jenkins/unittests/home-pvc-test.yaml new file mode 100644 index 0000000..1ad52e5 --- /dev/null +++ b/helm/jenkins/unittests/home-pvc-test.yaml @@ -0,0 +1,94 @@ +suite: PersistentVolumeClaim +release: + name: my-release + namespace: my-namespace +templates: + - home-pvc.yaml +tests: + - it: tests defaults + asserts: + - isKind: + of: PersistentVolumeClaim + - equal: + path: apiVersion + value: v1 + - equal: + path: metadata.name + value: my-release-jenkins + - equal: + path: metadata.namespace + value: my-namespace + - matchRegex: + path: metadata.labels.helm\.sh/chart + pattern: ^jenkins- + - isNull: + path: metadata.annotations + - contains: + path: spec.accessModes + content: ReadWriteOnce + - equal: + path: spec.resources.requests + value: + storage: 8Gi + - isNull: + path: spec.storageClassName + + - it: test different values + set: + persistence: + annotations: + my-annotation: value + accessMode: ReadWriteMany + size: 20Gi + storageClass: gp2 + asserts: + - equal: + path: metadata.annotations + value: + my-annotation: value + - contains: + path: spec.accessModes + content: ReadWriteMany + - equal: + path: spec.resources.requests + value: + storage: 20Gi + - equal: + path: spec.storageClassName + value: gp2 + + - it: existing claim + set: + persistence: + existingClaim: my-pvc + asserts: + - hasDocuments: + count: 0 + + - it: disable helm.sh label + set: + renderHelmLabels: false + asserts: + - equal: + path: metadata.labels + value: + app.kubernetes.io/component: jenkins-controller + app.kubernetes.io/instance: my-release + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: jenkins + + - it: add label + set: + renderHelmLabels: false + persistence: + labels: + test-label: test-value + asserts: + - equal: + path: metadata.labels + value: + app.kubernetes.io/component: jenkins-controller + app.kubernetes.io/instance: my-release + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: jenkins + test-label: test-value diff --git a/helm/jenkins/unittests/jcasc-config-test.yaml b/helm/jenkins/unittests/jcasc-config-test.yaml new file mode 100644 index 0000000..eb418c2 --- /dev/null +++ b/helm/jenkins/unittests/jcasc-config-test.yaml @@ -0,0 +1,2636 @@ +suite: Configuration as Code +templates: + - jcasc-config.yaml +tests: + - it: default config + release: + namespace: default + asserts: + - isKind: + of: ConfigMap + - hasDocuments: + count: 1 + - isNotEmpty: + path: data.jcasc-default-config\.yaml + - matchRegex: + path: metadata.labels.helm\.sh/chart + pattern: ^jenkins- + - equal: + path: data.jcasc-default-config\.yaml + value: |- + jenkins: + authorizationStrategy: + loggedInUsersCanDoAnything: + allowAnonymousRead: false + securityRealm: + local: + allowsSignup: false + enableCaptcha: false + users: + - id: "${chart-admin-username}" + name: "Jenkins Admin" + password: "${chart-admin-password}" + disableRememberMe: false + mode: NORMAL + numExecutors: 0 + labelString: "" + projectNamingStrategy: "standard" + markupFormatter: + plainText + clouds: + - kubernetes: + containerCapStr: "10" + defaultsProviderTemplate: "" + connectTimeout: "5" + readTimeout: "15" + jenkinsUrl: "http://RELEASE-NAME-jenkins.default.svc.cluster.local:8080" + jenkinsTunnel: "RELEASE-NAME-jenkins-agent.default.svc.cluster.local:50000" + maxRequestsPerHostStr: "32" + name: "kubernetes" + namespace: "default" + serverUrl: "https://kubernetes.default" + podLabels: + - key: "jenkins/RELEASE-NAME-jenkins-agent" + value: "true" + templates: + - name: "default" + namespace: "default" + id: 474be7705ac6cddeedf68ad2962972dd9921f64c6e534967402794fbf06a21ec + containers: + - name: "jnlp" + alwaysPullImage: false + args: "^${computer.jnlpmac} ^${computer.name}" + command: + envVars: + - envVar: + key: "JENKINS_URL" + value: "http://RELEASE-NAME-jenkins.default.svc.cluster.local:8080/" + image: "jenkins/inbound-agent:4.11.2-4" + privileged: "false" + resourceLimitCpu: 512m + resourceLimitMemory: 512Mi + resourceRequestCpu: 512m + resourceRequestMemory: 512Mi + runAsUser: + runAsGroup: + ttyEnabled: false + workingDir: /home/jenkins/agent + idleMinutes: 0 + instanceCap: 2147483647 + label: "RELEASE-NAME-jenkins-agent " + nodeUsageMode: "NORMAL" + podRetention: Never + showRawYaml: true + serviceAccount: "default" + slaveConnectTimeoutStr: "100" + yamlMergeStrategy: override + crumbIssuer: + standard: + excludeClientIPFromCrumb: true + security: + apiToken: + creationOfLegacyTokenEnabled: false + tokenGenerationOnCreationEnabled: false + usageStatisticsEnabled: true + unclassified: + location: + adminAddress: + url: http://RELEASE-NAME-jenkins:8080 + - it: agent namespace and templates + release: + namespace: controller-namespace + set: + additionalAgents: + maven: + namespace: maven + podName: maven + customJenkinsLabels: maven + image: jenkins/jnlp-agent-maven + tag: latest + python: + podName: python + customJenkinsLabels: python + sideContainerName: python + image: python + tag: "3" + command: /bin/sh -c + args: "cat" + TTYEnabled: true + agent: + namespace: jenkins-agents + podTemplates: + python3: | + - name: python3 + label: jenkins-python3 + serviceAccount: jenkins + containers: + - name: python + image: python:3 + command: "/bin/sh -c" + args: "cat" + ttyEnabled: true + privileged: true + resourceRequestCpu: "400m" + resourceRequestMemory: "512Mi" + resourceLimitCpu: "1" + resourceLimitMemory: "1024Mi" + asserts: + - equal: + path: data.jcasc-default-config\.yaml + value: |- + jenkins: + authorizationStrategy: + loggedInUsersCanDoAnything: + allowAnonymousRead: false + securityRealm: + local: + allowsSignup: false + enableCaptcha: false + users: + - id: "${chart-admin-username}" + name: "Jenkins Admin" + password: "${chart-admin-password}" + disableRememberMe: false + mode: NORMAL + numExecutors: 0 + labelString: "" + projectNamingStrategy: "standard" + markupFormatter: + plainText + clouds: + - kubernetes: + containerCapStr: "10" + defaultsProviderTemplate: "" + connectTimeout: "5" + readTimeout: "15" + jenkinsUrl: "http://RELEASE-NAME-jenkins.controller-namespace.svc.cluster.local:8080" + jenkinsTunnel: "RELEASE-NAME-jenkins-agent.controller-namespace.svc.cluster.local:50000" + maxRequestsPerHostStr: "32" + name: "kubernetes" + namespace: "jenkins-agents" + serverUrl: "https://kubernetes.default" + podLabels: + - key: "jenkins/RELEASE-NAME-jenkins-agent" + value: "true" + templates: + - name: "default" + namespace: "jenkins-agents" + id: 6e750ae7b000be7917df5b00a91d0d0923a73357848c683cad33a556119b7a51 + containers: + - name: "jnlp" + alwaysPullImage: false + args: "^${computer.jnlpmac} ^${computer.name}" + command: + envVars: + - envVar: + key: "JENKINS_URL" + value: "http://RELEASE-NAME-jenkins.controller-namespace.svc.cluster.local:8080/" + image: "jenkins/inbound-agent:4.11.2-4" + privileged: "false" + resourceLimitCpu: 512m + resourceLimitMemory: 512Mi + resourceRequestCpu: 512m + resourceRequestMemory: 512Mi + runAsUser: + runAsGroup: + ttyEnabled: false + workingDir: /home/jenkins/agent + idleMinutes: 0 + instanceCap: 2147483647 + label: "RELEASE-NAME-jenkins-agent " + nodeUsageMode: "NORMAL" + podRetention: Never + showRawYaml: true + serviceAccount: "default" + slaveConnectTimeoutStr: "100" + yamlMergeStrategy: override + - name: "maven" + namespace: "maven" + id: 10c1058e6b2f56024132b1e745b1dc59bb96efc1cb4ce96c7e7eeff69234d2ef + containers: + - name: "jnlp" + alwaysPullImage: false + args: "^${computer.jnlpmac} ^${computer.name}" + command: + envVars: + - envVar: + key: "JENKINS_URL" + value: "http://RELEASE-NAME-jenkins.controller-namespace.svc.cluster.local:8080/" + image: "jenkins/jnlp-agent-maven:latest" + privileged: "false" + resourceLimitCpu: 512m + resourceLimitMemory: 512Mi + resourceRequestCpu: 512m + resourceRequestMemory: 512Mi + runAsUser: + runAsGroup: + ttyEnabled: false + workingDir: /home/jenkins/agent + idleMinutes: 0 + instanceCap: 2147483647 + label: "RELEASE-NAME-jenkins-agent maven" + nodeUsageMode: "NORMAL" + podRetention: Never + showRawYaml: true + serviceAccount: "default" + slaveConnectTimeoutStr: "100" + yamlMergeStrategy: override + - name: "python" + namespace: "jenkins-agents" + id: 4b0b84d994ac4c762ae46ea55829ebde7bf02a03315ca47425c61efc160b5709 + containers: + - name: "python" + alwaysPullImage: false + args: "cat" + command: /bin/sh -c + envVars: + - envVar: + key: "JENKINS_URL" + value: "http://RELEASE-NAME-jenkins.controller-namespace.svc.cluster.local:8080/" + image: "python:3" + privileged: "false" + resourceLimitCpu: 512m + resourceLimitMemory: 512Mi + resourceRequestCpu: 512m + resourceRequestMemory: 512Mi + runAsUser: + runAsGroup: + ttyEnabled: true + workingDir: /home/jenkins/agent + idleMinutes: 0 + instanceCap: 2147483647 + label: "RELEASE-NAME-jenkins-agent python" + nodeUsageMode: "NORMAL" + podRetention: Never + showRawYaml: true + serviceAccount: "default" + slaveConnectTimeoutStr: "100" + yamlMergeStrategy: override + - name: python3 + label: jenkins-python3 + serviceAccount: jenkins + containers: + - name: python + image: python:3 + command: "/bin/sh -c" + args: "cat" + ttyEnabled: true + privileged: true + resourceRequestCpu: "400m" + resourceRequestMemory: "512Mi" + resourceLimitCpu: "1" + resourceLimitMemory: "1024Mi" + + crumbIssuer: + standard: + excludeClientIPFromCrumb: true + security: + apiToken: + creationOfLegacyTokenEnabled: false + tokenGenerationOnCreationEnabled: false + usageStatisticsEnabled: true + unclassified: + location: + adminAddress: + url: http://RELEASE-NAME-jenkins:8080 + - it: customized config + set: + controller: + disableRememberMe: true + executorMode: EXCLUSIVE + numExecutors: 1 + enableRawHtmlMarkupFormatter: true + JCasC: + authorizationStrategy: |- + globalMatrix: + permissions: + - "Overall/Read:anonymous" + configScripts: + welcome-message: | + jenkins: + systemMessage: Welcome to our CI\CD server. This Jenkins is configured and managed 'as code'. + securityRealm: local + jenkinsAdminEmail: admin@example.org + ingress: + hostName: jenkins.example.com + tls: + - hosts: + - jenkins.example.com + secretName: tlsSecret + agent: + namespace: default + containerCap: 22 + defaultsProviderTemplate: my-defaults + kubernetesConnectTimeout: 11 + kubernetesReadTimeout: 12 + podName: my-agent + sideContainerName: sideContainer + alwaysPullImage: true + command: /bin/command + image: my-image/jnlp + tag: v1.2.3 + privileged: true + resources: + limits: + cpu: 1024m + memory: 1Gi + requests: + cpu: 756m + memory: 768Mi + runAsUser: 2000 + runAsGroup: 2000 + TTYEnabled: true + workingDir: /workdir + envVars: + - name: VAR + value: value + idleMinutes: 30 + imagePullSecretName: pullSecret + nodeSelector: + jenkins-agent: v1 + selector: abc + podRetention: onFailure + connectTimeout: 111 + volumes: + - type: ConfigMap + configMapName: myconfigmap + mountPath: /var/myapp/myconfigmap + - type: EmptyDir + mountPath: /var/myapp/myemptydir + memory: false + - type: HostPath + hostPath: /var/lib/containers + mountPath: /var/myapp/myhostpath + - type: Nfs + mountPath: /var/myapp/mynfs + readOnly: false + serverAddress: "192.0.2.0" + serverPath: /var/lib/containers + - type: PVC + claimName: mypvc + mountPath: /var/myapp/mypvc + readOnly: false + - type: Secret + defaultMode: "600" + mountPath: /var/myapp/mysecret + secretName: mysecret + annotations: + ci.jenkins-agent/test: "custom" + yamlTemplate: |- + apiVersion: v1 + kind: Pod + spec: + tolerations: + - key: "key" + operator: "Equal" + value: "value" + yamlMergeStrategy: merge + serviceAccountAgent: + name: agent-serviceaccount + release: + name: my-release + namespace: other + asserts: + - hasDocuments: + count: 2 + - documentIndex: 0 + isKind: + of: ConfigMap + - matchRegex: + path: metadata.labels.helm\.sh/chart + pattern: ^jenkins- + - documentIndex: 0 + equal: + path: metadata.name + value: my-release-jenkins-jenkins-config-welcome-message + - documentIndex: 0 + equal: + path: metadata.namespace + value: other + - matchRegex: + path: metadata.labels.helm\.sh/chart + pattern: ^jenkins- + - documentIndex: 1 + isKind: + of: ConfigMap + - documentIndex: 1 + equal: + path: metadata.name + value: my-release-jenkins-jenkins-jcasc-config + - documentIndex: 1 + equal: + path: metadata.namespace + value: other + - documentIndex: 0 + equal: + path: metadata.labels.my-release-jenkins-jenkins-config + value: "true" + - documentIndex: 1 + equal: + path: metadata.labels.my-release-jenkins-jenkins-config + value: "true" + - documentIndex: 0 + equal: + path: data + value: + welcome-message.yaml: |- + jenkins: + systemMessage: Welcome to our CI\CD server. This Jenkins is configured and managed 'as code'. + - documentIndex: 1 + equal: + path: data.jcasc-default-config\.yaml + value: |- + jenkins: + authorizationStrategy: + globalMatrix: + permissions: + - "Overall/Read:anonymous" + securityRealm: + local + disableRememberMe: true + mode: EXCLUSIVE + numExecutors: 1 + labelString: "" + projectNamingStrategy: "standard" + markupFormatter: + rawHtml: + disableSyntaxHighlighting: true + clouds: + - kubernetes: + containerCapStr: "22" + defaultsProviderTemplate: "my-defaults" + connectTimeout: "11" + readTimeout: "12" + jenkinsUrl: "http://my-release-jenkins.other.svc.cluster.local:8080" + jenkinsTunnel: "my-release-jenkins-agent.other.svc.cluster.local:50000" + maxRequestsPerHostStr: "32" + name: "kubernetes" + namespace: "default" + serverUrl: "https://kubernetes.default" + podLabels: + - key: "jenkins/my-release-jenkins-agent" + value: "true" + templates: + - name: "my-agent" + namespace: "default" + annotations: + - key: ci.jenkins-agent/test + value: "custom" + id: 92000ebb9e31c9d9aa2d2e027689c250a56654ae91324129038586e9872d2c32 + containers: + - name: "sideContainer" + alwaysPullImage: true + args: "^${computer.jnlpmac} ^${computer.name}" + command: /bin/command + envVars: + - envVar: + key: "JENKINS_URL" + value: "http://my-release-jenkins.other.svc.cluster.local:8080/" + image: "my-image/jnlp:v1.2.3" + privileged: "true" + resourceLimitCpu: 1024m + resourceLimitMemory: 1Gi + resourceRequestCpu: 756m + resourceRequestMemory: 768Mi + runAsUser: 2000 + runAsGroup: 2000 + ttyEnabled: true + workingDir: /workdir + envVars: + - envVar: + key: VAR + value: value + idleMinutes: 30 + instanceCap: 2147483647 + imagePullSecrets: + - name: pullSecret + label: "my-release-jenkins-agent " + nodeSelector: jenkins-agent=v1,selector=abc + nodeUsageMode: "NORMAL" + podRetention: onFailure + showRawYaml: true + serviceAccount: "agent-serviceaccount" + slaveConnectTimeoutStr: "111" + volumes: + - configMapVolume: + configMapName: "myconfigmap" + mountPath: "/var/myapp/myconfigmap" + - emptyDirVolume: + memory: false + mountPath: "/var/myapp/myemptydir" + - hostPathVolume: + hostPath: "/var/lib/containers" + mountPath: "/var/myapp/myhostpath" + - nfsVolume: + mountPath: "/var/myapp/mynfs" + readOnly: false + serverAddress: "192.0.2.0" + serverPath: "/var/lib/containers" + - persistentVolumeClaim: + claimName: "mypvc" + mountPath: "/var/myapp/mypvc" + readOnly: false + - secretVolume: + defaultMode: "600" + mountPath: "/var/myapp/mysecret" + secretName: "mysecret" + yaml: |- + apiVersion: v1 + kind: Pod + spec: + tolerations: + - key: "key" + operator: "Equal" + value: "value" + yamlMergeStrategy: merge + crumbIssuer: + standard: + excludeClientIPFromCrumb: true + security: + apiToken: + creationOfLegacyTokenEnabled: false + tokenGenerationOnCreationEnabled: false + usageStatisticsEnabled: true + unclassified: + location: + adminAddress: admin@example.org + url: https://jenkins.example.com + - it: custom dynamic pvc workspace volume + set: + agent: + workspaceVolume: + type: "DynamicPVC" + accessModes: "ReadWriteOnce" + requestsSize: "2Gi" + storageClassName: "gp2" + release: + namespace: default + asserts: + - isKind: + of: ConfigMap + - hasDocuments: + count: 1 + - isNotEmpty: + path: data.jcasc-default-config\.yaml + - matchRegex: + path: metadata.labels.helm\.sh/chart + pattern: ^jenkins- + - equal: + path: data.jcasc-default-config\.yaml + value: |- + jenkins: + authorizationStrategy: + loggedInUsersCanDoAnything: + allowAnonymousRead: false + securityRealm: + local: + allowsSignup: false + enableCaptcha: false + users: + - id: "${chart-admin-username}" + name: "Jenkins Admin" + password: "${chart-admin-password}" + disableRememberMe: false + mode: NORMAL + numExecutors: 0 + labelString: "" + projectNamingStrategy: "standard" + markupFormatter: + plainText + clouds: + - kubernetes: + containerCapStr: "10" + defaultsProviderTemplate: "" + connectTimeout: "5" + readTimeout: "15" + jenkinsUrl: "http://RELEASE-NAME-jenkins.default.svc.cluster.local:8080" + jenkinsTunnel: "RELEASE-NAME-jenkins-agent.default.svc.cluster.local:50000" + maxRequestsPerHostStr: "32" + name: "kubernetes" + namespace: "default" + serverUrl: "https://kubernetes.default" + podLabels: + - key: "jenkins/RELEASE-NAME-jenkins-agent" + value: "true" + templates: + - name: "default" + namespace: "default" + id: 1ad31223960302cee30a36ce3d73e8017b8702e9b3100d9b3de3e11f00208958 + containers: + - name: "jnlp" + alwaysPullImage: false + args: "^${computer.jnlpmac} ^${computer.name}" + command: + envVars: + - envVar: + key: "JENKINS_URL" + value: "http://RELEASE-NAME-jenkins.default.svc.cluster.local:8080/" + image: "jenkins/inbound-agent:4.11.2-4" + privileged: "false" + resourceLimitCpu: 512m + resourceLimitMemory: 512Mi + resourceRequestCpu: 512m + resourceRequestMemory: 512Mi + runAsUser: + runAsGroup: + ttyEnabled: false + workingDir: /home/jenkins/agent + idleMinutes: 0 + instanceCap: 2147483647 + label: "RELEASE-NAME-jenkins-agent " + nodeUsageMode: "NORMAL" + podRetention: Never + showRawYaml: true + serviceAccount: "default" + slaveConnectTimeoutStr: "100" + workspaceVolume: + dynamicPVC: + accessModes: "ReadWriteOnce" + requestsSize: "2Gi" + storageClassName: "gp2" + yamlMergeStrategy: override + crumbIssuer: + standard: + excludeClientIPFromCrumb: true + security: + apiToken: + creationOfLegacyTokenEnabled: false + tokenGenerationOnCreationEnabled: false + usageStatisticsEnabled: true + unclassified: + location: + adminAddress: + url: http://RELEASE-NAME-jenkins:8080 + - it: custom emptyDir workspace volume + set: + agent: + workspaceVolume: + type: "EmptyDir" + memory: true + release: + namespace: default + asserts: + - isKind: + of: ConfigMap + - hasDocuments: + count: 1 + - isNotEmpty: + path: data.jcasc-default-config\.yaml + - matchRegex: + path: metadata.labels.helm\.sh/chart + pattern: ^jenkins- + - equal: + path: data.jcasc-default-config\.yaml + value: |- + jenkins: + authorizationStrategy: + loggedInUsersCanDoAnything: + allowAnonymousRead: false + securityRealm: + local: + allowsSignup: false + enableCaptcha: false + users: + - id: "${chart-admin-username}" + name: "Jenkins Admin" + password: "${chart-admin-password}" + disableRememberMe: false + mode: NORMAL + numExecutors: 0 + labelString: "" + projectNamingStrategy: "standard" + markupFormatter: + plainText + clouds: + - kubernetes: + containerCapStr: "10" + defaultsProviderTemplate: "" + connectTimeout: "5" + readTimeout: "15" + jenkinsUrl: "http://RELEASE-NAME-jenkins.default.svc.cluster.local:8080" + jenkinsTunnel: "RELEASE-NAME-jenkins-agent.default.svc.cluster.local:50000" + maxRequestsPerHostStr: "32" + name: "kubernetes" + namespace: "default" + serverUrl: "https://kubernetes.default" + podLabels: + - key: "jenkins/RELEASE-NAME-jenkins-agent" + value: "true" + templates: + - name: "default" + namespace: "default" + id: 830b3c578ad439b24340052e51aec67362fd63992a9298acaa59bfda3e99391f + containers: + - name: "jnlp" + alwaysPullImage: false + args: "^${computer.jnlpmac} ^${computer.name}" + command: + envVars: + - envVar: + key: "JENKINS_URL" + value: "http://RELEASE-NAME-jenkins.default.svc.cluster.local:8080/" + image: "jenkins/inbound-agent:4.11.2-4" + privileged: "false" + resourceLimitCpu: 512m + resourceLimitMemory: 512Mi + resourceRequestCpu: 512m + resourceRequestMemory: 512Mi + runAsUser: + runAsGroup: + ttyEnabled: false + workingDir: /home/jenkins/agent + idleMinutes: 0 + instanceCap: 2147483647 + label: "RELEASE-NAME-jenkins-agent " + nodeUsageMode: "NORMAL" + podRetention: Never + showRawYaml: true + serviceAccount: "default" + slaveConnectTimeoutStr: "100" + workspaceVolume: + emptyDirWorkspaceVolume: + memory: true + yamlMergeStrategy: override + crumbIssuer: + standard: + excludeClientIPFromCrumb: true + security: + apiToken: + creationOfLegacyTokenEnabled: false + tokenGenerationOnCreationEnabled: false + usageStatisticsEnabled: true + unclassified: + location: + adminAddress: + url: http://RELEASE-NAME-jenkins:8080 + - it: custom hostPath workspace volume + set: + agent: + workspaceVolume: + type: "HostPath" + hostPath: "/data" + release: + namespace: default + asserts: + - isKind: + of: ConfigMap + - hasDocuments: + count: 1 + - isNotEmpty: + path: data.jcasc-default-config\.yaml + - matchRegex: + path: metadata.labels.helm\.sh/chart + pattern: ^jenkins- + - equal: + path: data.jcasc-default-config\.yaml + value: |- + jenkins: + authorizationStrategy: + loggedInUsersCanDoAnything: + allowAnonymousRead: false + securityRealm: + local: + allowsSignup: false + enableCaptcha: false + users: + - id: "${chart-admin-username}" + name: "Jenkins Admin" + password: "${chart-admin-password}" + disableRememberMe: false + mode: NORMAL + numExecutors: 0 + labelString: "" + projectNamingStrategy: "standard" + markupFormatter: + plainText + clouds: + - kubernetes: + containerCapStr: "10" + defaultsProviderTemplate: "" + connectTimeout: "5" + readTimeout: "15" + jenkinsUrl: "http://RELEASE-NAME-jenkins.default.svc.cluster.local:8080" + jenkinsTunnel: "RELEASE-NAME-jenkins-agent.default.svc.cluster.local:50000" + maxRequestsPerHostStr: "32" + name: "kubernetes" + namespace: "default" + serverUrl: "https://kubernetes.default" + podLabels: + - key: "jenkins/RELEASE-NAME-jenkins-agent" + value: "true" + templates: + - name: "default" + namespace: "default" + id: f57fed930c6aa9841be0c245fbe803cea2eda8e2c9f0526e17c76e3f8bbd15c1 + containers: + - name: "jnlp" + alwaysPullImage: false + args: "^${computer.jnlpmac} ^${computer.name}" + command: + envVars: + - envVar: + key: "JENKINS_URL" + value: "http://RELEASE-NAME-jenkins.default.svc.cluster.local:8080/" + image: "jenkins/inbound-agent:4.11.2-4" + privileged: "false" + resourceLimitCpu: 512m + resourceLimitMemory: 512Mi + resourceRequestCpu: 512m + resourceRequestMemory: 512Mi + runAsUser: + runAsGroup: + ttyEnabled: false + workingDir: /home/jenkins/agent + idleMinutes: 0 + instanceCap: 2147483647 + label: "RELEASE-NAME-jenkins-agent " + nodeUsageMode: "NORMAL" + podRetention: Never + showRawYaml: true + serviceAccount: "default" + slaveConnectTimeoutStr: "100" + workspaceVolume: + hostPathWorkspaceVolume: + hostPath: "/data" + yamlMergeStrategy: override + crumbIssuer: + standard: + excludeClientIPFromCrumb: true + security: + apiToken: + creationOfLegacyTokenEnabled: false + tokenGenerationOnCreationEnabled: false + usageStatisticsEnabled: true + unclassified: + location: + adminAddress: + url: http://RELEASE-NAME-jenkins:8080 + - it: custom nfs workspace volume + set: + agent: + workspaceVolume: + type: "Nfs" + readOnly: false + serverAddress: "1.1.1.1" + serverPath: "/data" + release: + namespace: default + asserts: + - isKind: + of: ConfigMap + - hasDocuments: + count: 1 + - isNotEmpty: + path: data.jcasc-default-config\.yaml + - matchRegex: + path: metadata.labels.helm\.sh/chart + pattern: ^jenkins- + - equal: + path: data.jcasc-default-config\.yaml + value: |- + jenkins: + authorizationStrategy: + loggedInUsersCanDoAnything: + allowAnonymousRead: false + securityRealm: + local: + allowsSignup: false + enableCaptcha: false + users: + - id: "${chart-admin-username}" + name: "Jenkins Admin" + password: "${chart-admin-password}" + disableRememberMe: false + mode: NORMAL + numExecutors: 0 + labelString: "" + projectNamingStrategy: "standard" + markupFormatter: + plainText + clouds: + - kubernetes: + containerCapStr: "10" + defaultsProviderTemplate: "" + connectTimeout: "5" + readTimeout: "15" + jenkinsUrl: "http://RELEASE-NAME-jenkins.default.svc.cluster.local:8080" + jenkinsTunnel: "RELEASE-NAME-jenkins-agent.default.svc.cluster.local:50000" + maxRequestsPerHostStr: "32" + name: "kubernetes" + namespace: "default" + serverUrl: "https://kubernetes.default" + podLabels: + - key: "jenkins/RELEASE-NAME-jenkins-agent" + value: "true" + templates: + - name: "default" + namespace: "default" + id: 187b5b627e42eff0b4f267ba448c4d203ba08467233690bb00bf58d26045d689 + containers: + - name: "jnlp" + alwaysPullImage: false + args: "^${computer.jnlpmac} ^${computer.name}" + command: + envVars: + - envVar: + key: "JENKINS_URL" + value: "http://RELEASE-NAME-jenkins.default.svc.cluster.local:8080/" + image: "jenkins/inbound-agent:4.11.2-4" + privileged: "false" + resourceLimitCpu: 512m + resourceLimitMemory: 512Mi + resourceRequestCpu: 512m + resourceRequestMemory: 512Mi + runAsUser: + runAsGroup: + ttyEnabled: false + workingDir: /home/jenkins/agent + idleMinutes: 0 + instanceCap: 2147483647 + label: "RELEASE-NAME-jenkins-agent " + nodeUsageMode: "NORMAL" + podRetention: Never + showRawYaml: true + serviceAccount: "default" + slaveConnectTimeoutStr: "100" + workspaceVolume: + nfsWorkspaceVolume: + readOnly: false + serverAddress: "1.1.1.1" + serverPath: "/data" + yamlMergeStrategy: override + crumbIssuer: + standard: + excludeClientIPFromCrumb: true + security: + apiToken: + creationOfLegacyTokenEnabled: false + tokenGenerationOnCreationEnabled: false + usageStatisticsEnabled: true + unclassified: + location: + adminAddress: + url: http://RELEASE-NAME-jenkins:8080 + - it: custom pvc workspace volume + set: + agent: + workspaceVolume: + type: "PVC" + claimName: "my-claim" + readOnly: false + release: + namespace: default + asserts: + - isKind: + of: ConfigMap + - hasDocuments: + count: 1 + - isNotEmpty: + path: data.jcasc-default-config\.yaml + - matchRegex: + path: metadata.labels.helm\.sh/chart + pattern: ^jenkins- + - equal: + path: data.jcasc-default-config\.yaml + value: |- + jenkins: + authorizationStrategy: + loggedInUsersCanDoAnything: + allowAnonymousRead: false + securityRealm: + local: + allowsSignup: false + enableCaptcha: false + users: + - id: "${chart-admin-username}" + name: "Jenkins Admin" + password: "${chart-admin-password}" + disableRememberMe: false + mode: NORMAL + numExecutors: 0 + labelString: "" + projectNamingStrategy: "standard" + markupFormatter: + plainText + clouds: + - kubernetes: + containerCapStr: "10" + defaultsProviderTemplate: "" + connectTimeout: "5" + readTimeout: "15" + jenkinsUrl: "http://RELEASE-NAME-jenkins.default.svc.cluster.local:8080" + jenkinsTunnel: "RELEASE-NAME-jenkins-agent.default.svc.cluster.local:50000" + maxRequestsPerHostStr: "32" + name: "kubernetes" + namespace: "default" + serverUrl: "https://kubernetes.default" + podLabels: + - key: "jenkins/RELEASE-NAME-jenkins-agent" + value: "true" + templates: + - name: "default" + namespace: "default" + id: e00d701466613fe20ab781b75a1926a4031a76bdd0c219460c2f51559f923704 + containers: + - name: "jnlp" + alwaysPullImage: false + args: "^${computer.jnlpmac} ^${computer.name}" + command: + envVars: + - envVar: + key: "JENKINS_URL" + value: "http://RELEASE-NAME-jenkins.default.svc.cluster.local:8080/" + image: "jenkins/inbound-agent:4.11.2-4" + privileged: "false" + resourceLimitCpu: 512m + resourceLimitMemory: 512Mi + resourceRequestCpu: 512m + resourceRequestMemory: 512Mi + runAsUser: + runAsGroup: + ttyEnabled: false + workingDir: /home/jenkins/agent + idleMinutes: 0 + instanceCap: 2147483647 + label: "RELEASE-NAME-jenkins-agent " + nodeUsageMode: "NORMAL" + podRetention: Never + showRawYaml: true + serviceAccount: "default" + slaveConnectTimeoutStr: "100" + workspaceVolume: + persistentVolumeClaimWorkspaceVolume: + claimName: "my-claim" + readOnly: false + yamlMergeStrategy: override + crumbIssuer: + standard: + excludeClientIPFromCrumb: true + security: + apiToken: + creationOfLegacyTokenEnabled: false + tokenGenerationOnCreationEnabled: false + usageStatisticsEnabled: true + unclassified: + location: + adminAddress: + url: http://RELEASE-NAME-jenkins:8080 + - it: custom other workspace volume + set: + agent: + workspaceVolume: + type: "persistentVolumeClaimWorkspaceVolume" + claimName: "my-claim" + readOnly: false + release: + namespace: default + asserts: + - isKind: + of: ConfigMap + - hasDocuments: + count: 1 + - isNotEmpty: + path: data.jcasc-default-config\.yaml + - matchRegex: + path: metadata.labels.helm\.sh/chart + pattern: ^jenkins- + - equal: + path: data.jcasc-default-config\.yaml + value: |- + jenkins: + authorizationStrategy: + loggedInUsersCanDoAnything: + allowAnonymousRead: false + securityRealm: + local: + allowsSignup: false + enableCaptcha: false + users: + - id: "${chart-admin-username}" + name: "Jenkins Admin" + password: "${chart-admin-password}" + disableRememberMe: false + mode: NORMAL + numExecutors: 0 + labelString: "" + projectNamingStrategy: "standard" + markupFormatter: + plainText + clouds: + - kubernetes: + containerCapStr: "10" + defaultsProviderTemplate: "" + connectTimeout: "5" + readTimeout: "15" + jenkinsUrl: "http://RELEASE-NAME-jenkins.default.svc.cluster.local:8080" + jenkinsTunnel: "RELEASE-NAME-jenkins-agent.default.svc.cluster.local:50000" + maxRequestsPerHostStr: "32" + name: "kubernetes" + namespace: "default" + serverUrl: "https://kubernetes.default" + podLabels: + - key: "jenkins/RELEASE-NAME-jenkins-agent" + value: "true" + templates: + - name: "default" + namespace: "default" + id: f07d9eb43cda17bd6c3f448332448bd4a3eff51936cde7c7afc44b02dff8e299 + containers: + - name: "jnlp" + alwaysPullImage: false + args: "^${computer.jnlpmac} ^${computer.name}" + command: + envVars: + - envVar: + key: "JENKINS_URL" + value: "http://RELEASE-NAME-jenkins.default.svc.cluster.local:8080/" + image: "jenkins/inbound-agent:4.11.2-4" + privileged: "false" + resourceLimitCpu: 512m + resourceLimitMemory: 512Mi + resourceRequestCpu: 512m + resourceRequestMemory: 512Mi + runAsUser: + runAsGroup: + ttyEnabled: false + workingDir: /home/jenkins/agent + idleMinutes: 0 + instanceCap: 2147483647 + label: "RELEASE-NAME-jenkins-agent " + nodeUsageMode: "NORMAL" + podRetention: Never + showRawYaml: true + serviceAccount: "default" + slaveConnectTimeoutStr: "100" + workspaceVolume: + persistentVolumeClaimWorkspaceVolume: + claimName: "my-claim" + readOnly: false + yamlMergeStrategy: override + crumbIssuer: + standard: + excludeClientIPFromCrumb: true + security: + apiToken: + creationOfLegacyTokenEnabled: false + tokenGenerationOnCreationEnabled: false + usageStatisticsEnabled: true + unclassified: + location: + adminAddress: + url: http://RELEASE-NAME-jenkins:8080 + - it: disable helm.sh label + set: + renderHelmLabels: false + asserts: + - equal: + path: metadata.labels + value: + RELEASE-NAME-jenkins-jenkins-config: "true" + app.kubernetes.io/component: jenkins-controller + app.kubernetes.io/instance: RELEASE-NAME + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: jenkins + - it: disable agents + release: + namespace: controller-namespace + set: + agent.enabled: false + asserts: + - equal: + path: data.jcasc-default-config\.yaml + value: |- + jenkins: + authorizationStrategy: + loggedInUsersCanDoAnything: + allowAnonymousRead: false + securityRealm: + local: + allowsSignup: false + enableCaptcha: false + users: + - id: "${chart-admin-username}" + name: "Jenkins Admin" + password: "${chart-admin-password}" + disableRememberMe: false + mode: NORMAL + numExecutors: 0 + labelString: "" + projectNamingStrategy: "standard" + markupFormatter: + plainText + clouds: + - kubernetes: + containerCapStr: "10" + defaultsProviderTemplate: "" + connectTimeout: "5" + readTimeout: "15" + jenkinsUrl: "http://RELEASE-NAME-jenkins.controller-namespace.svc.cluster.local:8080" + jenkinsTunnel: "RELEASE-NAME-jenkins-agent.controller-namespace.svc.cluster.local:50000" + maxRequestsPerHostStr: "32" + name: "kubernetes" + namespace: "controller-namespace" + serverUrl: "https://kubernetes.default" + crumbIssuer: + standard: + excludeClientIPFromCrumb: true + security: + apiToken: + creationOfLegacyTokenEnabled: false + tokenGenerationOnCreationEnabled: false + usageStatisticsEnabled: true + unclassified: + location: + adminAddress: + url: http://RELEASE-NAME-jenkins:8080 + - it: disable default config + set: + controller.JCasC.defaultConfig: false + asserts: + - hasDocuments: + count: 0 + - it: custom jenkins label + set: + controller: + customJenkinsLabels: ["testlabel"] + release: + namespace: default + asserts: + - isKind: + of: ConfigMap + - hasDocuments: + count: 1 + - isNotEmpty: + path: data.jcasc-default-config\.yaml + - matchRegex: + path: metadata.labels.helm\.sh/chart + pattern: ^jenkins- + - equal: + path: data.jcasc-default-config\.yaml + value: |- + jenkins: + authorizationStrategy: + loggedInUsersCanDoAnything: + allowAnonymousRead: false + securityRealm: + local: + allowsSignup: false + enableCaptcha: false + users: + - id: "${chart-admin-username}" + name: "Jenkins Admin" + password: "${chart-admin-password}" + disableRememberMe: false + mode: NORMAL + numExecutors: 0 + labelString: "testlabel" + projectNamingStrategy: "standard" + markupFormatter: + plainText + clouds: + - kubernetes: + containerCapStr: "10" + defaultsProviderTemplate: "" + connectTimeout: "5" + readTimeout: "15" + jenkinsUrl: "http://RELEASE-NAME-jenkins.default.svc.cluster.local:8080" + jenkinsTunnel: "RELEASE-NAME-jenkins-agent.default.svc.cluster.local:50000" + maxRequestsPerHostStr: "32" + name: "kubernetes" + namespace: "default" + serverUrl: "https://kubernetes.default" + podLabels: + - key: "jenkins/RELEASE-NAME-jenkins-agent" + value: "true" + templates: + - name: "default" + namespace: "default" + id: 474be7705ac6cddeedf68ad2962972dd9921f64c6e534967402794fbf06a21ec + containers: + - name: "jnlp" + alwaysPullImage: false + args: "^${computer.jnlpmac} ^${computer.name}" + command: + envVars: + - envVar: + key: "JENKINS_URL" + value: "http://RELEASE-NAME-jenkins.default.svc.cluster.local:8080/" + image: "jenkins/inbound-agent:4.11.2-4" + privileged: "false" + resourceLimitCpu: 512m + resourceLimitMemory: 512Mi + resourceRequestCpu: 512m + resourceRequestMemory: 512Mi + runAsUser: + runAsGroup: + ttyEnabled: false + workingDir: /home/jenkins/agent + idleMinutes: 0 + instanceCap: 2147483647 + label: "RELEASE-NAME-jenkins-agent " + nodeUsageMode: "NORMAL" + podRetention: Never + showRawYaml: true + serviceAccount: "default" + slaveConnectTimeoutStr: "100" + yamlMergeStrategy: override + crumbIssuer: + standard: + excludeClientIPFromCrumb: true + security: + apiToken: + creationOfLegacyTokenEnabled: false + tokenGenerationOnCreationEnabled: false + usageStatisticsEnabled: true + unclassified: + location: + adminAddress: + url: http://RELEASE-NAME-jenkins:8080 + - it: adds custom labels on agent pods + set: + agent: + podLabels: + label-one: value-one + label-two: true + asserts: + - isKind: + of: ConfigMap + - hasDocuments: + count: 1 + - isNotEmpty: + path: data.jcasc-default-config\.yaml + - matchRegex: + path: metadata.labels.helm\.sh/chart + pattern: ^jenkins- + - equal: + path: data.jcasc-default-config\.yaml + value: |- + jenkins: + authorizationStrategy: + loggedInUsersCanDoAnything: + allowAnonymousRead: false + securityRealm: + local: + allowsSignup: false + enableCaptcha: false + users: + - id: "${chart-admin-username}" + name: "Jenkins Admin" + password: "${chart-admin-password}" + disableRememberMe: false + mode: NORMAL + numExecutors: 0 + labelString: "" + projectNamingStrategy: "standard" + markupFormatter: + plainText + clouds: + - kubernetes: + containerCapStr: "10" + defaultsProviderTemplate: "" + connectTimeout: "5" + readTimeout: "15" + jenkinsUrl: "http://RELEASE-NAME-jenkins.NAMESPACE.svc.cluster.local:8080" + jenkinsTunnel: "RELEASE-NAME-jenkins-agent.NAMESPACE.svc.cluster.local:50000" + maxRequestsPerHostStr: "32" + name: "kubernetes" + namespace: "NAMESPACE" + serverUrl: "https://kubernetes.default" + podLabels: + - key: "jenkins/RELEASE-NAME-jenkins-agent" + value: "true" + - key: "label-one" + value: "value-one" + - key: "label-two" + value: "true" + templates: + - name: "default" + namespace: "NAMESPACE" + id: bb8414f0110939ce3d28b4c3ef67e5d80466a91db851c429e89951bd7c91882b + containers: + - name: "jnlp" + alwaysPullImage: false + args: "^${computer.jnlpmac} ^${computer.name}" + command: + envVars: + - envVar: + key: "JENKINS_URL" + value: "http://RELEASE-NAME-jenkins.NAMESPACE.svc.cluster.local:8080/" + image: "jenkins/inbound-agent:4.11.2-4" + privileged: "false" + resourceLimitCpu: 512m + resourceLimitMemory: 512Mi + resourceRequestCpu: 512m + resourceRequestMemory: 512Mi + runAsUser: + runAsGroup: + ttyEnabled: false + workingDir: /home/jenkins/agent + idleMinutes: 0 + instanceCap: 2147483647 + label: "RELEASE-NAME-jenkins-agent " + nodeUsageMode: "NORMAL" + podRetention: Never + showRawYaml: true + serviceAccount: "default" + slaveConnectTimeoutStr: "100" + yamlMergeStrategy: override + crumbIssuer: + standard: + excludeClientIPFromCrumb: true + security: + apiToken: + creationOfLegacyTokenEnabled: false + tokenGenerationOnCreationEnabled: false + usageStatisticsEnabled: true + unclassified: + location: + adminAddress: + url: http://RELEASE-NAME-jenkins:8080 + - it: legacyRemotingSecurityEnabled = false + release: + namespace: default + set: + controller: + legacyRemotingSecurityEnabled: false + asserts: + - isKind: + of: ConfigMap + - hasDocuments: + count: 1 + - isNotEmpty: + path: data.jcasc-default-config\.yaml + - matchRegex: + path: metadata.labels.helm\.sh/chart + pattern: ^jenkins- + - equal: + path: data.jcasc-default-config\.yaml + value: |- + jenkins: + authorizationStrategy: + loggedInUsersCanDoAnything: + allowAnonymousRead: false + securityRealm: + local: + allowsSignup: false + enableCaptcha: false + users: + - id: "${chart-admin-username}" + name: "Jenkins Admin" + password: "${chart-admin-password}" + disableRememberMe: false + mode: NORMAL + numExecutors: 0 + labelString: "" + projectNamingStrategy: "standard" + markupFormatter: + plainText + clouds: + - kubernetes: + containerCapStr: "10" + defaultsProviderTemplate: "" + connectTimeout: "5" + readTimeout: "15" + jenkinsUrl: "http://RELEASE-NAME-jenkins.default.svc.cluster.local:8080" + jenkinsTunnel: "RELEASE-NAME-jenkins-agent.default.svc.cluster.local:50000" + maxRequestsPerHostStr: "32" + name: "kubernetes" + namespace: "default" + serverUrl: "https://kubernetes.default" + podLabels: + - key: "jenkins/RELEASE-NAME-jenkins-agent" + value: "true" + templates: + - name: "default" + namespace: "default" + id: 474be7705ac6cddeedf68ad2962972dd9921f64c6e534967402794fbf06a21ec + containers: + - name: "jnlp" + alwaysPullImage: false + args: "^${computer.jnlpmac} ^${computer.name}" + command: + envVars: + - envVar: + key: "JENKINS_URL" + value: "http://RELEASE-NAME-jenkins.default.svc.cluster.local:8080/" + image: "jenkins/inbound-agent:4.11.2-4" + privileged: "false" + resourceLimitCpu: 512m + resourceLimitMemory: 512Mi + resourceRequestCpu: 512m + resourceRequestMemory: 512Mi + runAsUser: + runAsGroup: + ttyEnabled: false + workingDir: /home/jenkins/agent + idleMinutes: 0 + instanceCap: 2147483647 + label: "RELEASE-NAME-jenkins-agent " + nodeUsageMode: "NORMAL" + podRetention: Never + showRawYaml: true + serviceAccount: "default" + slaveConnectTimeoutStr: "100" + yamlMergeStrategy: override + crumbIssuer: + standard: + excludeClientIPFromCrumb: true + security: + apiToken: + creationOfLegacyTokenEnabled: false + tokenGenerationOnCreationEnabled: false + usageStatisticsEnabled: true + unclassified: + location: + adminAddress: + url: http://RELEASE-NAME-jenkins:8080 + - it: legacyRemotingSecurityEnabled = true + release: + namespace: default + set: + controller: + legacyRemotingSecurityEnabled: true + asserts: + - isKind: + of: ConfigMap + - hasDocuments: + count: 1 + - isNotEmpty: + path: data.jcasc-default-config\.yaml + - matchRegex: + path: metadata.labels.helm\.sh/chart + pattern: ^jenkins- + - equal: + path: data.jcasc-default-config\.yaml + value: |- + jenkins: + authorizationStrategy: + loggedInUsersCanDoAnything: + allowAnonymousRead: false + securityRealm: + local: + allowsSignup: false + enableCaptcha: false + users: + - id: "${chart-admin-username}" + name: "Jenkins Admin" + password: "${chart-admin-password}" + disableRememberMe: false + remotingSecurity: + enabled: true + mode: NORMAL + numExecutors: 0 + labelString: "" + projectNamingStrategy: "standard" + markupFormatter: + plainText + clouds: + - kubernetes: + containerCapStr: "10" + defaultsProviderTemplate: "" + connectTimeout: "5" + readTimeout: "15" + jenkinsUrl: "http://RELEASE-NAME-jenkins.default.svc.cluster.local:8080" + jenkinsTunnel: "RELEASE-NAME-jenkins-agent.default.svc.cluster.local:50000" + maxRequestsPerHostStr: "32" + name: "kubernetes" + namespace: "default" + serverUrl: "https://kubernetes.default" + podLabels: + - key: "jenkins/RELEASE-NAME-jenkins-agent" + value: "true" + templates: + - name: "default" + namespace: "default" + id: 474be7705ac6cddeedf68ad2962972dd9921f64c6e534967402794fbf06a21ec + containers: + - name: "jnlp" + alwaysPullImage: false + args: "^${computer.jnlpmac} ^${computer.name}" + command: + envVars: + - envVar: + key: "JENKINS_URL" + value: "http://RELEASE-NAME-jenkins.default.svc.cluster.local:8080/" + image: "jenkins/inbound-agent:4.11.2-4" + privileged: "false" + resourceLimitCpu: 512m + resourceLimitMemory: 512Mi + resourceRequestCpu: 512m + resourceRequestMemory: 512Mi + runAsUser: + runAsGroup: + ttyEnabled: false + workingDir: /home/jenkins/agent + idleMinutes: 0 + instanceCap: 2147483647 + label: "RELEASE-NAME-jenkins-agent " + nodeUsageMode: "NORMAL" + podRetention: Never + showRawYaml: true + serviceAccount: "default" + slaveConnectTimeoutStr: "100" + yamlMergeStrategy: override + crumbIssuer: + standard: + excludeClientIPFromCrumb: true + security: + apiToken: + creationOfLegacyTokenEnabled: false + tokenGenerationOnCreationEnabled: false + usageStatisticsEnabled: true + unclassified: + location: + adminAddress: + url: http://RELEASE-NAME-jenkins:8080 + - it: empty projectNamingStrategy + release: + namespace: default + set: + controller: + projectNamingStrategy: + asserts: + - equal: + path: data.jcasc-default-config\.yaml + value: |- + jenkins: + authorizationStrategy: + loggedInUsersCanDoAnything: + allowAnonymousRead: false + securityRealm: + local: + allowsSignup: false + enableCaptcha: false + users: + - id: "${chart-admin-username}" + name: "Jenkins Admin" + password: "${chart-admin-password}" + disableRememberMe: false + mode: NORMAL + numExecutors: 0 + labelString: "" + markupFormatter: + plainText + clouds: + - kubernetes: + containerCapStr: "10" + defaultsProviderTemplate: "" + connectTimeout: "5" + readTimeout: "15" + jenkinsUrl: "http://RELEASE-NAME-jenkins.default.svc.cluster.local:8080" + jenkinsTunnel: "RELEASE-NAME-jenkins-agent.default.svc.cluster.local:50000" + maxRequestsPerHostStr: "32" + name: "kubernetes" + namespace: "default" + serverUrl: "https://kubernetes.default" + podLabels: + - key: "jenkins/RELEASE-NAME-jenkins-agent" + value: "true" + templates: + - name: "default" + namespace: "default" + id: 474be7705ac6cddeedf68ad2962972dd9921f64c6e534967402794fbf06a21ec + containers: + - name: "jnlp" + alwaysPullImage: false + args: "^${computer.jnlpmac} ^${computer.name}" + command: + envVars: + - envVar: + key: "JENKINS_URL" + value: "http://RELEASE-NAME-jenkins.default.svc.cluster.local:8080/" + image: "jenkins/inbound-agent:4.11.2-4" + privileged: "false" + resourceLimitCpu: 512m + resourceLimitMemory: 512Mi + resourceRequestCpu: 512m + resourceRequestMemory: 512Mi + runAsUser: + runAsGroup: + ttyEnabled: false + workingDir: /home/jenkins/agent + idleMinutes: 0 + instanceCap: 2147483647 + label: "RELEASE-NAME-jenkins-agent " + nodeUsageMode: "NORMAL" + podRetention: Never + showRawYaml: true + serviceAccount: "default" + slaveConnectTimeoutStr: "100" + yamlMergeStrategy: override + crumbIssuer: + standard: + excludeClientIPFromCrumb: true + security: + apiToken: + creationOfLegacyTokenEnabled: false + tokenGenerationOnCreationEnabled: false + usageStatisticsEnabled: true + unclassified: + location: + adminAddress: + url: http://RELEASE-NAME-jenkins:8080 + - it: non-string projectNamingStrategy + release: + namespace: default + set: + controller: + projectNamingStrategy: + myConfiguration: + mySetting1: true + mySetting2: something + asserts: + - equal: + path: data.jcasc-default-config\.yaml + value: |- + jenkins: + authorizationStrategy: + loggedInUsersCanDoAnything: + allowAnonymousRead: false + securityRealm: + local: + allowsSignup: false + enableCaptcha: false + users: + - id: "${chart-admin-username}" + name: "Jenkins Admin" + password: "${chart-admin-password}" + disableRememberMe: false + mode: NORMAL + numExecutors: 0 + labelString: "" + projectNamingStrategy: + myConfiguration: + mySetting1: true + mySetting2: something + markupFormatter: + plainText + clouds: + - kubernetes: + containerCapStr: "10" + defaultsProviderTemplate: "" + connectTimeout: "5" + readTimeout: "15" + jenkinsUrl: "http://RELEASE-NAME-jenkins.default.svc.cluster.local:8080" + jenkinsTunnel: "RELEASE-NAME-jenkins-agent.default.svc.cluster.local:50000" + maxRequestsPerHostStr: "32" + name: "kubernetes" + namespace: "default" + serverUrl: "https://kubernetes.default" + podLabels: + - key: "jenkins/RELEASE-NAME-jenkins-agent" + value: "true" + templates: + - name: "default" + namespace: "default" + id: 474be7705ac6cddeedf68ad2962972dd9921f64c6e534967402794fbf06a21ec + containers: + - name: "jnlp" + alwaysPullImage: false + args: "^${computer.jnlpmac} ^${computer.name}" + command: + envVars: + - envVar: + key: "JENKINS_URL" + value: "http://RELEASE-NAME-jenkins.default.svc.cluster.local:8080/" + image: "jenkins/inbound-agent:4.11.2-4" + privileged: "false" + resourceLimitCpu: 512m + resourceLimitMemory: 512Mi + resourceRequestCpu: 512m + resourceRequestMemory: 512Mi + runAsUser: + runAsGroup: + ttyEnabled: false + workingDir: /home/jenkins/agent + idleMinutes: 0 + instanceCap: 2147483647 + label: "RELEASE-NAME-jenkins-agent " + nodeUsageMode: "NORMAL" + podRetention: Never + showRawYaml: true + serviceAccount: "default" + slaveConnectTimeoutStr: "100" + yamlMergeStrategy: override + crumbIssuer: + standard: + excludeClientIPFromCrumb: true + security: + apiToken: + creationOfLegacyTokenEnabled: false + tokenGenerationOnCreationEnabled: false + usageStatisticsEnabled: true + unclassified: + location: + adminAddress: + url: http://RELEASE-NAME-jenkins:8080 + - it: specify security settings without apiToken override + release: + namespace: default + set: + controller: + JCasC: + security: + gitHostKeyVerificationConfiguration: + sshHostKeyVerificationStrategy: "acceptFirstConnectionStrategy" + asserts: + - equal: + path: data.jcasc-default-config\.yaml + value: |- + jenkins: + authorizationStrategy: + loggedInUsersCanDoAnything: + allowAnonymousRead: false + securityRealm: + local: + allowsSignup: false + enableCaptcha: false + users: + - id: "${chart-admin-username}" + name: "Jenkins Admin" + password: "${chart-admin-password}" + disableRememberMe: false + mode: NORMAL + numExecutors: 0 + labelString: "" + projectNamingStrategy: "standard" + markupFormatter: + plainText + clouds: + - kubernetes: + containerCapStr: "10" + defaultsProviderTemplate: "" + connectTimeout: "5" + readTimeout: "15" + jenkinsUrl: "http://RELEASE-NAME-jenkins.default.svc.cluster.local:8080" + jenkinsTunnel: "RELEASE-NAME-jenkins-agent.default.svc.cluster.local:50000" + maxRequestsPerHostStr: "32" + name: "kubernetes" + namespace: "default" + serverUrl: "https://kubernetes.default" + podLabels: + - key: "jenkins/RELEASE-NAME-jenkins-agent" + value: "true" + templates: + - name: "default" + namespace: "default" + id: 474be7705ac6cddeedf68ad2962972dd9921f64c6e534967402794fbf06a21ec + containers: + - name: "jnlp" + alwaysPullImage: false + args: "^${computer.jnlpmac} ^${computer.name}" + command: + envVars: + - envVar: + key: "JENKINS_URL" + value: "http://RELEASE-NAME-jenkins.default.svc.cluster.local:8080/" + image: "jenkins/inbound-agent:4.11.2-4" + privileged: "false" + resourceLimitCpu: 512m + resourceLimitMemory: 512Mi + resourceRequestCpu: 512m + resourceRequestMemory: 512Mi + runAsUser: + runAsGroup: + ttyEnabled: false + workingDir: /home/jenkins/agent + idleMinutes: 0 + instanceCap: 2147483647 + label: "RELEASE-NAME-jenkins-agent " + nodeUsageMode: "NORMAL" + podRetention: Never + showRawYaml: true + serviceAccount: "default" + slaveConnectTimeoutStr: "100" + yamlMergeStrategy: override + crumbIssuer: + standard: + excludeClientIPFromCrumb: true + security: + apiToken: + creationOfLegacyTokenEnabled: false + tokenGenerationOnCreationEnabled: false + usageStatisticsEnabled: true + gitHostKeyVerificationConfiguration: + sshHostKeyVerificationStrategy: acceptFirstConnectionStrategy + unclassified: + location: + adminAddress: + url: http://RELEASE-NAME-jenkins:8080 + - it: specify security settings without apiToken override + release: + namespace: default + set: + controller: + JCasC: + security: + apiToken: overridden + asserts: + - equal: + path: data.jcasc-default-config\.yaml + value: |- + jenkins: + authorizationStrategy: + loggedInUsersCanDoAnything: + allowAnonymousRead: false + securityRealm: + local: + allowsSignup: false + enableCaptcha: false + users: + - id: "${chart-admin-username}" + name: "Jenkins Admin" + password: "${chart-admin-password}" + disableRememberMe: false + mode: NORMAL + numExecutors: 0 + labelString: "" + projectNamingStrategy: "standard" + markupFormatter: + plainText + clouds: + - kubernetes: + containerCapStr: "10" + defaultsProviderTemplate: "" + connectTimeout: "5" + readTimeout: "15" + jenkinsUrl: "http://RELEASE-NAME-jenkins.default.svc.cluster.local:8080" + jenkinsTunnel: "RELEASE-NAME-jenkins-agent.default.svc.cluster.local:50000" + maxRequestsPerHostStr: "32" + name: "kubernetes" + namespace: "default" + serverUrl: "https://kubernetes.default" + podLabels: + - key: "jenkins/RELEASE-NAME-jenkins-agent" + value: "true" + templates: + - name: "default" + namespace: "default" + id: 474be7705ac6cddeedf68ad2962972dd9921f64c6e534967402794fbf06a21ec + containers: + - name: "jnlp" + alwaysPullImage: false + args: "^${computer.jnlpmac} ^${computer.name}" + command: + envVars: + - envVar: + key: "JENKINS_URL" + value: "http://RELEASE-NAME-jenkins.default.svc.cluster.local:8080/" + image: "jenkins/inbound-agent:4.11.2-4" + privileged: "false" + resourceLimitCpu: 512m + resourceLimitMemory: 512Mi + resourceRequestCpu: 512m + resourceRequestMemory: 512Mi + runAsUser: + runAsGroup: + ttyEnabled: false + workingDir: /home/jenkins/agent + idleMinutes: 0 + instanceCap: 2147483647 + label: "RELEASE-NAME-jenkins-agent " + nodeUsageMode: "NORMAL" + podRetention: Never + showRawYaml: true + serviceAccount: "default" + slaveConnectTimeoutStr: "100" + yamlMergeStrategy: override + crumbIssuer: + standard: + excludeClientIPFromCrumb: true + security: + apiToken: overridden + unclassified: + location: + adminAddress: + url: http://RELEASE-NAME-jenkins:8080 + - it: specify additional container + release: + namespace: default + set: + agent: + additionalContainers: + - sideContainerName: dind + image: docker + tag: dind + command: dockerd-entrypoint.sh + args: "" + privileged: true + asserts: + - equal: + path: data.jcasc-default-config\.yaml + value: |- + jenkins: + authorizationStrategy: + loggedInUsersCanDoAnything: + allowAnonymousRead: false + securityRealm: + local: + allowsSignup: false + enableCaptcha: false + users: + - id: "${chart-admin-username}" + name: "Jenkins Admin" + password: "${chart-admin-password}" + disableRememberMe: false + mode: NORMAL + numExecutors: 0 + labelString: "" + projectNamingStrategy: "standard" + markupFormatter: + plainText + clouds: + - kubernetes: + containerCapStr: "10" + defaultsProviderTemplate: "" + connectTimeout: "5" + readTimeout: "15" + jenkinsUrl: "http://RELEASE-NAME-jenkins.default.svc.cluster.local:8080" + jenkinsTunnel: "RELEASE-NAME-jenkins-agent.default.svc.cluster.local:50000" + maxRequestsPerHostStr: "32" + name: "kubernetes" + namespace: "default" + serverUrl: "https://kubernetes.default" + podLabels: + - key: "jenkins/RELEASE-NAME-jenkins-agent" + value: "true" + templates: + - name: "default" + namespace: "default" + id: 566cced37b2c61da0c884c892e5c0a58834fce925c6f836de7b65313a94be9e3 + containers: + - name: "jnlp" + alwaysPullImage: false + args: "^${computer.jnlpmac} ^${computer.name}" + command: + envVars: + - envVar: + key: "JENKINS_URL" + value: "http://RELEASE-NAME-jenkins.default.svc.cluster.local:8080/" + image: "jenkins/inbound-agent:4.11.2-4" + privileged: "false" + resourceLimitCpu: 512m + resourceLimitMemory: 512Mi + resourceRequestCpu: 512m + resourceRequestMemory: 512Mi + runAsUser: + runAsGroup: + ttyEnabled: false + workingDir: /home/jenkins/agent + - name: "dind" + alwaysPullImage: false + args: "" + command: dockerd-entrypoint.sh + envVars: + - envVar: + key: "JENKINS_URL" + value: "http://RELEASE-NAME-jenkins.default.svc.cluster.local:8080/" + image: "docker:dind" + privileged: "true" + resourceLimitCpu: 512m + resourceLimitMemory: 512Mi + resourceRequestCpu: 512m + resourceRequestMemory: 512Mi + runAsUser: + runAsGroup: + ttyEnabled: false + workingDir: /home/jenkins/agent + idleMinutes: 0 + instanceCap: 2147483647 + label: "RELEASE-NAME-jenkins-agent " + nodeUsageMode: "NORMAL" + podRetention: Never + showRawYaml: true + serviceAccount: "default" + slaveConnectTimeoutStr: "100" + yamlMergeStrategy: override + crumbIssuer: + standard: + excludeClientIPFromCrumb: true + security: + apiToken: + creationOfLegacyTokenEnabled: false + tokenGenerationOnCreationEnabled: false + usageStatisticsEnabled: true + unclassified: + location: + adminAddress: + url: http://RELEASE-NAME-jenkins:8080 + - it: specify additional container and overwrite in additional agent + release: + namespace: default + set: + agent: + additionalContainers: + - sideContainerName: dind + image: docker + tag: dind + command: dockerd-entrypoint.sh + args: "" + privileged: true + additionalAgents: + additional-agent: + podName: additional-agent + additionalContainers: + - sideContainerName: additional + image: my-additional-container-image + tag: latest + command: entrypoint.sh + args: arg1 arg2 + asserts: + - equal: + path: data.jcasc-default-config\.yaml + value: |- + jenkins: + authorizationStrategy: + loggedInUsersCanDoAnything: + allowAnonymousRead: false + securityRealm: + local: + allowsSignup: false + enableCaptcha: false + users: + - id: "${chart-admin-username}" + name: "Jenkins Admin" + password: "${chart-admin-password}" + disableRememberMe: false + mode: NORMAL + numExecutors: 0 + labelString: "" + projectNamingStrategy: "standard" + markupFormatter: + plainText + clouds: + - kubernetes: + containerCapStr: "10" + defaultsProviderTemplate: "" + connectTimeout: "5" + readTimeout: "15" + jenkinsUrl: "http://RELEASE-NAME-jenkins.default.svc.cluster.local:8080" + jenkinsTunnel: "RELEASE-NAME-jenkins-agent.default.svc.cluster.local:50000" + maxRequestsPerHostStr: "32" + name: "kubernetes" + namespace: "default" + serverUrl: "https://kubernetes.default" + podLabels: + - key: "jenkins/RELEASE-NAME-jenkins-agent" + value: "true" + templates: + - name: "default" + namespace: "default" + id: 566cced37b2c61da0c884c892e5c0a58834fce925c6f836de7b65313a94be9e3 + containers: + - name: "jnlp" + alwaysPullImage: false + args: "^${computer.jnlpmac} ^${computer.name}" + command: + envVars: + - envVar: + key: "JENKINS_URL" + value: "http://RELEASE-NAME-jenkins.default.svc.cluster.local:8080/" + image: "jenkins/inbound-agent:4.11.2-4" + privileged: "false" + resourceLimitCpu: 512m + resourceLimitMemory: 512Mi + resourceRequestCpu: 512m + resourceRequestMemory: 512Mi + runAsUser: + runAsGroup: + ttyEnabled: false + workingDir: /home/jenkins/agent + - name: "dind" + alwaysPullImage: false + args: "" + command: dockerd-entrypoint.sh + envVars: + - envVar: + key: "JENKINS_URL" + value: "http://RELEASE-NAME-jenkins.default.svc.cluster.local:8080/" + image: "docker:dind" + privileged: "true" + resourceLimitCpu: 512m + resourceLimitMemory: 512Mi + resourceRequestCpu: 512m + resourceRequestMemory: 512Mi + runAsUser: + runAsGroup: + ttyEnabled: false + workingDir: /home/jenkins/agent + idleMinutes: 0 + instanceCap: 2147483647 + label: "RELEASE-NAME-jenkins-agent " + nodeUsageMode: "NORMAL" + podRetention: Never + showRawYaml: true + serviceAccount: "default" + slaveConnectTimeoutStr: "100" + yamlMergeStrategy: override + - name: "additional-agent" + namespace: "default" + id: 0435d8506bd07c2eefccca326695b5a9a067849c450e3ee9fdcb13bede5c8e7b + containers: + - name: "jnlp" + alwaysPullImage: false + args: "^${computer.jnlpmac} ^${computer.name}" + command: + envVars: + - envVar: + key: "JENKINS_URL" + value: "http://RELEASE-NAME-jenkins.default.svc.cluster.local:8080/" + image: "jenkins/inbound-agent:4.11.2-4" + privileged: "false" + resourceLimitCpu: 512m + resourceLimitMemory: 512Mi + resourceRequestCpu: 512m + resourceRequestMemory: 512Mi + runAsUser: + runAsGroup: + ttyEnabled: false + workingDir: /home/jenkins/agent + - name: "additional" + alwaysPullImage: false + args: "arg1 arg2" + command: entrypoint.sh + envVars: + - envVar: + key: "JENKINS_URL" + value: "http://RELEASE-NAME-jenkins.default.svc.cluster.local:8080/" + image: "my-additional-container-image:latest" + privileged: "false" + resourceLimitCpu: 512m + resourceLimitMemory: 512Mi + resourceRequestCpu: 512m + resourceRequestMemory: 512Mi + runAsUser: + runAsGroup: + ttyEnabled: false + workingDir: /home/jenkins/agent + idleMinutes: 0 + instanceCap: 2147483647 + label: "RELEASE-NAME-jenkins-agent " + nodeUsageMode: "NORMAL" + podRetention: Never + showRawYaml: true + serviceAccount: "default" + slaveConnectTimeoutStr: "100" + yamlMergeStrategy: override + crumbIssuer: + standard: + excludeClientIPFromCrumb: true + security: + apiToken: + creationOfLegacyTokenEnabled: false + tokenGenerationOnCreationEnabled: false + usageStatisticsEnabled: true + unclassified: + location: + adminAddress: + url: http://RELEASE-NAME-jenkins:8080 + - it: specify additional container and clear in additional agent + release: + namespace: default + set: + agent: + additionalContainers: + - sideContainerName: dind + image: docker + tag: dind + command: dockerd-entrypoint.sh + args: "" + privileged: true + additionalAgents: + additional-agent: + podName: additional-agent + additionalContainers: [] + asserts: + - equal: + path: data.jcasc-default-config\.yaml + value: |- + jenkins: + authorizationStrategy: + loggedInUsersCanDoAnything: + allowAnonymousRead: false + securityRealm: + local: + allowsSignup: false + enableCaptcha: false + users: + - id: "${chart-admin-username}" + name: "Jenkins Admin" + password: "${chart-admin-password}" + disableRememberMe: false + mode: NORMAL + numExecutors: 0 + labelString: "" + projectNamingStrategy: "standard" + markupFormatter: + plainText + clouds: + - kubernetes: + containerCapStr: "10" + defaultsProviderTemplate: "" + connectTimeout: "5" + readTimeout: "15" + jenkinsUrl: "http://RELEASE-NAME-jenkins.default.svc.cluster.local:8080" + jenkinsTunnel: "RELEASE-NAME-jenkins-agent.default.svc.cluster.local:50000" + maxRequestsPerHostStr: "32" + name: "kubernetes" + namespace: "default" + serverUrl: "https://kubernetes.default" + podLabels: + - key: "jenkins/RELEASE-NAME-jenkins-agent" + value: "true" + templates: + - name: "default" + namespace: "default" + id: 566cced37b2c61da0c884c892e5c0a58834fce925c6f836de7b65313a94be9e3 + containers: + - name: "jnlp" + alwaysPullImage: false + args: "^${computer.jnlpmac} ^${computer.name}" + command: + envVars: + - envVar: + key: "JENKINS_URL" + value: "http://RELEASE-NAME-jenkins.default.svc.cluster.local:8080/" + image: "jenkins/inbound-agent:4.11.2-4" + privileged: "false" + resourceLimitCpu: 512m + resourceLimitMemory: 512Mi + resourceRequestCpu: 512m + resourceRequestMemory: 512Mi + runAsUser: + runAsGroup: + ttyEnabled: false + workingDir: /home/jenkins/agent + - name: "dind" + alwaysPullImage: false + args: "" + command: dockerd-entrypoint.sh + envVars: + - envVar: + key: "JENKINS_URL" + value: "http://RELEASE-NAME-jenkins.default.svc.cluster.local:8080/" + image: "docker:dind" + privileged: "true" + resourceLimitCpu: 512m + resourceLimitMemory: 512Mi + resourceRequestCpu: 512m + resourceRequestMemory: 512Mi + runAsUser: + runAsGroup: + ttyEnabled: false + workingDir: /home/jenkins/agent + idleMinutes: 0 + instanceCap: 2147483647 + label: "RELEASE-NAME-jenkins-agent " + nodeUsageMode: "NORMAL" + podRetention: Never + showRawYaml: true + serviceAccount: "default" + slaveConnectTimeoutStr: "100" + yamlMergeStrategy: override + - name: "additional-agent" + namespace: "default" + id: 0024a08654abb917be24d9bb330a5fc2f6cc003c117e12f685922fceae4a7e93 + containers: + - name: "jnlp" + alwaysPullImage: false + args: "^${computer.jnlpmac} ^${computer.name}" + command: + envVars: + - envVar: + key: "JENKINS_URL" + value: "http://RELEASE-NAME-jenkins.default.svc.cluster.local:8080/" + image: "jenkins/inbound-agent:4.11.2-4" + privileged: "false" + resourceLimitCpu: 512m + resourceLimitMemory: 512Mi + resourceRequestCpu: 512m + resourceRequestMemory: 512Mi + runAsUser: + runAsGroup: + ttyEnabled: false + workingDir: /home/jenkins/agent + idleMinutes: 0 + instanceCap: 2147483647 + label: "RELEASE-NAME-jenkins-agent " + nodeUsageMode: "NORMAL" + podRetention: Never + showRawYaml: true + serviceAccount: "default" + slaveConnectTimeoutStr: "100" + yamlMergeStrategy: override + crumbIssuer: + standard: + excludeClientIPFromCrumb: true + security: + apiToken: + creationOfLegacyTokenEnabled: false + tokenGenerationOnCreationEnabled: false + usageStatisticsEnabled: true + unclassified: + location: + adminAddress: + url: http://RELEASE-NAME-jenkins:8080 + - it: configure hostnetworking to agent + release: + namespace: default + set: + agent: + hostNetworking: true + asserts: + - equal: + path: data.jcasc-default-config\.yaml + value: |- + jenkins: + authorizationStrategy: + loggedInUsersCanDoAnything: + allowAnonymousRead: false + securityRealm: + local: + allowsSignup: false + enableCaptcha: false + users: + - id: "${chart-admin-username}" + name: "Jenkins Admin" + password: "${chart-admin-password}" + disableRememberMe: false + mode: NORMAL + numExecutors: 0 + labelString: "" + projectNamingStrategy: "standard" + markupFormatter: + plainText + clouds: + - kubernetes: + containerCapStr: "10" + defaultsProviderTemplate: "" + connectTimeout: "5" + readTimeout: "15" + jenkinsUrl: "http://RELEASE-NAME-jenkins.default.svc.cluster.local:8080" + jenkinsTunnel: "RELEASE-NAME-jenkins-agent.default.svc.cluster.local:50000" + maxRequestsPerHostStr: "32" + name: "kubernetes" + namespace: "default" + serverUrl: "https://kubernetes.default" + podLabels: + - key: "jenkins/RELEASE-NAME-jenkins-agent" + value: "true" + templates: + - name: "default" + namespace: "default" + id: 6afb0727de6aa635c049662e567ed2d245a99b8b58431273ba5698c3dcb30a1d + containers: + - name: "jnlp" + alwaysPullImage: false + args: "^${computer.jnlpmac} ^${computer.name}" + command: + envVars: + - envVar: + key: "JENKINS_URL" + value: "http://RELEASE-NAME-jenkins.default.svc.cluster.local:8080/" + image: "jenkins/inbound-agent:4.11.2-4" + privileged: "false" + resourceLimitCpu: 512m + resourceLimitMemory: 512Mi + resourceRequestCpu: 512m + resourceRequestMemory: 512Mi + runAsUser: + runAsGroup: + ttyEnabled: false + workingDir: /home/jenkins/agent + idleMinutes: 0 + instanceCap: 2147483647 + hostNetwork: true + label: "RELEASE-NAME-jenkins-agent " + nodeUsageMode: "NORMAL" + podRetention: Never + showRawYaml: true + serviceAccount: "default" + slaveConnectTimeoutStr: "100" + yamlMergeStrategy: override + crumbIssuer: + standard: + excludeClientIPFromCrumb: true + security: + apiToken: + creationOfLegacyTokenEnabled: false + tokenGenerationOnCreationEnabled: false + usageStatisticsEnabled: true + unclassified: + location: + adminAddress: + url: http://RELEASE-NAME-jenkins:8080 + - it: set secretEnvVars + set: + agent: + secretEnvVars: + - key: UNITTEST_PATH + secretKey: UNITTEST_K8S_PATH + secretName: k8s-unittest-secret-name + envVars: + - name: UNITTEST_ENV + value: testvalue + release: + namespace: default + asserts: + - isKind: + of: ConfigMap + - hasDocuments: + count: 1 + - isNotEmpty: + path: data.jcasc-default-config\.yaml + - matchRegex: + path: metadata.labels.helm\.sh/chart + pattern: ^jenkins- + - equal: + path: data.jcasc-default-config\.yaml + value: |- + jenkins: + authorizationStrategy: + loggedInUsersCanDoAnything: + allowAnonymousRead: false + securityRealm: + local: + allowsSignup: false + enableCaptcha: false + users: + - id: "${chart-admin-username}" + name: "Jenkins Admin" + password: "${chart-admin-password}" + disableRememberMe: false + mode: NORMAL + numExecutors: 0 + labelString: "" + projectNamingStrategy: "standard" + markupFormatter: + plainText + clouds: + - kubernetes: + containerCapStr: "10" + defaultsProviderTemplate: "" + connectTimeout: "5" + readTimeout: "15" + jenkinsUrl: "http://RELEASE-NAME-jenkins.default.svc.cluster.local:8080" + jenkinsTunnel: "RELEASE-NAME-jenkins-agent.default.svc.cluster.local:50000" + maxRequestsPerHostStr: "32" + name: "kubernetes" + namespace: "default" + serverUrl: "https://kubernetes.default" + podLabels: + - key: "jenkins/RELEASE-NAME-jenkins-agent" + value: "true" + templates: + - name: "default" + namespace: "default" + id: fda09c2a838ec94695b64700bb694959c5dd61bd9877d9da406ae93b1707200c + containers: + - name: "jnlp" + alwaysPullImage: false + args: "^${computer.jnlpmac} ^${computer.name}" + command: + envVars: + - envVar: + key: "JENKINS_URL" + value: "http://RELEASE-NAME-jenkins.default.svc.cluster.local:8080/" + image: "jenkins/inbound-agent:4.11.2-4" + privileged: "false" + resourceLimitCpu: 512m + resourceLimitMemory: 512Mi + resourceRequestCpu: 512m + resourceRequestMemory: 512Mi + runAsUser: + runAsGroup: + ttyEnabled: false + workingDir: /home/jenkins/agent + envVars: + - envVar: + key: UNITTEST_ENV + value: testvalue + - secretEnvVar: + key: UNITTEST_PATH + secretName: k8s-unittest-secret-name + secretKey: UNITTEST_K8S_PATH + optional: false + idleMinutes: 0 + instanceCap: 2147483647 + label: "RELEASE-NAME-jenkins-agent " + nodeUsageMode: "NORMAL" + podRetention: Never + showRawYaml: true + serviceAccount: "default" + slaveConnectTimeoutStr: "100" + yamlMergeStrategy: override + crumbIssuer: + standard: + excludeClientIPFromCrumb: true + security: + apiToken: + creationOfLegacyTokenEnabled: false + tokenGenerationOnCreationEnabled: false + usageStatisticsEnabled: true + unclassified: + location: + adminAddress: + url: http://RELEASE-NAME-jenkins:8080 \ No newline at end of file diff --git a/helm/jenkins/unittests/jenkins-agent-svc-test.yaml b/helm/jenkins/unittests/jenkins-agent-svc-test.yaml new file mode 100644 index 0000000..ec1048a --- /dev/null +++ b/helm/jenkins/unittests/jenkins-agent-svc-test.yaml @@ -0,0 +1,130 @@ +suite: Jenkins Agent Service +release: + name: my-release + namespace: my-namespace +templates: + - jenkins-agent-svc.yaml +tests: + - it: default tests + asserts: + - isKind: + of: Service + - equal: + path: apiVersion + value: v1 + - equal: + path: metadata.name + value: my-release-jenkins-agent + - equal: + path: metadata.namespace + value: my-namespace + - matchRegex: + path: metadata.labels.helm\.sh/chart + pattern: ^jenkins- + - isNull: + path: metadata.annotations + - equal: + path: spec + value: + ports: + - name: agent-listener + port: 50000 + targetPort: 50000 + selector: + app.kubernetes.io/component: jenkins-controller + app.kubernetes.io/instance: my-release + type: ClusterIP + - it: other values + set: + controller: + agentListenerServiceAnnotations: + key: value + agentListenerPort: 55555 + asserts: + - equal: + path: metadata.annotations + value: + key: value + - equal: + path: spec + value: + ports: + - name: agent-listener + port: 55555 + targetPort: 55555 + selector: + app.kubernetes.io/component: jenkins-controller + app.kubernetes.io/instance: my-release + type: ClusterIP + - it: node port random + set: + controller: + agentListenerServiceType: NodePort + asserts: + - equal: + path: spec + value: + ports: + - name: agent-listener + port: 50000 + targetPort: 50000 + selector: + app.kubernetes.io/component: jenkins-controller + app.kubernetes.io/instance: my-release + type: NodePort + - it: node port defined + set: + controller: + agentListenerServiceType: NodePort + agentListenerNodePort: 32123 + asserts: + - equal: + path: spec + value: + ports: + - name: agent-listener + port: 50000 + targetPort: 50000 + nodePort: 32123 + selector: + app.kubernetes.io/component: jenkins-controller + app.kubernetes.io/instance: my-release + type: NodePort + - it: load balancer + set: + controller: + agentListenerServiceType: LoadBalancer + agentListenerLoadBalancerIP: 10.10.10.10 + asserts: + - equal: + path: spec + value: + ports: + - name: agent-listener + port: 50000 + targetPort: 50000 + selector: + app.kubernetes.io/component: jenkins-controller + app.kubernetes.io/instance: my-release + type: LoadBalancer + loadBalancerIP: 10.10.10.10 + loadBalancerSourceRanges: + - 0.0.0.0/0 + - it: disable helm.sh label + set: + renderHelmLabels: false + asserts: + - equal: + path: metadata.labels + value: + app.kubernetes.io/component: jenkins-controller + app.kubernetes.io/instance: my-release + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: jenkins + - it: disable agent service + set: + controller: + agentListenerEnabled: false + asserts: + - hasDocuments: + count: 0 \ No newline at end of file diff --git a/helm/jenkins/unittests/jenkins-backup-cronjob-test.yaml b/helm/jenkins/unittests/jenkins-backup-cronjob-test.yaml new file mode 100644 index 0000000..e1dd18f --- /dev/null +++ b/helm/jenkins/unittests/jenkins-backup-cronjob-test.yaml @@ -0,0 +1,62 @@ +suite: Jenkins Backup Cronjob +release: + name: my-release + namespace: my-namespace +templates: + - jenkins-backup-cronjob.yaml +tests: + - it: test default values + set: + backup: + enabled: true + asserts: + - isKind: + of: CronJob + - equal: + path: spec.jobTemplate.spec.template.spec.securityContext + value: + fsGroup: 1000 + runAsUser: 1000 + - it: test empty backup.podSecurityContextOverride + set: + backup: + enabled: true + podSecurityContextOverride: {} + asserts: + - equal: + path: spec.jobTemplate.spec.template.spec.securityContext + value: {} + - it: test backup.podSecurityContextOverride + set: + backup: + enabled: true + podSecurityContextOverride: + runAsNonRoot: true + runAsUser: 4444 + supplementalGroups: [5555] + asserts: + - equal: + path: spec.jobTemplate.spec.template.spec.securityContext + value: + runAsNonRoot: true + runAsUser: 4444 + supplementalGroups: + - 5555 + - it: test empty backup.imagePullSecretName + set: + backup: + enabled: true + imagePullSecretName: + asserts: + - isNull: + path: spec.jobTemplate.spec.template.spec.imagePullSecrets + - it: test backup.imagePullSecretName + set: + backup: + enabled: true + imagePullSecretName: my-secret + asserts: + - equal: + path: spec.jobTemplate.spec.template.spec.imagePullSecrets + value: + - name: my-secret diff --git a/helm/jenkins/unittests/jenkins-controller-alerting-rules-test.yaml b/helm/jenkins/unittests/jenkins-controller-alerting-rules-test.yaml new file mode 100644 index 0000000..bdeece8 --- /dev/null +++ b/helm/jenkins/unittests/jenkins-controller-alerting-rules-test.yaml @@ -0,0 +1,79 @@ +suite: Controller Prometheus PrometheusRule +release: + name: my-release + namespace: my-namespace +templates: + - jenkins-controller-alerting-rules.yaml +tests: + - it: defaults + asserts: + - hasDocuments: + count: 0 + - it: enabled + set: + controller.prometheus: + enabled: true + alertingrules: + - name: ./jenkins.rules + rules: + - alert: JenkinsFailedPlugins + expr: jenkins_plugins_failed > 0 + for: 10m + labels: + severity: warning + annotations: + message: Some Jenkins plugins failed to load + asserts: + - isKind: + of: PrometheusRule + - equal: + path: apiVersion + value: monitoring.coreos.com/v1 + - equal: + path: metadata.name + value: my-release-jenkins + - matchRegex: + path: metadata.labels.helm\.sh/chart + pattern: ^jenkins- + - equal: + path: metadata.namespace + value: my-namespace + - matchRegex: + path: metadata.labels.helm\.sh/chart + pattern: ^jenkins- + - equal: + path: spec + value: + groups: + - name: ./jenkins.rules + rules: + - alert: JenkinsFailedPlugins + expr: jenkins_plugins_failed > 0 + for: 10m + labels: + severity: warning + annotations: + message: Some Jenkins plugins failed to load + - it: disable helm.sh label + set: + renderHelmLabels: false + controller.prometheus: + enabled: true + alertingrules: + - name: ./jenkins.rules + rules: + - alert: JenkinsFailedPlugins + expr: jenkins_plugins_failed > 0 + for: 10m + labels: + severity: warning + annotations: + message: Some Jenkins plugins failed to load + asserts: + - equal: + path: metadata.labels + value: + app.kubernetes.io/component: jenkins-controller + app.kubernetes.io/instance: my-release + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: jenkins \ No newline at end of file diff --git a/helm/jenkins/unittests/jenkins-controller-ingress-1.19-test.yaml b/helm/jenkins/unittests/jenkins-controller-ingress-1.19-test.yaml new file mode 100644 index 0000000..0183331 --- /dev/null +++ b/helm/jenkins/unittests/jenkins-controller-ingress-1.19-test.yaml @@ -0,0 +1,148 @@ +suite: Controller Primary Ingress +release: + name: my-release + namespace: my-namespace +templates: + - jenkins-controller-ingress.yaml +capabilities: + majorVersion: 1 + minorVersion: 19 +tests: + - it: test defaults + asserts: + - hasDocuments: + count: 0 + - it: enabled + set: + controller.ingress: + enabled: true + hostName: jenkins.example.com + ingressClassName: nginx + tls: + - secretName: tlsSecret + hosts: + - jenkins.example.com + asserts: + - isKind: + of: Ingress + - equal: + path: apiVersion + value: networking.k8s.io/v1 + - equal: + path: metadata.name + value: my-release-jenkins + - equal: + path: metadata.namespace + value: my-namespace + - matchRegex: + path: metadata.labels.helm\.sh/chart + pattern: ^jenkins- + - isNull: + path: metadata.annotations + - equal: + path: spec + value: + ingressClassName: nginx + rules: + - host: jenkins.example.com + http: + paths: + - backend: + service: + name: my-release-jenkins + port: + number: 8080 + pathType: ImplementationSpecific + tls: + - hosts: + - jenkins.example.com + secretName: tlsSecret + - it: other values + set: + controller.ingress: + enabled: true + hostName: jenkins.example.com + ingressClassName: nginx + annotations: + kubernetes.io/ingress.class: nginx + kubernetes.io/tls-acme: "true" + paths: + - backend: + service: + name: ssl-redirect + port: + number: use-annotation + pathType: ImplementationSpecific + - backend: + service: + name: >- + {{ template "jenkins.fullname" . }} + port: + number: 8080 + pathType: ImplementationSpecific + tls: + - secretName: tlsSecret + hosts: + - jenkins.example.com + asserts: + - equal: + path: metadata.annotations + value: + kubernetes.io/ingress.class: nginx + kubernetes.io/tls-acme: "true" + - equal: + path: spec + value: + ingressClassName: nginx + rules: + - host: jenkins.example.com + http: + paths: + - backend: + service: + name: ssl-redirect + port: + number: use-annotation + pathType: ImplementationSpecific + - backend: + service: + name: my-release-jenkins + port: + number: 8080 + pathType: ImplementationSpecific + tls: + - hosts: + - jenkins.example.com + secretName: tlsSecret + - it: disable helm.sh label + set: + renderHelmLabels: false + controller.ingress: + enabled: true + hostName: jenkins.example.com + ingressClassName: nginx + asserts: + - equal: + path: metadata.labels + value: + app.kubernetes.io/component: jenkins-controller + app.kubernetes.io/instance: my-release + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: jenkins + - it: empty paths + set: + controller.ingress: + enabled: true + paths: + asserts: + - equal: + path: spec.rules + value: + - http: + paths: + - backend: + service: + name: my-release-jenkins + port: + number: 8080 + pathType: ImplementationSpecific diff --git a/helm/jenkins/unittests/jenkins-controller-ingress-test.yaml b/helm/jenkins/unittests/jenkins-controller-ingress-test.yaml new file mode 100644 index 0000000..6508d7e --- /dev/null +++ b/helm/jenkins/unittests/jenkins-controller-ingress-test.yaml @@ -0,0 +1,145 @@ +suite: Controller Primary Ingress +release: + name: my-release + namespace: my-namespace +templates: + - jenkins-controller-ingress.yaml +capabilities: + majorVersion: 1 + minorVersion: 18 +tests: + - it: test defaults + asserts: + - hasDocuments: + count: 0 + - it: enabled + set: + controller.ingress: + enabled: true + hostName: jenkins.example.com + ingressClassName: nginx + tls: + - secretName: tlsSecret + hosts: + - jenkins.example.com + asserts: + - isKind: + of: Ingress + - equal: + path: apiVersion + value: networking.k8s.io/v1beta1 + - equal: + path: metadata.name + value: my-release-jenkins + - equal: + path: metadata.namespace + value: my-namespace + - matchRegex: + path: metadata.labels.helm\.sh/chart + pattern: ^jenkins- + - isNull: + path: metadata.annotations + - equal: + path: spec + value: + ingressClassName: nginx + rules: + - host: jenkins.example.com + http: + paths: + - backend: + serviceName: my-release-jenkins + servicePort: 8080 + tls: + - hosts: + - jenkins.example.com + secretName: tlsSecret + - it: other values + set: + controller.ingress: + enabled: true + hostName: jenkins.example.com + ingressClassName: nginx + annotations: + kubernetes.io/ingress.class: nginx + kubernetes.io/tls-acme: "true" + paths: + - backend: + serviceName: ssl-redirect + servicePort: use-annotation + - backend: + serviceName: >- + {{ template "jenkins.fullname" . }} + servicePort: 8080 + tls: + - secretName: tlsSecret + hosts: + - jenkins.example.com + asserts: + - equal: + path: metadata.annotations + value: + kubernetes.io/ingress.class: nginx + kubernetes.io/tls-acme: "true" + - equal: + path: spec + value: + ingressClassName: nginx + rules: + - host: jenkins.example.com + http: + paths: + - backend: + serviceName: ssl-redirect + servicePort: use-annotation + - backend: + serviceName: my-release-jenkins + servicePort: 8080 + tls: + - hosts: + - jenkins.example.com + secretName: tlsSecret + - it: disable helm.sh label + set: + renderHelmLabels: false + controller.ingress: + enabled: true + hostName: jenkins.example.com + ingressClassName: nginx + asserts: + - equal: + path: metadata.labels + value: + app.kubernetes.io/component: jenkins-controller + app.kubernetes.io/instance: my-release + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: jenkins + - it: empty paths + set: + controller.ingress: + enabled: true + paths: + asserts: + - equal: + path: spec.rules + value: + - http: + paths: + - backend: + serviceName: my-release-jenkins + servicePort: 8080 + - it: single path + set: + controller.ingress: + enabled: true + path: /jenkins/ + asserts: + - equal: + path: spec.rules + value: + - http: + paths: + - path: /jenkins/ + backend: + serviceName: my-release-jenkins + servicePort: 8080 diff --git a/helm/jenkins/unittests/jenkins-controller-networkpolicy-test.yaml b/helm/jenkins/unittests/jenkins-controller-networkpolicy-test.yaml new file mode 100644 index 0000000..09047ff --- /dev/null +++ b/helm/jenkins/unittests/jenkins-controller-networkpolicy-test.yaml @@ -0,0 +1,94 @@ +suite: Network Policy +release: + name: my-release + namespace: my-namespace +templates: + - jenkins-controller-networkpolicy.yaml +tests: + - it: tests defaults + asserts: + - hasDocuments: + count: 0 + - it: enabled + set: + networkPolicy.enabled: true + asserts: + - hasDocuments: + count: 2 + - isKind: + of: NetworkPolicy + - equal: + path: apiVersion + value: networking.k8s.io/v1 + - equal: + path: metadata.namespace + value: my-namespace + - matchRegex: + path: metadata.labels.helm\.sh/chart + pattern: ^jenkins- + - isNull: + path: metadata.annotations + - equal: + path: metadata.name + value: my-release-jenkins-controller + documentIndex: 0 + - equal: + path: spec + value: + ingress: + - ports: + - port: 8080 + - from: + - podSelector: + matchLabels: + jenkins/my-release-jenkins-agent: "true" + ports: + - port: 50000 + podSelector: + matchLabels: + app.kubernetes.io/component: jenkins-controller + app.kubernetes.io/instance: my-release + documentIndex: 0 + - equal: + path: spec + value: + podSelector: + matchLabels: + jenkins/my-release-jenkins-agent: "true" + documentIndex: 1 + - equal: + path: metadata.name + value: my-release-jenkins-agent + documentIndex: 1 + - it: disable helm.sh label + set: + renderHelmLabels: false + networkPolicy.enabled: true + asserts: + - equal: + path: metadata.labels + value: + app.kubernetes.io/component: jenkins-controller + app.kubernetes.io/instance: my-release + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: jenkins + - it: disable agent listener + set: + networkPolicy.enabled: true + controller.agentListenerEnabled: false + asserts: + - hasDocuments: + count: 2 + - isKind: + of: NetworkPolicy + - equal: + path: spec + value: + ingress: + - ports: + - port: 8080 + podSelector: + matchLabels: + app.kubernetes.io/component: jenkins-controller + app.kubernetes.io/instance: my-release + documentIndex: 0 diff --git a/helm/jenkins/unittests/jenkins-controller-pdb-1.21-test.yaml b/helm/jenkins/unittests/jenkins-controller-pdb-1.21-test.yaml new file mode 100644 index 0000000..c9b6bb7 --- /dev/null +++ b/helm/jenkins/unittests/jenkins-controller-pdb-1.21-test.yaml @@ -0,0 +1,44 @@ +suite: Controller Pod Disruption Budget +release: + name: my-release + namespace: my-namespace +templates: + - jenkins-controller-pdb.yaml +capabilities: + majorVersion: 1 + minorVersion: 21 +tests: + - it: test defaults + asserts: + - hasDocuments: + count: 0 + - it: enabled + set: + controller.podDisruptionBudget: + enabled: true + maxUnavailable: "0" + asserts: + - isKind: + of: PodDisruptionBudget + - equal: + path: apiVersion + value: policy/v1 + - equal: + path: metadata.name + value: my-release-jenkins-pdb + - equal: + path: metadata.namespace + value: my-namespace + - matchRegex: + path: metadata.labels.helm\.sh/chart + pattern: ^jenkins- + - isNull: + path: metadata.annotations + - equal: + path: spec + value: + maxUnavailable: 0 + selector: + matchLabels: + "app.kubernetes.io/instance": "my-release" + "app.kubernetes.io/name": "jenkins" diff --git a/helm/jenkins/unittests/jenkins-controller-pdb-test.yaml b/helm/jenkins/unittests/jenkins-controller-pdb-test.yaml new file mode 100644 index 0000000..7a43bfc --- /dev/null +++ b/helm/jenkins/unittests/jenkins-controller-pdb-test.yaml @@ -0,0 +1,57 @@ +suite: Controller Pod Disruption Budget +release: + name: my-release + namespace: my-namespace +templates: + - jenkins-controller-pdb.yaml +capabilities: + majorVersion: 1 + minorVersion: 18 +tests: + - it: test defaults + asserts: + - hasDocuments: + count: 0 + - it: enabled + set: + controller.podDisruptionBudget: + enabled: true + maxUnavailable: "0" + asserts: + - isKind: + of: PodDisruptionBudget + - equal: + path: apiVersion + value: policy/v1beta1 + - equal: + path: metadata.name + value: my-release-jenkins-pdb + - equal: + path: metadata.namespace + value: my-namespace + - matchRegex: + path: metadata.labels.helm\.sh/chart + pattern: ^jenkins- + - isNull: + path: metadata.annotations + - equal: + path: spec + value: + maxUnavailable: 0 + selector: + matchLabels: + "app.kubernetes.io/instance": "my-release" + "app.kubernetes.io/name": "jenkins" + - it: disable helm.sh label + set: + renderHelmLabels: false + controller.podDisruptionBudget: + enabled: true + asserts: + - equal: + path: metadata.labels + value: + app.kubernetes.io/component: jenkins-controller + app.kubernetes.io/instance: my-release + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: jenkins diff --git a/helm/jenkins/unittests/jenkins-controller-secondary-ingress-1.19-test.yaml b/helm/jenkins/unittests/jenkins-controller-secondary-ingress-1.19-test.yaml new file mode 100644 index 0000000..8df3a34 --- /dev/null +++ b/helm/jenkins/unittests/jenkins-controller-secondary-ingress-1.19-test.yaml @@ -0,0 +1,78 @@ +suite: Controller Secondary Ingress +release: + name: my-release + namespace: my-namespace +templates: + - jenkins-controller-secondary-ingress.yaml +capabilities: + majorVersion: 1 + minorVersion: 19 +tests: + - it: test defaults + asserts: + - hasDocuments: + count: 0 + - it: enabled + set: + controller.secondaryingress: + enabled: true + hostName: jenkins.example.com + ingressClassName: nginx + paths: + - /github-webhook + tls: + - secretName: tlsSecret + hosts: + - jenkins.example.com + asserts: + - isKind: + of: Ingress + - equal: + path: apiVersion + value: networking.k8s.io/v1 + - equal: + path: metadata.name + value: my-release-jenkins-secondary + - equal: + path: metadata.namespace + value: my-namespace + - matchRegex: + path: metadata.labels.helm\.sh/chart + pattern: ^jenkins- + - isNull: + path: metadata.annotations + - equal: + path: spec + value: + ingressClassName: nginx + rules: + - host: jenkins.example.com + http: + paths: + - backend: + service: + name: my-release-jenkins + port: + number: 8080 + path: /github-webhook + pathType: ImplementationSpecific + tls: + - hosts: + - jenkins.example.com + secretName: tlsSecret + - it: disable helm.sh label + set: + renderHelmLabels: false + controller.secondaryingress: + enabled: true + hostName: jenkins.example.com + paths: + - /github-webhook + asserts: + - equal: + path: metadata.labels + value: + app.kubernetes.io/component: jenkins-controller + app.kubernetes.io/instance: my-release + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: jenkins diff --git a/helm/jenkins/unittests/jenkins-controller-secondary-ingress-test.yaml b/helm/jenkins/unittests/jenkins-controller-secondary-ingress-test.yaml new file mode 100644 index 0000000..b5aed8c --- /dev/null +++ b/helm/jenkins/unittests/jenkins-controller-secondary-ingress-test.yaml @@ -0,0 +1,76 @@ +suite: Controller Secondary Ingress +release: + name: my-release + namespace: my-namespace +templates: + - jenkins-controller-secondary-ingress.yaml +capabilities: + majorVersion: 1 + minorVersion: 18 +tests: + - it: test defaults + asserts: + - hasDocuments: + count: 0 + - it: enabled + set: + controller.secondaryingress: + enabled: true + hostName: jenkins.example.com + ingressClassName: nginx + paths: + - /github-webhook + tls: + - secretName: tlsSecret + hosts: + - jenkins.example.com + asserts: + - isKind: + of: Ingress + - equal: + path: apiVersion + value: networking.k8s.io/v1beta1 + - equal: + path: metadata.name + value: my-release-jenkins-secondary + - equal: + path: metadata.namespace + value: my-namespace + - matchRegex: + path: metadata.labels.helm\.sh/chart + pattern: ^jenkins- + - isNull: + path: metadata.annotations + - equal: + path: spec + value: + ingressClassName: nginx + rules: + - host: jenkins.example.com + http: + paths: + - backend: + serviceName: my-release-jenkins + servicePort: 8080 + path: /github-webhook + tls: + - hosts: + - jenkins.example.com + secretName: tlsSecret + - it: disable helm.sh label + set: + renderHelmLabels: false + controller.secondaryingress: + enabled: true + hostName: jenkins.example.com + ingressClassName: nginx + paths: + - /github-webhook + asserts: + - equal: + path: metadata.labels + value: + app.kubernetes.io/component: jenkins-controller + app.kubernetes.io/instance: my-release + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: jenkins diff --git a/helm/jenkins/unittests/jenkins-controller-servicemonitor_test.yaml b/helm/jenkins/unittests/jenkins-controller-servicemonitor_test.yaml new file mode 100644 index 0000000..c875bdb --- /dev/null +++ b/helm/jenkins/unittests/jenkins-controller-servicemonitor_test.yaml @@ -0,0 +1,82 @@ +suite: Controller Prometheus ServiceMonitor +release: + name: my-release + namespace: my-namespace +templates: + - jenkins-controller-servicemonitor.yaml +tests: + - it: defaults + asserts: + - hasDocuments: + count: 0 + - it: enabled + set: + controller.prometheus.enabled: true + asserts: + - isKind: + of: ServiceMonitor + - equal: + path: apiVersion + value: monitoring.coreos.com/v1 + - equal: + path: metadata.name + value: my-release-jenkins + - equal: + path: metadata.namespace + value: my-namespace + - matchRegex: + path: metadata.labels.helm\.sh/chart + pattern: ^jenkins- + - equal: + path: spec + value: + endpoints: + - interval: 60s + port: http + path: /prometheus + jobLabel: my-release-jenkins + namespaceSelector: + matchNames: + - "my-namespace" + selector: + matchLabels: + "app.kubernetes.io/instance": "my-release" + "app.kubernetes.io/component": "jenkins-controller" + - it: custom values + set: + controller: + jenkinsUriPrefix: /prefix + prometheus: + enabled: true + scrapeInterval: 120s + scrapeEndpoint: /monitoring + asserts: + - equal: + path: spec + value: + endpoints: + - interval: 120s + port: http + path: /prefix/monitoring + jobLabel: my-release-jenkins + namespaceSelector: + matchNames: + - "my-namespace" + selector: + matchLabels: + "app.kubernetes.io/instance": "my-release" + "app.kubernetes.io/component": "jenkins-controller" + - it: disable helm.sh label + set: + renderHelmLabels: false + controller: + prometheus: + enabled: true + asserts: + - equal: + path: metadata.labels + value: + app.kubernetes.io/component: jenkins-controller + app.kubernetes.io/instance: my-release + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: jenkins \ No newline at end of file diff --git a/helm/jenkins/unittests/jenkins-controller-statefulset-test.yaml b/helm/jenkins/unittests/jenkins-controller-statefulset-test.yaml new file mode 100644 index 0000000..cd2079f --- /dev/null +++ b/helm/jenkins/unittests/jenkins-controller-statefulset-test.yaml @@ -0,0 +1,700 @@ +suite: Jenkins Controller +release: + name: my-release + namespace: my-namespace +templates: + - jenkins-controller-statefulset.yaml + - config.yaml +tests: + - it: default values + template: jenkins-controller-statefulset.yaml + asserts: + - isKind: + of: StatefulSet + - equal: + path: apiVersion + value: apps/v1beta1 + - equal: + path: metadata.name + value: my-release-jenkins + - equal: + path: metadata.namespace + value: my-namespace + - matchRegex: + path: metadata.labels.helm\.sh/chart + pattern: ^jenkins- + - isNull: + path: metadata.annotations + - equal: + path: spec.replicas + value: 1 + - equal: + path: spec.selector + value: + matchLabels: + app.kubernetes.io/component: jenkins-controller + app.kubernetes.io/instance: my-release + - equal: + path: spec + value: + serviceName: my-release-jenkins + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/component: jenkins-controller + app.kubernetes.io/instance: my-release + template: + metadata: + annotations: + checksum/config: d00c6603a9397bc202be5072a81644630af27fe47c7e542ea6b066073458af83 + labels: + app.kubernetes.io/component: jenkins-controller + app.kubernetes.io/instance: my-release + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: jenkins + spec: + containers: + - args: + - --httpPort=8080 + env: + - name: SECRETS + value: /run/secrets/additional + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: JAVA_OPTS + value: "-Dcasc.reload.token=$(POD_NAME) " + - name: JENKINS_OPTS + value: "--webroot=/var/jenkins_cache/war " + - name: JENKINS_SLAVE_AGENT_PORT + value: "50000" + - name: CASC_JENKINS_CONFIG + value: /var/jenkins_home/casc_configs + image: jenkins/jenkins:2.375.1-jdk11 + imagePullPolicy: Always + securityContext: + runAsUser: 1000 + runAsGroup: 1000 + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + livenessProbe: + failureThreshold: 5 + httpGet: + path: /login + port: http + periodSeconds: 10 + timeoutSeconds: 5 + name: jenkins + ports: + - containerPort: 8080 + name: http + - containerPort: 50000 + name: agent-listener + readinessProbe: + failureThreshold: 3 + httpGet: + path: /login + port: http + periodSeconds: 10 + timeoutSeconds: 5 + resources: + limits: + cpu: 2000m + memory: 4096Mi + requests: + cpu: 50m + memory: 256Mi + startupProbe: + httpGet: + path: "/login" + port: http + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 12 + volumeMounts: + - mountPath: /var/jenkins_home + name: jenkins-home + readOnly: false + - mountPath: /var/jenkins_config + name: jenkins-config + readOnly: true + - mountPath: /usr/share/jenkins/ref/plugins/ + name: plugin-dir + readOnly: false + - mountPath: /var/jenkins_home/casc_configs + name: sc-config-volume + - mountPath: /run/secrets/additional + name: jenkins-secrets + readOnly: true + - mountPath: /var/jenkins_cache + name: jenkins-cache + - mountPath: /tmp + name: tmp-volume + - env: + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: LABEL + value: my-release-jenkins-jenkins-config + - name: FOLDER + value: /var/jenkins_home/casc_configs + - name: NAMESPACE + value: my-namespace + - name: REQ_URL + value: http://localhost:8080/reload-configuration-as-code/?casc-reload-token=$(POD_NAME) + - name: REQ_METHOD + value: POST + - name: REQ_RETRY_CONNECT + value: "10" + image: kiwigrid/k8s-sidecar:1.15.0 + imagePullPolicy: IfNotPresent + securityContext: + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + name: config-reload + resources: {} + volumeMounts: + - mountPath: /var/jenkins_home/casc_configs + name: sc-config-volume + - mountPath: /var/jenkins_home + name: jenkins-home + initContainers: + - command: + - sh + - /var/jenkins_config/apply_config.sh + image: jenkins/jenkins:2.375.1-jdk11 + imagePullPolicy: Always + securityContext: + runAsUser: 1000 + runAsGroup: 1000 + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + name: init + resources: + limits: + cpu: 2000m + memory: 4096Mi + requests: + cpu: 50m + memory: 256Mi + volumeMounts: + - mountPath: /var/jenkins_home + name: jenkins-home + - mountPath: /var/jenkins_config + name: jenkins-config + - mountPath: /usr/share/jenkins/ref/plugins + name: plugins + - mountPath: /var/jenkins_plugins + name: plugin-dir + - mountPath: /tmp + name: tmp-volume + securityContext: + fsGroup: 1000 + runAsUser: 1000 + runAsNonRoot: true + serviceAccountName: my-release-jenkins + volumes: + - emptyDir: {} + name: plugins + - configMap: + name: my-release-jenkins + name: jenkins-config + - emptyDir: {} + name: plugin-dir + - name: jenkins-secrets + projected: + sources: + - secret: + name: my-release-jenkins + items: + - key: jenkins-admin-user + path: chart-admin-username + - key: jenkins-admin-password + path: chart-admin-password + - emptyDir: {} + name: jenkins-cache + - name: jenkins-home + persistentVolumeClaim: + claimName: my-release-jenkins + - emptyDir: {} + name: sc-config-volume + - emptyDir: {} + name: tmp-volume + - it: test different values + template: jenkins-controller-statefulset.yaml + capabilities: + apiVersions: + - scheduling.k8s.io/v1beta1 + set: + controller: + statefulSetAnnotations: + my-annotation: value + schedulerName: my-scheduler + nodeSelector: + nodeLabel: value + tolerations: + - key: "key" + operator: "Equal" + value: "value" + effect: "NoSchedule" + affinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: security + operator: In + values: + - S1 + topologyKey: failure-domain.beta.kubernetes.io/zone + terminationGracePeriodSeconds: 120 + priorityClassName: important + runAsUser: 2000 + fsGroup: 4000 + securityContextCapabilities: + drop: + - NET_RAW + hostNetworking: true + terminationMessagePath: /tmp/termination-log-diff + terminationMessagePolicy: FallbackToLogsOnError + hostAliases: + - ip: 192.168.50.50 + hostnames: + - something.local + updateStrategy: + type: OnDelete + serviceAccount.name: my-serviceaccount + asserts: + - equal: + path: metadata.annotations + value: + my-annotation: value + - equal: + path: spec.template.spec.schedulerName + value: my-scheduler + - equal: + path: spec.template.spec.nodeSelector + value: + nodeLabel: value + - equal: + path: spec.template.spec.tolerations + value: + - key: "key" + operator: "Equal" + value: "value" + effect: "NoSchedule" + - equal: + path: spec.template.spec.affinity + value: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: security + operator: In + values: + - S1 + topologyKey: failure-domain.beta.kubernetes.io/zone + - equal: + path: spec.template.spec.terminationGracePeriodSeconds + value: 120 + - equal: + path: spec.template.spec.priorityClassName + value: important + - equal: + path: spec.template.spec.securityContext + value: + runAsUser: 2000 + fsGroup: 4000 + runAsNonRoot: true + capabilities: + drop: + - NET_RAW + - equal: + path: spec.template.spec.serviceAccountName + value: my-serviceaccount + - equal: + path: spec.template.spec.hostNetwork + value: true + - equal: + path: spec.template.spec.containers[0].terminationMessagePath + value: /tmp/termination-log-diff + - equal: + path: spec.template.spec.containers[0].terminationMessagePolicy + value: FallbackToLogsOnError + - equal: + path: spec.template.spec.dnsPolicy + value: ClusterFirstWithHostNet + - equal: + path: spec.template.spec.hostAliases + value: + - ip: 192.168.50.50 + hostnames: + - something.local + - equal: + path: spec.updateStrategy.type + value: OnDelete + - it: configure image tag + template: jenkins-controller-statefulset.yaml + set: + controller.tag: 2.249.1-slim + controller.imagePullPolicy: IfNotPresent + asserts: + - equal: + path: spec.template.spec.containers[0].image + value: jenkins/jenkins:2.249.1-slim + - equal: + path: spec.template.spec.containers[0].imagePullPolicy + value: IfNotPresent + - it: configure image tag label + template: jenkins-controller-statefulset.yaml + set: + controller.tagLabel: alpine + asserts: + - equal: + path: spec.template.spec.containers[0].image + value: jenkins/jenkins:2.375.1-alpine + - it: configure empty image tag label + template: jenkins-controller-statefulset.yaml + set: + controller.tagLabel: + asserts: + - equal: + path: spec.template.spec.containers[0].image + value: jenkins/jenkins:2.375.1 + - it: custom image + template: jenkins-controller-statefulset.yaml + set: + controller: + image: registry/image + tag: my-tag + javaOpts: -Dio.jenkins.plugins.kubernetes.disableNoDelayProvisioning=true + asserts: + - equal: + path: spec.template.spec.containers[0].image + value: registry/image:my-tag + - contains: + path: spec.template.spec.containers[0].env + content: + name: JAVA_OPTS + value: >- + -Dcasc.reload.token=$(POD_NAME) -Dio.jenkins.plugins.kubernetes.disableNoDelayProvisioning=true + - it: disable helm.sh label + template: jenkins-controller-statefulset.yaml + set: + renderHelmLabels: false + asserts: + - equal: + path: metadata.labels + value: + app.kubernetes.io/component: jenkins-controller + app.kubernetes.io/instance: my-release + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: jenkins + - it: java & jenkins opts with quotes + template: jenkins-controller-statefulset.yaml + set: + controller: + javaOpts: >- + -Dhudson.model.DirectoryBrowserSupport.CSP="default-src 'self';" + jenkinsOpts: >- + -Dtest="custom: 'true'" + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: JAVA_OPTS + value: >- + -Dcasc.reload.token=$(POD_NAME) -Dhudson.model.DirectoryBrowserSupport.CSP="default-src 'self';" + - contains: + path: spec.template.spec.containers[0].env + content: + name: JENKINS_OPTS + value: >- + --webroot=/var/jenkins_cache/war -Dtest="custom: 'true'" + - it: test empty controller.podSecurityContextOverride + template: jenkins-controller-statefulset.yaml + set: + controller: + podSecurityContextOverride: {} + asserts: + - equal: + path: spec.template.spec.securityContext + value: {} + - it: test controller.podSecurityContextOverride + template: jenkins-controller-statefulset.yaml + set: + controller: + podSecurityContextOverride: + runAsNonRoot: true + runAsUser: 4444 + supplementalGroups: [5555] + asserts: + - equal: + path: spec.template.spec.securityContext + value: + runAsNonRoot: true + runAsUser: 4444 + supplementalGroups: + - 5555 + - it: test 2 additional secrets + template: jenkins-controller-statefulset.yaml + set: + controller.additionalSecrets: + - name: something + value: secret + - name: anotherthing + value: anothersecret + asserts: + - equal: + path: spec.template.spec.containers[0].volumeMounts[4] + value: + mountPath: /run/secrets/additional + name: jenkins-secrets + readOnly: true + - equal: + path: spec.template.spec.volumes[3] + value: + name: jenkins-secrets + projected: + sources: + - secret: + name: my-release-jenkins-additional-secrets + - secret: + name: my-release-jenkins + items: + - key: jenkins-admin-user + path: chart-admin-username + - key: jenkins-admin-password + path: chart-admin-password + - it: test existing secret without additionalExistingSecrets + template: jenkins-controller-statefulset.yaml + set: + controller.existingSecret: my-exisiting-credentials + asserts: + - equal: + path: spec.template.spec.containers[0].volumeMounts[4] + value: + mountPath: /run/secrets/additional + name: jenkins-secrets + readOnly: true + - equal: + path: spec.template.spec.volumes[3] + value: + name: jenkins-secrets + projected: + sources: + - secret: + name: my-release-jenkins + items: + - key: jenkins-admin-user + path: chart-admin-username + - key: jenkins-admin-password + path: chart-admin-password + - secret: + name: my-exisiting-credentials + - it: test existing secret with additionalExistingSecrets + template: jenkins-controller-statefulset.yaml + set: + controller.existingSecret: my-exisiting-credentials + controller.additionalExistingSecrets: + - name: my-exisiting-credentials + keyName: github-username + - name: my-exisiting-credentials + keyName: github-password + asserts: + - equal: + path: spec.template.spec.containers[0].volumeMounts[4] + value: + mountPath: /run/secrets/additional + name: jenkins-secrets + readOnly: true + - equal: + path: spec.template.spec.volumes[3] + value: + name: jenkins-secrets + projected: + sources: + - secret: + items: + - key: github-username + path: my-exisiting-credentials-github-username + name: my-exisiting-credentials + - secret: + items: + - key: github-password + path: my-exisiting-credentials-github-password + name: my-exisiting-credentials + - secret: + name: my-release-jenkins + items: + - key: jenkins-admin-user + path: chart-admin-username + - key: jenkins-admin-password + path: chart-admin-password + - secret: + name: my-exisiting-credentials + - it: test templated environment variables + template: jenkins-controller-statefulset.yaml + set: + testValue: some-value + controller.initContainerEnv: + - name: "TEST_ENV_VAR_INIT" + value: "test-env-var-init" + - name: "TEST_ENV_VAR_INIT_TEMPLATED" + value: "{{ .Values.testValue }}" + controller.sidecars.configAutoReload.env: + - name: "TEST_ENV_VAR_CONFIG" + value: "test-env-var-config" + - name: "TEST_ENV_VAR_CONFIG_TEMPLATED" + value: "{{ .Values.testValue }}" + controller.containerEnv: + - name: "TEST_ENV_VAR_CONTAINER" + value: "test-env-var-container" + - name: "TEST_ENV_VAR__CONTAINER_TEMPLATED" + value: "{{ .Values.testValue }}" + controller.initContainerEnvFrom: + - configMapRef: + name: special-config + controller.sidecars.configAutoReload.envFrom: + - configMapRef: + name: special-config + controller.containerEnvFrom: + - configMapRef: + name: special-config + asserts: + - contains: + path: spec.template.spec.initContainers[0].env + content: + name: "TEST_ENV_VAR_INIT" + value: "test-env-var-init" + - contains: + path: spec.template.spec.initContainers[0].env + content: + name: "TEST_ENV_VAR_INIT_TEMPLATED" + value: "some-value" + - contains: + path: spec.template.spec.containers[1].env + content: + name: "TEST_ENV_VAR_CONFIG" + value: "test-env-var-config" + - contains: + path: spec.template.spec.containers[1].env + content: + name: "TEST_ENV_VAR_CONFIG_TEMPLATED" + value: "some-value" + - contains: + path: spec.template.spec.containers[0].env + content: + name: "TEST_ENV_VAR_CONTAINER" + value: "test-env-var-container" + - contains: + path: spec.template.spec.containers[0].env + content: + name: "TEST_ENV_VAR__CONTAINER_TEMPLATED" + value: "some-value" + - contains: + path: spec.template.spec.initContainers[0].envFrom + content: + configMapRef: + name: special-config + - contains: + path: spec.template.spec.containers[0].envFrom + content: + configMapRef: + name: special-config + - contains: + path: spec.template.spec.containers[1].envFrom + content: + configMapRef: + name: special-config + - it: overrides container args + template: jenkins-controller-statefulset.yaml + set: + controller.overrideArgs: + - --httpPort=8080 + - --requestHeaderSize=32768 + asserts: + - equal: + path: spec.template.spec.containers[0].args + value: + - --httpPort=8080 + - --requestHeaderSize=32768 + - it: allows templating in container args overrides + template: jenkins-controller-statefulset.yaml + set: + controller.overrideArgs: + - --httpPort={{.Values.controller.targetPort}} + - --requestHeaderSize=32768 + asserts: + - equal: + path: spec.template.spec.containers[0].args + value: + - --httpPort=8080 + - --requestHeaderSize=32768 + - it: render pod annotations + template: jenkins-controller-statefulset.yaml + set: + controller: + podAnnotations: + templated-annotations: "{{ .Release.Name }}" + fixed-annotation: some-fixed-annotation + asserts: + - matchSnapshot: + path: spec.template.metadata.annotations + - it: + template: jenkins-controller-statefulset.yaml + set: + controller: + installPlugins: false + asserts: + - notContains: + path: spec.template.spec.volumes + content: + name: plugins + emptyDir: {} + - notContains: + path: spec.template.spec.initContainers[0].volumeMounts + content: + name: plugins + - it: + template: jenkins-controller-statefulset.yaml + set: + controller: + JCasC: + configUrls: + - https://acme.org/jenkins.yaml + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: "CASC_JENKINS_CONFIG" + value: "/var/jenkins_home/casc_configs,https://acme.org/jenkins.yaml" + + - it: + template: jenkins-controller-statefulset.yaml + set: + controller: + JCasC: + configUrls: + - https://acme.org/jenkins.yaml + - https://foobar.org/jenkins.yaml + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: "CASC_JENKINS_CONFIG" + value: "/var/jenkins_home/casc_configs,https://acme.org/jenkins.yaml,https://foobar.org/jenkins.yaml" + + - it: + template: jenkins-controller-statefulset.yaml + set: + controller: + JCasC: + configUrls: [] + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: "CASC_JENKINS_CONFIG" + value: "/var/jenkins_home/casc_configs" diff --git a/helm/jenkins/unittests/jenkins-controller-svc-test.yaml b/helm/jenkins/unittests/jenkins-controller-svc-test.yaml new file mode 100644 index 0000000..f1349ee --- /dev/null +++ b/helm/jenkins/unittests/jenkins-controller-svc-test.yaml @@ -0,0 +1,158 @@ +suite: Jenkins Controller +release: + name: my-release + namespace: my-namespace +templates: + - jenkins-controller-svc.yaml +tests: + - it: default tests + asserts: + - isKind: + of: Service + - equal: + path: apiVersion + value: v1 + - equal: + path: metadata.name + value: my-release-jenkins + - equal: + path: metadata.namespace + value: my-namespace + - matchRegex: + path: metadata.labels.helm\.sh/chart + pattern: ^jenkins- + - isNull: + path: metadata.annotations + - equal: + path: spec + value: + ports: + - name: http + port: 8080 + targetPort: 8080 + selector: + app.kubernetes.io/component: jenkins-controller + app.kubernetes.io/instance: my-release + type: ClusterIP + - it: other values + set: + controller: + serviceLabels: + label: label-value + serviceAnnotations: + key: value + clusterIP: 10.10.10.11 + servicePort: 8888 + targetPort: 7777 + extraPorts: + - name: BuildInfoProxy + port: 9000 + asserts: + - equal: + path: metadata.labels.label + value: label-value + - equal: + path: metadata.annotations + value: + key: value + - equal: + path: spec + value: + clusterIP: 10.10.10.11 + ports: + - name: http + port: 8888 + targetPort: 7777 + - name: BuildInfoProxy + port: 9000 + targetPort: 9000 + selector: + app.kubernetes.io/component: jenkins-controller + app.kubernetes.io/instance: my-release + type: ClusterIP + - it: extraPort with targetPort + set: + controller: + serviceLabels: + label: label-value + serviceAnnotations: + key: value + clusterIP: 10.10.10.11 + servicePort: 8888 + targetPort: 7777 + extraPorts: + - name: https + port: 443 + targetPort: 8080 + asserts: + - equal: + path: metadata.labels.label + value: label-value + - equal: + path: metadata.annotations + value: + key: value + - equal: + path: spec + value: + clusterIP: 10.10.10.11 + ports: + - name: http + port: 8888 + targetPort: 7777 + - name: https + port: 443 + targetPort: 8080 + selector: + app.kubernetes.io/component: jenkins-controller + app.kubernetes.io/instance: my-release + type: ClusterIP + - it: node port + set: + controller: + serviceType: NodePort + nodePort: 11111 + asserts: + - equal: + path: spec + value: + ports: + - name: http + port: 8080 + targetPort: 8080 + nodePort: 11111 + selector: + app.kubernetes.io/component: jenkins-controller + app.kubernetes.io/instance: my-release + type: NodePort + - it: load balancer + set: + controller: + serviceType: LoadBalancer + loadBalancerIP: 10.10.10.10 + asserts: + - equal: + path: spec + value: + loadBalancerIP: 10.10.10.10 + loadBalancerSourceRanges: + - 0.0.0.0/0 + ports: + - name: http + port: 8080 + targetPort: 8080 + selector: + app.kubernetes.io/component: jenkins-controller + app.kubernetes.io/instance: my-release + type: LoadBalancer + - it: disable helm.sh label + set: + renderHelmLabels: false + asserts: + - equal: + path: metadata.labels + value: + app.kubernetes.io/component: jenkins-controller + app.kubernetes.io/instance: my-release + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: jenkins diff --git a/helm/jenkins/unittests/rbac-test.yaml b/helm/jenkins/unittests/rbac-test.yaml new file mode 100644 index 0000000..592373e --- /dev/null +++ b/helm/jenkins/unittests/rbac-test.yaml @@ -0,0 +1,217 @@ +suite: Role Based Access Control +release: + name: my-release + namespace: my-namespace +templates: + - rbac.yaml +tests: + - it: test default number of documents + asserts: + - hasDocuments: + count: 4 + - it: disable auto reload + set: + controller.sidecars.configAutoReload.enabled: false + asserts: + - hasDocuments: + count: 2 + + - it: disable rbac create + set: + rbac.create: false + asserts: + - hasDocuments: + count: 0 + + - it: Role schedule-agents + documentIndex: 0 + asserts: + - isKind: + of: Role + - equal: + path: apiVersion + value: rbac.authorization.k8s.io/v1 + - equal: + path: metadata.name + value: my-release-jenkins-schedule-agents + - equal: + path: metadata.namespace + value: my-namespace + - equal: + path: rules + value: + - apiGroups: [""] + resources: ["pods", "pods/exec", "pods/log", "persistentvolumeclaims", "events"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["pods", "pods/exec", "persistentvolumeclaims"] + verbs: ["create", "delete", "deletecollection", "patch", "update"] + + - it: RoleBinding schedule-agents + documentIndex: 1 + asserts: + - isKind: + of: RoleBinding + - equal: + path: apiVersion + value: rbac.authorization.k8s.io/v1 + - equal: + path: metadata.name + value: my-release-jenkins-schedule-agents + - equal: + path: metadata.namespace + value: my-namespace + - equal: + path: roleRef + value: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: my-release-jenkins-schedule-agents + - equal: + path: subjects + value: + - kind: ServiceAccount + name: my-release-jenkins + namespace: my-namespace + + - it: Separate Agent Namespace + set: + agent.namespace: agent-namespace + asserts: + - equal: + path: metadata.namespace + value: agent-namespace + documentIndex: 0 + - equal: + path: subjects + value: + - kind: ServiceAccount + name: my-release-jenkins + namespace: my-namespace + documentIndex: 1 + + - it: Role casc-reload + documentIndex: 2 + asserts: + - isKind: + of: Role + - equal: + path: apiVersion + value: rbac.authorization.k8s.io/v1 + - equal: + path: metadata.name + value: my-release-jenkins-casc-reload + - equal: + path: metadata.namespace + value: my-namespace + - equal: + path: rules + value: + - apiGroups: [""] + resources: ["configmaps"] + verbs: ["get", "watch", "list"] + + - it: RoleBinding casc-reload + documentIndex: 3 + asserts: + - isKind: + of: RoleBinding + - equal: + path: apiVersion + value: rbac.authorization.k8s.io/v1 + - equal: + path: metadata.name + value: my-release-jenkins-watch-configmaps + - equal: + path: metadata.namespace + value: my-namespace + - equal: + path: roleRef + value: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: my-release-jenkins-casc-reload + - equal: + path: subjects + value: + - kind: ServiceAccount + name: my-release-jenkins + namespace: my-namespace + + - it: enable read secrets + set: + rbac.readSecrets: true + asserts: + - hasDocuments: + count: 6 + - matchRegex: + path: metadata.labels.helm\.sh/chart + pattern: ^jenkins- + + - it: disable helm.sh label + set: + renderHelmLabels: false + rbac.readSecrets: true + asserts: + - hasDocuments: + count: 6 + - equal: + path: metadata.labels + value: + app.kubernetes.io/component: jenkins-controller + app.kubernetes.io/instance: my-release + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: jenkins + + - it: Role read-secrets + set: + rbac.readSecrets: true + documentIndex: 2 + asserts: + - isKind: + of: Role + - equal: + path: apiVersion + value: rbac.authorization.k8s.io/v1 + - equal: + path: metadata.name + value: my-release-jenkins-read-secrets + - equal: + path: metadata.namespace + value: my-namespace + - equal: + path: rules + value: + - apiGroups: [""] + resources: ["secrets"] + verbs: ["get", "watch", "list"] + + - it: RoleBinding read-secrets + set: + rbac.readSecrets: true + documentIndex: 3 + asserts: + - isKind: + of: RoleBinding + - equal: + path: apiVersion + value: rbac.authorization.k8s.io/v1 + - equal: + path: metadata.name + value: my-release-jenkins-read-secrets + - equal: + path: metadata.namespace + value: my-namespace + - equal: + path: roleRef + value: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: my-release-jenkins-read-secrets + - equal: + path: subjects + value: + - kind: ServiceAccount + name: my-release-jenkins + namespace: my-namespace + diff --git a/helm/jenkins/unittests/secret-additional-test.yaml b/helm/jenkins/unittests/secret-additional-test.yaml new file mode 100644 index 0000000..99d4456 --- /dev/null +++ b/helm/jenkins/unittests/secret-additional-test.yaml @@ -0,0 +1,41 @@ +suite: Controller Admin Additional Secrets +release: + name: my-release + namespace: my-namespace +templates: + - secret-additional.yaml +tests: + - it: tests defaults + asserts: + - hasDocuments: + count: 0 + - it: tests 2 additional secrets + set: + controller.additionalSecrets: + - name: something + value: secret + - name: anotherthing + value: anothersecret + asserts: + - isKind: + of: Secret + - equal: + path: apiVersion + value: v1 + - equal: + path: metadata.name + value: my-release-jenkins-additional-secrets + - equal: + path: metadata.namespace + value: my-namespace + - matchRegex: + path: metadata.labels.helm\.sh/chart + pattern: ^jenkins- + - isNull: + path: metadata.annotations + - equal: + path: data.something + value: c2VjcmV0 + - equal: + path: data.anotherthing + value: YW5vdGhlcnNlY3JldA== diff --git a/helm/jenkins/unittests/secret-claims-test.yaml b/helm/jenkins/unittests/secret-claims-test.yaml new file mode 100644 index 0000000..d7ca286 --- /dev/null +++ b/helm/jenkins/unittests/secret-claims-test.yaml @@ -0,0 +1,82 @@ +suite: Controller Secret Claims +release: + name: my-release + namespace: my-namespace +templates: + - secret-claims.yaml +tests: + - it: tests defaults + asserts: + - hasDocuments: + count: 0 + - it: tests 2 secret claims + set: + controller.secretClaims: + - name: simple-secret + path: secret/path + - name: complex-secret + path: secret/complex + type: kubernetes.io/tls + renew: 60 + asserts: + - hasDocuments: + count: 2 + - documentIndex: 0 + isKind: + of: SecretClaim + - documentIndex: 0 + equal: + path: apiVersion + value: vaultproject.io/v1 + - documentIndex: 0 + equal: + path: metadata.name + value: my-release-jenkins-simple-secret + - documentIndex: 0 + matchRegex: + path: metadata.labels.helm\.sh/chart + pattern: ^jenkins- + - documentIndex: 0 + isNull: + path: metadata.annotations + - documentIndex: 0 + equal: + path: spec.type + value: Opaque + - documentIndex: 0 + equal: + path: spec.path + value: secret/path + - documentIndex: 0 + isNull: + path: spec.renew + - documentIndex: 1 + isKind: + of: SecretClaim + - documentIndex: 1 + equal: + path: apiVersion + value: vaultproject.io/v1 + - documentIndex: 1 + equal: + path: metadata.name + value: my-release-jenkins-complex-secret + - documentIndex: 1 + matchRegex: + path: metadata.labels.helm\.sh/chart + pattern: ^jenkins- + - documentIndex: 1 + isNull: + path: metadata.annotations + - documentIndex: 1 + equal: + path: spec.type + value: kubernetes.io/tls + - documentIndex: 1 + equal: + path: spec.path + value: secret/complex + - documentIndex: 1 + equal: + path: spec.renew + value: 60 \ No newline at end of file diff --git a/helm/jenkins/unittests/secret-existing-test.yaml b/helm/jenkins/unittests/secret-existing-test.yaml new file mode 100644 index 0000000..1c56a6e --- /dev/null +++ b/helm/jenkins/unittests/secret-existing-test.yaml @@ -0,0 +1,52 @@ +suite: Controller Additional Existing Secrets +release: + name: my-release + namespace: my-namespace +templates: + - jenkins-controller-statefulset.yaml + - config.yaml +tests: + - it: test additional existing secrets StatefulSet + template: jenkins-controller-statefulset.yaml + set: + controller.additionalExistingSecrets: + - name: "{{ .Release.Name }}-secret" + keyName: username + - name: "{{ .Release.Name }}-secret" + keyName: password + controller.existingSecret: my-existing-credentials + + asserts: + - isKind: + of: StatefulSet + - equal: + path: spec.template.spec.containers[0].volumeMounts[4] + value: + mountPath: /run/secrets/additional + name: jenkins-secrets + readOnly: true + - equal: + path: spec.template.spec.volumes[3] + value: + name: jenkins-secrets + projected: + sources: + - secret: + name: my-release-secret + items: + - key: username + path: my-release-secret-username + - secret: + name: my-release-secret + items: + - key: password + path: my-release-secret-password + - secret: + name: my-release-jenkins + items: + - key: jenkins-admin-user + path: chart-admin-username + - key: jenkins-admin-password + path: chart-admin-password + - secret: + name: my-existing-credentials diff --git a/helm/jenkins/unittests/secret-test.yaml b/helm/jenkins/unittests/secret-test.yaml new file mode 100644 index 0000000..12ea5c1 --- /dev/null +++ b/helm/jenkins/unittests/secret-test.yaml @@ -0,0 +1,65 @@ +suite: Controller Admin Credentials +release: + name: my-release + namespace: my-namespace +templates: + - secret.yaml +tests: + - it: tests defaults + asserts: + - isKind: + of: Secret + - equal: + path: apiVersion + value: v1 + - equal: + path: metadata.name + value: my-release-jenkins + - equal: + path: metadata.namespace + value: my-namespace + - matchRegex: + path: metadata.labels.helm\.sh/chart + pattern: ^jenkins- + - isNull: + path: metadata.annotations + - equal: + path: data.jenkins-admin-user + value: YWRtaW4= + - isNotNull: + path: data.jenkins-admin-password + - it: set admin password + set: + controller.adminPassword: secret + asserts: + - equal: + path: data.jenkins-admin-user + value: YWRtaW4= + - equal: + path: data.jenkins-admin-password + value: c2VjcmV0 + - it: disable helm.sh label + set: + renderHelmLabels: false + asserts: + - equal: + path: metadata.labels + value: + app.kubernetes.io/component: jenkins-controller + app.kubernetes.io/instance: my-release + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: jenkins + - it: disable + set: + controller: + adminSecret: false + asserts: + - hasDocuments: + count: 0 + - it: disable + set: + controller.admin.existingSecret: my-secret + asserts: + - hasDocuments: + count: 0 + diff --git a/helm/jenkins/unittests/service-account-agent-test.yaml b/helm/jenkins/unittests/service-account-agent-test.yaml new file mode 100644 index 0000000..e4cf7e8 --- /dev/null +++ b/helm/jenkins/unittests/service-account-agent-test.yaml @@ -0,0 +1,83 @@ +suite: Controller Service Account +release: + name: my-release + namespace: my-namespace +templates: + - service-account-agent.yaml +tests: + - it: test defaults + asserts: + - hasDocuments: + count: 0 + - it: create service account for agents + set: + serviceAccountAgent: + create: true + asserts: + - isKind: + of: ServiceAccount + - equal: + path: apiVersion + value: v1 + - equal: + path: metadata.name + value: my-release-jenkins-agent + - equal: + path: metadata.namespace + value: my-namespace + - matchRegex: + path: metadata.labels.helm\.sh/chart + pattern: ^jenkins- + - isNull: + path: metadata.annotations + - it: agent namespace + set: + serviceAccountAgent: + create: true + annotations: + key: value + agent: + namespace: agents + asserts: + - isKind: + of: ServiceAccount + - equal: + path: apiVersion + value: v1 + - equal: + path: metadata.name + value: my-release-jenkins-agent + - equal: + path: metadata.namespace + value: agents + - matchRegex: + path: metadata.labels.helm\.sh/chart + pattern: ^jenkins- + - equal: + path: metadata.annotations + value: + key: value + - it: disable helm.sh label + set: + renderHelmLabels: false + serviceAccountAgent: + create: true + asserts: + - equal: + path: metadata.labels + value: + app.kubernetes.io/component: jenkins-controller + app.kubernetes.io/instance: my-release + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: jenkins + - it: agent image pull secret + set: + renderHelmLabels: false + serviceAccountAgent: + create: true + imagePullSecretName: ips-name + asserts: + - equal: + path: imagePullSecrets + value: + - name: ips-name diff --git a/helm/jenkins/unittests/service-account-test.yaml b/helm/jenkins/unittests/service-account-test.yaml new file mode 100644 index 0000000..b33aaad --- /dev/null +++ b/helm/jenkins/unittests/service-account-test.yaml @@ -0,0 +1,58 @@ +suite: Controller Service Account +release: + name: my-release + namespace: my-namespace +templates: + - service-account.yaml +tests: + - it: tests defaults + asserts: + - isKind: + of: ServiceAccount + - equal: + path: apiVersion + value: v1 + - equal: + path: metadata.name + value: my-release-jenkins + - equal: + path: metadata.namespace + value: my-namespace + - matchRegex: + path: metadata.labels.helm\.sh/chart + pattern: ^jenkins- + - isNull: + path: metadata.annotations + + - it: disable helm.sh label + set: + renderHelmLabels: false + asserts: + - equal: + path: metadata.labels + value: + app.kubernetes.io/component: jenkins-controller + app.kubernetes.io/instance: my-release + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: jenkins + + - it: disabled + set: + serviceAccount: + create: false + asserts: + - hasDocuments: + count: 0 + + - it: controller image pull secret + set: + renderHelmLabels: false + serviceAccount: + create: true + imagePullSecretName: ips-name + asserts: + - equal: + path: imagePullSecrets + value: + - name: ips-name + diff --git a/helm/jenkins/values.yaml b/helm/jenkins/values.yaml new file mode 100644 index 0000000..ab9367f --- /dev/null +++ b/helm/jenkins/values.yaml @@ -0,0 +1,950 @@ +# Default values for jenkins. +# This is a YAML-formatted file. +# Declare name/value pairs to be passed into your templates. +# name: value + +## Overrides for generated resource names +# See templates/_helpers.tpl +# nameOverride: +# fullnameOverride: +# namespaceOverride: + +# For FQDN resolving of the controller service. Change this value to match your existing configuration. +# ref: https://github.com/kubernetes/dns/blob/master/docs/specification.md +clusterZone: "cluster.local" + +renderHelmLabels: true + +controller: + # Used for label app.kubernetes.io/component + componentName: "jenkins-controller" + image: "jenkins/jenkins" + # tag: "2.375.1-jdk11" + tagLabel: jdk11 + imagePullPolicy: "Always" + imagePullSecretName: + # Optionally configure lifetime for controller-container + lifecycle: + # postStart: + # exec: + # command: + # - "uname" + # - "-a" + disableRememberMe: false + numExecutors: 0 + # configures the executor mode of the Jenkins node. Possible values are: NORMAL or EXCLUSIVE + executorMode: "NORMAL" + # This is ignored if enableRawHtmlMarkupFormatter is true + markupFormatter: plainText + customJenkinsLabels: [] + # The default configuration uses this secret to configure an admin user + # If you don't need that user or use a different security realm then you can disable it + adminSecret: true + + hostNetworking: false + # When enabling LDAP or another non-Jenkins identity source, the built-in admin account will no longer exist. + # If you disable the non-Jenkins identity store and instead use the Jenkins internal one, + # you should revert controller.adminUser to your preferred admin user: + adminUser: "admin" + # adminPassword: + admin: + existingSecret: "" + userKey: jenkins-admin-user + passwordKey: jenkins-admin-password + # This values should not be changed unless you use your custom image of jenkins or any devired from. If you want to use + # Cloudbees Jenkins Distribution docker, you should set jenkinsHome: "/var/cloudbees-jenkins-distribution" + jenkinsHome: "/var/jenkins_home" + # This values should not be changed unless you use your custom image of jenkins or any devired from. If you want to use + # Cloudbees Jenkins Distribution docker, you should set jenkinsRef: "/usr/share/cloudbees-jenkins-distribution/ref" + jenkinsRef: "/usr/share/jenkins/ref" + # Path to the jenkins war file which is used by jenkins-plugin-cli. + jenkinsWar: "/usr/share/jenkins/jenkins.war" + # Overrides the default arguments passed to the war + # overrideArgs: + # - --httpPort=8080 + resources: + requests: + cpu: "50m" + memory: "256Mi" + limits: + cpu: "2000m" + memory: "4096Mi" + # Overrides the init container default values + # initContainerResources: + # requests: + # cpu: "50m" + # memory: "256Mi" + # limits: + # cpu: "2000m" + # memory: "4096Mi" + # Environment variables that get added to the init container (useful for e.g. http_proxy) + # initContainerEnv: + # - name: http_proxy + # value: "http://192.168.64.1:3128" + # containerEnv: + # - name: http_proxy + # value: "http://192.168.64.1:3128" + # Set min/max heap here if needed with: + # javaOpts: "-Xms512m -Xmx512m" + # jenkinsOpts: "" + # If you are using the ingress definitions provided by this chart via the `controller.ingress` block the configured hostname will be the ingress hostname starting with `https://` or `http://` depending on the `tls` configuration. + # The Protocol can be overwritten by specifying `controller.jenkinsUrlProtocol`. + # jenkinsUrlProtocol: "https" + # If you are not using the provided ingress you can specify `controller.jenkinsUrl` to change the url definition. + # jenkinsUrl: "" + # If you set this prefix and use ingress controller then you might want to set the ingress path below + # jenkinsUriPrefix: "/jenkins" + # Enable pod security context (must be `true` if podSecurityContextOverride, runAsUser or fsGroup are set) + usePodSecurityContext: true + # Note that `runAsUser`, `fsGroup`, and `securityContextCapabilities` are + # being deprecated and replaced by `podSecurityContextOverride`. + # Set runAsUser to 1000 to let Jenkins run as non-root user 'jenkins' which exists in 'jenkins/jenkins' docker image. + # When setting runAsUser to a different value than 0 also set fsGroup to the same value: + runAsUser: 1000 + fsGroup: 1000 + # If you have PodSecurityPolicies that require dropping of capabilities as suggested by CIS K8s benchmark, put them here + securityContextCapabilities: {} + # drop: + # - NET_RAW + # Completely overwrites the contents of the `securityContext`, ignoring the + # values provided for the deprecated fields: `runAsUser`, `fsGroup`, and + # `securityContextCapabilities`. In the case of mounting an ext4 filesystem, + # it might be desirable to use `supplementalGroups` instead of `fsGroup` in + # the `securityContext` block: https://github.com/kubernetes/kubernetes/issues/67014#issuecomment-589915496 + # podSecurityContextOverride: + # runAsUser: 1000 + # runAsNonRoot: true + # supplementalGroups: [1000] + # # capabilities: {} + # Container securityContext + containerSecurityContext: + runAsUser: 1000 + runAsGroup: 1000 + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + servicePort: 8080 + targetPort: 8080 + # For minikube, set this to NodePort, elsewhere use LoadBalancer + # Use ClusterIP if your setup includes ingress controller + serviceType: ClusterIP + # Use Local to preserve the client source IP and avoids a second hop for LoadBalancer and Nodeport type services, + # but risks potentially imbalanced traffic spreading. + serviceExternalTrafficPolicy: + # Jenkins controller service annotations + serviceAnnotations: {} + # Jenkins controller custom labels + statefulSetLabels: {} + # foo: bar + # bar: foo + # Jenkins controller service labels + serviceLabels: {} + # service.beta.kubernetes.io/aws-load-balancer-backend-protocol: https + # Put labels on Jenkins controller pod + podLabels: {} + # Used to create Ingress record (should used with ServiceType: ClusterIP) + # nodePort: + # -Dcom.sun.management.jmxremote.port=4000 + # -Dcom.sun.management.jmxremote.authenticate=false + # -Dcom.sun.management.jmxremote.ssl=false + # jmxPort: 4000 + # Optionally configure other ports to expose in the controller container + extraPorts: [] + # - name: BuildInfoProxy + # port: 9000 + # targetPort: 9010 (Optional: Use to explicitly set targetPort if different from port) + + # List of plugins to be install during Jenkins controller start + installPlugins: + - kubernetes:3734.v562b_b_a_627ea_c + - workflow-aggregator:590.v6a_d052e5a_a_b_5 + - git:4.13.0 + - configuration-as-code:1569.vb_72405b_80249 + + # Set to false to download the minimum required version of all dependencies. + installLatestPlugins: true + + # Set to true to download latest dependencies of any plugin that is requested to have the latest version. + installLatestSpecifiedPlugins: false + + # List of plugins to install in addition to those listed in controller.installPlugins + additionalPlugins: [] + + # Enable to initialize the Jenkins controller only once on initial installation. + # Without this, whenever the controller gets restarted (Evicted, etc.) it will fetch plugin updates which has the potential to cause breakage. + # Note that for this to work, `persistence.enabled` needs to be set to `true` + initializeOnce: false + + # Enable to always override the installed plugins with the values of 'controller.installPlugins' on upgrade or redeployment. + # overwritePlugins: true + + # Configures if plugins bundled with `controller.image` should be overwritten with the values of 'controller.installPlugins' on upgrade or redeployment. + overwritePluginsFromImage: true + + # Configures the restrictions for naming projects. Set this key to null or empty to skip it in the default config. + projectNamingStrategy: standard + + # Enable HTML parsing using OWASP Markup Formatter Plugin (antisamy-markup-formatter), useful with ghprb plugin. + # The plugin is not installed by default, please update controller.installPlugins. + enableRawHtmlMarkupFormatter: false + # Used to approve a list of groovy functions in pipelines used the script-security plugin. Can be viewed under /scriptApproval + scriptApproval: [] + # - "method groovy.json.JsonSlurperClassic parseText java.lang.String" + # - "new groovy.json.JsonSlurperClassic" + # List of groovy init scripts to be executed during Jenkins controller start + initScripts: [] + # - | + # print 'adding global pipeline libraries, register properties, bootstrap jobs...' + + # 'name' is a name of an existing secret in same namespace as jenkins, + # 'keyName' is the name of one of the keys inside current secret. + # the 'name' and 'keyName' are concatenated with a '-' in between, so for example: + # an existing secret "secret-credentials" and a key inside it named "github-password" should be used in Jcasc as ${secret-credentials-github-password} + # 'name' and 'keyName' must be lowercase RFC 1123 label must consist of lower case alphanumeric characters or '-', + # and must start and end with an alphanumeric character (e.g. 'my-name', or '123-abc') + # existingSecret existing secret "secret-credentials" and a key inside it named "github-username" should be used in Jcasc as ${github-username} + # When using existingSecret no need to specify the keyName under additionalExistingSecrets. + existingSecret: + + additionalExistingSecrets: [] + # - name: secret-name-1 + # keyName: username + # - name: secret-name-1 + # keyName: password + + additionalSecrets: [] + # - name: nameOfSecret + # value: secretText + + # Generate SecretClaim resources in order to create Kubernetes secrets from HashiCorp Vault using kube-vault-controller. + # 'name' is name of the secret that will be created in Kubernetes. The Jenkins fullname is prepended to this value. + # 'path' is the fully qualified path to the secret in Vault + # 'type' is an optional Kubernetes secret type. Defaults to 'Opaque' + # 'renew' is an optional secret renewal time in seconds + secretClaims: [] + # - name: secretName # required + # path: testPath # required + # type: kubernetes.io/tls # optional + # renew: 60 # optional + + # Name of default cloud configuration. + cloudName: "kubernetes" + + # Below is the implementation of Jenkins Configuration as Code. Add a key under configScripts for each configuration area, + # where each corresponds to a plugin or section of the UI. Each key (prior to | character) is just a label, and can be any value. + # Keys are only used to give the section a meaningful name. The only restriction is they may only contain RFC 1123 \ DNS label + # characters: lowercase letters, numbers, and hyphens. The keys become the name of a configuration yaml file on the controller in + # /var/jenkins_home/casc_configs (by default) and will be processed by the Configuration as Code Plugin. The lines after each | + # become the content of the configuration yaml file. The first line after this is a JCasC root element, eg jenkins, credentials, + # etc. Best reference is https:///configuration-as-code/reference. The example below creates a welcome message: + JCasC: + defaultConfig: true + configUrls: [] + # - https://acme.org/jenkins.yaml + # Remote URL:s for configuration files. + configScripts: {} + # welcome-message: | + # jenkins: + # systemMessage: Welcome to our CI\CD server. This Jenkins is configured and managed 'as code'. + # Allows adding to the top-level security JCasC section. For legacy, default the chart includes apiToken configurations + security: + apiToken: + creationOfLegacyTokenEnabled: false + tokenGenerationOnCreationEnabled: false + usageStatisticsEnabled: true + # Ignored if securityRealm is defined in controller.JCasC.configScripts + securityRealm: |- + local: + allowsSignup: false + enableCaptcha: false + users: + - id: "${chart-admin-username}" + name: "Jenkins Admin" + password: "${chart-admin-password}" + # Ignored if authorizationStrategy is defined in controller.JCasC.configScripts + authorizationStrategy: |- + loggedInUsersCanDoAnything: + allowAnonymousRead: false + # Optionally specify additional init-containers + customInitContainers: [] + # - name: custom-init + # image: "alpine:3.7" + # imagePullPolicy: Always + # command: [ "uname", "-a" ] + + sidecars: + configAutoReload: + # If enabled: true, Jenkins Configuration as Code will be reloaded on-the-fly without a reboot. If false or not-specified, + # jcasc changes will cause a reboot and will only be applied at the subsequent start-up. Auto-reload uses the + # http:///reload-configuration-as-code endpoint to reapply config when changes to the configScripts are detected. + enabled: true + image: kiwigrid/k8s-sidecar:1.15.0 + imagePullPolicy: IfNotPresent + resources: {} + # limits: + # cpu: 100m + # memory: 100Mi + # requests: + # cpu: 50m + # memory: 50Mi + # How many connection-related errors to retry on + reqRetryConnect: 10 + # env: + # - name: REQ_TIMEOUT + # value: "30" + # SSH port value can be set to any unused TCP port. The default, 1044, is a non-standard SSH port that has been chosen at random. + # Is only used to reload jcasc config from the sidecar container running in the Jenkins controller pod. + # This TCP port will not be open in the pod (unless you specifically configure this), so Jenkins will not be + # accessible via SSH from outside of the pod. Note if you use non-root pod privileges (runAsUser & fsGroup), + # this must be > 1024: + sshTcpPort: 1044 + # folder in the pod that should hold the collected dashboards: + folder: "/var/jenkins_home/casc_configs" + # If specified, the sidecar will search for JCasC config-maps inside this namespace. + # Otherwise the namespace in which the sidecar is running will be used. + # It's also possible to specify ALL to search in all namespaces: + # searchNamespace: + containerSecurityContext: + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + + # Allows you to inject additional/other sidecars + other: [] + ## The example below runs the client for https://smee.io as sidecar container next to Jenkins, + ## that allows to trigger build behind a secure firewall. + ## https://jenkins.io/blog/2019/01/07/webhook-firewalls/#triggering-builds-with-webhooks-behind-a-secure-firewall + ## + ## Note: To use it you should go to https://smee.io/new and update the url to the generete one. + # - name: smee + # image: docker.io/twalter/smee-client:1.0.2 + # args: ["--port", "{{ .Values.controller.servicePort }}", "--path", "/github-webhook/", "--url", "https://smee.io/new"] + # resources: + # limits: + # cpu: 50m + # memory: 128Mi + # requests: + # cpu: 10m + # memory: 32Mi + # Name of the Kubernetes scheduler to use + schedulerName: "" + # Node labels and tolerations for pod assignment + # ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector + # ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#taints-and-tolerations-beta-feature + nodeSelector: {} + + terminationGracePeriodSeconds: + + terminationMessagePath: + terminationMessagePolicy: + + tolerations: [] + + affinity: {} + # Leverage a priorityClass to ensure your pods survive resource shortages + # ref: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/ + priorityClassName: + + podAnnotations: {} + # Add StatefulSet annotations + statefulSetAnnotations: {} + + # StatefulSet updateStrategy + # ref: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#update-strategies + updateStrategy: {} + + ingress: + enabled: false + # Override for the default paths that map requests to the backend + paths: [] + # - backend: + # serviceName: ssl-redirect + # servicePort: use-annotation + # - backend: + # serviceName: >- + # {{ template "jenkins.fullname" . }} + # # Don't use string here, use only integer value! + # servicePort: 8080 + # For Kubernetes v1.14+, use 'networking.k8s.io/v1beta1' + # For Kubernetes v1.19+, use 'networking.k8s.io/v1' + apiVersion: "extensions/v1beta1" + labels: {} + annotations: {} + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: "true" + # For Kubernetes >= 1.18 you should specify the ingress-controller via the field ingressClassName + # See https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/#specifying-the-class-of-an-ingress + # ingressClassName: nginx + # Set this path to jenkinsUriPrefix above or use annotations to rewrite path + # path: "/jenkins" + # configures the hostname e.g. jenkins.example.com + hostName: + tls: + # - secretName: jenkins.cluster.local + # hosts: + # - jenkins.cluster.local + + # often you want to have your controller all locked down and private + # but you still want to get webhooks from your SCM + # A secondary ingress will let you expose different urls + # with a differnt configuration + secondaryingress: + enabled: false + # paths you want forwarded to the backend + # ex /github-webhook + paths: [] + # For Kubernetes v1.14+, use 'networking.k8s.io/v1beta1' + # For Kubernetes v1.19+, use 'networking.k8s.io/v1' + apiVersion: "extensions/v1beta1" + labels: {} + annotations: {} + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: "true" + # For Kubernetes >= 1.18 you should specify the ingress-controller via the field ingressClassName + # See https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/#specifying-the-class-of-an-ingress + # ingressClassName: nginx + # configures the hostname e.g. jenkins-external.example.com + hostName: + tls: + # - secretName: jenkins-external.example.com + # hosts: + # - jenkins-external.example.com + + # If you're running on GKE and need to configure a backendconfig + # to finish ingress setup, use the following values. + # Docs: https://cloud.google.com/kubernetes-engine/docs/concepts/backendconfig + backendconfig: + enabled: false + apiVersion: "extensions/v1beta1" + name: + labels: {} + annotations: {} + spec: {} + + # Openshift route + route: + enabled: false + labels: {} + annotations: {} + # path: "/jenkins" + + # controller.hostAliases allows for adding entries to Pod /etc/hosts: + # https://kubernetes.io/docs/concepts/services-networking/add-entries-to-pod-etc-hosts-with-host-aliases/ + hostAliases: [] + # - ip: 192.168.50.50 + # hostnames: + # - something.local + # - ip: 10.0.50.50 + # hostnames: + # - other.local + + # Expose Prometheus metrics + prometheus: + # If enabled, add the prometheus plugin to the list of plugins to install + # https://plugins.jenkins.io/prometheus + enabled: false + # Additional labels to add to the ServiceMonitor object + serviceMonitorAdditionalLabels: {} + # Set a custom namespace where to deploy ServiceMonitor resource + # serviceMonitorNamespace: monitoring + scrapeInterval: 60s + # This is the default endpoint used by the prometheus plugin + scrapeEndpoint: /prometheus + # Additional labels to add to the PrometheusRule object + alertingRulesAdditionalLabels: {} + # An array of prometheus alerting rules + # See here: https://prometheus.io/docs/prometheus/latest/configuration/alerting_rules/ + # The `groups` root object is added by default, simply add the rule entries + alertingrules: [] + # Set a custom namespace where to deploy PrometheusRule resource + prometheusRuleNamespace: "" + + googlePodMonitor: + # If enabled, It creates Google Managed Prometheus scraping config + enabled: false + # Set a custom namespace where to deploy PodMonitoring resource + # serviceMonitorNamespace: "" + scrapeInterval: 60s + # This is the default endpoint used by the prometheus plugin + scrapeEndpoint: /prometheus + + # Can be used to disable rendering controller test resources when using helm template + testEnabled: true + + httpsKeyStore: + jenkinsHttpsJksSecretName: '' + enable: false + httpPort: 8081 + path: "/var/jenkins_keystore" + fileName: "keystore.jks" + password: "password" + # Convert keystore.jks files content to base64 ( cat keystore.jks | base64 ) and put the output here + jenkinsKeyStoreBase64Encoded: | + /u3+7QAAAAIAAAABAAAAAQANamVua2luc2NpLmNvbQAAAW2r/b1ZAAAFATCCBP0wDgYKKwYBBAEq + AhEBAQUABIIE6QbCqasvoHS0pSwYqSvdydMCB9t+VNfwhFIiiuAelJfO5sSe2SebJbtwHgLcRz1Z + gMtWgOSFdl3bWSzA7vrW2LED52h+jXLYSWvZzuDuh8hYO85m10ikF6QR+dTi4jra0whIFDvq3pxe + TnESxEsN+DvbZM3jA3qsjQJSeISNpDjO099dqQvHpnCn18lyk7J4TWJ8sOQQb1EM2zDAfAOSqA/x + QuPEFl74DlY+5DIk6EBvpmWhaMSvXzWZACGA0sYqa157dq7O0AqmuLG/EI5EkHETO4CrtBW+yLcy + 2dUCXOMA+j+NjM1BjrQkYE5vtSfNO6lFZcISyKo5pTFlcA7ut0Fx2nZ8GhHTn32CpeWwNcZBn1gR + pZVt6DxVVkhTAkMLhR4rL2wGIi/1WRs23ZOLGKtyDNvDHnQyDiQEoJGy9nAthA8aNHa3cfdF10vB + Drb19vtpFHmpvKEEhpk2EBRF4fTi644Fuhu2Ied6118AlaPvEea+n6G4vBz+8RWuVCmZjLU+7h8l + Hy3/WdUPoIL5eW7Kz+hS+sRTFzfu9C48dMkQH3a6f3wSY+mufizNF9U298r98TnYy+PfDJK0bstG + Ph6yPWx8DGXKQBwrhWJWXI6JwZDeC5Ny+l8p1SypTmAjpIaSW3ge+KgcL6Wtt1R5hUV1ajVwVSUi + HF/FachKqPqyLJFZTGjNrxnmNYpt8P1d5JTvJfmfr55Su/P9n7kcyWp7zMcb2Q5nlXt4tWogOHLI + OzEWKCacbFfVHE+PpdrcvCVZMDzFogIq5EqGTOZe2poPpBVE+1y9mf5+TXBegy5HToLWvmfmJNTO + NCDuBjgLs2tdw2yMPm4YEr57PnMX5gGTC3f2ZihXCIJDCRCdQ9sVBOjIQbOCzxFXkVITo0BAZhCi + Yz61wt3Ud8e//zhXWCkCsSV+IZCxxPzhEFd+RFVjW0Nm9hsb2FgAhkXCjsGROgoleYgaZJWvQaAg + UyBzMmKDPKTllBHyE3Gy1ehBNGPgEBChf17/9M+j8pcm1OmlM434ctWQ4qW7RU56//yq1soFY0Te + fu2ei03a6m68fYuW6s7XEEK58QisJWRAvEbpwu/eyqfs7PsQ+zSgJHyk2rO95IxdMtEESb2GRuoi + Bs+AHNdYFTAi+GBWw9dvEgqQ0Mpv0//6bBE/Fb4d7b7f56uUNnnE7mFnjGmGQN+MvC62pfwfvJTT + EkT1iZ9kjM9FprTFWXT4UmO3XTvesGeE50sV9YPm71X4DCQwc4KE8vyuwj0s6oMNAUACW2ClU9QQ + y0tRpaF1tzs4N42Q5zl0TzWxbCCjAtC3u6xf+c8MCGrr7DzNhm42LOQiHTa4MwX4x96q7235oiAU + iQqSI/hyF5yLpWw4etyUvsx2/0/0wkuTU1FozbLoCWJEWcPS7QadMrRRISxHf0YobIeQyz34regl + t1qSQ3dCU9D6AHLgX6kqllx4X0fnFq7LtfN7fA2itW26v+kAT2QFZ3qZhINGfofCja/pITC1uNAZ + gsJaTMcQ600krj/ynoxnjT+n1gmeqThac6/Mi3YlVeRtaxI2InL82ZuD+w/dfY9OpPssQjy3xiQa + jPuaMWXRxz/sS9syOoGVH7XBwKrWpQcpchozWJt40QV5DslJkclcr8aC2AGlzuJMTdEgz1eqV0+H + bAXG9HRHN/0eJTn1/QAAAAEABVguNTA5AAADjzCCA4swggJzAhRGqVxH4HTLYPGO4rzHcCPeGDKn + xTANBgkqhkiG9w0BAQsFADCBgTELMAkGA1UEBhMCY2ExEDAOBgNVBAgMB29udGFyaW8xEDAOBgNV + BAcMB3Rvcm9udG8xFDASBgNVBAoMC2plbmtpbnN0ZXN0MRkwFwYDVQQDDBBqZW5raW5zdGVzdC5p + bmZvMR0wGwYJKoZIhvcNAQkBFg50ZXN0QHRlc3QuaW5mbzAeFw0xOTEwMDgxNTI5NTVaFw0xOTEx + MDcxNTI5NTVaMIGBMQswCQYDVQQGEwJjYTEQMA4GA1UECAwHb250YXJpbzEQMA4GA1UEBwwHdG9y + b250bzEUMBIGA1UECgwLamVua2luc3Rlc3QxGTAXBgNVBAMMEGplbmtpbnN0ZXN0LmluZm8xHTAb + BgkqhkiG9w0BCQEWDnRlc3RAdGVzdC5pbmZvMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC + AQEA02q352JTHGvROMBhSHvSv+vnoOTDKSTz2aLQn0tYrIRqRo+8bfmMjXuhkwZPSnCpvUGNAJ+w + Jrt/dqMoYUjCBkjylD/qHmnXN5EwS1cMg1Djh65gi5JJLFJ7eNcoSsr/0AJ+TweIal1jJSP3t3PF + 9Uv21gm6xdm7HnNK66WpUUXLDTKaIs/jtagVY1bLOo9oEVeLN4nT2CYWztpMvdCyEDUzgEdDbmrP + F5nKUPK5hrFqo1Dc5rUI4ZshL3Lpv398aMxv6n2adQvuL++URMEbXXBhxOrT6rCtYzbcR5fkwS9i + d3Br45CoWOQro02JAepoU0MQKY5+xQ4Bq9Q7tB9BAwIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQAe + 4xc+mSvKkrKBHg9/zpkWgZUiOp4ENJCi8H4tea/PCM439v6y/kfjT/okOokFvX8N5aa1OSz2Vsrl + m8kjIc6hiA7bKzT6lb0EyjUShFFZ5jmGVP4S7/hviDvgB5yEQxOPpumkdRP513YnEGj/o9Pazi5h + /MwpRxxazoda9r45kqQpyG+XoM4pB+Fd3JzMc4FUGxfVPxJU4jLawnJJiZ3vqiSyaB0YyUL+Er1Q + 6NnqtR4gEBF0ZVlQmkycFvD4EC2boP943dLqNUvop+4R3SM1QMM6P5u8iTXtHd/VN4MwMyy1wtog + hYAzODo1Jt59pcqqKJEas0C/lFJEB3frw4ImNx5fNlJYOpx+ijfQs9m39CevDq0= + +agent: + enabled: true + defaultsProviderTemplate: "" + # URL for connecting to the Jenkins contoller + jenkinsUrl: + # connect to the specified host and port, instead of connecting directly to the Jenkins controller + jenkinsTunnel: + kubernetesConnectTimeout: 5 + kubernetesReadTimeout: 15 + maxRequestsPerHostStr: "32" + namespace: + image: "jenkins/inbound-agent" + tag: "4.11.2-4" + workingDir: "/home/jenkins/agent" + nodeUsageMode: "NORMAL" + customJenkinsLabels: [] + # name of the secret to be used for image pulling + imagePullSecretName: + componentName: "jenkins-agent" + websocket: false + privileged: false + runAsUser: + runAsGroup: + hostNetworking: false + resources: + requests: + cpu: "512m" + memory: "512Mi" + limits: + cpu: "512m" + memory: "512Mi" + # You may want to change this to true while testing a new image + alwaysPullImage: false + # Controls how agent pods are retained after the Jenkins build completes + # Possible values: Always, Never, OnFailure + podRetention: "Never" + # Disable if you do not want the Yaml the agent pod template to show up + # in the job Console Output. This can be helpful for either security reasons + # or simply to clean up the output to make it easier to read. + showRawYaml: true + # You can define the volumes that you want to mount for this container + # Allowed types are: ConfigMap, EmptyDir, HostPath, Nfs, PVC, Secret + # Configure the attributes as they appear in the corresponding Java class for that type + # https://github.com/jenkinsci/kubernetes-plugin/tree/master/src/main/java/org/csanchez/jenkins/plugins/kubernetes/volumes + volumes: [] + # - type: ConfigMap + # configMapName: myconfigmap + # mountPath: /var/myapp/myconfigmap + # - type: EmptyDir + # mountPath: /var/myapp/myemptydir + # memory: false + # - type: HostPath + # hostPath: /var/lib/containers + # mountPath: /var/myapp/myhostpath + # - type: Nfs + # mountPath: /var/myapp/mynfs + # readOnly: false + # serverAddress: "192.0.2.0" + # serverPath: /var/lib/containers + # - type: PVC + # claimName: mypvc + # mountPath: /var/myapp/mypvc + # readOnly: false + # - type: Secret + # defaultMode: "600" + # mountPath: /var/myapp/mysecret + # secretName: mysecret + # Pod-wide environment, these vars are visible to any container in the agent pod + + # You can define the workspaceVolume that you want to mount for this container + # Allowed types are: DynamicPVC, EmptyDir, HostPath, Nfs, PVC + # Configure the attributes as they appear in the corresponding Java class for that type + # https://github.com/jenkinsci/kubernetes-plugin/tree/master/src/main/java/org/csanchez/jenkins/plugins/kubernetes/volumes/workspace + workspaceVolume: {} + ## DynamicPVC example + # type: DynamicPVC + # configMapName: myconfigmap + ## EmptyDir example + # type: EmptyDir + # memory: false + ## HostPath example + # type: HostPath + # hostPath: /var/lib/containers + ## NFS example + # type: Nfs + # readOnly: false + # serverAddress: "192.0.2.0" + # serverPath: /var/lib/containers + ## PVC example + # type: PVC + # claimName: mypvc + # readOnly: false + # + # Pod-wide environment, these vars are visible to any container in the agent pod + envVars: [] + # - name: PATH + # value: /usr/local/bin + # Mount a secret as environment variable + secretEnvVars: [] + # - key: PATH + # optional: false # default: false + # secretKey: MY-K8S-PATH + # secretName: my-k8s-secret + nodeSelector: {} + # Key Value selectors. Ex: + # jenkins-agent: v1 + + # Executed command when side container gets started + command: + args: "${computer.jnlpmac} ${computer.name}" + # Side container name + sideContainerName: "jnlp" + # Doesn't allocate pseudo TTY by default + TTYEnabled: false + # Max number of spawned agent + containerCap: 10 + # Pod name + podName: "default" + # Allows the Pod to remain active for reuse until the configured number of + # minutes has passed since the last step was executed on it. + idleMinutes: 0 + # Raw yaml template for the Pod. For example this allows usage of toleration for agent pods. + # https://github.com/jenkinsci/kubernetes-plugin#using-yaml-to-define-pod-templates + # https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ + yamlTemplate: "" + # yamlTemplate: |- + # apiVersion: v1 + # kind: Pod + # spec: + # tolerations: + # - key: "key" + # operator: "Equal" + # value: "value" + # Defines how the raw yaml field gets merged with yaml definitions from inherited pod templates: merge or override + yamlMergeStrategy: "override" + # Timeout in seconds for an agent to be online + connectTimeout: 100 + # Annotations to apply to the pod. + annotations: {} + + # Add additional containers to the agents. + # Containers specified here are added to all agents. Set key empty to remove container from additional agents. + additionalContainers: [] + # - sideContainerName: dind + # image: docker + # tag: dind + # command: dockerd-entrypoint.sh + # args: "" + # privileged: true + # resources: + # requests: + # cpu: 500m + # memory: 1Gi + # limits: + # cpu: 1 + # memory: 2Gi + + # Disable the default Jenkins Agent configuration. + # Useful when configuring agents only with the podTemplates value, since the default podTemplate populated by values mentioned above will be excluded in the rendered template. + disableDefaultAgent: false + + # Below is the implementation of custom pod templates for the default configured kubernetes cloud. + # Add a key under podTemplates for each pod template. Each key (prior to | character) is just a label, and can be any value. + # Keys are only used to give the pod template a meaningful name. The only restriction is they may only contain RFC 1123 \ DNS label + # characters: lowercase letters, numbers, and hyphens. Each pod template can contain multiple containers. + # For this pod templates configuration to be loaded the following values must be set: + # controller.JCasC.defaultConfig: true + # Best reference is https:///configuration-as-code/reference#Cloud-kubernetes. The example below creates a python pod template. + podTemplates: {} + # python: | + # - name: python + # label: jenkins-python + # serviceAccount: jenkins + # containers: + # - name: python + # image: python:3 + # command: "/bin/sh -c" + # args: "cat" + # ttyEnabled: true + # privileged: true + # resourceRequestCpu: "400m" + # resourceRequestMemory: "512Mi" + # resourceLimitCpu: "1" + # resourceLimitMemory: "1024Mi" + +# Here you can add additional agents +# They inherit all values from `agent` so you only need to specify values which differ +additionalAgents: {} +# maven: +# podName: maven +# customJenkinsLabels: maven +# # An example of overriding the jnlp container +# # sideContainerName: jnlp +# image: jenkins/jnlp-agent-maven +# tag: latest +# python: +# podName: python +# customJenkinsLabels: python +# sideContainerName: python +# image: python +# tag: "3" +# command: "/bin/sh -c" +# args: "cat" +# TTYEnabled: true + +persistence: + enabled: true + ## A manually managed Persistent Volume and Claim + ## Requires persistence.enabled: true + ## If defined, PVC must be created manually before volume will be bound + existingClaim: + ## jenkins data Persistent Volume Storage Class + ## If defined, storageClassName: + ## If set to "-", storageClassName: "", which disables dynamic provisioning + ## If undefined (the default) or set to null, no storageClassName spec is + ## set, choosing the default provisioner. (gp2 on AWS, standard on + ## GKE, AWS & OpenStack) + ## + storageClass: + annotations: {} + labels: {} + accessMode: "ReadWriteOnce" + size: "8Gi" + volumes: + # - name: nothing + # emptyDir: {} + mounts: + # - mountPath: /var/nothing + # name: nothing + # readOnly: true + +networkPolicy: + # Enable creation of NetworkPolicy resources. + enabled: false + # For Kubernetes v1.4, v1.5 and v1.6, use 'extensions/v1beta1' + # For Kubernetes v1.7, use 'networking.k8s.io/v1' + apiVersion: networking.k8s.io/v1 + # You can allow agents to connect from both within the cluster (from within specific/all namespaces) AND/OR from a given external IP range + internalAgents: + allowed: true + podLabels: {} + namespaceLabels: {} + # project: myproject + externalAgents: {} + # ipCIDR: 172.17.0.0/16 + # except: + # - 172.17.1.0/24 + +## Install Default RBAC roles and bindings +rbac: + create: true + readSecrets: false + +serviceAccount: + create: true + # The name of the service account is autogenerated by default + name: + annotations: {} + imagePullSecretName: + + +serviceAccountAgent: + # Specifies whether a ServiceAccount should be created + create: false + # The name of the ServiceAccount to use. + # If not set and create is true, a name is generated using the fullname template + name: + annotations: {} + imagePullSecretName: + +## Backup cronjob configuration +## Ref: https://github.com/maorfr/kube-tasks +backup: + # Backup must use RBAC + # So by enabling backup you are enabling RBAC specific for backup + enabled: false + # Used for label app.kubernetes.io/component + componentName: "backup" + # Schedule to run jobs. Must be in cron time format + # Ref: https://crontab.guru/ + schedule: "0 2 * * *" + labels: {} + serviceAccount: + create: true + name: + annotations: {} + # Example for authorization to AWS S3 using kube2iam or IRSA + # Can also be done using environment variables + # iam.amazonaws.com/role: "jenkins" + # "eks.amazonaws.com/role-arn": "arn:aws:iam::123456789012:role/jenkins-backup" + # Set this to terminate the job that is running/failing continously and set the job status to "Failed" + activeDeadlineSeconds: "" + image: + repository: "maorfr/kube-tasks" + tag: "0.2.0" + imagePullSecretName: + # Additional arguments for kube-tasks + # Ref: https://github.com/maorfr/kube-tasks#simple-backup + extraArgs: [] + # Add existingSecret for AWS credentials + existingSecret: {} + ## Example for using an existing secret + # jenkinsaws: + ## Use this key for AWS access key ID + # awsaccesskey: jenkins_aws_access_key + ## Use this key for AWS secret access key + # awssecretkey: jenkins_aws_secret_key + # Add additional environment variables + # jenkinsgcp: + ## Use this key for GCP credentials + # gcpcredentials: credentials.json + env: [] + # Example environment variable required for AWS credentials chain + # - name: "AWS_REGION" + # value: "us-east-1" + resources: + requests: + memory: 1Gi + cpu: 1 + limits: + memory: 1Gi + cpu: 1 + # Destination to store the backup artifacts + # Supported cloud storage services: AWS S3, Minio S3, Azure Blob Storage, Google Cloud Storage + # Additional support can added. Visit this repository for details + # Ref: https://github.com/maorfr/skbn + destination: "s3://jenkins-data/backup" + # By enabling only the jenkins_home/jobs folder gets backed up, not the whole jenkins instance + onlyJobs: false + # Enable backup pod security context (must be `true` if runAsUser or fsGroup are set) + usePodSecurityContext: true + # When setting runAsUser to a different value than 0 also set fsGroup to the same value: + runAsUser: 1000 + fsGroup: 1000 + securityContextCapabilities: {} + # drop: + # - NET_RAW +checkDeprecation: true + +awsSecurityGroupPolicies: + enabled: false + policies: + - name: "" + securityGroupIds: [] + podSelector: {} diff --git a/helm/nexus-repository-manager/.helmignore b/helm/nexus-repository-manager/.helmignore new file mode 100644 index 0000000..9301b24 --- /dev/null +++ b/helm/nexus-repository-manager/.helmignore @@ -0,0 +1,24 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*~ +# Various IDEs +.project +.idea/ +*.tmproj +# OWNERS file for Kubernetes +OWNERS +*.tar diff --git a/helm/nexus-repository-manager/Chart.yaml b/helm/nexus-repository-manager/Chart.yaml new file mode 100644 index 0000000..adaf2a5 --- /dev/null +++ b/helm/nexus-repository-manager/Chart.yaml @@ -0,0 +1,24 @@ +apiVersion: v2 +appVersion: 3.52.0 +description: Sonatype Nexus Repository Manager - Universal Binary repository +home: https://www.sonatype.com/nexus-repository-oss +icon: https://sonatype.github.io/helm3-charts/NexusRepo_Vertical.svg +keywords: +- artifacts +- dependency +- management +- sonatype +- nexus +- repository +- quickstart +- ci +- repository-manager +- nexus3 +maintainers: +- email: support@sonatype.com + name: Sonatype +name: nexus-repository-manager +sources: +- https://github.com/sonatype/nexus-public +type: application +version: 52.0.0 diff --git a/helm/nexus-repository-manager/LICENSE b/helm/nexus-repository-manager/LICENSE new file mode 100644 index 0000000..84cbff0 --- /dev/null +++ b/helm/nexus-repository-manager/LICENSE @@ -0,0 +1,13 @@ +Copyright (c) 2020-present Sonatype, Inc. + +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/helm/nexus-repository-manager/README.md b/helm/nexus-repository-manager/README.md new file mode 100644 index 0000000..abbf35d --- /dev/null +++ b/helm/nexus-repository-manager/README.md @@ -0,0 +1,236 @@ + +# ⚠️ Archive Notice + +As of October 24, 2023, we will no longer update or support this Helm chart. + +Deploying Nexus Repository in containers with an embedded database has been known to corrupt the database under some circumstances. We strongly recommend that you use an external PostgreSQL database for Kubernetes deployments. + +If you are deploying in AWS, you can use our [AWS Helm chart](https://github.com/sonatype/nxrm3-helm-repository/tree/main/nxrm-aws-resiliency) to deploy Nexus Repository in an EKS cluster. + +We do not currently provide Helm charts for on-premises deployments using PostgreSQL. For those wishing to deploy on premises, see our [Single Data Center On-Premises Deployment Example Using Kubernetes documentation](https://help.sonatype.com/repomanager3/planning-your-implementation/resiliency-and-high-availability/single-data-center-on-premises-deployment-example-using-kubernetes) for information and sample YAMLs to help you plan a resilient on-premises deployment. + +# Nexus Repository + +[Nexus Repository OSS](https://www.sonatype.com/nexus-repository-oss) provides universal support for all major build tools. + +- Store and distribute Maven/Java, npm, NuGet, Helm, Docker, p2, OBR, APT, Go, R, Conan components and more. +- Manage components from dev through delivery: binaries, containers, assemblies, and finished goods. +- Support for the Java Virtual Machine (JVM) ecosystem, including Gradle, Ant, Maven, and Ivy. +- Compatible with popular tools like Eclipse, IntelliJ, Hudson, Jenkins, Puppet, Chef, Docker, and more. + +*Efficiency and Flexibility to Empower Development Teams* + +- Streamline productivity by sharing components internally. +- Gain insight into component security, license, and quality issues. +- Build off-line with remote package availability. +- Integrate with industry-leading build tools. +--- + +## Introduction + +This chart installs a single Nexus Repository instance within a Kubernetes cluster that has a single node (server) configured. It is not appropriate for a resilient Nexus Repository deployment. Refer to our [resiliency documentation](https://help.sonatype.com/repomanager3/planning-your-implementation/resiliency-and-high-availability) for information about resilient Nexus Repository deployment options. + +Use the checklist below to determine if this Helm chart is suitable for your deployment needs. + +### When to Use This Helm Chart +Use this Helm chart if you are doing any of the following: +- Deploying either Nexus Repository Pro or OSS to an on-premises environment with bare metal/VM server (Node) +- Deploying a single Nexus Repository instance within a Kubernetes cluster that has a single Node configured + +> **Note**: If you are using Nexus Repository Pro, your license file and embedded database will reside on the node and be mounted on the container as a Persistent Volume (required). + + +### When Not to Use This Helm Chart +Do not use this Helm chart and, instead, refer to our [resiliency documentation](https://help.sonatype.com/repomanager3/planning-your-implementation/resiliency-and-high-availability) if you are doing any of the following: + +- Deploying Nexus Repository Pro to a cloud environment with the desire for automatic failover across Availability Zones (AZs) within a single region +- Planning to configure a single Nexus Repository Pro instance within your Kubernetes/EKS cluster with two or more nodes spread across different AZs within an AWS region +- Using an external PostgreSQL database + +> **Note**: A Nexus Repository Pro license is required for our resilient deployment options. Your Nexus Repository Pro license file must be stored externally as either mounted from AWS Secrets/Azure Key Vault in AWS/Azure deployments or mounted using Kustomize for on-premises deployments (required). + +> **Note**: We do not currently provide Helm charts for our resilient deployment options. + +--- + +## Prerequisites for This Chart + +- Kubernetes 1.19+ +- PV provisioner support in the underlying infrastructure +- Helm 3 + +### With Open Docker Image + +By default, this Chart uses Sonatype's Public Docker image. If you want to use a different image, run with the following: `--set nexus.imageName=/`. + +## Adding the Sonatype Repository to your Helm + +To add as a Helm Repo +```helm repo add sonatype https://sonatype.github.io/helm3-charts/``` + +--- + +## Testing the Chart +To test the chart, use the following: +```bash +$ helm install --dry-run --debug --generate-name ./ +``` +To test the chart with your own values, use the following: +```bash +$ helm install --dry-run --debug --generate-name -f myvalues.yaml ./ +``` + +--- + +## Installing the Chart + +To install the chart, use the following: + +```bash +$ helm install nexus-rm sonatype/nexus-repository-manager [ --version v29.2.0 ] +``` + +The above command deploys Nexus Repository on the Kubernetes cluster in the default configuration. + +You can pass custom configuration values as follows: + +```bash +$ helm install -f myvalues.yaml sonatype-nexus ./ +``` + +The default login is randomized and can be found in `/nexus-data/admin.password` or you can get the initial static passwords (admin/admin123) +by setting the environment variable `NEXUS_SECURITY_RANDOMPASSWORD` to `false` in your `values.yaml`. + +--- + +## Uninstalling the Chart + +To uninstall/delete the deployment, use the following: + +```bash +$ helm list +NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION +plinking-gopher default 1 2021-03-10 15:44:57.301847 -0800 PST deployed nexus-repository-manager-29.2.0 3.29.2 +$ helm delete plinking-gopher +``` + +The command removes all the Kubernetes components associated with the chart and deletes the release. + +--- + +## Configuration + +The following table lists the configurable parameters of the Nexus chart and their default values. + +| Parameter | Description | Default | +|--------------------------------------------|----------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------| +| `deploymentStrategy` | Deployment Strategy | `Recreate` | +| `nexus.imagePullPolicy` | Nexus Repository image pull policy | `IfNotPresent` | +| `imagePullSecrets` | The names of the kubernetes secrets with credentials to login to a registry | `[]` | +| `nexus.docker.enabled` | Enable/disable Docker support | `false` | +| `nexus.docker.registries` | Support multiple Docker registries | (see below) | +| `nexus.docker.registries[0].host` | Host for the Docker registry | `cluster.local` | +| `nexus.docker.registries[0].port` | Port for the Docker registry | `5000` | +| `nexus.docker.registries[0].secretName` | TLS Secret Name for the ingress | `registrySecret` | +| `nexus.env` | Nexus Repository environment variables | `[{INSTALL4J_ADD_VM_PARAMS: -Xms1200M -Xmx1200M -XX:MaxDirectMemorySize=2G -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap}]` | +| `nexus.resources` | Nexus Repository resource requests and limits | `{}` | +| `nexus.nexusPort` | Internal port for Nexus Repository service | `8081` | +| `nexus.securityContext` | Security Context (for enabling official image use `fsGroup: 2000`) | `{}` | +| `nexus.labels` | Service labels | `{}` | +| `nexus.podAnnotations` | Pod Annotations | `{}` | +| `nexus.livenessProbe.initialDelaySeconds` | LivenessProbe initial delay | 30 | +| `nexus.livenessProbe.periodSeconds` | Seconds between polls | 30 | +| `nexus.livenessProbe.failureThreshold` | Number of attempts before failure | 6 | +| `nexus.livenessProbe.timeoutSeconds` | Time in seconds after liveness probe times out | `nil` | +| `nexus.livenessProbe.path` | Path for LivenessProbe | / | +| `nexus.readinessProbe.initialDelaySeconds` | ReadinessProbe initial delay | 30 | +| `nexus.readinessProbe.periodSeconds` | Seconds between polls | 30 | +| `nexus.readinessProbe.failureThreshold` | Number of attempts before failure | 6 | +| `nexus.readinessProbe.timeoutSeconds` | Time in seconds after readiness probe times out | `nil` | +| `nexus.readinessProbe.path` | Path for ReadinessProbe | / | +| `nexus.hostAliases` | Aliases for IPs in /etc/hosts | [] | +| `nexus.properties.override` | Set to true to override default nexus.properties | `false` | +| `nexus.properties.data` | A map of custom nexus properties if `override` is set to true | `nexus.scripts.allowCreation: true` | +| `ingress.enabled` | Create an ingress for Nexus Repository | `false` | +| `ingress.annotations` | Annotations to enhance ingress configuration | `{kubernetes.io/ingress.class: nginx}` | +| `ingress.tls.secretName` | Name of the secret storing TLS cert, `false` to use the Ingress' default certificate | `nexus-tls` | +| `ingress.path` | Path for ingress rules. GCP users should set to `/*`. | `/` | +| `tolerations` | tolerations list | `[]` | +| `config.enabled` | Enable configmap | `false` | +| `config.mountPath` | Path to mount the config | `/sonatype-nexus-conf` | +| `config.data` | Configmap data | `nil` | +| `deployment.annotations` | Annotations to enhance deployment configuration | `{}` | +| `deployment.initContainers` | Init containers to run before main containers | `nil` | +| `deployment.postStart.command` | Command to run after starting the container | `nil` | +| `deployment.terminationGracePeriodSeconds` | Update termination grace period (in seconds) | 120s | +| `deployment.additionalContainers` | Add additional Container | `nil` | +| `deployment.additionalVolumes` | Add additional Volumes | `nil` | +| `deployment.additionalVolumeMounts` | Add additional Volume mounts | `nil` | +| `secret.enabled` | Enable secret | `false` | +| `secret.mountPath` | Path to mount the secret | `/etc/secret-volume` | +| `secret.readOnly` | Secret readonly state | `true` | +| `secret.data` | Secret data | `nil` | +| `service.enabled` | Enable additional service | `true` | +| `service.name` | Service name | `nexus3` | +| `service.labels` | Service labels | `nil` | +| `service.annotations` | Service annotations | `nil` | +| `service.type` | Service Type | `ClusterIP` | +| `route.enabled` | Set to true to create route for additional service | `false` | +| `route.name` | Name of route | `docker` | +| `route.portName` | Target port name of service | `docker` | +| `route.labels` | Labels to be added to route | `{}` | +| `route.annotations` | Annotations to be added to route | `{}` | +| `route.path` | Host name of Route e.g. jenkins.example.com | nil | +| `serviceAccount.create` | Set to true to create ServiceAccount | `true` | +| `serviceAccount.annotations` | Set annotations for ServiceAccount | `{}` | +| `serviceAccount.name` | The name of the service account to use. Auto-generate if not set and create is true. | `{}` | +| `persistence.enabled` | Set false to eliminate persistent storage | `true` | +| `persistence.existingClaim` | Specify the name of an existing persistent volume claim to use instead of creating a new one | nil | +| `persistence.storageSize` | Size of the storage the chart will request | `8Gi` | + +### Persistence + +By default, a `PersistentVolumeClaim` is created and mounted into the `/nexus-data` directory. In order to disable this functionality, you can change the `values.yaml` to disable persistence, which will use an `emptyDir` instead. + +> *"An emptyDir volume is first created when a Pod is assigned to a Node, and exists as long as that Pod is running on that node. When a Pod is removed from a node for any reason, the data in the emptyDir is deleted forever."* + +## Using the Image from the Red Hat Registry + +To use the [Nexus Repository Manager image available from Red Hat's registry](https://catalog.redhat.com/software/containers/sonatype/nexus-repository-manager/594c281c1fbe9847af657690), +you'll need to: +* Load the credentials for the registry as a secret in your cluster + ```shell + kubectl create secret docker-registry redhat-pull-secret \ + --docker-server=registry.connect.redhat.com \ + --docker-username= \ + --docker-password= \ + --docker-email= + ``` + See Red Hat's [Registry Authentication documentation](https://access.redhat.com/RegistryAuthentication) + for further details. +* Provide the name of the secret in `imagePullSecrets` in this chart's `values.yaml` + ```yaml + imagePullSecrets: + - name: redhat-pull-secret + ``` +* Set `image.name` and `image.tag` in `values.yaml` + ```yaml + image: + repository: registry.connect.redhat.com/sonatype/nexus-repository-server + tag: 3.39.0-ubi-1 + ``` + +--- diff --git a/helm/nexus-repository-manager/override-values.yaml b/helm/nexus-repository-manager/override-values.yaml new file mode 100644 index 0000000..f9b0597 --- /dev/null +++ b/helm/nexus-repository-manager/override-values.yaml @@ -0,0 +1,39 @@ +nameOverride: "nexus-repository-manager" + +nexus: + docker: + enabled: true + registries: + - host: chart.local + port: 5000 + secretName: registry-secret + nodePort: 30500 + env: + - name: INSTALL4J_ADD_VM_PARAMS + value: |- + -Xms2703M -Xmx2703M + -XX:MaxDirectMemorySize=2703M + -XX:ActiveProcessorCount=4 + -XX:+UnlockExperimentalVMOptions + -XX:+UseCGroupMemoryLimitForHeap + -Djava.util.prefs.userRoot=/nexus-data/javaprefs + - name: NEXUS_SECURITY_RANDOMPASSWORD + value: "true" + resources: + requests: + cpu: 500m + memory: 2048Mi + limits: + cpu: 4000m + memory: 8192Mi + livenessProbe: + initialDelaySeconds: 300 + readinessProbe: + initialDelaySeconds: 300 + +service: + type: NodePort + nodePort: 32080 + +persistence: + storageClass: "nfs-provisioner-mgmt" diff --git a/helm/nexus-repository-manager/templates/NOTES.txt b/helm/nexus-repository-manager/templates/NOTES.txt new file mode 100644 index 0000000..ed3c454 --- /dev/null +++ b/helm/nexus-repository-manager/templates/NOTES.txt @@ -0,0 +1,27 @@ +{{- if .Values.ingress.enabled }} +1. Your ingresses are available here: + http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $.Values.ingress.hostRepo }}{{ $.Values.ingress.hostPath }} + {{- if $.Values.nexus.docker.enabled }} + {{- range $registry := .Values.nexus.docker.registries }} + https://{{ $registry.host }}/ + {{- end }} + {{- end }} +{{- else if contains "NodePort" .Values.service.type }} +1. Get the application URL by running these commands: + export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "nexus.fullname" . }}) + export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") + Your application is available at http://$NODE_IP:$NODE_PORT +{{- else if contains "LoadBalancer" .Values.service.type }} +1. Get the application URL by running these commands: + 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 "nexus.fullname" . }}' + export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "nexus.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") + {{- range $index, $port := .Values.service.ports }} + Your application is available at http://$SERVICE_IP:{{ $port }} + {{- end }} +{{- else if contains "ClusterIP" .Values.service.type }} +1. Get the application URL by running these commands: + export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "nexus.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") + kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8081:80 + Your application is available at http://127.0.0.1 +{{- end }} diff --git a/helm/nexus-repository-manager/templates/_helpers.tpl b/helm/nexus-repository-manager/templates/_helpers.tpl new file mode 100644 index 0000000..e726f1f --- /dev/null +++ b/helm/nexus-repository-manager/templates/_helpers.tpl @@ -0,0 +1,63 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "nexus.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 "nexus.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 "nexus.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Common labels +*/}} +{{- define "nexus.labels" -}} +helm.sh/chart: {{ include "nexus.chart" . }} +{{ include "nexus.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end -}} + +{{/* +Selector labels +*/}} +{{- define "nexus.selectorLabels" -}} +app.kubernetes.io/name: {{ include "nexus.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end -}} + +{{/* +Create the name of the service account to use +*/}} +{{- define "nexus.serviceAccountName" -}} +{{- if .Values.serviceAccount.create -}} + {{ default (include "nexus.fullname" .) .Values.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.serviceAccount.name }} +{{- end -}} +{{- end -}} diff --git a/helm/nexus-repository-manager/templates/configmap-properties.yaml b/helm/nexus-repository-manager/templates/configmap-properties.yaml new file mode 100644 index 0000000..c1a5808 --- /dev/null +++ b/helm/nexus-repository-manager/templates/configmap-properties.yaml @@ -0,0 +1,17 @@ +{{- if .Values.nexus.properties.override -}} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "nexus.name" . }}-properties + labels: {{- include "nexus.labels" . | nindent 4 }} + {{- if .Values.nexus.extraLabels }} + {{- with .Values.nexus.extraLabels }} + {{ toYaml . | indent 4 }} + {{- end }} + {{- end }} +data: + nexus.properties: | + {{- range $k, $v := .Values.nexus.properties.data }} + {{ $k }}={{ $v }} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/helm/nexus-repository-manager/templates/configmap.yaml b/helm/nexus-repository-manager/templates/configmap.yaml new file mode 100644 index 0000000..55418b1 --- /dev/null +++ b/helm/nexus-repository-manager/templates/configmap.yaml @@ -0,0 +1,15 @@ +{{- if .Values.config.enabled -}} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "nexus.name" . }}-conf + labels: +{{ include "nexus.labels" . | indent 4 }} + {{- if .Values.nexus.extraLabels }} + {{- with .Values.nexus.extraLabels }} + {{ toYaml . | indent 4 }} + {{- end }} + {{- end }} +data: +{{ toYaml .Values.config.data | indent 2 }} +{{- end }} \ No newline at end of file diff --git a/helm/nexus-repository-manager/templates/deployment.yaml b/helm/nexus-repository-manager/templates/deployment.yaml new file mode 100644 index 0000000..d3eea71 --- /dev/null +++ b/helm/nexus-repository-manager/templates/deployment.yaml @@ -0,0 +1,163 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "nexus.fullname" . }} + labels: +{{ include "nexus.labels" . | indent 4 }} + {{- if .Values.nexus.extraLabels }} + {{- with .Values.nexus.extraLabels }} + {{ toYaml . | indent 4 }} + {{- end }} + {{- end }} +{{- if .Values.deployment.annotations }} + annotations: + {{ toYaml .Values.deployment.annotations | nindent 4 }} +{{- end }} +spec: + replicas: 1 + strategy: + type: {{ .Values.deploymentStrategy }} + selector: + matchLabels: + {{- include "nexus.selectorLabels" . | nindent 6 }} + {{- if .Values.nexus.extraSelectorLabels }} + {{- with .Values.nexus.extraSelectorLabels }} + {{ toYaml . | indent 6 }} + {{- end }} + {{- end }} + template: + metadata: + annotations: + checksum/configmap-properties: {{ include (print .Template.BasePath "/configmap-properties.yaml") $ | sha256sum }} + {{- if .Values.nexus.podAnnotations }} + {{ toYaml .Values.nexus.podAnnotations | nindent 8}} + {{- end }} + labels: + {{- include "nexus.selectorLabels" . | nindent 8 }} + spec: + serviceAccountName: {{ include "nexus.serviceAccountName" . }} + {{- if .Values.deployment.initContainers }} + initContainers: + {{ toYaml .Values.deployment.initContainers | nindent 6 }} + {{- end }} + {{- if .Values.nexus.nodeSelector }} + nodeSelector: + {{ toYaml .Values.nexus.nodeSelector | nindent 8 }} + {{- end }} + {{- if .Values.nexus.hostAliases }} + hostAliases: + {{ toYaml .Values.nexus.hostAliases | nindent 8 }} + {{- end }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.deployment.terminationGracePeriodSeconds }} + terminationGracePeriodSeconds: {{ .Values.deployment.terminationGracePeriodSeconds }} + {{- end }} + containers: + - name: {{ .Chart.Name }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + + lifecycle: + {{- if .Values.deployment.postStart.command }} + postStart: + exec: + command: {{ .Values.deployment.postStart.command }} + {{- end }} + env: + {{ toYaml .Values.nexus.env | nindent 12 }} + envFrom: + {{ toYaml .Values.nexus.envFrom | nindent 12 }} + resources: + {{ toYaml .Values.nexus.resources | nindent 12 }} + ports: + - name: nexus-ui + containerPort: {{ .Values.nexus.nexusPort }} + {{- if .Values.nexus.docker.enabled }} + {{- range .Values.nexus.docker.registries }} + - name: docker-{{ .port }} + containerPort: {{ .port }} + {{- end }} + {{- end }} + livenessProbe: + httpGet: + path: {{ .Values.nexus.livenessProbe.path }} + port: {{ .Values.nexus.nexusPort }} + initialDelaySeconds: {{ .Values.nexus.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.nexus.livenessProbe.periodSeconds }} + failureThreshold: {{ .Values.nexus.livenessProbe.failureThreshold }} + {{- if .Values.nexus.livenessProbe.timeoutSeconds }} + timeoutSeconds: {{ .Values.nexus.livenessProbe.timeoutSeconds }} + {{- end }} + readinessProbe: + httpGet: + path: {{ .Values.nexus.readinessProbe.path }} + port: {{ .Values.nexus.nexusPort }} + initialDelaySeconds: {{ .Values.nexus.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.nexus.readinessProbe.periodSeconds }} + failureThreshold: {{ .Values.nexus.readinessProbe.failureThreshold }} + {{- if .Values.nexus.readinessProbe.timeoutSeconds }} + timeoutSeconds: {{ .Values.nexus.readinessProbe.timeoutSeconds }} + {{- end }} + volumeMounts: + - mountPath: /nexus-data + name: {{ template "nexus.name" . }}-data + {{- if .Values.config.enabled }} + - mountPath: {{ .Values.config.mountPath }} + name: {{ template "nexus.name" . }}-conf + {{- end }} + {{- if .Values.nexus.properties.override }} + - mountPath: /nexus-data/etc/nexus.properties + name: {{ template "nexus.name" . }}-properties + subPath: nexus.properties + {{- end }} + {{- if .Values.secret.enabled }} + - mountPath: {{ .Values.secret.mountPath }} + name: {{ template "nexus.name" . }}-secret + readOnly: {{ .Values.secret.readOnly }} + {{- end }} + {{- if .Values.deployment.additionalVolumeMounts}} + {{ toYaml .Values.deployment.additionalVolumeMounts | nindent 12 }} + {{- end }} + {{- if .Values.deployment.additionalContainers }} + {{ toYaml .Values.deployment.additionalContainers | nindent 8 }} + {{- end }} + {{- if .Values.nexus.securityContext }} + securityContext: + {{ toYaml .Values.nexus.securityContext | nindent 8 }} + {{- end }} + volumes: + - name: {{ template "nexus.name" . }}-data + {{- if .Values.persistence.enabled }} + persistentVolumeClaim: + claimName: {{ .Values.persistence.existingClaim | default (printf "%s-%s" (include "nexus.fullname" .) "data") }} + {{- else }} + emptyDir: {} + {{- end }} + {{- if .Values.config.enabled }} + - name: {{ template "nexus.name" . }}-conf + configMap: + name: {{ template "nexus.name" . }}-conf + {{- end }} + {{- if .Values.nexus.properties.override }} + - name: {{ template "nexus.name" . }}-properties + configMap: + name: {{ template "nexus.name" . }}-properties + items: + - key: nexus.properties + path: nexus.properties + {{- end }} + {{- if .Values.secret.enabled }} + - name: {{ template "nexus.name" . }}-secret + secret: + secretName: {{ template "nexus.name" . }}-secret + {{- end }} + {{- if .Values.deployment.additionalVolumes }} + {{ toYaml .Values.deployment.additionalVolumes | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{ toYaml . | nindent 8 }} + {{- end }} diff --git a/helm/nexus-repository-manager/templates/ingress.yaml b/helm/nexus-repository-manager/templates/ingress.yaml new file mode 100644 index 0000000..198fdfe --- /dev/null +++ b/helm/nexus-repository-manager/templates/ingress.yaml @@ -0,0 +1,85 @@ +{{- if .Values.ingress.enabled -}} +{{- $fullName := include "nexus.fullname" . -}} +{{- $svcPort := .Values.nexus.nexusPort -}} +{{- $ingressPath := .Values.ingress.path -}} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ $fullName }} + labels: + {{- include "nexus.labels" . | nindent 4 }} + {{- if .Values.nexus.extraLabels }} + {{- with .Values.nexus.extraLabels }} + {{ toYaml . | indent 4 }} + {{- end }} + {{- end }} + {{- with .Values.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if .Values.ingress.ingressClassName }} + ingressClassName: {{ .Values.ingress.ingressClassName }} + {{- end }} + {{- if .Values.ingress.tls }} + tls: + {{- range .Values.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ . | quote }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} + {{- end }} + rules: + - host: {{ .Values.ingress.hostRepo }} + http: + paths: + - path: {{ .Values.ingress.hostPath }} + pathType: Prefix + backend: + service: + name: {{ $fullName }} + port: + number: 8081 + +{{ if .Values.nexus.docker.enabled }} +{{ range $registry := .Values.nexus.docker.registries }} +--- +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ $fullName | trunc 49 }}-docker-{{ $registry.port }} + labels: + {{- include "nexus.labels" $ | nindent 4 }} + {{- if $.Values.nexus.extraLabels }} + {{- with $.Values.nexus.extraLabels }} + {{ toYaml . | indent 4 }} + {{- end }} + {{- end }} + {{- with $.Values.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if $.Values.ingress.ingressClassName }} + ingressClassName: {{ $.Values.ingress.ingressClassName }} + {{- end }} + tls: + - hosts: + - {{ $registry.host | quote }} + secretName: {{ $registry.secretName }} + rules: + - host: {{ $registry.host }} + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: {{ $fullName | trunc 49 }}-docker-{{ $registry.port }} + port: + number: {{ $registry.port }} +{{- end }} {{- /* range of nexus.docker.registries */ -}} +{{- end }} {{- /* nexus.docker.enabled */ -}} +{{- end }} {{- /* ingress.enabled */ -}} diff --git a/helm/nexus-repository-manager/templates/proxy-route.yaml b/helm/nexus-repository-manager/templates/proxy-route.yaml new file mode 100644 index 0000000..f66e135 --- /dev/null +++ b/helm/nexus-repository-manager/templates/proxy-route.yaml @@ -0,0 +1,23 @@ +{{- if .Values.nexusProxyRoute.enabled }} +apiVersion: route.openshift.io/v1 +kind: Route +metadata: + name: {{ template "nexus.fullname" . }} + labels: {{ .Values.nexusProxyRoute.labels }} + annotations: + {{- range $key, $value := .Values.nexusProxyRoute.annotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} +spec: + host: {{ .Values.nexusProxyRoute.path }} + port: + targetPort: {{ template "nexus.fullname" . }} + tls: + insecureEdgeTerminationPolicy: Redirect + termination: edge + to: + kind: Service + name: {{ template "nexus.fullname" . }} + weight: 100 + wildcardPolicy: None +{{- end }} diff --git a/helm/nexus-repository-manager/templates/pv.yaml b/helm/nexus-repository-manager/templates/pv.yaml new file mode 100644 index 0000000..1f17872 --- /dev/null +++ b/helm/nexus-repository-manager/templates/pv.yaml @@ -0,0 +1,26 @@ +{{- if not .Values.statefulset.enabled }} +{{- if .Values.persistence.pdName -}} +apiVersion: v1 +kind: PersistentVolume +metadata: + name: {{ .Values.persistence.pdName }} + labels: +{{ include "nexus.labels" . | indent 4 }} + {{- if .Values.nexus.extraLabels }} + {{- with .Values.nexus.extraLabels }} + {{ toYaml . | indent 4 }} + {{- end }} + {{- end }} +spec: + capacity: + storage: {{ .Values.persistence.storageSize }} + accessModes: + - ReadWriteOnce + claimRef: + namespace: {{ .Release.Namespace }} + name: {{ template "nexus.fullname" . }}-data + gcePersistentDisk: + pdName: {{ .Values.persistence.pdName }} + fsType: {{ .Values.persistence.fsType }} +{{- end }} +{{- end }} diff --git a/helm/nexus-repository-manager/templates/pvc.yaml b/helm/nexus-repository-manager/templates/pvc.yaml new file mode 100644 index 0000000..32e9b78 --- /dev/null +++ b/helm/nexus-repository-manager/templates/pvc.yaml @@ -0,0 +1,30 @@ +{{- if and .Values.persistence.enabled (not .Values.persistence.existingClaim) }} +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: + name: {{ template "nexus.fullname" . }}-data + labels: +{{ include "nexus.labels" . | indent 4 }} + {{- if .Values.nexus.extraLabels }} + {{- with .Values.nexus.extraLabels }} + {{ toYaml . | indent 4 }} + {{- end }} + {{- end }} +{{- if .Values.persistence.annotations }} + annotations: +{{ toYaml .Values.persistence.annotations | indent 4 }} +{{- end }} +spec: + accessModes: + - {{ .Values.persistence.accessMode | quote }} + resources: + requests: + storage: {{ .Values.persistence.storageSize | quote }} +{{- if .Values.persistence.storageClass }} +{{- if (eq "-" .Values.persistence.storageClass) }} + storageClassName: "" +{{- else }} + storageClassName: "{{ .Values.persistence.storageClass }}" +{{- end }} +{{- end }} +{{- end }} diff --git a/helm/nexus-repository-manager/templates/route.yaml b/helm/nexus-repository-manager/templates/route.yaml new file mode 100644 index 0000000..cf76e5b --- /dev/null +++ b/helm/nexus-repository-manager/templates/route.yaml @@ -0,0 +1,27 @@ +{{- if .Values.route.enabled }} +apiVersion: route.openshift.io/v1 +kind: Route +metadata: + name: {{ .Values.route.name }} + labels: {{ .Values.route.labels }} + annotations: + {{- range $key, $value := .Values.route.annotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} +spec: + host: {{ .Values.route.path }} + port: + targetPort: {{ .Values.service.portName }} + tls: + insecureEdgeTerminationPolicy: Redirect + termination: edge + to: + kind: Service +{{- if .Values.service.name }} + name: {{ .Values.service.name }} +{{- else }} + name: {{ template "nexus.name" . }}-service +{{- end }} + weight: 100 + wildcardPolicy: None +{{- end }} diff --git a/helm/nexus-repository-manager/templates/secret.yaml b/helm/nexus-repository-manager/templates/secret.yaml new file mode 100644 index 0000000..3dbbcd4 --- /dev/null +++ b/helm/nexus-repository-manager/templates/secret.yaml @@ -0,0 +1,15 @@ +{{- if .Values.secret.enabled -}} +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "nexus.name" . }}-secret + labels: +{{ include "nexus.labels" . | indent 4 }} + {{- if .Values.nexus.extraLabels }} + {{- with .Values.nexus.extraLabels }} + {{ toYaml . | indent 4 }} + {{- end }} + {{- end }} +data: +{{ toYaml .Values.secret.data | indent 2 }} +{{- end}} diff --git a/helm/nexus-repository-manager/templates/service.yaml b/helm/nexus-repository-manager/templates/service.yaml new file mode 100644 index 0000000..d3d202c --- /dev/null +++ b/helm/nexus-repository-manager/templates/service.yaml @@ -0,0 +1,69 @@ +{{- if .Values.service.enabled -}} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "nexus.fullname" . }} +{{- if .Values.service.annotations }} + annotations: +{{ toYaml .Values.service.annotations | indent 4 }} +{{- end }} + labels: + {{- include "nexus.labels" . | nindent 4 }} + {{- if .Values.nexus.extraLabels }} + {{- with .Values.nexus.extraLabels }} + {{ toYaml . | indent 4 }} + {{- end }} + {{- end }} +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.nexus.nexusPort }} + protocol: TCP + name: nexus-ui + {{- if eq .Values.service.type "NodePort" }} + nodePort: {{ .Values.service.nodePort }} + {{- end }} + selector: + {{- include "nexus.selectorLabels" . | nindent 4 }} + {{- if .Values.nexus.extraSelectorLabels }} + {{- with .Values.nexus.extraSelectorLabels }} + {{ toYaml . | indent 4 }} + {{- end }} + {{- end }} + +{{- if .Values.nexus.docker.enabled }} +{{- range $registry := .Values.nexus.docker.registries }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "nexus.fullname" $ | trunc 49 }}-docker-{{ $registry.port }} +{{- if $.Values.service.annotations }} + annotations: +{{ toYaml $.Values.service.annotations | indent 4 }} +{{- end }} + labels: + {{- include "nexus.labels" $ | nindent 4 }} + {{- if $.Values.nexus.extraLabels }} + {{- with $.Values.nexus.extraLabels }} + {{ toYaml . | indent 4 }} + {{- end }} + {{- end }} +spec: + type: {{ $.Values.service.type }} + ports: + - port: {{ $registry.port }} + protocol: TCP + name: docker-{{ $registry.port }} + selector: + {{- include "nexus.selectorLabels" $ | nindent 4 }} + {{- if $.Values.nexus.extraSelectorLabels }} + {{- with $.Values.nexus.extraSelectorLabels }} + {{ toYaml . | indent 4 }} + {{- end }} + {{- end }} +{{- end }} + +{{- end }} +{{- end }} diff --git a/helm/nexus-repository-manager/templates/serviceaccount.yaml b/helm/nexus-repository-manager/templates/serviceaccount.yaml new file mode 100644 index 0000000..5bb8fa5 --- /dev/null +++ b/helm/nexus-repository-manager/templates/serviceaccount.yaml @@ -0,0 +1,15 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "nexus.serviceAccountName" . }} + labels: {{- include "nexus.labels" . | nindent 4 }} + {{- if .Values.nexus.extraLabels }} + {{- with .Values.nexus.extraLabels }} + {{ toYaml . | indent 4 }} + {{- end }} + {{- end }} + {{- with .Values.serviceAccount.annotations }} + annotations: {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/helm/nexus-repository-manager/values.yaml b/helm/nexus-repository-manager/values.yaml new file mode 100644 index 0000000..09a7e44 --- /dev/null +++ b/helm/nexus-repository-manager/values.yaml @@ -0,0 +1,184 @@ +--- +statefulset: + # This is not supported + enabled: false +deploymentStrategy: Recreate +image: + # Sonatype Official Public Image + repository: sonatype/nexus3 + tag: 3.52.0 + pullPolicy: IfNotPresent +imagePullSecrets: +# for image registries that require login, specify the name of the existing +# kubernetes secret +# - name: + +nexus: + docker: + enabled: false + # registries: + # - host: chart.local + # port: 5000 + # secretName: registry-secret + env: + # minimum recommended memory settings for a small, person instance from + # https://help.sonatype.com/repomanager3/product-information/system-requirements + - name: INSTALL4J_ADD_VM_PARAMS + value: |- + -Xms2703M -Xmx2703M + -XX:MaxDirectMemorySize=2703M + -XX:+UnlockExperimentalVMOptions + -XX:+UseCGroupMemoryLimitForHeap + -Djava.util.prefs.userRoot=/nexus-data/javaprefs + - name: NEXUS_SECURITY_RANDOMPASSWORD + value: "true" + properties: + override: false + data: + nexus.scripts.allowCreation: true + # See this article for ldap configuratioon options https://support.sonatype.com/hc/en-us/articles/216597138-Setting-Advanced-LDAP-Connection-Properties-in-Nexus-Repository-Manager + # nexus.ldap.env.java.naming.security.authentication: simple + # nodeSelector: + # cloud.google.com/gke-nodepool: default-pool + resources: + # minimum recommended memory settings for a small, person instance from + # https://help.sonatype.com/repomanager3/product-information/system-requirements + # requests: + # cpu: 4 + # memory: 8Gi + # limits: + # cpu: 4 + # memory: 8Gi + + # The ports should only be changed if the nexus image uses a different port + nexusPort: 8081 + + # Default the pods UID and GID to match the nexus3 container. + # Customize or remove these values from the securityContext as appropriate for + # your deployment environment. + securityContext: + runAsUser: 200 + runAsGroup: 200 + fsGroup: 200 + podAnnotations: {} + livenessProbe: + initialDelaySeconds: 30 + periodSeconds: 30 + failureThreshold: 6 + timeoutSeconds: 10 + path: / + readinessProbe: + initialDelaySeconds: 30 + periodSeconds: 30 + failureThreshold: 6 + timeoutSeconds: 10 + path: / + # hostAliases allows the modification of the hosts file inside a container + hostAliases: [] + # - ip: "192.168.1.10" + # hostnames: + # - "example.com" + # - "www.example.com" + +nameOverride: "" +fullnameOverride: "" + +deployment: + # # Add annotations in deployment to enhance deployment configurations + annotations: {} + # # Add init containers. e.g. to be used to give specific permissions for nexus-data. + # # Add your own init container or uncomment and modify the given example. + initContainers: + # - name: fmp-volume-permission + # image: busybox + # imagePullPolicy: IfNotPresent + # command: ['chown','-R', '200', '/nexus-data'] + # volumeMounts: + # - name: nexus-data + # mountPath: /nexus-data + # Uncomment and modify this to run a command after starting the nexus container. + postStart: + command: # '["/bin/sh", "-c", "ls"]' + preStart: + command: # '["/bin/rm", "-f", "/path/to/lockfile"]' + terminationGracePeriodSeconds: 120 + additionalContainers: + additionalVolumes: + additionalVolumeMounts: + +ingress: + enabled: false + ingressClassName: nginx + annotations: + nginx.ingress.kubernetes.io/proxy-body-size: "0" + hostPath: / + hostRepo: repo.demo + # tls: + # - secretName: nexus-local-tls + # hosts: + # - repo.demo + + +service: + name: nexus3 + enabled: true + labels: {} + annotations: {} + type: ClusterIP + + +route: + enabled: false + name: docker + portName: docker + labels: + annotations: + # path: /docker + +nexusProxyRoute: + enabled: false + labels: + annotations: + # path: /nexus + +persistence: + enabled: true + accessMode: ReadWriteOnce + ## If defined, storageClass: + ## If set to "-", storageClass: "", which disables dynamic provisioning + ## If undefined (the default) or set to null, no storageClass spec is + ## set, choosing the default provisioner. (gp2 on AWS, standard on + ## GKE, AWS & OpenStack) + ## + # existingClaim: + # annotations: + # "helm.sh/resource-policy": keep + # storageClass: "-" + storageSize: 8Gi + # If PersistentDisk already exists you can create a PV for it by including the 2 following keypairs. + # pdName: nexus-data-disk + # fsType: ext4 + +tolerations: [] + +# Enable configmap and add data in configmap +config: + enabled: false + mountPath: /sonatype-nexus-conf + data: [] + +# # To use an additional secret, set enable to true and add data +secret: + enabled: false + mountPath: /etc/secret-volume + readOnly: true + data: [] + +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: "" diff --git a/helm/nfs-provisioner-nas/Chart.yaml b/helm/nfs-provisioner-nas/Chart.yaml new file mode 100644 index 0000000..1c6528a --- /dev/null +++ b/helm/nfs-provisioner-nas/Chart.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +appVersion: 4.0.2 +description: nfs-subdir-external-provisioner is an automatic provisioner that used your *already configured* NFS server, automatically creating Persistent Volumes. +home: https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner +keywords: +- nfs +- storage +- provisioner +kubeVersion: '>=1.9.0-0' +name: nfs-subdir-external-provisioner +sources: +- https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner +version: 4.0.17 diff --git a/helm/nfs-provisioner-nas/README.md b/helm/nfs-provisioner-nas/README.md new file mode 100644 index 0000000..9e58ffb --- /dev/null +++ b/helm/nfs-provisioner-nas/README.md @@ -0,0 +1,99 @@ +# NFS Subdirectory External Provisioner Helm Chart + +The [NFS subdir external provisioner](https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner) is an automatic provisioner for Kubernetes that uses your *already configured* NFS server, automatically creating Persistent Volumes. + +## TL;DR; + +```console +$ helm repo add nfs-subdir-external-provisioner https://kubernetes-sigs.github.io/nfs-subdir-external-provisioner/ +$ helm install nfs-subdir-external-provisioner nfs-subdir-external-provisioner/nfs-subdir-external-provisioner \ + --set nfs.server=x.x.x.x \ + --set nfs.path=/exported/path +``` + +## Introduction + +This charts installs custom [storage class](https://kubernetes.io/docs/concepts/storage/storage-classes/) into a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. It also installs a [NFS client provisioner](https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner) into the cluster which dynamically creates persistent volumes from single NFS share. + +## Prerequisites + +- Kubernetes >=1.9 +- Existing NFS Share + +## Installing the Chart + +To install the chart with the release name `my-release`: + +```console +$ helm install my-release nfs-subdir-external-provisioner/nfs-subdir-external-provisioner \ + --set nfs.server=x.x.x.x \ + --set nfs.path=/exported/path +``` + +The command deploys the given storage class in the default configuration. It can be used afterwards to provision persistent volumes. The [configuration](#configuration) section lists the parameters that can be configured during installation. + +> **Tip**: List all releases using `helm list` + +## Uninstalling the Chart + +To uninstall/delete the `my-release` deployment: + +```console +$ helm delete my-release +``` + +The command removes all the Kubernetes components associated with the chart and deletes the release. + +## Configuration + +The following tables lists the configurable parameters of this chart and their default values. + +| Parameter | Description | Default | +| ----------------------------------- | ----------------------------------------------------------------------------------------------------- | -------------------------------------------------------- | +| `replicaCount` | Number of provisioner instances to deployed | `1` | +| `strategyType` | Specifies the strategy used to replace old Pods by new ones | `Recreate` | +| `image.repository` | Provisioner image | `k8s.gcr.io/sig-storage/nfs-subdir-external-provisioner` | +| `image.tag` | Version of provisioner image | `v4.0.2` | +| `image.pullPolicy` | Image pull policy | `IfNotPresent` | +| `imagePullSecrets` | Image pull secrets | `[]` | +| `storageClass.name` | Name of the storageClass | `nfs-client` | +| `storageClass.defaultClass` | Set as the default StorageClass | `false` | +| `storageClass.allowVolumeExpansion` | Allow expanding the volume | `true` | +| `storageClass.reclaimPolicy` | Method used to reclaim an obsoleted volume | `Delete` | +| `storageClass.provisionerName` | Name of the provisionerName | null | +| `storageClass.archiveOnDelete` | Archive PVC when deleting | `true` | +| `storageClass.onDelete` | Strategy on PVC deletion. Overrides archiveOnDelete when set to lowercase values 'delete' or 'retain' | null | +| `storageClass.pathPattern` | Specifies a template for the directory name | null | +| `storageClass.accessModes` | Set access mode for PV | `ReadWriteOnce` | +| `storageClass.volumeBindingMode` | Set volume binding mode for Storage Class | `Immediate` | +| `storageClass.annotations` | Set additional annotations for the StorageClass | `{}` | +| `leaderElection.enabled` | Enables or disables leader election | `true` | +| `nfs.server` | Hostname of the NFS server (required) | null (ip or hostname) | +| `nfs.path` | Basepath of the mount point to be used | `/nfs-storage` | +| `nfs.mountOptions` | Mount options (e.g. 'nfsvers=3') | null | +| `nfs.volumeName` | Volume name used inside the pods | `nfs-subdir-external-provisioner-root` | +| `nfs.reclaimPolicy` | Reclaim policy for the main nfs volume used for subdir provisioning | `Retain` | +| `resources` | Resources required (e.g. CPU, memory) | `{}` | +| `rbac.create` | Use Role-based Access Control | `true` | +| `podSecurityPolicy.enabled` | Create & use Pod Security Policy resources | `false` | +| `podAnnotations` | Additional annotations for the Pods | `{}` | +| `priorityClassName` | Set pod priorityClassName | null | +| `serviceAccount.create` | Should we create a ServiceAccount | `true` | +| `serviceAccount.name` | Name of the ServiceAccount to use | null | +| `serviceAccount.annotations` | Additional annotations for the ServiceAccount | `{}` | +| `nodeSelector` | Node labels for pod assignment | `{}` | +| `affinity` | Affinity settings | `{}` | +| `tolerations` | List of node taints to tolerate | `[]` | +| `labels` | Additional labels for any resource created | `{}` | + +## Install Multiple Provisioners + +It is possible to install more than one provisioner in your cluster to have access to multiple nfs servers and/or multiple exports from a single nfs server. Each provisioner must have a different `storageClass.provisionerName` and a different `storageClass.name`. For example: + +```console +helm install second-nfs-subdir-external-provisioner nfs-subdir-external-provisioner/nfs-subdir-external-provisioner \ + --set nfs.server=y.y.y.y \ + --set nfs.path=/other/exported/path \ + --set storageClass.name=second-nfs-client \ + --set storageClass.provisionerName=k8s-sigs.io/second-nfs-subdir-external-provisioner +``` diff --git a/helm/nfs-provisioner-nas/ci/test-values.yaml b/helm/nfs-provisioner-nas/ci/test-values.yaml new file mode 100644 index 0000000..4237de5 --- /dev/null +++ b/helm/nfs-provisioner-nas/ci/test-values.yaml @@ -0,0 +1,5 @@ +nfs: + server: 127.0.0.1 +podSecurityPolicy: + enabled: true +buildMode: true diff --git a/helm/nfs-provisioner-nas/override-values.yaml b/helm/nfs-provisioner-nas/override-values.yaml new file mode 100644 index 0000000..4c4556e --- /dev/null +++ b/helm/nfs-provisioner-nas/override-values.yaml @@ -0,0 +1,17 @@ +nfs: + server: 10.10.43.42 + path: /volume1/data + mountOptions: + - nfsvers=4.1 + - rsize=1048576 + - wsize=1048576 + - hard + - timeo=600 + - retrans=2 + - noresvport + +storageClass: + name: nfs-provisioner-mgmt-nas + accessModes: ReadWriteMany + pathPattern: "${.PVC.name}" + reclaimPolicy: Retain \ No newline at end of file diff --git a/helm/nfs-provisioner-nas/templates/_helpers.tpl b/helm/nfs-provisioner-nas/templates/_helpers.tpl new file mode 100644 index 0000000..c6c4f79 --- /dev/null +++ b/helm/nfs-provisioner-nas/templates/_helpers.tpl @@ -0,0 +1,92 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "nfs-subdir-external-provisioner.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 "nfs-subdir-external-provisioner.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 "nfs-subdir-external-provisioner.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{- define "nfs-subdir-external-provisioner.provisionerName" -}} +{{- if .Values.storageClass.provisionerName -}} +{{- printf .Values.storageClass.provisionerName -}} +{{- else -}} +cluster.local/{{ template "nfs-subdir-external-provisioner.fullname" . -}} +{{- end -}} +{{- end -}} + +{{/* +Create the name of the service account to use +*/}} +{{- define "nfs-subdir-external-provisioner.serviceAccountName" -}} +{{- if .Values.serviceAccount.create -}} + {{ default (include "nfs-subdir-external-provisioner.fullname" .) .Values.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for podSecurityPolicy. +*/}} +{{- define "podSecurityPolicy.apiVersion" -}} +{{- if semverCompare ">=1.10-0" .Capabilities.KubeVersion.GitVersion -}} +{{- print "policy/v1beta1" -}} +{{- else -}} +{{- print "extensions/v1beta1" -}} +{{- end -}} +{{- end -}} + +{{/* +Common labels +*/}} +{{- define "nfs-subdir-external-provisioner.labels" -}} +chart: {{ template "nfs-subdir-external-provisioner.chart" . }} +heritage: {{ .Release.Service }} +{{ include "nfs-subdir-external-provisioner.selectorLabels" . }} +{{- with .Values.labels }} +{{- toYaml . | nindent 0 }} +{{- end }} +{{- end }} + +{{/* +Pod template labels +*/}} +{{- define "nfs-subdir-external-provisioner.podLabels" -}} +{{ include "nfs-subdir-external-provisioner.selectorLabels" . }} +{{- with .Values.labels }} +{{- toYaml . | nindent 0 }} +{{- end }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "nfs-subdir-external-provisioner.selectorLabels" -}} +app: {{ template "nfs-subdir-external-provisioner.name" . }} +release: {{ .Release.Name }} +{{- end }} diff --git a/helm/nfs-provisioner-nas/templates/clusterrole.yaml b/helm/nfs-provisioner-nas/templates/clusterrole.yaml new file mode 100644 index 0000000..078cfcc --- /dev/null +++ b/helm/nfs-provisioner-nas/templates/clusterrole.yaml @@ -0,0 +1,30 @@ +{{- if .Values.rbac.create }} +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + labels: + {{- include "nfs-subdir-external-provisioner.labels" . | nindent 4 }} + name: {{ template "nfs-subdir-external-provisioner.fullname" . }}-runner +rules: + - apiGroups: [""] + resources: ["nodes"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["persistentvolumes"] + verbs: ["get", "list", "watch", "create", "delete"] + - apiGroups: [""] + resources: ["persistentvolumeclaims"] + verbs: ["get", "list", "watch", "update"] + - apiGroups: ["storage.k8s.io"] + resources: ["storageclasses"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["events"] + verbs: ["create", "update", "patch"] +{{- if .Values.podSecurityPolicy.enabled }} + - apiGroups: ['extensions'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: [{{ template "nfs-subdir-external-provisioner.fullname" . }}] +{{- end }} +{{- end }} diff --git a/helm/nfs-provisioner-nas/templates/clusterrolebinding.yaml b/helm/nfs-provisioner-nas/templates/clusterrolebinding.yaml new file mode 100644 index 0000000..c5e5582 --- /dev/null +++ b/helm/nfs-provisioner-nas/templates/clusterrolebinding.yaml @@ -0,0 +1,16 @@ +{{- if .Values.rbac.create }} +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + labels: + {{- include "nfs-subdir-external-provisioner.labels" . | nindent 4 }} + name: run-{{ template "nfs-subdir-external-provisioner.fullname" . }} +subjects: + - kind: ServiceAccount + name: {{ template "nfs-subdir-external-provisioner.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: {{ template "nfs-subdir-external-provisioner.fullname" . }}-runner + apiGroup: rbac.authorization.k8s.io +{{- end }} diff --git a/helm/nfs-provisioner-nas/templates/deployment.yaml b/helm/nfs-provisioner-nas/templates/deployment.yaml new file mode 100644 index 0000000..15a574b --- /dev/null +++ b/helm/nfs-provisioner-nas/templates/deployment.yaml @@ -0,0 +1,83 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "nfs-subdir-external-provisioner.fullname" . }} + labels: + {{- include "nfs-subdir-external-provisioner.labels" . | nindent 4 }} +spec: + replicas: {{ .Values.replicaCount }} + strategy: + type: {{ .Values.strategyType }} + selector: + matchLabels: + {{- include "nfs-subdir-external-provisioner.selectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + {{- with .Values.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if and (.Values.tolerations) (semverCompare "<1.6-0" .Capabilities.KubeVersion.GitVersion) }} + scheduler.alpha.kubernetes.io/tolerations: '{{ toJson .Values.tolerations }}' + {{- end }} + labels: + {{- include "nfs-subdir-external-provisioner.podLabels" . | nindent 8 }} + spec: + serviceAccountName: {{ template "nfs-subdir-external-provisioner.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + {{- if .Values.nodeSelector }} + nodeSelector: +{{ toYaml .Values.nodeSelector | indent 8 }} + {{- end }} + {{- if .Values.affinity }} + affinity: +{{ toYaml .Values.affinity | indent 8 }} + {{- end }} + {{- if .Values.priorityClassName }} + priorityClassName: {{ .Values.priorityClassName | quote }} + {{- end }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + containers: + - name: {{ .Chart.Name }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + volumeMounts: + - name: {{ .Values.nfs.volumeName }} + mountPath: /persistentvolumes + env: + - name: PROVISIONER_NAME + value: {{ template "nfs-subdir-external-provisioner.provisionerName" . }} + - name: NFS_SERVER + value: {{ .Values.nfs.server }} + - name: NFS_PATH + value: {{ .Values.nfs.path }} + {{- if eq .Values.leaderElection.enabled false }} + - name: ENABLE_LEADER_ELECTION + value: "false" + {{- end }} + {{- with .Values.resources }} + resources: +{{ toYaml . | indent 12 }} + {{- end }} + volumes: + - name: {{ .Values.nfs.volumeName }} +{{- if .Values.buildMode }} + emptyDir: {} +{{- else if .Values.nfs.mountOptions }} + persistentVolumeClaim: + claimName: pvc-{{ template "nfs-subdir-external-provisioner.fullname" . }} +{{- else }} + nfs: + server: {{ .Values.nfs.server }} + path: {{ .Values.nfs.path }} +{{- end }} + {{- if and (.Values.tolerations) (semverCompare "^1.6-0" .Capabilities.KubeVersion.GitVersion) }} + tolerations: +{{ toYaml .Values.tolerations | indent 6 }} + {{- end }} diff --git a/helm/nfs-provisioner-nas/templates/persistentvolume.yaml b/helm/nfs-provisioner-nas/templates/persistentvolume.yaml new file mode 100644 index 0000000..9d6ba4d --- /dev/null +++ b/helm/nfs-provisioner-nas/templates/persistentvolume.yaml @@ -0,0 +1,26 @@ +{{ if .Values.nfs.mountOptions -}} +apiVersion: v1 +kind: PersistentVolume +metadata: + name: pv-{{ template "nfs-subdir-external-provisioner.fullname" . }} + labels: + {{- include "nfs-subdir-external-provisioner.labels" . | nindent 4 }} + nfs-subdir-external-provisioner: {{ template "nfs-subdir-external-provisioner.fullname" . }} +spec: + capacity: + storage: 10Mi + volumeMode: Filesystem + accessModes: + - {{ .Values.storageClass.accessModes }} + persistentVolumeReclaimPolicy: {{ .Values.nfs.reclaimPolicy }} + storageClassName: "" + {{- if .Values.nfs.mountOptions }} + mountOptions: + {{- range .Values.nfs.mountOptions }} + - {{ . }} + {{- end }} + {{- end }} + nfs: + server: {{ .Values.nfs.server }} + path: {{ .Values.nfs.path }} +{{ end -}} diff --git a/helm/nfs-provisioner-nas/templates/persistentvolumeclaim.yaml b/helm/nfs-provisioner-nas/templates/persistentvolumeclaim.yaml new file mode 100644 index 0000000..993dc53 --- /dev/null +++ b/helm/nfs-provisioner-nas/templates/persistentvolumeclaim.yaml @@ -0,0 +1,19 @@ +{{ if .Values.nfs.mountOptions -}} +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: + name: pvc-{{ template "nfs-subdir-external-provisioner.fullname" . }} + labels: + {{- include "nfs-subdir-external-provisioner.labels" . | nindent 4 }} +spec: + accessModes: + - {{ .Values.storageClass.accessModes }} + volumeMode: Filesystem + storageClassName: "" + selector: + matchLabels: + nfs-subdir-external-provisioner: {{ template "nfs-subdir-external-provisioner.fullname" . }} + resources: + requests: + storage: 10Mi +{{ end -}} diff --git a/helm/nfs-provisioner-nas/templates/podsecuritypolicy.yaml b/helm/nfs-provisioner-nas/templates/podsecuritypolicy.yaml new file mode 100644 index 0000000..5e3274a --- /dev/null +++ b/helm/nfs-provisioner-nas/templates/podsecuritypolicy.yaml @@ -0,0 +1,29 @@ +{{- if .Values.podSecurityPolicy.enabled }} +apiVersion: {{ template "podSecurityPolicy.apiVersion" . }} +kind: PodSecurityPolicy +metadata: + name: {{ template "nfs-subdir-external-provisioner.fullname" . }} + labels: + {{- include "nfs-subdir-external-provisioner.labels" . | nindent 4 }} +spec: + privileged: false + allowPrivilegeEscalation: false + requiredDropCapabilities: + - ALL + volumes: + - 'secret' + - 'nfs' + - 'persistentVolumeClaim' + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'RunAsAny' + fsGroup: + rule: 'RunAsAny' + readOnlyRootFilesystem: false +{{- end }} diff --git a/helm/nfs-provisioner-nas/templates/role.yaml b/helm/nfs-provisioner-nas/templates/role.yaml new file mode 100644 index 0000000..9d17581 --- /dev/null +++ b/helm/nfs-provisioner-nas/templates/role.yaml @@ -0,0 +1,18 @@ +{{- if .Values.rbac.create }} +kind: Role +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + labels: + {{- include "nfs-subdir-external-provisioner.labels" . | nindent 4 }} + name: leader-locking-{{ template "nfs-subdir-external-provisioner.fullname" . }} +rules: + - apiGroups: [""] + resources: ["endpoints"] + verbs: ["get", "list", "watch", "create", "update", "patch"] +{{- if .Values.podSecurityPolicy.enabled }} + - apiGroups: ['extensions'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: [{{ template "nfs-subdir-external-provisioner.fullname" . }}] +{{- end }} +{{- end }} diff --git a/helm/nfs-provisioner-nas/templates/rolebinding.yaml b/helm/nfs-provisioner-nas/templates/rolebinding.yaml new file mode 100644 index 0000000..6bba960 --- /dev/null +++ b/helm/nfs-provisioner-nas/templates/rolebinding.yaml @@ -0,0 +1,16 @@ +{{- if .Values.rbac.create }} +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + labels: + {{- include "nfs-subdir-external-provisioner.labels" . | nindent 4 }} + name: leader-locking-{{ template "nfs-subdir-external-provisioner.fullname" . }} +subjects: + - kind: ServiceAccount + name: {{ template "nfs-subdir-external-provisioner.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: Role + name: leader-locking-{{ template "nfs-subdir-external-provisioner.fullname" . }} + apiGroup: rbac.authorization.k8s.io +{{- end }} diff --git a/helm/nfs-provisioner-nas/templates/serviceaccount.yaml b/helm/nfs-provisioner-nas/templates/serviceaccount.yaml new file mode 100644 index 0000000..a68ff9e --- /dev/null +++ b/helm/nfs-provisioner-nas/templates/serviceaccount.yaml @@ -0,0 +1,12 @@ +{{ if .Values.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + {{- include "nfs-subdir-external-provisioner.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ template "nfs-subdir-external-provisioner.serviceAccountName" . }} +{{- end -}} diff --git a/helm/nfs-provisioner-nas/templates/storageclass.yaml b/helm/nfs-provisioner-nas/templates/storageclass.yaml new file mode 100644 index 0000000..fc360ce --- /dev/null +++ b/helm/nfs-provisioner-nas/templates/storageclass.yaml @@ -0,0 +1,33 @@ +{{ if .Values.storageClass.create -}} +apiVersion: storage.k8s.io/v1 +kind: StorageClass +metadata: + labels: + {{- include "nfs-subdir-external-provisioner.labels" . | nindent 4 }} + name: {{ .Values.storageClass.name }} + annotations: + {{- if .Values.storageClass.defaultClass }} + storageclass.kubernetes.io/is-default-class: "true" + {{- end }} + {{- with .Values.storageClass.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} +provisioner: {{ template "nfs-subdir-external-provisioner.provisionerName" . }} +allowVolumeExpansion: {{ .Values.storageClass.allowVolumeExpansion }} +reclaimPolicy: {{ .Values.storageClass.reclaimPolicy }} +volumeBindingMode: {{ .Values.storageClass.volumeBindingMode }} +parameters: + archiveOnDelete: "{{ .Values.storageClass.archiveOnDelete }}" + {{- if .Values.storageClass.pathPattern }} + pathPattern: "{{ .Values.storageClass.pathPattern }}" + {{- end }} + {{- if .Values.storageClass.onDelete }} + onDelete: "{{ .Values.storageClass.onDelete }}" + {{- end }} +{{- if .Values.nfs.mountOptions }} +mountOptions: + {{- range .Values.nfs.mountOptions }} + - {{ . }} + {{- end }} +{{- end }} +{{ end -}} diff --git a/helm/nfs-provisioner-nas/test/configmap.yaml b/helm/nfs-provisioner-nas/test/configmap.yaml new file mode 100644 index 0000000..5864097 --- /dev/null +++ b/helm/nfs-provisioner-nas/test/configmap.yaml @@ -0,0 +1,52 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: dsk-vault-agent-config +data: + server.tmpl: | + {{ with secret "tls/data/server" }}{{ toJSON .Data.data }} + {{ end }} + + client.tmpl: | + {{ with secret "tls/data/client" }}{{ toJSON .Data.data }} + {{ end }} + + agent.hcl: | + pid_file = "./pidfile" + + vault { + address="http://vault-ui.dsk-middle:8200" + } + + auto_auth { + method { + type = "approle" + config = { + role_id_file_path = "/vault-agent/role-id" + secret_id_file_path = "/vault-agent/secret-id" + remove_secret_id_file_after_reading = false + } + } + + sink { + type = "file" + config = { + path = "/vault-agent/.vault-token" + mode = 0644 + } + } + } + + template_config { + static_secret_render_interval = "10s" + } + + template { + source = "/vault-agent/conf/server.tmpl" + destination = "/vault-agent/serverTls" + } + + template { + source = "/vault-agent/conf/client.tmpl" + destination = "/vault-agent/clientTls" + } diff --git a/helm/nfs-provisioner-nas/test/deployment.yaml b/helm/nfs-provisioner-nas/test/deployment.yaml new file mode 100644 index 0000000..650af00 --- /dev/null +++ b/helm/nfs-provisioner-nas/test/deployment.yaml @@ -0,0 +1,42 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: dsk-vault-agent + labels: + app: dsk-vault-agent +spec: + replicas: 1 + selector: + matchLabels: + app: dsk-vault-agent + template: + metadata: + labels: + app: dsk-vault-agent + spec: + containers: + - name: vault-agent + image: vault + volumeMounts: + - name: vault-volume + mountPath: /vault-agent + - name: config + mountPath: /vault-agent/conf + command: [ "vault" ] + args: [ "agent", "-config=/vault-agent/conf/agent.hcl" ] + volumes: + - name: vault-volume + persistentVolumeClaim: + claimName: dsk-vault-test + - name: config + configMap: + name: dsk-vault-agent-config + items: + - key: agent.hcl + path: agent.hcl + - key: server.tmpl + path: server.tmpl + - key: client.tmpl + path: client.tmpl + + diff --git a/helm/nfs-provisioner-nas/test/pvc.yaml b/helm/nfs-provisioner-nas/test/pvc.yaml new file mode 100644 index 0000000..612ed9a --- /dev/null +++ b/helm/nfs-provisioner-nas/test/pvc.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: dsk-vault-test +spec: + storageClassName: nfs-client-test + accessModes: + - ReadWriteMany + resources: + requests: + storage: 1Gi diff --git a/helm/nfs-provisioner-nas/values.yaml b/helm/nfs-provisioner-nas/values.yaml new file mode 100644 index 0000000..f626023 --- /dev/null +++ b/helm/nfs-provisioner-nas/values.yaml @@ -0,0 +1,110 @@ +replicaCount: 1 +strategyType: Recreate + +image: + repository: k8s.gcr.io/sig-storage/nfs-subdir-external-provisioner + tag: v4.0.2 + pullPolicy: IfNotPresent +imagePullSecrets: [] + +nfs: + server: + path: /nfs-storage + mountOptions: + volumeName: nfs-subdir-external-provisioner-root + # Reclaim policy for the main nfs volume + reclaimPolicy: Retain + +# For creating the StorageClass automatically: +storageClass: + create: true + + # Set a provisioner name. If unset, a name will be generated. + # provisionerName: + + # Set StorageClass as the default StorageClass + # Ignored if storageClass.create is false + defaultClass: false + + # Set a StorageClass name + # Ignored if storageClass.create is false + name: nfs-client + + # Allow volume to be expanded dynamically + allowVolumeExpansion: true + + # Method used to reclaim an obsoleted volume + reclaimPolicy: Delete + + # When set to false your PVs will not be archived by the provisioner upon deletion of the PVC. + archiveOnDelete: true + + # If it exists and has 'delete' value, delete the directory. If it exists and has 'retain' value, save the directory. + # Overrides archiveOnDelete. + # Ignored if value not set. + onDelete: + + # Specifies a template for creating a directory path via PVC metadata's such as labels, annotations, name or namespace. + # Ignored if value not set. + pathPattern: + + # Set access mode - ReadWriteOnce, ReadOnlyMany or ReadWriteMany + accessModes: ReadWriteOnce + + # Set volume bindinng mode - Immediate or WaitForFirstConsumer + volumeBindingMode: Immediate + + # Storage class annotations + annotations: {} + +leaderElection: + # When set to false leader election will be disabled + enabled: true + +## For RBAC support: +rbac: + # Specifies whether RBAC resources should be created + create: true + +# If true, create & use Pod Security Policy resources +# https://kubernetes.io/docs/concepts/policy/pod-security-policy/ +podSecurityPolicy: + enabled: false + +# Deployment pod annotations +podAnnotations: {} + +## Set pod priorityClassName +# priorityClassName: "" + +podSecurityContext: {} + +securityContext: {} + +serviceAccount: + # Specifies whether a ServiceAccount should be created + create: true + + # Annotations to add to the service account + annotations: {} + + # The name of the ServiceAccount to use. + # If not set and create is true, a name is generated using the fullname template + name: + +resources: {} + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + +nodeSelector: {} + +tolerations: [] + +affinity: {} + +# Additional labels for any resource created +labels: {} diff --git a/helm/openebs/Chart.lock b/helm/openebs/Chart.lock new file mode 100644 index 0000000..1dbac25 --- /dev/null +++ b/helm/openebs/Chart.lock @@ -0,0 +1,27 @@ +dependencies: +- name: openebs-ndm + repository: https://openebs.github.io/node-disk-manager + version: 2.1.0 +- name: localpv-provisioner + repository: https://openebs.github.io/dynamic-localpv-provisioner + version: 3.4.1 +- name: cstor + repository: https://openebs.github.io/cstor-operators + version: 3.5.0 +- name: jiva + repository: https://openebs.github.io/jiva-operator + version: 3.5.1 +- name: zfs-localpv + repository: https://openebs.github.io/zfs-localpv + version: 2.3.1 +- name: lvm-localpv + repository: https://openebs.github.io/lvm-localpv + version: 1.3.0 +- name: nfs-provisioner + repository: https://openebs.github.io/dynamic-nfs-provisioner + version: 0.10.0 +- name: mayastor + repository: https://openebs.github.io/mayastor-extensions + version: 2.4.0 +digest: sha256:189f7edfd9afecb40e757800569aa71a053d986fb9520aec22d08e134a7f6038 +generated: "2023-09-06T06:22:45.720572899Z" diff --git a/helm/openebs/Chart.yaml b/helm/openebs/Chart.yaml new file mode 100644 index 0000000..bedaa0b --- /dev/null +++ b/helm/openebs/Chart.yaml @@ -0,0 +1,57 @@ +apiVersion: v2 +appVersion: 3.9.0 +dependencies: +- condition: openebs-ndm.enabled + name: openebs-ndm + repository: https://openebs.github.io/node-disk-manager + version: 2.1.0 +- condition: localpv-provisioner.enabled + name: localpv-provisioner + repository: https://openebs.github.io/dynamic-localpv-provisioner + version: 3.4.1 +- condition: cstor.enabled + name: cstor + repository: https://openebs.github.io/cstor-operators + version: 3.5.0 +- condition: jiva.enabled + name: jiva + repository: https://openebs.github.io/jiva-operator + version: 3.5.1 +- condition: zfs-localpv.enabled + name: zfs-localpv + repository: https://openebs.github.io/zfs-localpv + version: 2.3.1 +- condition: lvm-localpv.enabled + name: lvm-localpv + repository: https://openebs.github.io/lvm-localpv + version: 1.3.0 +- condition: nfs-provisioner.enabled + name: nfs-provisioner + repository: https://openebs.github.io/dynamic-nfs-provisioner + version: 0.10.0 +- condition: mayastor.enabled + name: mayastor + repository: https://openebs.github.io/mayastor-extensions + version: 2.4.0 +description: Containerized Attached Storage for Kubernetes +home: http://www.openebs.io/ +icon: https://raw.githubusercontent.com/cncf/artwork/HEAD/projects/openebs/icon/color/openebs-icon-color.png +keywords: +- cloud-native-storage +- block-storage +- local-storage +- iSCSI +- NVMe +- storage +- kubernetes +maintainers: +- email: kiran.mova@mayadata.io + name: kmova +- email: prateek.pandey@mayadata.io + name: prateekpandey14 +- email: shovan.maity@mayadata.io + name: shovanmaity +name: openebs +sources: +- https://github.com/openebs/openebs +version: 3.9.0 diff --git a/helm/openebs/OWNERS b/helm/openebs/OWNERS new file mode 100644 index 0000000..874423e --- /dev/null +++ b/helm/openebs/OWNERS @@ -0,0 +1,6 @@ +approvers: +- kmova +- prateekpandey14 +reviewers: +- kmova +- prateekpandey14 diff --git a/helm/openebs/README.md b/helm/openebs/README.md new file mode 100644 index 0000000..0d2ab1b --- /dev/null +++ b/helm/openebs/README.md @@ -0,0 +1,204 @@ +## :warning: Compatibility + +The OpenEBS helm chart now supports the installation of Mayastor. Please note the following before installing Mayastor: +1. Mayastor is incompatible with NDM (openebs-ndm) and cStor (cstor). Installing Mayastor alongside NDM and cStor may cause it to behave in unexpected ways. +2. A `helm install` with the `--set mayastor.enabled=true` option set will not deploy the LocalPV Provisioner and NDM. +3. A `helm upgrade` with the `--set mayastor.enabled=true` option set will remove the LocalPV Provisioner and NDM, if they are present. This does not affect any LocalPV volumes you have already provisioned, they will continue to work as expected. +4. Mayastor deployment scenarios involving other OpenEBS storage engines are not tested. It is recommended that you do not install Mayastor along with other storage engines. + +# OpenEBS Helm Chart + +[OpenEBS](https://openebs.io) helps Developers and Platform SREs easily deploy Kubernetes Stateful Workloads that require fast and highly reliable container attached storage. OpenEBS can be deployed on any Kubernetes cluster - either in cloud, on-premise (virtual or bare metal) or developer laptop (minikube). + +OpenEBS Data Engines and Control Plane are implemented as micro-services, deployed as containers and orchestrated by Kubernetes itself. An added advantage of being a completely Kubernetes native solution is that administrators and developers can interact and manage OpenEBS using all the wonderful tooling that is available for Kubernetes like kubectl, Helm, Prometheus, Grafana, etc. + +OpenEBS turns any storage available on the Kubernetes worker nodes into local or distributed Kubernetes Persistent Volumes. +* Local Volumes are accessible only from a single node in the cluster. Pods using Local Volume have to be scheduled on the node where volume is provisioned. Local Volumes are typically preferred for distributed workloads like Cassandra, MongoDB, Elastic, etc that are distributed in nature and have high availability built into them. Depending on the type of storage attached to your Kubernetes worker nodes, you can select from different flavors of Dynamic Local PV - Hostpath, Device, LVM, ZFS or Rawfile. +* Replicated Volumes as the name suggests, are those that have their data synchronously replicated to multiple nodes. Volumes can sustain node failures. The replication also can be setup across availability zones helping applications move across availability zones. Depending on the type of storage attached to your Kubernetes worker nodes and application performance requirements, you can select from Jiva, cStor or Mayastor. + +## Documentation and user guides + +You can run OpenEBS on any Kubernetes 1.21+ cluster in a matter of minutes. See the [Quickstart Guide to OpenEBS](https://openebs.io/) for detailed instructions. + +## Getting started + +### How to customize OpenEBS Helm chart? + +OpenEBS helm chart is an umbrella chart that pulls together engine specific charts. The engine charts are included as dependencies. +arts/openebs/Chart.yaml). +OpenEBS helm chart will includes common components that are used by multiple engines like: +- Node Disk Manager related components +- Dynamic Local Provisioner related components +- Security Policies like RBAC, PSP, Kyverno + +```bash +openebs +├── (default) openebs-ndm +├── (default) localpv-provisioner +├── mayastor +├── jiva +├── cstor +├── zfs-localpv +└── lvm-localpv +└── nfs-provisioner +``` + +To install the engine charts, the helm install must be provided with a engine enabled flag like `cstor.enabled=true` or `zfs-localpv.enabled=true` or by passing a custom values.yaml with required engines enabled. + +### Prerequisites + +- Kubernetes 1.18+ with RBAC enabled +- When using cstor and jiva engines, iSCSI utils must be installed on all the nodes where stateful pods are going to run. +- Depending on the engine and type of platform, you may have to customize the values or run additional pre-requisistes. Refer to [documentation](https://openebs.io). + +### Setup Helm Repository + +Before installing OpenEBS Helm charts, you need to add the [OpenEBS Helm repository](https://openebs.github.io/charts) to your Helm client. + +```bash +helm repo add openebs https://openebs.github.io/charts +helm repo update +``` + +### Installing OpenEBS + +```bash +helm install --name `my-release` --namespace openebs openebs/openebs --create-namespace +``` + +Examples: +- Assuming the release will be called openebs, the command would be: + ```bash + helm install --name openebs --namespace openebs openebs/openebs --create-namespace + ``` +- To install OpenEBS with mayastor CSI driver, run + ```bash + helm install openebs openebs/openebs --namespace openebs --create-namespace --set mayastor.enabled=true + ``` +> **Note:** : mayastor will be installed without the default openebs engines + +- To install OpenEBS with cStor CSI driver, run + ```bash + helm install openebs openebs/openebs --namespace openebs --create-namespace --set cstor.enabled=true + ``` + +- To install/enable a new engine on the installed helm release `openebs`, you can run the helm upgrade command as follows: + ```bash + helm upgrade openebs openebs/openebs --namespace openebs --reuse-values --set jiva.enabled=true + ``` + +- To disable legacy out of tree jiva and cstor provisioners, run the following command. + ```bash + helm upgrade openebs openebs/openebs --namespace openebs --reuse-values --set legacy.enabled=false + ``` + +### To uninstall/delete instance with release name + +```bash +helm ls --all +helm delete `my-release` +``` + +> **Tip**: Prior to deleting the helm chart, make sure all the storage volumes and pools are deleted. + +## Configuration + +The following table lists the common configurable parameters of the OpenEBS chart and their default values. For a full list of configurable parameters check out the [values.yaml](https://github.com/openebs/charts/blob/HEAD/charts/openebs/values.yaml). + +| Parameter | Description | Default | +| ------------------------------------------- | ---------------------------------------------------------------------------- | ------------------------------------------------------------------------ | +| `apiserver.enabled` | Enable API Server | `true` | +| `apiserver.image` | Image for API Server | `openebs/m-apiserver` | +| `apiserver.imageTag` | Image Tag for API Server | `2.12.2` | +| `cleanup.image.registry` | Cleanup pre hook image registry | `nil` | +| `cleanup.image.repository` | Cleanup pre hook image repository | `"bitnami/kubectl"` | +| `cleanup.image.tag` | Cleanup pre hook image tag | `if not provided determined by the k8s version` | +| `crd.enableInstall` | Enable installation of CRDs by OpenEBS | `true` | +| `cstor.pool.image` | Image for cStor Pool | `openebs/cstor-pool` | +| `cstor.pool.imageTag` | Image Tag for cStor Pool | `2.12.2` | +| `cstor.poolMgmt.image` | Image for cStor Pool Management | `openebs/cstor-pool-mgmt` | +| `cstor.poolMgmt.imageTag` | Image Tag for cStor Pool Management | `2.12.2` | +| `cstor.target.image` | Image for cStor Target | `openebs/cstor-istgt` | +| `cstor.target.imageTag` | Image Tag for cStor Target | `2.12.2` | +| `cstor.volumeMgmt.image` | Image for cStor Volume Management | `openebs/cstor-volume-mgmt` | +| `cstor.volumeMgmt.imageTag` | Image Tag for cStor Volume Management | `2.12.2` | +| `defaultStorageConfig.enabled` | Enable default storage class installation | `true` | +| `featureGates.enabled` | Enable feature gates | `true` | +| `featureGates.GPTBasedUUID.enabled` | Enable feature gate : GPTBasedUUID | `true` | +| `featureGates.APIService.enabled` | Enable feature gate : APIService | `false` | +| `featureGates.UseOSDisk.enabled` | Enable feature gate : UseOSDisk | `false` | +| `featureGates.ChangeDetection.enabled` | Enable feature gate : ChangeDetection | `false` | +| `healthCheck.initialDelaySeconds` | Delay before liveness probe is initiated | `30` | +| `healthCheck.periodSeconds` | How often to perform the liveness probe | `60` | +| `helper.image` | Image for helper | `openebs/linux-utils` | +| `helper.imageTag` | Image Tag for helper | `3.4.0` | +| `image.pullPolicy` | Container pull policy | `IfNotPresent` | +| `image.repository` | Specify which docker registry to use | `""` | +| `jiva.defaultStoragePath` | hostpath used by default Jiva StorageClass | `/var/openebs` | +| `jiva.image` | Image for Jiva | `openebs/jiva` | +| `jiva.imageTag` | Image Tag for Jiva | `2.12.2` | +| `jiva.replicas` | Number of Jiva Replicas | `3` | +| `localprovisioner.basePath` | BasePath for hostPath volumes on Nodes | `/var/openebs/local` | +| `localprovisioner.enabled` | Enable localProvisioner | `true` | +| `localprovisioner.image` | Image for localProvisioner | `openebs/provisioner-localpv` | +| `localprovisioner.imageTag` | Image Tag for localProvisioner | `3.4.0` | +| `mayastor.enabled` | Enable mayastor (disables localprovisioner and ndm) | `false` | +| `mayastor.etcd.replicaCount` | Set the number of etcd replicas in the | `3` | +| `mayastor.etcd.persistence.storageClass` | Set the StorageClass name used to provision the volume(s) for the etcd | `""` | +| `mayastor.etcd.persistence.size` | Set the size of the volume(s) used by the etcd | `""` | +| `mayastor.image.registry` | Set the container image registry for the mayastor containers | `"docker.io"` | +| `mayastor.image.repo` | Set the container image repository for the mayastor containers | `"openebs"` | +| `mayastor.image.tag` | Set the container image tag for the mayastor containers | `"v2.4.0"` | +| `mayastor.image.pullPolicy` | Set the container ImagePullPolicy for the mayastor containers | `"Always"` | +| `mayastor.csi.image.registry` | Set the container image registry for the Kubernetes CSI sidecar containers | `"registry.k8s.io"` | +| `mayastor.csi.image.repo` | Set the container image repository for the Kubernetes CSI sidecar containers | `"sig-storage"` | +| `mayastor.csi.image.pullPolicy` | Set the container ImagePullPolicy for the Kubernetes CSI sidecar containers | `"IfNotPresent"` | +| `mayastor.csi.node.kubeletDir` | Set kubelet directory for Kubernetes CSI plugin registration | `"/var/lib/kubelet"` | +| `mayastor.base.jaeger.enabled` | Enable Jaeger tracing for mayastor | `"false"` | +| `mayastor.jaeger-operator.jaeger.create` | Create Jaeger operator | `"false"` | +| `mayastor.jaeger-operator.crd.install` | Create Jaeger CustomResourceDefinition | `"false"` | +| `mayastor.jaeger-operator.rbac.clusterRole` | Create Jaeger Kubernetes RBAC ClusterRole | `"true"` | +| `mayastor.loki-stack.enabled` | Enable loki log collection for Mayastor components | `"true"` | +| `mayastor.loki-stack.promtail.enabled` | Enables promtail for scraping logs from nodes components | `"true"` | +| `ndm.enabled` | Enable Node Disk Manager | `true` | +| `ndm.filters.enableOsDiskExcludeFilter` | Enable filters of OS disk exclude | `true` | +| `ndm.filters.enablePathFilter` | Enable filters of paths | `true` | +| `ndm.filters.enableVendorFilter` | Enable filters of vendors | `true` | +| `ndm.filters.excludePaths` | Exclude devices with specified path patterns | `/dev/loop,/dev/fd0,/dev/sr0,/dev/ram,/dev/dm-,/dev/md,/dev/rbd,/dev/zd` | +| `ndm.filters.excludeVendors` | Exclude devices with specified vendor | `CLOUDBYT,OpenEBS` | +| `ndm.filters.includePaths` | Include devices with specified path patterns | `""` | +| `ndm.filters.osDiskExcludePaths` | Paths/Mounts to be excluded by OS Disk Filter | `/,/etc/hosts,/boot` | +| `ndm.image` | Image for Node Disk Manager | `openebs/node-disk-manager` | +| `ndm.imageTag` | Image Tag for Node Disk Manager | `2.1.0` | +| `ndmOperator.enabled` | Enable NDM Operator | `true` | +| `ndmOperator.image` | Image for NDM Operator | `openebs/node-disk-operator` | +| `ndmOperator.imageTag` | Image Tag for NDM Operator | `2.1.0` | +| `ndm.probes.enableSeachest` | Enable Seachest probe for NDM | `false` | +| `policies.monitoring.image` | Image for Prometheus Exporter | `openebs/m-exporter` | +| `policies.monitoring.imageTag` | Image Tag for Prometheus Exporter | `2.12.2` | +| `provisioner.enabled` | Enable Provisioner | `true` | +| `provisioner.image` | Image for Provisioner | `openebs/openebs-k8s-provisioner` | +| `provisioner.imageTag` | Image Tag for Provisioner | `2.12.2` | +| `rbac.create` | Enable RBAC Resources | `true` | +| `rbac.kyvernoEnabled` | Create Kyverno policy resources | `false` | +| `rbac.pspEnabled` | Create pod security policy resources | `false` | +| `snapshotOperator.controller.image` | Image for Snapshot Controller | `openebs/snapshot-controller` | +| `snapshotOperator.controller.imageTag` | Image Tag for Snapshot Controller | `2.12.2` | +| `snapshotOperator.enabled` | Enable Snapshot Provisioner | `true` | +| `snapshotOperator.provisioner.image` | Image for Snapshot Provisioner | `openebs/snapshot-provisioner` | +| `snapshotOperator.provisioner.imageTag` | Image Tag for Snapshot Provisioner | `2.12.2` | +| `varDirectoryPath.baseDir` | To store debug info of OpenEBS containers | `/var/openebs` | +| `webhook.enabled` | Enable admission server | `true` | +| `webhook.hostNetwork` | Use hostNetwork in admission server | `false` | +| `webhook.image` | Image for admission server | `openebs/admission-server` | +| `webhook.imageTag` | Image Tag for admission server | `2.12.2` | + +Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. + +Alternatively, a YAML file that specifies the values for the parameters can be provided while installing the chart. For example, + +```bash +helm install --name `my-release` -f values.yaml --namespace openebs openebs/openebs --create-namespace +``` + +> **Tip**: You can use the default [values.yaml](values.yaml) diff --git a/helm/openebs/charts/cstor/.helmignore b/helm/openebs/charts/cstor/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/helm/openebs/charts/cstor/.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/helm/openebs/charts/cstor/Chart.lock b/helm/openebs/charts/cstor/Chart.lock new file mode 100644 index 0000000..da43d9e --- /dev/null +++ b/helm/openebs/charts/cstor/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: openebs-ndm + repository: https://openebs.github.io/node-disk-manager + version: 2.1.0 +digest: sha256:47adcc8a92ea7ce83ca7f37f05f9e2f4c10154adc9551bd92e92c1ca5608f131 +generated: "2023-07-26T01:22:54.45340259Z" diff --git a/helm/openebs/charts/cstor/Chart.yaml b/helm/openebs/charts/cstor/Chart.yaml new file mode 100644 index 0000000..8125f89 --- /dev/null +++ b/helm/openebs/charts/cstor/Chart.yaml @@ -0,0 +1,29 @@ +apiVersion: v2 +appVersion: 3.5.0 +dependencies: +- condition: openebsNDM.enabled + name: openebs-ndm + repository: https://openebs.github.io/node-disk-manager + version: 2.1.0 +description: CStor-Operator helm chart for Kubernetes +home: http://www.openebs.io/ +icon: https://raw.githubusercontent.com/cncf/artwork/master/projects/openebs/icon/color/openebs-icon-color.png +keywords: +- cloud-native-storage +- block-storage +- iSCSI +- storage +- cstor +- cstor-operators +maintainers: +- email: kiran.mova@mayadata.io + name: kiranmova +- email: prateek.pandey@mayadata.io + name: prateekpandey14 +- email: sonasingh46@gmail.com + name: sonasingh46 +name: cstor +sources: +- https://github.com/openebs/cstor-operators +type: application +version: 3.5.0 diff --git a/helm/openebs/charts/cstor/README.md b/helm/openebs/charts/cstor/README.md new file mode 100644 index 0000000..ef70ec1 --- /dev/null +++ b/helm/openebs/charts/cstor/README.md @@ -0,0 +1,251 @@ +# OpenEBS CStor + +[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) +![Release Charts](https://github.com/openebs/cstor-operators/workflows/Release%20Charts/badge.svg?branch=master) +![Chart Lint and Test](https://github.com/openebs/cstor-operators/workflows/Chart%20Lint%20and%20Test/badge.svg) + +OpenEBS CStor helm chart for Kubernetes. This chart bootstraps OpenEBS cstor operators and csi driver deployment on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager + +**Homepage:** + +## Maintainers + +| Name | Email | Url | +| ---- | ------ | --- | +| kiranmova | kiran.mova@mayadata.io | | +| prateekpandey14 | prateek.pandey@mayadata.io | | +| sonasingh46 | sonasingh46@gmail.com | | + +## Get Repo Info + +```console +helm repo add openebs-cstor https://openebs.github.io/cstor-operators +helm repo update +``` + +_See [helm repo](https://helm.sh/docs/helm/helm_repo/) for command documentation._ + +## Install Chart + +Please visit the [link](https://openebs.github.io/cstor-operators) for install instructions via helm3. + +```console +# Helm +$ helm install [RELEASE_NAME] openebs-cstor/cstor --namespace [NAMESPACE] +``` +
+ Click here if you're using MicroK8s. + + ```console + microk8s helm3 install [RELEASE_NAME] openebs-cstor/cstor --namespace [NAMESPACE] --set-string csiNode.kubeletDir="/var/snap/microk8s/common/var/lib/kubelet/" + ``` +
+ +_See [configuration](#configuration) below._ + +_See [helm install](https://helm.sh/docs/helm/helm_install/) for command documentation._ + + +## Dependencies + +By default this chart installs additional, dependent charts: + +| Repository | Name | Version | +|------------|------|---------| +| https://openebs.github.io/node-disk-manager | openebs-ndm | 2.1.0 | + +To disable the dependency during installation, set `openebsNDM.enabled` to `false`. + +_See [helm dependency](https://helm.sh/docs/helm/helm_dependency/) for command documentation._ + +## Uninstall Chart + +```console +# Helm +$ helm uninstall [RELEASE_NAME] --namespace [NAMESPACE] +``` + +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._ + +## Upgrading Chart + +```console +# Helm +$ helm upgrade [RELEASE_NAME] [CHART] --install --namespace [NAMESPACE] +``` + +## Configuration + +The following table lists the configurable parameters of the OpenEBS CStor chart and their default values. + +You can modify different parameters by specifying the desired value in the `helm install` command by using the `--set` and/or the `--set-string` flag(s). You can modify the parameters of the [Node Disk Manager chart](https://openebs.github.io/node-disk-manager) by adding `openebs-ndm` before the desired parameter in the `helm install` command. + +In the following sample command we modify `csiNode.nodeSelector` from the cstor chart and `ndm.nodeSelector` from the openebs-ndm chart to only schedule pods on nodes labelled with `openebs.io/data-plane=true`. We also enable the 'Use OS-disk' feature gate using the `featureGates.UseOSDisk.enabled` parameter from the openebs-ndm chart. + + +```console +helm install openebs-cstor openebs-cstor/cstor --namespace openebs --create-namespace \ + --set-string csiNode.nodeSelector."openebs\.io/data-plane"=true \ + --set-string openebs-ndm.ndm.nodeSelector."openebs\.io/data-plane"=true \ + --set openebs-ndm.featureGates.UseOSDisk.enabled=true +``` +
+ Click here if you're using MicroK8s. + + If you are using MicroK8s, it is necessary to add the following flag: + + ```console + --set-string csiNode.kubeletDir="/var/snap/microk8s/common/var/lib/kubelet/" + ``` +
+ +| Key | Type | Default | Description | +|-----|------|-------------------------------------------------------------|-------------| +| admissionServer.annotations | object | `{}` | Admission webhook annotations | +| admissionServer.componentName | string | `"cstor-admission-webhook"` | Admission webhook Component Name | +| admissionServer.failurePolicy | string | `"Fail"` | Admission Webhook failure policy | +| admissionServer.image.pullPolicy | string | `"IfNotPresent"` | Admission webhook image pull policy | +| admissionServer.image.registry | string | `nil` | Admission webhook image registry | +| admissionServer.image.repository | string | `"openebs/cstor-webhook"` | Admission webhook image repo | +| admissionServer.image.tag | string | `"3.5.0"` | Admission webhook image tag | +| admissionServer.nodeSelector | object | `{}` | Admission webhook pod node selector | +| admissionServer.podAnnotations | object | `{}` | Admission webhook pod annotations | +| admissionServer.resources | object | `{}` | Admission webhook pod resources | +| admissionServer.securityContext | object | `{}` | Admission webhook security context | +| admissionServer.tolerations | list | `[]` | Admission webhook tolerations | +| cleanup.image.registry | string | `nil` | cleanup pre hook image registry | +| cleanup.image.repository | string | `"bitnami/kubectl"` | cleanup pre hook image repository | +| csiController.annotations | object | `{}` | CSI controller annotations | +| csiController.attacher.image.pullPolicy | string | `"IfNotPresent"` | CSI attacher image pull policy | +| csiController.attacher.image.registry | string | `"registry.k8s.io/"` | CSI attacher image registry | +| csiController.attacher.image.repository | string | `"sig-storage/csi-attacher"` | CSI attacher image repo | +| csiController.attacher.image.tag | string | `"v4.3.0"` | CSI attacher image tag | +| csiController.attacher.logLevel | string | _unspecified_ | Override log level for CSI attacher container (1 = least verbose, 5 = most verbose) | +| csiController.attacher.name | string | `"csi-attacher"` | CSI attacher container name| +| csiController.componentName | string | `"openebs-cstor-csi-controller"` | CSI controller component name | +| csiController.logLevel | string | `"5"` | Default log level for all CSI controller containers (1 = least verbose, 5 = most verbose) unless overridden for a specific container | +| csiController.nodeSelector | object | `{}` | CSI controller pod node selector | +| csiController.podAnnotations | object | `{}` | CSI controller pod annotations | +| csiController.provisioner.image.pullPolicy | string | `"IfNotPresent"` | CSI provisioner image pull policy | +| csiController.provisioner.image.registry | string | `"registry.k8s.io/"` | CSI provisioner image pull registry | +| csiController.provisioner.image.repository | string | `"sig-storage/csi-provisioner"` | CSI provisioner image pull repository | +| csiController.provisioner.image.tag | string | `"v3.5.0"` | CSI provisioner image tag | +| csiController.provisioner.logLevel | string | _unspecified_ | Override log level for CSI provisioner container (1 = least verbose, 5 = most verbose) | +| csiController.provisioner.name | string | `"csi-provisioner"` | CSI provisioner container name | +| csiController.resizer.image.pullPolicy | string | `"IfNotPresent"` | CSI resizer image pull policy | +| csiController.resizer.image.registry | string | `"registry.k8s.io/"` | CSI resizer image registry | +| csiController.resizer.image.repository | string | `"sig-storage/csi-resizer"` | CSI resizer image repository| +| csiController.resizer.image.tag | string | `"v1.8.0"` | CSI resizer image tag | +| csiController.resizer.logLevel | string | _unspecified_ | Override log level for CSI resizer container (1 = least verbose, 5 = most verbose) | +| csiController.resizer.name | string | `"csi-resizer"` | CSI resizer container name | +| csiController.resources | object | `{}` | CSI controller container resources | +| csiController.securityContext | object | `{}` | CSI controller security context | +| csiController.snapshotController.image.pullPolicy | string | `"IfNotPresent"` | CSI snapshot controller image pull policy | +| csiController.snapshotController.image.registry | string | `"k8s.gcr.io/"` | CSI snapshot controller image registry | +| csiController.snapshotController.image.repository | string | `"sig-storage/snapshot-controller"` | CSI snapshot controller image repository | +| csiController.snapshotController.image.tag | string | `"v6.2.2"` | CSI snapshot controller image tag | +| csiController.snapshotController.logLevel | string | _unspecified_ | Override log level for CSI snapshot controller container (1 = least verbose, 5 = most verbose) | +| csiController.snapshotController.name | string | `"snapshot-controller"` | CSI snapshot controller container name | +| csiController.snapshotter.image.pullPolicy | string | `"IfNotPresent"` | CSI snapshotter image pull policy | +| csiController.snapshotter.image.registry | string | `"registry..k8s.io/"` | CSI snapshotter image pull registry | +| csiController.snapshotter.image.repository | string | `"sig-storage/csi-snapshotter"` | CSI snapshotter image repository | +| csiController.snapshotter.image.tag | string | `"v6.2.2"` | CSI snapshotter image tag | +| csiController.snapshotter.name | string | `"csi-snapshotter"` | CSI snapshotter container name | +| csiController.tolerations | list | `[]` | CSI controller pod tolerations | +| csiNode.annotations | object | `{}` | CSI Node annotations | +| csiNode.componentName | string | `"openebs-cstor-csi-node"` | CSI Node component name | +| csiNode.driverRegistrar.image.pullPolicy | string | `"IfNotPresent"` | CSI Node driver registrar image pull policy| +| csiNode.driverRegistrar.image.registry | string | `"registry.k8s.io/"` | CSI Node driver registrar image registry | +| csiNode.driverRegistrar.image.repository | string | `"sig-storage/csi-node-driver-registrar"` | CSI Node driver registrar image repository | +| csiNode.driverRegistrar.image.tag | string | `"v2.8.0"` | CSI Node driver registrar image tag| +| csiNode.driverRegistrar.logLevel | string | _unspecified_ | Override log level for CSI node driver registrar container (1 = least verbose, 5 = most verbose) | +| csiNode.driverRegistrar.name | string | `"csi-node-driver-registrar"` | CSI Node driver registrar container name | +| csiNode.kubeletDir | string | `"/var/lib/kubelet/"` | Kubelet root dir | +| csiNode.labels | object | `{}` | CSI Node pod labels | +| csiNode.logLevel | string | `"5"` | Default log level for CSI node containers (1 = least verbose, 5 = most verbose) unless overriden for a specific container | +| csiNode.nodeSelector | object | `{}` | CSI Node pod nodeSelector | +| csiNode.podAnnotations | object | `{}` | CSI Node pod annotations | +| csiNode.resources | object | `{}` | CSI Node pod resources | +| csiNode.securityContext | object | `{}` | CSI Node pod security context | +| csiNode.tolerations | list | `[]` | CSI Node pod tolerations | +| csiNode.updateStrategy.type | string | `"RollingUpdate"` | CSI Node daemonset update strategy | +| cspcOperator.annotations | object | `{}` | CSPC operator annotations | +| cspcOperator.componentName | string | `"cspc-operator"` | CSPC operator component name | +| cspcOperator.cstorPool.image.registry | string | `nil` | CStor pool image registry | +| cspcOperator.cstorPool.image.repository | string | `"openebs/cstor-pool"` | CStor pool image repository| +| cspcOperator.cstorPool.image.tag | string | `"3.5.0"` | CStor pool image tag | +| cspcOperator.cstorPoolExporter.image.registry | string | `nil` | CStor pool exporter image registry | +| cspcOperator.cstorPoolExporter.image.repository | string | `"openebs/m-exporter"` | CStor pool exporter image repository | +| cspcOperator.cstorPoolExporter.image.tag | string | `"3.5.0"` | CStor pool exporter image tag | +| cspcOperator.image.pullPolicy | string | `"IfNotPresent"` | CSPC operator image pull policy | +| cspcOperator.image.registry | string | `nil` | CSPC operator image registry | +| cspcOperator.image.repository | string | `"openebs/cspc-operator"` | CSPC operator image repository | +| cspcOperator.image.tag | string | `"3.5.0"` | CSPC operator image tag | +| cspcOperator.nodeSelector | object | `{}` | CSPC operator pod nodeSelector| +| cspcOperator.podAnnotations | object | `{}` | CSPC operator pod annotations | +| cspcOperator.poolManager.image.registry | string | `nil` | CStor Pool Manager image registry | +| cspcOperator.poolManager.image.repository | string | `"openebs/cstor-pool-manager"` | CStor Pool Manager image repository | +| cspcOperator.poolManager.image.tag | string | `"3.5.0"` | CStor Pool Manager image tag | +| cspcOperator.resources | object | `{}` | CSPC operator pod resources | +| cspcOperator.resyncInterval | string | `"30"` | CSPC operator resync interval | +| cspcOperator.securityContext | object | `{}` | CSPC operator security context | +| cspcOperator.tolerations | list | `[]` | CSPC operator pod tolerations | +| cspcOperator.baseDir | string | `"/var/openebs"` | base directory for openebs cStor pools on host path to store pool related information | +| cspcOperator.sparseDir | string | `"/var/openebs/sparse"` | sparse directory to access sparse based devices | +| cstorCSIPlugin.image.pullPolicy | string | `"IfNotPresent"` | CStor CSI driver image pull policy | +| cstorCSIPlugin.image.registry | string | `nil` | CStor CSI driver image registry | +| cstorCSIPlugin.image.repository | string | `"openebs/cstor-csi-driver"` | CStor CSI driver image repository | +| cstorCSIPlugin.image.tag | string | `"3.5.0"` | CStor CSI driver image tag | +| cstorCSIPlugin.name | string | `"cstor-csi-plugin"` | CStor CSI driver container name | +| cstorCSIPlugin.remount | string | `"true"` | Enable/disable auto-remount when volume recovers from read-only state | +| cvcOperator.annotations | object | `{}` | CVC operator annotations | +| cvcOperator.componentName | string | `"cvc-operator"` | CVC operator component name | +| cvcOperator.image.pullPolicy | string | `"IfNotPresent"` | CVC operator image pull policy | +| cvcOperator.image.registry | string | `nil` | CVC operator image registry | +| cvcOperator.image.repository | string | `"openebs/cvc-operator"` | CVC operator image repository | +| cvcOperator.image.tag | string | `"3.5.0"` | CVC operator image tag | +| cvcOperator.logLevel | string | `"2"` | Log level for CVC operator container (1 = least verbose, 5 = most verbose) | +| cvcOperator.nodeSelector | object | `{}` | CVC operator pod nodeSelector | +| cvcOperator.podAnnotations | object | `{}` | CVC operator pod annotations | +| cvcOperator.resources | object | `{}` |CVC operator pod resources | +| cvcOperator.resyncInterval | string | `"30"` | CVC operator resync interval | +| cvcOperator.securityContext | object | `{}` | CVC operator security context | +| cvcOperator.target.image.registry | string | `nil` | Volume Target image registry | +| cvcOperator.target.image.repository | string | `"openebs/cstor-istgt"` | Volume Target image repository | +| cvcOperator.target.image.tag | string | `"3.5.0"` | Volume Target image tag | +| cvcOperator.tolerations | list | `[]` | CVC operator pod tolerations | +| cvcOperator.volumeExporter.image.registry | string | `nil` | Volume exporter image registry | +| cvcOperator.volumeExporter.image.repository | string | `"openebs/m-exporter"` | Volume exporter image repository | +| cvcOperator.volumeExporter.image.tag | string | `"3.5.0"` | Volume exporter image tag | +| cvcOperator.volumeMgmt.image.registry | string | `nil` | Volume mgmt image registry | +| cvcOperator.volumeMgmt.image.repository | string | `"openebs/cstor-volume-manager"` | Volume mgmt image repository | +| cvcOperator.volumeMgmt.image.tag | string | `"3.5.0"` | Volume mgmt image tag| +| cvcOperator.baseDir | string | `"/var/openebs"` | CVC operator base directory for openebs on host path | +| imagePullSecrets | string | `nil` | Image registry pull secrets | +| openebsNDM.enabled | bool | `true` | Enable OpenEBS NDM dependency | +| openebs-ndm.featureGates.APIService.enabled | bool | `true` | Enable 'API Service' feature gate for NDM | +| openebs-ndm.featureGates.GPTBasedUUID.enabled | bool | `true` | Enable 'GPT-based UUID' feature gate for NDM | +| openebs-ndm.featureGates.UseOSDisk.enabled | bool | `false` | Enable 'Use OS-disk' feature gate for NDM | +| openebs-ndm.helperPod.image.registry | string | `nil` | Registry for helper image | +| openebs-ndm.helperPod.image.repository | string | `openebs/linux-utils` | Image repository for helper pod | +| openebs-ndm.ndm.filters.enableOsDiskExcludeFilter | bool | `true` | Enable filters of OS disk exclude | +| openebs-ndm.ndm.filters.enableVendorFilter | bool | `true` | Enable filters of vendors | +| openebs-ndm.ndm.filters.excludeVendors | string | `"CLOUDBYT,OpenEBS"` | Exclude devices with specified vendor | +| openebs-ndm.ndm.filters.enablePathFilter | bool | `true` | Enable filters of paths | +| openebs-ndm.ndm.filters.includePaths | string | `""` | Include devices with specified path patterns | +| openebs-ndm.ndm.filters.excludePaths | string | `"loop,fd0,sr0,/dev/ram,/dev/dm-,/dev/md,/dev/rbd,/dev/zd"` | Exclude devices with specified path patterns | +| openebs-ndm.ndm.image.registry | string | `nil` | Registry for Node Disk Manager image | +| openebs-ndm.ndm.image.repository | string | `openebs/node-disk-manager` | Image repository for Node Disk Manager | +| openebs-ndm.ndm.nodeSelector | object | `{}` | Nodeselector for daemonset pods | +| openebs-ndm.ndmOperator.image.registry | string | `nil` | Registry for NDM operator image | +| openebs-ndm.ndmOperator.image.repository | string | `openebs/node-disk-operator` | Image repository for NDM operator | +| rbac.create | bool | `true` | Enable RBAC | +| rbac.pspEnabled | bool | `false` | Enable PodSecurityPolicy | +| release.version | string | `"3.5.0"` | Openebs CStor release version | +| serviceAccount.annotations | object | `{}` | Service Account annotations | +| serviceAccount.csiController.create | bool | `true` | Enable CSI Controller ServiceAccount | +| serviceAccount.csiController.name | string | `"openebs-cstor-csi-controller-sa"` | CSI Controller ServiceAccount name | +| serviceAccount.csiNode.create | bool | `true` | Enable CSI Node ServiceAccount | +| serviceAccount.csiNode.name | string | `"openebs-cstor-csi-node-sa"` | CSI Node ServiceAccount name | diff --git a/helm/openebs/charts/cstor/charts/openebs-ndm/Chart.yaml b/helm/openebs/charts/cstor/charts/openebs-ndm/Chart.yaml new file mode 100644 index 0000000..53484cd --- /dev/null +++ b/helm/openebs/charts/cstor/charts/openebs-ndm/Chart.yaml @@ -0,0 +1,23 @@ +apiVersion: v2 +appVersion: 2.1.0 +description: Helm chart for OpenEBS Node Disk Manager - a Kubernetes native storage + device management solution. For instructions on how to install, refer to https://openebs.github.io/node-disk-manager/. +home: http://www.openebs.io/ +icon: https://raw.githubusercontent.com/cncf/artwork/master/projects/openebs/icon/color/openebs-icon-color.png +keywords: +- cloud-native-storage +- block-storage +- ndm +- disk-inventory +- storage +maintainers: +- email: akhil.mohan@mayadata.io + name: akhilerm +- email: michaelfornaro@gmail.com + name: xUnholy +- email: prateek.pandey@mayadata.io + name: prateekpandey14 +name: openebs-ndm +sources: +- https://github.com/openebs/node-disk-manager +version: 2.1.0 diff --git a/helm/openebs/charts/cstor/charts/openebs-ndm/README.md b/helm/openebs/charts/cstor/charts/openebs-ndm/README.md new file mode 100644 index 0000000..399a687 --- /dev/null +++ b/helm/openebs/charts/cstor/charts/openebs-ndm/README.md @@ -0,0 +1,93 @@ +## Introduction + +This chart bootstraps OpenEBS NDM deployment on a [Kubernetes](http://kubernetes.io) cluster using the +[Helm](https://helm.sh) package manager. + +## Installation + +You can run OpenEBS NDM on any Kubernetes 1.17+ cluster in a matter of seconds. + +Please visit the [link](https://openebs.github.io/node-disk-manager/) for install instructions via helm3. + +## Configuration + +The following table lists the configurable parameters of the OpenEBS NDM chart and their default values. + +| Parameter | Description | Default | +|-------------------------------------------------------------|-------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------| +| `imagePullSecrets` | Provides image pull secrect | `""` | +| `ndm.enabled` | Enable Node Disk Manager | `true` | +| `ndm.image.registry` | Registry for Node Disk Manager image | `""` | +| `ndm.image.repository` | Image repository for Node Disk Manager | `openebs/node-disk-manager` | +| `ndm.image.pullPolicy` | Image pull policy for Node Disk Manager | `IfNotPresent` | +| `ndm.image.tag` | Image tag for Node Disk Manager | `2.1.0` | +| `ndm.sparse.path` | Directory where Sparse files are created | `/var/openebs/sparse` | +| `ndm.sparse.size` | Size of the sparse file in bytes | `10737418240` | +| `ndm.sparse.count` | Number of sparse files to be created | `0` | +| `ndm.updateStrategy.type` | Update strategy for NDM daemonset | `RollingUpdate` | +| `ndm.annotations` | Annotations for NDM daemonset metadata | `""` | +| `ndm.podAnnotations` | Annotations for NDM daemonset's pods metadata | `""` | +| `ndm.resources` | Resource and request and limit for containers | `""` | +| `ndm.podLabels` | Appends labels to the pods | `""` | +| `ndm.nodeSelector` | Nodeselector for daemonset pods | `""` | +| `ndm.tolerations` | NDM daemonset's pod toleration values | `""` | +| `ndm.securityContext` | Seurity context for container | `""` | +| `ndm.filters.enableOsDiskExcludeFilter` | Enable filters of OS disk exclude | `true` | +| `ndm.filters.osDiskExcludePaths` | Paths/Mountpoints to be excluded by OS Disk Filter | `/,/etc/hosts,/boot` | +| `ndm.filters.enableVendorFilter` | Enable filters of vendors | `true` | +| `ndm.filters.excludeVendors` | Exclude devices with specified vendor | `CLOUDBYT,OpenEBS` | +| `ndm.filters.enablePathFilter` | Enable filters of paths | `true` | +| `ndm.filters.includePaths` | Include devices with specified path patterns | `""` | +| `ndm.filters.excludePaths` | Exclude devices with specified path patterns | `loop,fd0,sr0,/dev/ram,/dev/dm-,/dev/md,/dev/rbd,/dev/zd` | +| `ndm.probes.enableSeachest` | Enable Seachest probe for NDM | `false` | +| `ndm.probes.enableUdevProbe` | Enable Udev probe for NDM | `true` | +| `ndm.probes.enableSmartProbe` | Enable Smart probe for NDM | `true` | +| `ndm.metaConfig.nodeLabelPattern` | Config for adding node labels as BD labels | `kubernetes.io*,beta.kubernetes.io*` | +| `ndm.metaConfig.deviceLabelTypes` | Config for adding device attributes as BD labels | `.spec.details.vendor,.spec.details.model,.spec.details.driveType,.spec.filesystem.fsType` | +| `ndmOperator.enabled` | Enable NDM Operator | `true` | +| `ndmOperator.replica` | Pod replica count for NDM operator | `1` | +| `ndmOperator.upgradeStrategy` | Update strategy NDM operator | `"Recreate"` | +| `ndmOperator.image.registry` | Registry for NDM operator image | `""` | +| `ndmOperator.image.repository` | Image repository for NDM operator | `openebs/node-disk-operator` | +| `ndmOperator.image.pullPolicy` | Image pull policy for NDM operator | `IfNotPresent` | +| `ndmOperator.image.tag` | Image tag for NDM operator | `2.1.0` | +| `ndmOperator.annotations` | Annotations for NDM operator metadata | `""` | +| `ndmOperator.podAnnotations` | Annotations for NDM operator's pods metadata | `""` | +| `ndmOperator.resources` | Resource and request and limit for containers | `""` | +| `ndmOperator.podLabels` | Appends labels to the pods | `""` | +| `ndmOperator.nodeSelector` | Nodeselector for operator pods | `""` | +| `ndmOperator.tolerations` | NDM operator's pod toleration values | `""` | +| `ndmOperator.securityContext` | Security context for container | `""` | +| `ndmExporter.enabled` | Enable NDM Exporters | `false` | +| `ndmExporter.image.registry` | Registry for NDM Exporters image | `""` | +| `ndmExporter.repository` | Image repository for NDM Exporters | `openebs/node-disk-exporter` | +| `ndmExporter.pullPolicy` | Image pull policy for NDM Exporters | `IfNotPresent` | +| `ndmExporter.tag` | Image tag for NDM Exporters | `2.1.0` | +| `ndmExporter.nodeExporter.metricsPort` | The TCP port number used for exposing NDM node exporter metrics | `9101` | +| `ndmExporter.nodeExporter.nodeExporter.nodeSelector` | Node selector for NDM node exporter pods | `9101` | +| `ndmExporter.nodeExporter.nodeExporter.tolerations` | NDM node exporter toleration values | `9101` | +| `ndmExporter.clusterExporter.metricsPort` | The TCP port number used for exposing NDM cluster exporter metrics | `9100` | +| `ndmExporter.clusterExporter.clusterExpoerter.nodeSelector` | Node selector for NDM cluster exporter pod | `9100` | +| `ndmExporter.clusterExporter.clusterExpoerter.tolerations` | NDM cluster exporter toleraion values | `9100` | +| `featureGates.APIService.enabled` | Enable the gRPC API service of NDM | `false` | +| `featureGates.UseOSDisk.enabled` | Enable feature-gate to use free space on OS disk | `false` | +| `featureGates.ChangeDetection.enabled` | Enable feature-gate to detect mountpoint/filesystem/size changes | `false` | +| `featureGates.PartitionTableUUID.enabled` | Enable feature-gate to use partition table UUID instead of creating partition | `true` | +| `helperPod.image.registry` | Registry for helper image | `""` | +| `helperPod.image.repository` | Image for helper pod | `openebs/linux-utils` | +| `helperPod.image.pullPolicy` | Pull policy for helper pod | `IfNotPresent` | +| `helperPod.image.tag` | Image tag for helper image | `3.4.0` | +| `varDirectoryPath.baseDir` | Directory to store debug info and so forth | `/var/openebs` | +| `serviceAccount.create` | Create a service account or not | `true` | +| `serviceAccount.name` | Name for the service account | `true` | + + +Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. + +Alternatively, a YAML file that specifies the values for the parameters can be provided while installing the chart. For example, + +```bash +helm install -f values.yaml ndm/openebs-ndm +``` + +> **Tip**: You can use the default [values.yaml](values.yaml) diff --git a/helm/openebs/charts/cstor/charts/openebs-ndm/crds/blockdevice.yaml b/helm/openebs/charts/cstor/charts/openebs-ndm/crds/blockdevice.yaml new file mode 100644 index 0000000..95f4070 --- /dev/null +++ b/helm/openebs/charts/cstor/charts/openebs-ndm/crds/blockdevice.yaml @@ -0,0 +1,241 @@ + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.5.0 + creationTimestamp: null + name: blockdevices.openebs.io +spec: + group: openebs.io + names: + kind: BlockDevice + listKind: BlockDeviceList + plural: blockdevices + shortNames: + - bd + singular: blockdevice + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.nodeAttributes.nodeName + name: NodeName + type: string + - jsonPath: .spec.path + name: Path + priority: 1 + type: string + - jsonPath: .spec.filesystem.fsType + name: FSType + priority: 1 + type: string + - jsonPath: .spec.capacity.storage + name: Size + type: string + - jsonPath: .status.claimState + name: ClaimState + type: string + - jsonPath: .status.state + name: Status + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: BlockDevice is the Schema for the blockdevices 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: DeviceSpec defines the properties and runtime status of a BlockDevice + properties: + aggregateDevice: + description: AggregateDevice was intended to store the hierarchical information in cases of LVM. However this is currently not implemented and may need to be re-looked into for better design. To be deprecated + type: string + capacity: + description: Capacity + properties: + logicalSectorSize: + description: LogicalSectorSize is blockdevice logical-sector size in bytes + format: int32 + type: integer + physicalSectorSize: + description: PhysicalSectorSize is blockdevice physical-Sector size in bytes + format: int32 + type: integer + storage: + description: Storage is the blockdevice capacity in bytes + format: int64 + type: integer + required: + - storage + type: object + claimRef: + description: ClaimRef is the reference to the BDC which has claimed this BD + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: 'If referring to a piece of an object instead of an entire object, this string should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. For example, if the object reference is to a container within a pod, this would take on a value like: "spec.containers{name}" (where "name" refers to the name of the container that triggered the event) or if no container name is specified "spec.containers[2]" (container with index 2 in this pod). This syntax is chosen only to have some well-defined way of referencing a part of an object. TODO: this design is not final and this field is subject to change in the future.' + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: 'Specific resourceVersion to which this reference is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + details: + description: Details contain static attributes of BD like model,serial, and so forth + properties: + compliance: + description: Compliance is standards/specifications version implemented by device firmware such as SPC-1, SPC-2, etc + type: string + deviceType: + description: DeviceType represents the type of device like sparse, disk, partition, lvm, crypt + enum: + - disk + - partition + - sparse + - loop + - lvm + - crypt + - dm + - mpath + type: string + driveType: + description: DriveType is the type of backing drive, HDD/SSD + enum: + - HDD + - SSD + - Unknown + - "" + type: string + firmwareRevision: + description: FirmwareRevision is the disk firmware revision + type: string + hardwareSectorSize: + description: HardwareSectorSize is the hardware sector size in bytes + format: int32 + type: integer + logicalBlockSize: + description: LogicalBlockSize is the logical block size in bytes reported by /sys/class/block/sda/queue/logical_block_size + format: int32 + type: integer + model: + description: Model is model of disk + type: string + physicalBlockSize: + description: PhysicalBlockSize is the physical block size in bytes reported by /sys/class/block/sda/queue/physical_block_size + format: int32 + type: integer + serial: + description: Serial is serial number of disk + type: string + vendor: + description: Vendor is vendor of disk + type: string + type: object + devlinks: + description: DevLinks contains soft links of a block device like /dev/by-id/... /dev/by-uuid/... + items: + description: DeviceDevLink holds the mapping between type and links like by-id type or by-path type link + properties: + kind: + description: Kind is the type of link like by-id or by-path. + enum: + - by-id + - by-path + type: string + links: + description: Links are the soft links + items: + type: string + type: array + type: object + type: array + filesystem: + description: FileSystem contains mountpoint and filesystem type + properties: + fsType: + description: Type represents the FileSystem type of the block device + type: string + mountPoint: + description: MountPoint represents the mountpoint of the block device. + type: string + type: object + nodeAttributes: + description: NodeAttributes has the details of the node on which BD is attached + properties: + nodeName: + description: NodeName is the name of the Kubernetes node resource on which the device is attached + type: string + type: object + parentDevice: + description: "ParentDevice was intended to store the UUID of the parent Block Device as is the case for partitioned block devices. \n For example: /dev/sda is the parent for /dev/sda1 To be deprecated" + type: string + partitioned: + description: Partitioned represents if BlockDevice has partitions or not (Yes/No) Currently always default to No. To be deprecated + enum: + - "Yes" + - "No" + type: string + path: + description: Path contain devpath (e.g. /dev/sdb) + type: string + required: + - capacity + - devlinks + - nodeAttributes + - path + type: object + status: + description: DeviceStatus defines the observed state of BlockDevice + properties: + claimState: + description: ClaimState represents the claim state of the block device + enum: + - Claimed + - Unclaimed + - Released + type: string + state: + description: State is the current state of the blockdevice (Active/Inactive/Unknown) + enum: + - Active + - Inactive + - Unknown + type: string + required: + - claimState + - state + type: object + type: object + served: true + storage: true + subresources: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/helm/openebs/charts/cstor/charts/openebs-ndm/crds/blockdeviceclaim.yaml b/helm/openebs/charts/cstor/charts/openebs-ndm/crds/blockdeviceclaim.yaml new file mode 100644 index 0000000..81b9a35 --- /dev/null +++ b/helm/openebs/charts/cstor/charts/openebs-ndm/crds/blockdeviceclaim.yaml @@ -0,0 +1,144 @@ + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.5.0 + creationTimestamp: null + name: blockdeviceclaims.openebs.io +spec: + group: openebs.io + names: + kind: BlockDeviceClaim + listKind: BlockDeviceClaimList + plural: blockdeviceclaims + shortNames: + - bdc + singular: blockdeviceclaim + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.blockDeviceName + name: BlockDeviceName + type: string + - jsonPath: .status.phase + name: Phase + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: BlockDeviceClaim is the Schema for the blockdeviceclaims 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: DeviceClaimSpec defines the request details for a BlockDevice + properties: + blockDeviceName: + description: BlockDeviceName is the reference to the block-device backing this claim + type: string + blockDeviceNodeAttributes: + description: BlockDeviceNodeAttributes is the attributes on the node from which a BD should be selected for this claim. It can include nodename, failure domain etc. + properties: + hostName: + description: HostName represents the hostname of the Kubernetes node resource where the BD should be present + type: string + nodeName: + description: NodeName represents the name of the Kubernetes node resource where the BD should be present + type: string + type: object + deviceClaimDetails: + description: Details of the device to be claimed + properties: + allowPartition: + description: AllowPartition represents whether to claim a full block device or a device that is a partition + type: boolean + blockVolumeMode: + description: 'BlockVolumeMode represents whether to claim a device in Block mode or Filesystem mode. These are use cases of BlockVolumeMode: 1) Not specified: VolumeMode check will not be effective 2) VolumeModeBlock: BD should not have any filesystem or mountpoint 3) VolumeModeFileSystem: BD should have a filesystem and mountpoint. If DeviceFormat is specified then the format should match with the FSType in BD' + type: string + formatType: + description: Format of the device required, eg:ext4, xfs + type: string + type: object + deviceType: + description: DeviceType represents the type of drive like SSD, HDD etc., + nullable: true + type: string + hostName: + description: Node name from where blockdevice has to be claimed. To be deprecated. Use NodeAttributes.HostName instead + type: string + resources: + description: Resources will help with placing claims on Capacity, IOPS + properties: + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum resources required. eg: if storage resource of 10G is requested minimum capacity of 10G should be available TODO for validating' + type: object + required: + - requests + type: object + selector: + description: Selector is used to find block devices to be considered for claiming + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + type: object + status: + description: DeviceClaimStatus defines the observed state of BlockDeviceClaim + properties: + phase: + description: Phase represents the current phase of the claim + type: string + required: + - phase + type: object + type: object + served: true + storage: true + subresources: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/helm/openebs/charts/cstor/charts/openebs-ndm/templates/NOTES.txt b/helm/openebs/charts/cstor/charts/openebs-ndm/templates/NOTES.txt new file mode 100644 index 0000000..3c84551 --- /dev/null +++ b/helm/openebs/charts/cstor/charts/openebs-ndm/templates/NOTES.txt @@ -0,0 +1,8 @@ +The OpenEBS Node Disk Manager has been installed. Check its status by running: +$ kubectl get pods -n {{ .Release.Namespace }} + +Use `kubectl get bd -n {{ .Release.Namespace }} ` to see the list of +blockdevices attached to the Kubernetes cluster nodes. + +For more information, visit our Slack at https://openebs.io/community or view +the documentation online at http://docs.openebs.io/. diff --git a/helm/openebs/charts/cstor/charts/openebs-ndm/templates/_helpers.tpl b/helm/openebs/charts/cstor/charts/openebs-ndm/templates/_helpers.tpl new file mode 100644 index 0000000..c975510 --- /dev/null +++ b/helm/openebs/charts/cstor/charts/openebs-ndm/templates/_helpers.tpl @@ -0,0 +1,242 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +This name is used for ndm daemonset +*/}} +{{- define "openebs-ndm.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "openebs-ndm.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified ndm daemonset 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 "openebs-ndm.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains .Release.Name $name }} +{{- $name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{- define "openebs-ndm.operator.name" -}} +{{- $ndmName := default .Chart.Name .Values.ndmOperator.nameOverride | trunc 63 | trimSuffix "-" }} +{{- $componentName := .Values.ndmOperator.name | trunc 63 | trimSuffix "-" }} +{{- printf "%s-%s" $ndmName $componentName | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified ndm operator 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 "openebs-ndm.operator.fullname" -}} +{{- if .Values.ndmOperator.fullnameOverride }} +{{- .Values.ndmOperator.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $ndmOperatorName := include "openebs-ndm.operator.name" .}} + +{{- $name := default $ndmOperatorName .Values.ndmOperator.nameOverride }} +{{- if contains .Release.Name $name }} +{{- $name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{- define "openebs-ndm.cluster-exporter.name" -}} +{{- $ndmName := default .Chart.Name .Values.ndmExporter.clusterExporter.nameOverride | trunc 63 | trimSuffix "-" }} +{{- $componentName := .Values.ndmExporter.clusterExporter.name | trunc 63 | trimSuffix "-" }} +{{- printf "%s-%s" $ndmName $componentName | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified ndm cluster exporter 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 "openebs-ndm.cluster-exporter.fullname" -}} +{{- if .Values.ndmExporter.clusterExporter.fullnameOverride }} +{{- .Values.ndmExporter.clusterExporter.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $ndmClusterExporterName := include "openebs-ndm.cluster-exporter.name" .}} + +{{- $name := default $ndmClusterExporterName .Values.ndmExporter.clusterExporter.nameOverride }} +{{- if contains .Release.Name $name }} +{{- $name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{- define "openebs-ndm.exporter.name" -}} +{{- $ndmName := .Chart.Name | trunc 63 | trimSuffix "-" }} +{{- $componentName := "exporter" | trunc 63 | trimSuffix "-" }} +{{- printf "%s-%s" $ndmName $componentName | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{- define "openebs-ndm.node-exporter.name" -}} +{{- $ndmName := default .Chart.Name .Values.ndmExporter.nodeExporter.nameOverride | trunc 63 | trimSuffix "-" }} +{{- $componentName := .Values.ndmExporter.nodeExporter.name | trunc 63 | trimSuffix "-" }} +{{- printf "%s-%s" $ndmName $componentName | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified ndm node exporter 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 "openebs-ndm.node-exporter.fullname" -}} +{{- if .Values.ndmExporter.nodeExporter.fullnameOverride }} +{{- .Values.ndmExporter.nodeExporter.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $ndmNodeExporterName := include "openebs-ndm.node-exporter.name" .}} + +{{- $name := default $ndmNodeExporterName .Values.ndmExporter.nodeExporter.nameOverride }} +{{- if contains .Release.Name $name }} +{{- $name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "openebs-ndm.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "openebs-ndm.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} + +{{/* +Define meta labels for ndm components +*/}} +{{- define "openebs-ndm.common.metaLabels" -}} +chart: {{ template "openebs-ndm.chart" . }} +heritage: {{ .Release.Service }} +openebs.io/version: {{ .Values.release.version | quote }} +{{- end -}} + + +{{/* +Create match labels for ndm daemonset component +*/}} +{{- define "openebs-ndm.matchLabels" -}} +app: {{ template "openebs-ndm.name" . }} +release: {{ .Release.Name }} +component: {{ .Values.ndm.componentName | quote }} +{{- end -}} + +{{/* +Create component labels for ndm daemonset component +*/}} +{{- define "openebs-ndm.componentLabels" -}} +openebs.io/component-name: {{ .Values.ndm.componentName | quote }} +{{- end -}} + + +{{/* +Create labels for ndm daemonset component +*/}} +{{- define "openebs-ndm.labels" -}} +{{ include "openebs-ndm.common.metaLabels" . }} +{{ include "openebs-ndm.matchLabels" . }} +{{ include "openebs-ndm.componentLabels" . }} +{{- end -}} + +{{/* +Create match labels for ndm operator deployment +*/}} +{{- define "openebs-ndm.operator.matchLabels" -}} +app: {{ template "openebs-ndm.operator.name" . }} +release: {{ .Release.Name }} +component: {{ default (include "openebs-ndm.operator.name" .) .Values.ndmOperator.componentName }} +{{- end -}} + +{{/* +Create component labels for ndm operator component +*/}} +{{- define "openebs-ndm.operator.componentLabels" -}} +openebs.io/component-name: {{ default (include "openebs-ndm.operator.name" .) .Values.ndmOperator.componentName }} +{{- end -}} + + +{{/* +Create labels for ndm operator component +*/}} +{{- define "openebs-ndm.operator.labels" -}} +{{ include "openebs-ndm.common.metaLabels" . }} +{{ include "openebs-ndm.operator.matchLabels" . }} +{{ include "openebs-ndm.operator.componentLabels" . }} +{{- end -}} + +{{/* +Create match labels for ndm cluster exporter deployment +*/}} +{{- define "openebs-ndm.cluster-exporter.matchLabels" -}} +app: {{ template "openebs-ndm.exporter.name" . }} +release: {{ .Release.Name }} +component: {{ default (include "openebs-ndm.cluster-exporter.name" .) .Values.ndmExporter.clusterExporter.componentName }} +{{- end -}} + +{{/* +Create component labels for ndm cluster exporter component +*/}} +{{- define "openebs-ndm.cluster-exporter.componentLabels" -}} +openebs.io/component-name: {{ default (include "openebs-ndm.cluster-exporter.name" .) .Values.ndmExporter.clusterExporter.componentName }} +{{- end -}} + + +{{/* +Create labels for ndm cluster exporter component +*/}} +{{- define "openebs-ndm.cluster-exporter.labels" -}} +{{ include "openebs-ndm.common.metaLabels" . }} +{{ include "openebs-ndm.cluster-exporter.matchLabels" . }} +{{ include "openebs-ndm.cluster-exporter.componentLabels" . }} +{{- end -}} + +{{/* +Create match labels for ndm node exporter deployment +*/}} +{{- define "openebs-ndm.node-exporter.matchLabels" -}} +app: {{ template "openebs-ndm.exporter.name" . }} +release: {{ .Release.Name }} +component: {{ default (include "openebs-ndm.node-exporter.name" .) .Values.ndmExporter.nodeExporter.componentName }} +{{- end -}} + +{{/* +Create component labels for ndm node exporter component +*/}} +{{- define "openebs-ndm.node-exporter.componentLabels" -}} +openebs.io/component-name: {{ default (include "openebs-ndm.node-exporter.name" .) .Values.ndmExporter.nodeExporter.componentName }} +{{- end -}} + + +{{/* +Create labels for ndm cluster node component +*/}} +{{- define "openebs-ndm.node-exporter.labels" -}} +{{ include "openebs-ndm.common.metaLabels" . }} +{{ include "openebs-ndm.node-exporter.matchLabels" . }} +{{ include "openebs-ndm.node-exporter.componentLabels" . }} +{{- end -}} diff --git a/helm/openebs/charts/cstor/charts/openebs-ndm/templates/cluster-exporter-service.yaml b/helm/openebs/charts/cstor/charts/openebs-ndm/templates/cluster-exporter-service.yaml new file mode 100644 index 0000000..719f6b4 --- /dev/null +++ b/helm/openebs/charts/cstor/charts/openebs-ndm/templates/cluster-exporter-service.yaml @@ -0,0 +1,18 @@ +{{- if and .Values.ndmExporter.enabled .Values.ndmExporter.clusterExporter.metricsPort }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "openebs-ndm.cluster-exporter.fullname" . }}-service + labels: + {{- include "openebs-ndm.cluster-exporter.labels" . | nindent 4 }} +spec: + clusterIP: None + ports: + - name: metrics + port: {{ .Values.ndmExporter.clusterExporter.metricsPort }} + targetPort: {{ .Values.ndmExporter.clusterExporter.metricsPort }} + selector: + {{- with .Values.ndmExporter.clusterExporter.podLabels }} + {{ toYaml . }} + {{- end }} + {{- end }} diff --git a/helm/openebs/charts/cstor/charts/openebs-ndm/templates/cluster-exporter.yaml b/helm/openebs/charts/cstor/charts/openebs-ndm/templates/cluster-exporter.yaml new file mode 100644 index 0000000..af8b1e6 --- /dev/null +++ b/helm/openebs/charts/cstor/charts/openebs-ndm/templates/cluster-exporter.yaml @@ -0,0 +1,60 @@ +{{- if .Values.ndmExporter.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "openebs-ndm.cluster-exporter.fullname" . }} + labels: + {{- include "openebs-ndm.cluster-exporter.labels" . | nindent 4 }} +spec: + replicas: 1 + strategy: + type: Recreate + selector: + matchLabels: + {{- include "openebs-ndm.cluster-exporter.matchLabels" . | nindent 6 }} + template: + metadata: + labels: + {{- include "openebs-ndm.cluster-exporter.labels" . | nindent 8 }} + {{- with .Values.ndmExporter.clusterExporter.podLabels }} + {{ toYaml . }} + {{- end }} + spec: + serviceAccountName: {{ template "openebs-ndm.serviceAccountName" . }} + containers: + - name: {{ template "openebs-ndm.cluster-exporter.fullname" . }} + image: "{{ .Values.ndmExporter.image.registry }}{{ .Values.ndmExporter.image.repository }}:{{ .Values.ndmExporter.image.tag }}" + command: + - /usr/local/bin/exporter + args: + - "start" + - "--mode=cluster" + - "--port=$(METRICS_LISTEN_PORT)" + - "--metrics=/metrics" + ports: + - containerPort: {{ .Values.ndmExporter.clusterExporter.metricsPort }} + protocol: TCP + name: metrics + imagePullPolicy: {{ .Values.ndmExporter.image.pullPolicy }} + env: + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + {{- if .Values.ndmExporter.clusterExporter.metricsPort }} + - name: METRICS_LISTEN_PORT + value: :{{ .Values.ndmExporter.clusterExporter.metricsPort }} + {{- end }} +{{- if .Values.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | indent 8 }} +{{- end }} +{{- if .Values.ndmExporter.clusterExporter.nodeSelector }} + nodeSelector: +{{ toYaml .Values.ndmExporter.clusterExporter.nodeSelector | indent 8 }} +{{- end }} +{{- if .Values.ndmExporter.clusterExporter.tolerations }} + tolerations: +{{ toYaml .Values.ndmExporter.clusterExporter.tolerations | indent 8 }} +{{- end }} +{{- end }} diff --git a/helm/openebs/charts/cstor/charts/openebs-ndm/templates/configmap.yaml b/helm/openebs/charts/cstor/charts/openebs-ndm/templates/configmap.yaml new file mode 100644 index 0000000..99b814d --- /dev/null +++ b/helm/openebs/charts/cstor/charts/openebs-ndm/templates/configmap.yaml @@ -0,0 +1,45 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "openebs-ndm.fullname" . }}-config +data: + # node-disk-manager-config contains config of available probes and filters. + # Probes and Filters will initialize with default values if config for that + # filter or probe are not present in configmap + + # udev-probe is default or primary probe it should be enabled to run ndm + # filterconfigs contains configs of filters. To provide a group of include + # and exclude values add it as , separated string + node-disk-manager.config: | + probeconfigs: + - key: udev-probe + name: udev probe + state: {{ .Values.ndm.probes.enableUdevProbe }} + - key: seachest-probe + name: seachest probe + state: {{ .Values.ndm.probes.enableSeachest }} + - key: smart-probe + name: smart probe + state: {{ .Values.ndm.probes.enableSmartProbe }} + filterconfigs: + - key: os-disk-exclude-filter + name: os disk exclude filter + state: {{ .Values.ndm.filters.enableOsDiskExcludeFilter }} + exclude: "{{ .Values.ndm.filters.osDiskExcludePaths }}" + - key: vendor-filter + name: vendor filter + state: {{ .Values.ndm.filters.enableVendorFilter }} + include: "" + exclude: "{{ .Values.ndm.filters.excludeVendors }}" + - key: path-filter + name: path filter + state: {{ .Values.ndm.filters.enablePathFilter }} + include: "{{ .Values.ndm.filters.includePaths }}" + exclude: "{{ .Values.ndm.filters.excludePaths }}" + metaconfigs: + - key: node-labels + name: node labels + pattern: "{{ .Values.ndm.metaConfig.nodeLabelPattern }}" + - key: device-labels + name: device labels + type: "{{ .Values.ndm.metaConfig.deviceLabelTypes }}" diff --git a/helm/openebs/charts/cstor/charts/openebs-ndm/templates/daemonset.yaml b/helm/openebs/charts/cstor/charts/openebs-ndm/templates/daemonset.yaml new file mode 100644 index 0000000..715db87 --- /dev/null +++ b/helm/openebs/charts/cstor/charts/openebs-ndm/templates/daemonset.yaml @@ -0,0 +1,179 @@ +{{- if .Values.ndm.enabled }} +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: {{ template "openebs-ndm.fullname" . }} + {{- with .Values.ndm.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "openebs-ndm.labels" . | nindent 4 }} +spec: + updateStrategy: +{{ toYaml .Values.ndm.updateStrategy | indent 4 }} + selector: + matchLabels: + {{- include "openebs-ndm.matchLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.ndm.podAnnotations }} + annotations: {{ toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "openebs-ndm.labels" . | nindent 8 }} + {{- with .Values.ndm.podLabels}} + {{ toYaml . }} + {{- end}} + spec: + serviceAccountName: {{ template "openebs-ndm.serviceAccountName" . }} +{{- if .Values.featureGates.enabled }} +{{- if .Values.featureGates.APIService.enabled }} + hostPID: true +{{- end}} +{{- end}} + containers: + - name: {{ template "openebs-ndm.name" . }} + image: "{{ .Values.ndm.image.registry }}{{ .Values.ndm.image.repository }}:{{ .Values.ndm.image.tag }}" + args: + - -v=4 +{{- if .Values.featureGates.enabled }} +{{- if .Values.featureGates.GPTBasedUUID.enabled }} + - --feature-gates={{ .Values.featureGates.GPTBasedUUID.featureGateFlag }} +{{- end}} +{{- if .Values.featureGates.APIService.enabled }} + - --feature-gates={{ .Values.featureGates.APIService.featureGateFlag }} + - --api-service-address={{ .Values.featureGates.APIService.address }} +{{- end}} +{{- if .Values.featureGates.UseOSDisk.enabled }} + - --feature-gates={{ .Values.featureGates.UseOSDisk.featureGateFlag }} +{{- end}} +{{- if .Values.featureGates.ChangeDetection.enabled }} + - --feature-gates={{ .Values.featureGates.ChangeDetection.featureGateFlag }} +{{- end}} +{{- if .Values.featureGates.PartitionTableUUID.enabled }} + - --feature-gates={{ .Values.featureGates.PartitionTableUUID.featureGateFlag }} +{{- end}} +{{- end}} + imagePullPolicy: {{ .Values.ndm.image.pullPolicy }} + resources: +{{ toYaml .Values.ndm.resources | indent 12 }} + securityContext: + privileged: true + env: + # namespace in which NDM is installed will be passed to NDM Daemonset + # as environment variable + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + # pass hostname as env variable using downward API to the NDM container + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName +{{- if .Values.ndm.sparse }} +{{- if .Values.ndm.sparse.path }} + # specify the directory where the sparse files need to be created. + # if not specified, then sparse files will not be created. + - name: SPARSE_FILE_DIR + value: "{{ .Values.ndm.sparse.path }}" +{{- end }} +{{- if .Values.ndm.sparse.size }} + # Size(bytes) of the sparse file to be created. + - name: SPARSE_FILE_SIZE + value: "{{ .Values.ndm.sparse.size }}" +{{- end }} +{{- if .Values.ndm.sparse.count }} + # Specify the number of sparse files to be created + - name: SPARSE_FILE_COUNT + value: "{{ .Values.ndm.sparse.count }}" +{{- end }} +{{- end }} + # Process name used for matching is limited to the 15 characters + # present in the pgrep output. + # So fullname can be used here with pgrep (cmd is < 15 chars). + livenessProbe: + exec: + command: + - pgrep + - "ndm" + initialDelaySeconds: {{ .Values.ndm.healthCheck.initialDelaySeconds }} + periodSeconds: {{ .Values.ndm.healthCheck.periodSeconds }} + volumeMounts: + - name: config + mountPath: /host/node-disk-manager.config + subPath: node-disk-manager.config + readOnly: true + - name: udev + mountPath: /run/udev + - name: procmount + mountPath: /host/proc + readOnly: true + - name: devmount + mountPath: /dev + - name: basepath + mountPath: /var/openebs/ndm +{{- if .Values.ndm.sparse }} +{{- if .Values.ndm.sparse.path }} + - name: sparsepath + mountPath: {{ .Values.ndm.sparse.path }} +{{- end }} +{{- end }} + volumes: + - name: config + configMap: + name: {{ include "openebs-ndm.fullname" . }}-config + - name: udev + hostPath: + path: /run/udev + type: Directory + # mount /proc (to access mount file of process 1 of host) inside container + # to read mount-point of disks and partitions + - name: procmount + hostPath: + path: /proc + type: Directory + - name: devmount + # the /dev directory is mounted so that we have access to the devices that + # are connected at runtime of the pod. + hostPath: + path: /dev + type: Directory + - name: basepath + hostPath: + path: "{{ .Values.varDirectoryPath.baseDir }}/ndm" + type: DirectoryOrCreate +{{- if .Values.ndm.sparse }} +{{- if .Values.ndm.sparse.path }} + - name: sparsepath + hostPath: + path: {{ .Values.ndm.sparse.path }} +{{- end }} +{{- end }} + # By default the node-disk-manager will be run on all kubernetes nodes + # If you would like to limit this to only some nodes, say the nodes + # that have storage attached, you could label those node and use + # nodeSelector. + # + # e.g. label the storage nodes with - "openebs.io/nodegroup"="storage-node" + # kubectl label node "openebs.io/nodegroup"="storage-node" + #nodeSelector: + # "openebs.io/nodegroup": "storage-node" +{{- if .Values.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | indent 8 }} +{{- end }} +{{- if .Values.ndm.nodeSelector }} + nodeSelector: +{{ toYaml .Values.ndm.nodeSelector | indent 8 }} +{{- end }} +{{- if .Values.ndm.tolerations }} + tolerations: +{{ toYaml .Values.ndm.tolerations | indent 8 }} +{{- end }} +{{- if .Values.ndm.securityContext }} + securityContext: +{{ toYaml .Values.ndm.securityContext | indent 8 }} +{{- end }} + hostNetwork: true +{{- end }} diff --git a/helm/openebs/charts/cstor/charts/openebs-ndm/templates/deployment.yaml b/helm/openebs/charts/cstor/charts/openebs-ndm/templates/deployment.yaml new file mode 100644 index 0000000..213a861 --- /dev/null +++ b/helm/openebs/charts/cstor/charts/openebs-ndm/templates/deployment.yaml @@ -0,0 +1,87 @@ +{{- if .Values.ndmOperator.enabled }} +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "openebs-ndm.operator.fullname" . }} + {{- with .Values.ndmOperator.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "openebs-ndm.operator.labels" . | nindent 4 }} +spec: + replicas: {{ .Values.ndmOperator.replicas }} + strategy: + type: "Recreate" + rollingUpdate: null + selector: + matchLabels: + {{- include "openebs-ndm.operator.matchLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.ndmOperator.podAnnotations }} + annotations: {{ toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "openebs-ndm.operator.labels" . | nindent 8 }} + {{- with .Values.ndmOperator.podLabels}} + {{ toYaml . }} + {{- end}} + spec: + serviceAccountName: {{ template "openebs-ndm.serviceAccountName" . }} + containers: + - name: {{ template "openebs-ndm.operator.fullname" . }} + image: "{{ .Values.ndmOperator.image.registry }}{{ .Values.ndmOperator.image.repository }}:{{ .Values.ndmOperator.image.tag }}" + imagePullPolicy: {{ .Values.ndmOperator.image.pullPolicy }} + resources: +{{ toYaml .Values.ndmOperator.resources | indent 12 }} + livenessProbe: + httpGet: + path: /healthz + port: 8585 + initialDelaySeconds: {{ .Values.ndmOperator.healthCheck.initialDelaySeconds }} + periodSeconds: {{ .Values.ndmOperator.healthCheck.periodSeconds }} + readinessProbe: + httpGet: + path: /readyz + port: 8585 + initialDelaySeconds: {{ .Values.ndmOperator.readinessCheck.initialDelaySeconds }} + periodSeconds: {{ .Values.ndmOperator.readinessCheck.periodSeconds }} + env: + - name: WATCH_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: SERVICE_ACCOUNT + valueFrom: + fieldRef: + fieldPath: spec.serviceAccountName + - name: OPERATOR_NAME + value: "node-disk-operator" + - name: CLEANUP_JOB_IMAGE + value: "{{ .Values.helperPod.image.registry }}{{ .Values.helperPod.image.repository }}:{{ .Values.helperPod.image.tag }}" +{{- if .Values.imagePullSecrets }} + - name: OPENEBS_IO_IMAGE_PULL_SECRETS + value: "{{- range $index, $secret := .Values.imagePullSecrets}}{{if $index}},{{end}}{{ $secret.name }}{{- end}}" +{{- end }} +{{- if .Values.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | indent 8 }} +{{- end }} +{{- if .Values.ndmOperator.nodeSelector }} + nodeSelector: +{{ toYaml .Values.ndmOperator.nodeSelector | indent 8 }} +{{- end }} +{{- if .Values.ndmOperator.securityContext }} + securityContext: +{{ toYaml .Values.ndmOperator.securityContext | indent 8 }} +{{- end }} +{{- if .Values.ndmOperator.tolerations }} + tolerations: +{{ toYaml .Values.ndmOperator.tolerations | indent 8 }} +{{- end }} +{{- end }} diff --git a/helm/openebs/charts/cstor/charts/openebs-ndm/templates/node-exporter-service.yaml b/helm/openebs/charts/cstor/charts/openebs-ndm/templates/node-exporter-service.yaml new file mode 100644 index 0000000..026b77d --- /dev/null +++ b/helm/openebs/charts/cstor/charts/openebs-ndm/templates/node-exporter-service.yaml @@ -0,0 +1,18 @@ +{{- if and .Values.ndmExporter.enabled .Values.ndmExporter.nodeExporter.metricsPort }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "openebs-ndm.node-exporter.fullname" . }}-service + labels: + {{- include "openebs-ndm.node-exporter.labels" . | nindent 4 }} +spec: + clusterIP: None + ports: + - name: metrics + port: {{ .Values.ndmExporter.nodeExporter.metricsPort }} + targetPort: {{ .Values.ndmExporter.nodeExporter.metricsPort }} + selector: + {{- with .Values.ndmExporter.nodeExporter.podLabels }} + {{ toYaml . }} + {{- end }} + {{- end }} diff --git a/helm/openebs/charts/cstor/charts/openebs-ndm/templates/node-exporter.yaml b/helm/openebs/charts/cstor/charts/openebs-ndm/templates/node-exporter.yaml new file mode 100644 index 0000000..cd5f635 --- /dev/null +++ b/helm/openebs/charts/cstor/charts/openebs-ndm/templates/node-exporter.yaml @@ -0,0 +1,62 @@ +{{- if .Values.ndmExporter.enabled }} +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: {{ template "openebs-ndm.node-exporter.fullname" . }} + labels: + {{- include "openebs-ndm.node-exporter.labels" . | nindent 4 }} +spec: + updateStrategy: + type: RollingUpdate + selector: + matchLabels: + {{- include "openebs-ndm.node-exporter.matchLabels" . | nindent 6 }} + template: + metadata: + labels: + {{- include "openebs-ndm.node-exporter.labels" . | nindent 8 }} + {{- with .Values.ndmExporter.nodeExporter.podLabels }} + {{ toYaml . }} + {{- end }} + spec: + serviceAccountName: {{ template "openebs-ndm.serviceAccountName" . }} + containers: + - name: {{ template "openebs-ndm.node-exporter.fullname" . }} + image: "{{ .Values.ndmExporter.image.registry }}{{ .Values.ndmExporter.image.repository }}:{{ .Values.ndmExporter.image.tag }}" + command: + - /usr/local/bin/exporter + args: + - "start" + - "--mode=node" + - "--port=$(METRICS_LISTEN_PORT)" + - "--metrics=/metrics" + ports: + - containerPort: {{ .Values.ndmExporter.nodeExporter.metricsPort }} + protocol: TCP + name: metrics + imagePullPolicy: {{ .Values.ndmExporter.image.pullPolicy }} + securityContext: + privileged: true + env: + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + {{- if .Values.ndmExporter.nodeExporter.metricsPort }} + - name: METRICS_LISTEN_PORT + value: :{{ .Values.ndmExporter.nodeExporter.metricsPort }} + {{- end }} +{{- if .Values.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | indent 8 }} +{{- end }} +{{- if .Values.ndmExporter.nodeExporter.nodeSelector }} + nodeSelector: +{{ toYaml .Values.ndmExporter.nodeExporter.nodeSelector | indent 8 }} +{{- end }} +{{- if .Values.ndmExporter.nodeExporter.tolerations }} + tolerations: +{{ toYaml .Values.ndmExporter.nodeExporter.tolerations | indent 8 }} +{{- end }} +{{- end }} + diff --git a/helm/openebs/charts/cstor/charts/openebs-ndm/templates/rbac.yaml b/helm/openebs/charts/cstor/charts/openebs-ndm/templates/rbac.yaml new file mode 100644 index 0000000..8e81c49 --- /dev/null +++ b/helm/openebs/charts/cstor/charts/openebs-ndm/templates/rbac.yaml @@ -0,0 +1,44 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "openebs-ndm.serviceAccountName" . }} +{{- end }} +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ include "openebs-ndm.fullname" . }} +rules: + - apiGroups: ["*"] + resources: ["nodes", "pods", "events", "configmaps", "jobs"] + verbs: + - '*' + - apiGroups: ["apiextensions.k8s.io"] + resources: ["customresourcedefinitions"] + verbs: + - '*' + - apiGroups: + - openebs.io + resources: + - blockdevices + - blockdeviceclaims + verbs: + - '*' +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ include "openebs-ndm.fullname" . }} +subjects: + - kind: ServiceAccount + name: {{ include "openebs-ndm.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} + - kind: User + name: system:serviceaccount:default:default + apiGroup: rbac.authorization.k8s.io +roleRef: + kind: ClusterRole + name: {{ include "openebs-ndm.fullname" . }} + apiGroup: rbac.authorization.k8s.io +--- diff --git a/helm/openebs/charts/cstor/charts/openebs-ndm/values.yaml b/helm/openebs/charts/cstor/charts/openebs-ndm/values.yaml new file mode 100644 index 0000000..2548606 --- /dev/null +++ b/helm/openebs/charts/cstor/charts/openebs-ndm/values.yaml @@ -0,0 +1,156 @@ +# Default values for ndm. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. +release: + version: "2.1.0" + +imagePullSecrets: +# - name: "image-pull-secret" + +ndm: + componentName: ndm + enabled: true + image: + # Make sure that registry name end with a '/'. + # For example : quay.io/ is a correct value here and quay.io is incorrect + registry: + repository: openebs/node-disk-manager + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: 2.1.0 + sparse: + path: "/var/openebs/sparse" + size: "10737418240" + count: "0" + updateStrategy: + type: RollingUpdate + annotations: {} + podAnnotations: {} + resources: {} + # limits: + # cpu: 10m + # memory: 32Mi + # requests: + # cpu: 10m + # memory: 32Mi + ## Labels to be added to ndm daemonset pods + podLabels: + name: openebs-ndm + nodeSelector: {} + tolerations: [] + securityContext: {} + filters: + enableOsDiskExcludeFilter: true + osDiskExcludePaths: "/,/etc/hosts,/boot" + enableVendorFilter: true + excludeVendors: "CLOUDBYT,OpenEBS" + enablePathFilter: true + includePaths: "" + excludePaths: "loop,fd0,sr0,/dev/ram,/dev/dm-,/dev/md,/dev/rbd,/dev/zd" + probes: + enableSeachest: false + enableUdevProbe: true + enableSmartProbe: true + metaConfig: + nodeLabelPattern: "" + deviceLabelTypes: "" + healthCheck: + initialDelaySeconds: 30 + periodSeconds: 60 + +ndmOperator: + name: operator + enabled: true + image: + registry: + repository: openebs/node-disk-operator + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: 2.1.0 + podLabels: + name: openebs-ndm-operator + annotations: {} + podAnnotations: {} + nodeSelector: {} + resources: {} + securityContext: {} + tolerations: [] + healthCheck: + initialDelaySeconds: 15 + periodSeconds: 20 + readinessCheck: + initialDelaySeconds: 5 + periodSeconds: 10 + replicas: 1 + upgradeStrategy: Recreate + +ndmExporter: + enabled: false + image: + registry: + repository: openebs/node-disk-exporter + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: 2.1.0 + nodeExporter: + name: node-exporter + podLabels: + name: openebs-ndm-node-exporter + # The TCP port number used for exposing ndm-node-exporter metrics. + # If not set, service will not be created to expose metrics endpoint to serviceMonitor + # and listen-port flag will not be set and container port will be empty. + metricsPort: 9101 + nodeSelector: {} + tolerations: [] + clusterExporter: + name: cluster-exporter + podLabels: + name: openebs-ndm-cluster-exporter + # The TCP port number used for exposing ndm-cluster-exporter metrics. + # If not set, service will not be created to expose metrics endpoint to serviceMonitor + # and listen-port flag will not be set and container port will be empty. + metricsPort: 9100 + nodeSelector: {} + tolerations: [] + +helperPod: + image: + registry: "" + repository: openebs/linux-utils + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: 3.4.0 + +crd: + enableInstall: false + +featureGates: + enabled: true + GPTBasedUUID: + enabled: true + featureGateFlag: "GPTBasedUUID" + APIService: + enabled: false + featureGateFlag: "APIService" + address: "0.0.0.0:9115" + UseOSDisk: + enabled: false + featureGateFlag: "UseOSDisk" + ChangeDetection: + enabled: false + featureGateFlag: "ChangeDetection" + PartitionTableUUID: + enabled: false + featureGateFlag: "PartitionTableUUID" + +# Directory used by the OpenEBS to store debug information and so forth +# that are generated in the course of running OpenEBS containers. +varDirectoryPath: + baseDir: "/var/openebs" + +serviceAccount: + # Specifies whether a service account should be created + create: true + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: openebs-ndm diff --git a/helm/openebs/charts/cstor/crds/cstorbackup.yaml b/helm/openebs/charts/cstor/crds/cstorbackup.yaml new file mode 100644 index 0000000..1063d8b --- /dev/null +++ b/helm/openebs/charts/cstor/crds/cstorbackup.yaml @@ -0,0 +1,87 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.10.0 + creationTimestamp: null + name: cstorbackups.cstor.openebs.io +spec: + group: cstor.openebs.io + names: + kind: CStorBackup + listKind: CStorBackupList + plural: cstorbackups + shortNames: + - cbackup + singular: cstorbackup + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Name of the volume for which this backup is destined + jsonPath: .spec.volumeName + name: Volume + type: string + - description: Name of the backup or scheduled backup + jsonPath: .spec.backupName + name: Backup/Schedule + type: string + - description: Identifies the phase of the backup + jsonPath: .status + name: Status + type: string + name: v1 + schema: + openAPIV3Schema: + description: CStorBackup describes a cstor backup resource created as a custom + resource + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: CStorBackupSpec is the spec for a CStorBackup resource + properties: + backupDest: + description: BackupDest is the remote address for backup transfer + type: string + backupName: + description: BackupName is the name of the backup or scheduled backup + type: string + localSnap: + description: LocalSnap is the flag to enable local snapshot only + type: boolean + prevSnapName: + description: PrevSnapName is the last completed-backup's snapshot + name + type: string + snapName: + description: SnapName is the name of the current backup snapshot + type: string + volumeName: + description: VolumeName is the name of the volume for which this backup + is destined + type: string + required: + - backupName + - snapName + - volumeName + type: object + status: + description: CStorBackupStatus is a string type that represents the status + of the backup + type: string + required: + - spec + type: object + served: true + storage: true + subresources: {} diff --git a/helm/openebs/charts/cstor/crds/cstorcompletedbackup.yaml b/helm/openebs/charts/cstor/crds/cstorcompletedbackup.yaml new file mode 100644 index 0000000..9b2683c --- /dev/null +++ b/helm/openebs/charts/cstor/crds/cstorcompletedbackup.yaml @@ -0,0 +1,74 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.10.0 + creationTimestamp: null + name: cstorcompletedbackups.cstor.openebs.io +spec: + group: cstor.openebs.io + names: + kind: CStorCompletedBackup + listKind: CStorCompletedBackupList + plural: cstorcompletedbackups + shortNames: + - ccompletedbackup + singular: cstorcompletedbackup + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Volume name on which backup is performed + jsonPath: .spec.volumeName + name: Volume + type: string + - description: Name of the backup or scheduled backup + jsonPath: .spec.backupName + name: Backup/Schedule + type: string + - description: Last successfully backup snapshot + jsonPath: .spec.lastSnapName + name: LastSnap + type: string + name: v1 + schema: + openAPIV3Schema: + description: CStorCompletedBackup describes a cstor completed-backup resource + created as custom resource + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: CStorCompletedBackupSpec is the spec for a CStorBackup resource + properties: + backupName: + description: BackupName is the name of backup or scheduled backup + type: string + lastSnapName: + description: LastSnapName is the name of last completed-backup's snapshot + name + type: string + secondLastSnapName: + description: SecondLastSnapName is the name of second last 'successfully' + completed-backup's snapshot + type: string + volumeName: + description: VolumeName is the name of volume for which this backup + is destined + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: {} diff --git a/helm/openebs/charts/cstor/crds/cstorpoolcluster.yaml b/helm/openebs/charts/cstor/crds/cstorpoolcluster.yaml new file mode 100644 index 0000000..8f92f4f --- /dev/null +++ b/helm/openebs/charts/cstor/crds/cstorpoolcluster.yaml @@ -0,0 +1,485 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.10.0 + creationTimestamp: null + name: cstorpoolclusters.cstor.openebs.io +spec: + group: cstor.openebs.io + names: + kind: CStorPoolCluster + listKind: CStorPoolClusterList + plural: cstorpoolclusters + shortNames: + - cspc + singular: cstorpoolcluster + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: The number of healthy cStorPoolInstances + jsonPath: .status.healthyInstances + name: HealthyInstances + type: integer + - description: The number of provisioned cStorPoolInstances + jsonPath: .status.provisionedInstances + name: ProvisionedInstances + type: integer + - description: The number of desired cStorPoolInstances + jsonPath: .status.desiredInstances + name: DesiredInstances + type: integer + - description: Age of CStorPoolCluster + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: CStorPoolCluster describes a CStorPoolCluster custom resource. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: CStorPoolClusterSpec is the spec for a CStorPoolClusterSpec + resource + properties: + auxResources: + description: AuxResources are the compute resources required by the + cstor-pool pod side car containers. + nullable: true + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute resources + allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + pools: + description: Pools is the spec for pools for various nodes where it + should be created. + items: + description: PoolSpec is the spec for pool on node where it should + be created. + properties: + dataRaidGroups: + description: DataRaidGroups is the raid group configuration + for the given pool. + items: + description: RaidGroup contains the details of a raid group + for the pool + properties: + blockDevices: + items: + description: CStorPoolInstanceBlockDevice contains the + details of block devices that constitutes a raid group. + properties: + blockDeviceName: + description: BlockDeviceName is the name of the + block device. + type: string + capacity: + description: Capacity is the capacity of the block + device. It is system generated + format: int64 + type: integer + devLink: + description: DevLink is the dev link for block devices + type: string + required: + - blockDeviceName + type: object + type: array + required: + - blockDevices + type: object + type: array + nodeSelector: + additionalProperties: + type: string + description: NodeSelector is the labels that will be used to + select a node for pool provisioning. Required field + type: object + poolConfig: + description: PoolConfig is the default pool config that applies + to the pool on node. + properties: + auxResources: + description: AuxResources are the compute resources required + by the cstor-pool pod side car containers. + nullable: true + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of + compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount + of compute resources required. If Requests is omitted + for a container, it defaults to Limits if that is + explicitly specified, otherwise to an implementation-defined + value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + compression: + description: 'Compression to enable compression Optional + -- defaults to off Possible values : lz, off' + type: string + dataRaidGroupType: + description: DataRaidGroupType is the raid type. + type: string + priorityClassName: + description: PriorityClassName if specified applies to this + pool pod If left empty, DefaultPriorityClassName is applied. + (See CStorPoolClusterSpec.DefaultPriorityClassName) If + both are empty, not priority class is applied. + nullable: true + type: string + resources: + description: Resources are the compute resources required + by the cstor-pool container. + nullable: true + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of + compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount + of compute resources required. If Requests is omitted + for a container, it defaults to Limits if that is + explicitly specified, otherwise to an implementation-defined + value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + roThresholdLimit: + description: 'ROThresholdLimit is threshold(percentage base) + limit for pool read only mode. If ROThresholdLimit(%) + amount of pool storage is reached then pool will set to + readonly. NOTE: 1. If ROThresholdLimit is set to 100 then + entire pool storage will be used by default it will be + set to 85%. 2. ROThresholdLimit value will be 0 <= ROThresholdLimit + <= 100.' + nullable: true + type: integer + thickProvision: + description: ThickProvision to enable thick provisioning + Optional -- defaults to false + type: boolean + tolerations: + description: Tolerations, if specified, the pool pod's tolerations. + items: + description: The pod this Toleration is attached to tolerates + any taint that matches the triple + using the matching operator . + properties: + effect: + description: Effect indicates the taint effect to + match. Empty means match all taint effects. When + specified, allowed values are NoSchedule, PreferNoSchedule + and NoExecute. + type: string + key: + description: Key is the taint key that the toleration + applies to. Empty means match all taint keys. If + the key is empty, operator must be Exists; this + combination means to match all values and all keys. + type: string + operator: + description: Operator represents a key's relationship + to the value. Valid operators are Exists and Equal. + Defaults to Equal. Exists is equivalent to wildcard + for value, so that a pod can tolerate all taints + of a particular category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period + of time the toleration (which must be of effect + NoExecute, otherwise this field is ignored) tolerates + the taint. By default, it is not set, which means + tolerate the taint forever (do not evict). Zero + and negative values will be treated as 0 (evict + immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration + matches to. If the operator is Exists, the value + should be empty, otherwise just a regular string. + type: string + type: object + nullable: true + type: array + writeCacheGroupType: + description: WriteCacheGroupType is the write cache raid + type. + type: string + required: + - dataRaidGroupType + type: object + writeCacheRaidGroups: + description: WriteCacheRaidGroups is the write cache raid group. + items: + description: RaidGroup contains the details of a raid group + for the pool + properties: + blockDevices: + items: + description: CStorPoolInstanceBlockDevice contains the + details of block devices that constitutes a raid group. + properties: + blockDeviceName: + description: BlockDeviceName is the name of the + block device. + type: string + capacity: + description: Capacity is the capacity of the block + device. It is system generated + format: int64 + type: integer + devLink: + description: DevLink is the dev link for block devices + type: string + required: + - blockDeviceName + type: object + type: array + required: + - blockDevices + type: object + nullable: true + type: array + required: + - dataRaidGroups + - nodeSelector + type: object + type: array + priorityClassName: + description: DefaultPriorityClassName if specified applies to all + the pool pods in the pool spec if the priorityClass at the pool + level is not specified. + type: string + resources: + description: DefaultResources are the compute resources required by + the cstor-pool container. If the resources at PoolConfig is not + specified, this is written to CSPI PoolConfig. + nullable: true + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute resources + allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + tolerations: + description: Tolerations, if specified, are the pool pod's tolerations + If tolerations at PoolConfig is empty, this is written to CSPI PoolConfig. + items: + description: The pod this Toleration is attached to tolerates any + taint that matches the triple using the matching + operator . + properties: + effect: + description: Effect indicates the taint effect to match. Empty + means match all taint effects. When specified, allowed values + are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Key is the taint key that the toleration applies + to. Empty means match all taint keys. If the key is empty, + operator must be Exists; this combination means to match all + values and all keys. + type: string + operator: + description: Operator represents a key's relationship to the + value. Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod + can tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period of time + the toleration (which must be of effect NoExecute, otherwise + this field is ignored) tolerates the taint. By default, it + is not set, which means tolerate the taint forever (do not + evict). Zero and negative values will be treated as 0 (evict + immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration matches + to. If the operator is Exists, the value should be empty, + otherwise just a regular string. + type: string + type: object + nullable: true + type: array + type: object + status: + description: CStorPoolClusterStatus represents the latest available observations + of a CSPC's current state. + properties: + conditions: + description: Current state of CSPC. + items: + description: CStorPoolClusterCondition describes the state of a + CSPC at a certain point. + properties: + lastTransitionTime: + description: Last time the condition transitioned from one status + to another. + format: date-time + type: string + lastUpdateTime: + description: The last time this condition was updated. + format: date-time + type: string + message: + description: A human readable message indicating details about + the transition. + type: string + reason: + description: The reason for the condition's last transition. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: Type of CSPC condition. + type: string + required: + - status + - type + type: object + nullable: true + type: array + desiredInstances: + description: DesiredInstances is the number of CSPI(s) that should + be provisioned. + format: int32 + nullable: true + type: integer + healthyInstances: + description: HealthyInstances is the number of CSPI(s) that are healthy. + format: int32 + nullable: true + type: integer + provisionedInstances: + description: ProvisionedInstances is the the number of CSPI present + at the current state. + format: int32 + nullable: true + type: integer + type: object + versionDetails: + description: VersionDetails provides the details for upgrade + properties: + autoUpgrade: + description: If AutoUpgrade is set to true then the resource is upgraded + automatically without any manual steps + type: boolean + desired: + description: Desired is the version that we want to upgrade or the + control plane version + type: string + status: + description: Status gives the status of reconciliation triggered when + the desired and current version are not same + properties: + current: + description: Current is the version of resource + type: string + dependentsUpgraded: + description: DependentsUpgraded gives the details whether all + children of a resource are upgraded to desired version or not + type: boolean + lastUpdateTime: + description: LastUpdateTime is the time the status was last updated + format: date-time + nullable: true + type: string + message: + description: Message is a human readable message if some error + occurs + type: string + reason: + description: Reason is the actual reason for the error state + type: string + state: + description: State is the state of reconciliation + type: string + type: object + type: object + required: + - spec + type: object + served: true + storage: true + subresources: {} diff --git a/helm/openebs/charts/cstor/crds/cstorpoolinstance.yaml b/helm/openebs/charts/cstor/crds/cstorpoolinstance.yaml new file mode 100644 index 0000000..4981ac0 --- /dev/null +++ b/helm/openebs/charts/cstor/crds/cstorpoolinstance.yaml @@ -0,0 +1,449 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.10.0 + creationTimestamp: null + name: cstorpoolinstances.cstor.openebs.io +spec: + group: cstor.openebs.io + names: + kind: CStorPoolInstance + listKind: CStorPoolInstanceList + plural: cstorpoolinstances + shortNames: + - cspi + singular: cstorpoolinstance + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Host name where cstorpool instances scheduled + jsonPath: .spec.hostName + name: HostName + type: string + - description: The amount of storage space within the pool that has been physically + allocated + jsonPath: .status.capacity.used + name: Allocated + priority: 1 + type: string + - description: The amount of usable free space available in the pool + jsonPath: .status.capacity.free + name: Free + type: string + - description: Total amount of usable space in pool + jsonPath: .status.capacity.total + name: Capacity + type: string + - description: Identifies the pool read only mode + jsonPath: .status.readOnly + name: ReadOnly + type: boolean + - description: Represents no.of replicas present in the pool + jsonPath: .status.provisionedReplicas + name: ProvisionedReplicas + type: integer + - description: Represents no.of healthy replicas present in the pool + jsonPath: .status.healthyReplicas + name: HealthyReplicas + type: integer + - description: Represents the type of the storage pool + jsonPath: .spec.poolConfig.dataRaidGroupType + name: Type + priority: 1 + type: string + - description: Identifies the current health of the pool + jsonPath: .status.phase + name: Status + type: string + - description: Age of CStorPoolInstance + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: CStorPoolInstance describes a cstor pool instance resource. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: Spec is the specification of the cstorpoolinstance resource. + properties: + dataRaidGroups: + description: DataRaidGroups is the raid group configuration for the + given pool. + items: + description: RaidGroup contains the details of a raid group for + the pool + properties: + blockDevices: + items: + description: CStorPoolInstanceBlockDevice contains the details + of block devices that constitutes a raid group. + properties: + blockDeviceName: + description: BlockDeviceName is the name of the block + device. + type: string + capacity: + description: Capacity is the capacity of the block device. + It is system generated + format: int64 + type: integer + devLink: + description: DevLink is the dev link for block devices + type: string + required: + - blockDeviceName + type: object + type: array + required: + - blockDevices + type: object + type: array + hostName: + description: HostName is the name of kubernetes node where the pool + should be created. + type: string + nodeSelector: + additionalProperties: + type: string + description: NodeSelector is the labels that will be used to select + a node for pool provisioning. Required field + type: object + poolConfig: + description: PoolConfig is the default pool config that applies to + the pool on node. + properties: + auxResources: + description: AuxResources are the compute resources required by + the cstor-pool pod side car containers. + nullable: true + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + compression: + description: 'Compression to enable compression Optional -- defaults + to off Possible values : lz, off' + type: string + dataRaidGroupType: + description: DataRaidGroupType is the raid type. + type: string + priorityClassName: + description: PriorityClassName if specified applies to this pool + pod If left empty, DefaultPriorityClassName is applied. (See + CStorPoolClusterSpec.DefaultPriorityClassName) If both are empty, + not priority class is applied. + nullable: true + type: string + resources: + description: Resources are the compute resources required by the + cstor-pool container. + nullable: true + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + roThresholdLimit: + description: 'ROThresholdLimit is threshold(percentage base) limit + for pool read only mode. If ROThresholdLimit(%) amount of pool + storage is reached then pool will set to readonly. NOTE: 1. + If ROThresholdLimit is set to 100 then entire pool storage will + be used by default it will be set to 85%. 2. ROThresholdLimit + value will be 0 <= ROThresholdLimit <= 100.' + nullable: true + type: integer + thickProvision: + description: ThickProvision to enable thick provisioning Optional + -- defaults to false + type: boolean + tolerations: + description: Tolerations, if specified, the pool pod's tolerations. + items: + description: The pod this Toleration is attached to tolerates + any taint that matches the triple using + the matching operator . + properties: + effect: + description: Effect indicates the taint effect to match. + Empty means match all taint effects. When specified, allowed + values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Key is the taint key that the toleration applies + to. Empty means match all taint keys. If the key is empty, + operator must be Exists; this combination means to match + all values and all keys. + type: string + operator: + description: Operator represents a key's relationship to + the value. Valid operators are Exists and Equal. Defaults + to Equal. Exists is equivalent to wildcard for value, + so that a pod can tolerate all taints of a particular + category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period of + time the toleration (which must be of effect NoExecute, + otherwise this field is ignored) tolerates the taint. + By default, it is not set, which means tolerate the taint + forever (do not evict). Zero and negative values will + be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration matches + to. If the operator is Exists, the value should be empty, + otherwise just a regular string. + type: string + type: object + nullable: true + type: array + writeCacheGroupType: + description: WriteCacheGroupType is the write cache raid type. + type: string + required: + - dataRaidGroupType + type: object + writeCacheRaidGroups: + description: WriteCacheRaidGroups is the write cache raid group. + items: + description: RaidGroup contains the details of a raid group for + the pool + properties: + blockDevices: + items: + description: CStorPoolInstanceBlockDevice contains the details + of block devices that constitutes a raid group. + properties: + blockDeviceName: + description: BlockDeviceName is the name of the block + device. + type: string + capacity: + description: Capacity is the capacity of the block device. + It is system generated + format: int64 + type: integer + devLink: + description: DevLink is the dev link for block devices + type: string + required: + - blockDeviceName + type: object + type: array + required: + - blockDevices + type: object + nullable: true + type: array + required: + - dataRaidGroups + - nodeSelector + type: object + status: + description: Status is the possible statuses of the cstorpoolinstance + resource. + properties: + capacity: + description: Capacity describes the capacity details of a cstor pool + properties: + free: + anyOf: + - type: integer + - type: string + description: Amount of usable space in the pool after excluding + metadata and raid parity + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + total: + anyOf: + - type: integer + - type: string + description: Sum of usable capacity in all the data raidgroups + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + used: + anyOf: + - type: integer + - type: string + description: Amount of physical data (and its metadata) written + to pool after applying compression, etc.., + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + zfs: + description: ZFSCapacityAttributes contains advanced information + about pool capacity details + properties: + logicalUsed: + anyOf: + - type: integer + - type: string + description: LogicalUsed is the amount of space that is "logically" + consumed by this pool and all its descendents. The logical + space ignores the effect of the compression and copies properties, + giving a quantity closer to the amount of data that applications + see. However, it does include space consumed by metadata. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + required: + - logicalUsed + type: object + required: + - free + - total + - used + - zfs + type: object + conditions: + description: Current state of CSPI with details. + items: + description: CSPIConditionType describes the state of a CSPI at + a certain point. + properties: + lastTransitionTime: + description: Last time the condition transitioned from one status + to another. + format: date-time + type: string + lastUpdateTime: + description: The last time this condition was updated. + format: date-time + type: string + message: + description: A human readable message indicating details about + the transition. + type: string + reason: + description: The reason for the condition's last transition. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: Type of CSPC condition. + type: string + required: + - status + - type + type: object + type: array + healthyReplicas: + description: HealthyReplicas describes the total count of healthy + Volume Replicas in the cstor pool + format: int32 + type: integer + phase: + description: The phase of a CStorPool is a simple, high-level summary + of the pool state on the node. + type: string + provisionedReplicas: + description: ProvisionedReplicas describes the total count of Volume + Replicas present in the cstor pool + format: int32 + type: integer + readOnly: + description: ReadOnly if pool is readOnly or not + type: boolean + required: + - healthyReplicas + - provisionedReplicas + - readOnly + type: object + versionDetails: + description: VersionDetails is the openebs version. + properties: + autoUpgrade: + description: If AutoUpgrade is set to true then the resource is upgraded + automatically without any manual steps + type: boolean + desired: + description: Desired is the version that we want to upgrade or the + control plane version + type: string + status: + description: Status gives the status of reconciliation triggered when + the desired and current version are not same + properties: + current: + description: Current is the version of resource + type: string + dependentsUpgraded: + description: DependentsUpgraded gives the details whether all + children of a resource are upgraded to desired version or not + type: boolean + lastUpdateTime: + description: LastUpdateTime is the time the status was last updated + format: date-time + nullable: true + type: string + message: + description: Message is a human readable message if some error + occurs + type: string + reason: + description: Reason is the actual reason for the error state + type: string + state: + description: State is the state of reconciliation + type: string + type: object + type: object + required: + - spec + type: object + served: true + storage: true + subresources: {} diff --git a/helm/openebs/charts/cstor/crds/cstorrestore.yaml b/helm/openebs/charts/cstor/crds/cstorrestore.yaml new file mode 100644 index 0000000..26963df --- /dev/null +++ b/helm/openebs/charts/cstor/crds/cstorrestore.yaml @@ -0,0 +1,100 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.10.0 + creationTimestamp: null + name: cstorrestores.cstor.openebs.io +spec: + group: cstor.openebs.io + names: + kind: CStorRestore + listKind: CStorRestoreList + plural: cstorrestores + shortNames: + - crestore + singular: cstorrestore + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Name of the snapshot which is restored + jsonPath: .spec.restoreName + name: Backup + type: string + - description: Volume on which restore is performed + jsonPath: .spec.volumeName + name: Volume + type: string + - description: Identifies the state of the restore + jsonPath: .status + name: Status + type: string + name: v1 + schema: + openAPIV3Schema: + description: CStorRestore describes a cstor restore resource created as a + custom resource + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: CStorRestoreSpec is the spec for a CStorRestore resource + properties: + localRestore: + description: Local defines whether restore is from local/remote + type: boolean + maxretrycount: + description: MaxRestoreRetryCount is the maximum number of attempt, + will be performed to restore + type: integer + restoreName: + description: RestoreName holds restore name + type: string + restoreSrc: + description: RestoreSrc can be ip:port in case of restore from remote + or volumeName in case of local restore + type: string + retrycount: + description: RetryCount represents the number of restore attempts + performed for the restore + type: integer + size: + anyOf: + - type: integer + - type: string + description: Size represents the size of a snapshot to restore + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + storageClass: + description: StorageClass represents name of StorageClass of restore + volume + type: string + volumeName: + description: VolumeName is used to restore the data to corresponding + volume + type: string + required: + - restoreName + - restoreSrc + - volumeName + type: object + status: + description: CStorRestoreStatus is a string type that represents the status + of the restore + type: string + required: + - spec + type: object + served: true + storage: true + subresources: {} diff --git a/helm/openebs/charts/cstor/crds/cstorvolume.yaml b/helm/openebs/charts/cstor/crds/cstorvolume.yaml new file mode 100644 index 0000000..9d7d19e --- /dev/null +++ b/helm/openebs/charts/cstor/crds/cstorvolume.yaml @@ -0,0 +1,265 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.10.0 + creationTimestamp: null + name: cstorvolumes.cstor.openebs.io +spec: + group: cstor.openebs.io + names: + kind: CStorVolume + listKind: CStorVolumeList + plural: cstorvolumes + shortNames: + - cv + singular: cstorvolume + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Current volume capacity + jsonPath: .status.capacity + name: Capacity + type: string + - description: Identifies the current health of the volume + jsonPath: .status.phase + name: Status + type: string + - description: Age of CStorVolume + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: CStorVolume describes a cstor volume resource created as custom + resource + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: CStorVolumeSpec is the spec for a CStorVolume resource + properties: + capacity: + anyOf: + - type: integer + - type: string + description: Capacity represents the desired size of the underlying + volume. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + consistencyFactor: + description: ConsistencyFactor is minimum number of volume replicas + i.e. `RF/2 + 1` has to be connected to the target for write operations. + Basically more then 50% of replica has to be connected to target. + type: integer + desiredReplicationFactor: + description: DesiredReplicationFactor represents maximum number of + replicas that are allowed to connect to the target. Required for + scale operations + type: integer + iqn: + description: Target iSCSI Qualified Name.combination of nodeBase + type: string + replicaDetails: + description: ReplicaDetails refers to the trusty replica information + properties: + knownReplicas: + additionalProperties: + type: string + description: KnownReplicas represents the replicas that target + can trust to read data + type: object + type: object + replicationFactor: + description: ReplicationFactor represents number of volume replica + created during volume provisioning connect to the target + type: integer + targetIP: + description: TargetIP IP of the iSCSI target service + type: string + targetPort: + description: iSCSI Target Port typically TCP ports 3260 + type: string + targetPortal: + description: iSCSI Target Portal. The Portal is combination of IP:port + (typically TCP ports 3260) + type: string + type: object + status: + description: CStorVolumeStatus is for handling status of cvr. + properties: + capacity: + anyOf: + - type: integer + - type: string + description: Represents the actual capacity of the underlying volume. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + conditions: + description: Current Condition of cstorvolume. If underlying persistent + volume is being resized then the Condition will be set to 'ResizePending'. + items: + description: CStorVolumeCondition contains details about state of + cstorvolume + properties: + lastProbeTime: + description: Last time we probed the condition. + format: date-time + type: string + lastTransitionTime: + description: Last time the condition transitioned from one status + to another. + format: date-time + type: string + message: + description: Human-readable message indicating details about + last transition. + type: string + reason: + description: Unique, this should be a short, machine understandable + string that gives the reason for condition's last transition. + If it reports "ResizePending" that means the underlying cstorvolume + is being resized. + type: string + status: + description: ConditionStatus states in which state condition + is present + type: string + type: + description: CStorVolumeConditionType is a valid value of CStorVolumeCondition.Type + type: string + required: + - status + - type + type: object + type: array + lastTransitionTime: + description: LastTransitionTime refers to the time when the phase + changes + format: date-time + nullable: true + type: string + lastUpdateTime: + description: LastUpdateTime refers to the time when last status updated + due to any operations + format: date-time + nullable: true + type: string + message: + description: A human-readable message indicating details about why + the volume is in this state. + type: string + phase: + description: CStorVolumePhase is to hold result of action. + type: string + replicaDetails: + description: ReplicaDetails refers to the trusty replica information + properties: + knownReplicas: + additionalProperties: + type: string + description: KnownReplicas represents the replicas that target + can trust to read data + type: object + type: object + replicaStatuses: + items: + description: ReplicaStatus stores the status of replicas + properties: + checkpointedIOSeq: + description: Represents IO number of replica persisted on the + disk + type: string + inflightRead: + description: Ongoing reads I/O from target to replica + type: string + inflightSync: + description: Ongoing sync I/O from target to replica + type: string + inflightWrite: + description: ongoing writes I/O from target to replica + type: string + mode: + description: Mode represents replica status i.e. Healthy, Degraded + type: string + quorum: + description: 'Quorum indicates wheather data wrtitten to the + replica is lost or exists. "0" means: data has been lost( + might be ephimeral case) and will recostruct data from other + Healthy replicas in a write-only mode 1 means: written data + is exists on replica' + type: string + replicaId: + description: ID is replica unique identifier + type: string + upTime: + description: time since the replica connected to target + type: integer + required: + - checkpointedIOSeq + - inflightRead + - inflightSync + - inflightWrite + - mode + - quorum + - replicaId + - upTime + type: object + type: array + type: object + versionDetails: + description: VersionDetails provides the details for upgrade + properties: + autoUpgrade: + description: If AutoUpgrade is set to true then the resource is upgraded + automatically without any manual steps + type: boolean + desired: + description: Desired is the version that we want to upgrade or the + control plane version + type: string + status: + description: Status gives the status of reconciliation triggered when + the desired and current version are not same + properties: + current: + description: Current is the version of resource + type: string + dependentsUpgraded: + description: DependentsUpgraded gives the details whether all + children of a resource are upgraded to desired version or not + type: boolean + lastUpdateTime: + description: LastUpdateTime is the time the status was last updated + format: date-time + nullable: true + type: string + message: + description: Message is a human readable message if some error + occurs + type: string + reason: + description: Reason is the actual reason for the error state + type: string + state: + description: State is the state of reconciliation + type: string + type: object + type: object + required: + - spec + type: object + served: true + storage: true + subresources: {} diff --git a/helm/openebs/charts/cstor/crds/cstorvolumeattachment.yaml b/helm/openebs/charts/cstor/crds/cstorvolumeattachment.yaml new file mode 100644 index 0000000..b4b163e --- /dev/null +++ b/helm/openebs/charts/cstor/crds/cstorvolumeattachment.yaml @@ -0,0 +1,122 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.10.0 + creationTimestamp: null + name: cstorvolumeattachments.cstor.openebs.io +spec: + group: cstor.openebs.io + names: + kind: CStorVolumeAttachment + listKind: CStorVolumeAttachmentList + plural: cstorvolumeattachments + shortNames: + - cva + singular: cstorvolumeattachment + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + description: CStorVolumeAttachment represents a CSI based volume + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: CStorVolumeAttachmentSpec is the spec for a CStorVolume resource + properties: + iscsi: + description: ISCSIInfo specific to ISCSI protocol, this is filled + only if the volume type is iSCSI + properties: + iqn: + description: Iqn of this volume + type: string + iscsiInterface: + description: IscsiInterface of this volume + type: string + lun: + description: 'Lun specify the lun number 0, 1.. on iSCSI Volume. + (default: 0)' + type: string + targetPortal: + description: TargetPortal holds the target portal of this volume + type: string + type: object + volume: + description: Volume specific info + properties: + accessModes: + description: AccessMode of a volume will hold the access mode + of the volume + items: + type: string + type: array + accessType: + description: AccessType of a volume will indicate if the volume + will be used as a block device or mounted on a path + type: string + capacity: + description: Capacity of the volume + type: string + devicePath: + description: Device Path specifies the device path which is returned + when the iSCSI login is successful + type: string + fsType: + description: FSType of a volume will specify the format type - + ext4(default), xfs of PV + type: string + mountOptions: + description: MountOptions specifies the options with which mount + needs to be attempted + items: + type: string + type: array + name: + description: Name of the CSI volume + type: string + ownerNodeID: + description: OwnerNodeID is the Node ID which is also the owner + of this Volume + type: string + readOnly: + description: ReadOnly specifies if the volume needs to be mounted + in ReadOnly mode + type: boolean + stagingTargetPath: + description: StagingPath of the volume will hold the path on which + the volume is mounted on that node + type: string + targetPath: + description: TargetPath of the volume will hold the path on which + the volume is bind mounted on that node + type: string + required: + - name + - ownerNodeID + type: object + required: + - iscsi + - volume + type: object + status: + description: CStorVolumeAttachmentStatus status represents the current + mount status of the volume + type: string + required: + - spec + type: object + served: true + storage: true diff --git a/helm/openebs/charts/cstor/crds/cstorvolumeconfig.yaml b/helm/openebs/charts/cstor/crds/cstorvolumeconfig.yaml new file mode 100644 index 0000000..4642a9b --- /dev/null +++ b/helm/openebs/charts/cstor/crds/cstorvolumeconfig.yaml @@ -0,0 +1,758 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.10.0 + creationTimestamp: null + name: cstorvolumeconfigs.cstor.openebs.io +spec: + group: cstor.openebs.io + names: + kind: CStorVolumeConfig + listKind: CStorVolumeConfigList + plural: cstorvolumeconfigs + shortNames: + - cvc + singular: cstorvolumeconfig + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Identifies the volume capacity + jsonPath: .status.capacity.storage + name: Capacity + type: string + - description: Identifies the volume provisioning status + jsonPath: .status.phase + name: Status + type: string + - description: Age of CStorVolumeReplica + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: CStorVolumeConfig describes a cstor volume config resource created + as custom resource. CStorVolumeConfig is a request for creating cstor volume + related resources like deployment, svc etc. + 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 + publish: + description: Publish contains info related to attachment of a volume to + a node. i.e. NodeId etc. + properties: + nodeId: + description: NodeID contains publish info related to attachment of + a volume to a node. + type: string + type: object + spec: + description: Spec defines a specification of a cstor volume config required + to provisione cstor volume resources + properties: + capacity: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: Capacity represents the actual resources of the underlying + cstor volume. + type: object + cstorVolumeRef: + description: CStorVolumeRef has the information about where CstorVolumeClaim + is created from. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: 'If referring to a piece of an object instead of + an entire object, this string should contain a valid JSON/Go + field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within + a pod, this would take on a value like: "spec.containers{name}" + (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" + (container with index 2 in this pod). This syntax is chosen + only to have some well-defined way of referencing a part of + an object. TODO: this design is not final and this field is + subject to change in the future.' + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: 'Specific resourceVersion to which this reference + is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + x-kubernetes-map-type: atomic + cstorVolumeSource: + description: CStorVolumeSource contains the source volumeName@snapShotname + combaination. This will be filled only if it is a clone creation. + type: string + policy: + description: Policy contains volume specific required policies target + and replicas + properties: + provision: + description: replicaAffinity is set to true then volume replica + resources need to be distributed across the pool instances + properties: + blockSize: + description: BlockSize is the logical block size in multiple + of 512 bytes BlockSize specifies the block size of the volume. + The blocksize cannot be changed once the volume has been + written, so it should be set at volume creation time. The + default blocksize for volumes is 4 Kbytes. Any power of + 2 from 512 bytes to 128 Kbytes is valid. + format: int32 + type: integer + replicaAffinity: + description: replicaAffinity is set to true then volume replica + resources need to be distributed across the cstor pool instances + based on the given topology + type: boolean + required: + - replicaAffinity + type: object + replica: + description: ReplicaSpec represents configuration related to replicas + resources + properties: + compression: + description: The zle compression algorithm compresses runs + of zeros. + type: string + zvolWorkers: + description: IOWorkers represents number of threads that executes + client IOs + type: string + type: object + replicaPoolInfo: + description: 'ReplicaPoolInfo holds the pool information of volume + replicas. Ex: If volume is provisioned on which CStor pool volume + replicas exist' + items: + description: ReplicaPoolInfo represents the pool information + of volume replica + properties: + poolName: + description: PoolName represents the pool name where volume + replica exists + type: string + required: + - poolName + type: object + type: array + target: + description: TargetSpec represents configuration related to cstor + target and its resources + properties: + affinity: + description: PodAffinity if specified, are the target pod's + affinities + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods + to nodes that satisfy the affinity expressions specified + by this field, but it may choose a node that violates + one or more of the expressions. The node that is most + preferred is the one with the greatest sum of weights, + i.e. for each node that meets all of the scheduling + requirements (resource request, requiredDuringScheduling + affinity expressions, etc.), compute a sum by iterating + through the elements of this field and adding "weight" + to the sum if the node has pods which matches the corresponding + podAffinityTerm; the node(s) with the highest sum are + the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied + to the union of the namespaces selected by + this field and the ones listed in the namespaces + field. null selector and null or empty namespaces + list means "this pod's namespace". An empty + selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. + The term is applied to the union of the namespaces + listed in this field and the ones selected + by namespaceSelector. null or empty namespaces + list and null namespaceSelector means "this + pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the + pods matching the labelSelector in the specified + namespaces, where co-located is defined as + running on a node whose value of the label + with key topologyKey matches that of any node + on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the + corresponding podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by + this field are not met at scheduling time, the pod will + not be scheduled onto the node. If the affinity requirements + specified by this field cease to be met at some point + during pod execution (e.g. due to a pod label update), + the system may or may not try to eventually evict the + pod from its node. When there are multiple elements, + the lists of nodes corresponding to each podAffinityTerm + are intersected, i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not + co-located (anti-affinity) with, where co-located + is defined as running on a node whose value of the + label with key matches that of any node + on which a pod of the set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied + to the union of the namespaces selected by this + field and the ones listed in the namespaces field. + null selector and null or empty namespaces list + means "this pod's namespace". An empty selector + ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. The + term is applied to the union of the namespaces + listed in this field and the ones selected by + namespaceSelector. null or empty namespaces list + and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey + matches that of any node on which any of the selected + pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + auxResources: + description: AuxResources are the compute resources required + by the cstor-target pod side car containers. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of + compute resources required. If Requests is omitted for + a container, it defaults to Limits if that is explicitly + specified, otherwise to an implementation-defined value. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + luWorkers: + description: IOWorkers sets the number of threads that are + working on above queue + format: int64 + type: integer + monitor: + description: Monitor enables or disables the target exporter + sidecar + type: boolean + nodeSelector: + additionalProperties: + type: string + description: NodeSelector is the labels that will be used + to select a node for target pod scheduleing Required field + type: object + priorityClassName: + description: PriorityClassName if specified applies to this + target pod If left empty, no priority class is applied. + type: string + queueDepth: + description: QueueDepth sets the queue size at iSCSI target + which limits the ongoing IO count from client + type: string + replicationFactor: + description: ReplicationFactor represents maximum number of + replicas that are allowed to connect to the target + format: int64 + type: integer + resources: + description: Resources are the compute resources required + by the cstor-target container. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of + compute resources required. If Requests is omitted for + a container, it defaults to Limits if that is explicitly + specified, otherwise to an implementation-defined value. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + tolerations: + description: Tolerations, if specified, are the target pod's + tolerations + items: + description: The pod this Toleration is attached to tolerates + any taint that matches the triple using + the matching operator . + properties: + effect: + description: Effect indicates the taint effect to match. + Empty means match all taint effects. When specified, + allowed values are NoSchedule, PreferNoSchedule and + NoExecute. + type: string + key: + description: Key is the taint key that the toleration + applies to. Empty means match all taint keys. If the + key is empty, operator must be Exists; this combination + means to match all values and all keys. + type: string + operator: + description: Operator represents a key's relationship + to the value. Valid operators are Exists and Equal. + Defaults to Equal. Exists is equivalent to wildcard + for value, so that a pod can tolerate all taints of + a particular category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period + of time the toleration (which must be of effect NoExecute, + otherwise this field is ignored) tolerates the taint. + By default, it is not set, which means tolerate the + taint forever (do not evict). Zero and negative values + will be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration + matches to. If the operator is Exists, the value should + be empty, otherwise just a regular string. + type: string + type: object + type: array + type: object + type: object + provision: + description: Provision represents the initial volume configuration + for the underlying cstor volume based on the persistent volume request + by user. Provision properties are immutable + properties: + capacity: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: Capacity represents initial capacity of volume replica + required during volume clone operations to maintain some metadata + info related to child resources like snapshot, cloned volumes. + type: object + replicaCount: + description: ReplicaCount represents initial cstor volume replica + count, its will not be updated later on based on scale up/down + operations, only readonly operations and validations. + type: integer + required: + - capacity + - replicaCount + type: object + required: + - capacity + - policy + - provision + type: object + status: + description: Status represents the current information/status for the + cstor volume config, populated by the controller. + properties: + capacity: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: Capacity the actual resources of the underlying volume. + type: object + condition: + items: + description: CStorVolumeConfigCondition contains details about state + of cstor volume + properties: + lastProbeTime: + description: Last time we probed the condition. + format: date-time + type: string + lastTransitionTime: + description: Last time the condition transitioned from one status + to another. + format: date-time + type: string + message: + description: Human-readable message indicating details about + last transition. + type: string + reason: + description: Reason is a brief CamelCase string that describes + any failure + type: string + type: + description: Current Condition of cstor volume config. If underlying + persistent volume is being resized then the Condition will + be set to 'ResizeStarted' etc + type: string + required: + - message + - reason + - type + type: object + type: array + phase: + description: Phase represents the current phase of CStorVolumeConfig. + type: string + poolInfo: + description: PoolInfo represents current pool names where volume replicas + exists + items: + type: string + type: array + type: object + versionDetails: + description: VersionDetails provides the details for upgrade + properties: + autoUpgrade: + description: If AutoUpgrade is set to true then the resource is upgraded + automatically without any manual steps + type: boolean + desired: + description: Desired is the version that we want to upgrade or the + control plane version + type: string + status: + description: Status gives the status of reconciliation triggered when + the desired and current version are not same + properties: + current: + description: Current is the version of resource + type: string + dependentsUpgraded: + description: DependentsUpgraded gives the details whether all + children of a resource are upgraded to desired version or not + type: boolean + lastUpdateTime: + description: LastUpdateTime is the time the status was last updated + format: date-time + nullable: true + type: string + message: + description: Message is a human readable message if some error + occurs + type: string + reason: + description: Reason is the actual reason for the error state + type: string + state: + description: State is the state of reconciliation + type: string + type: object + type: object + required: + - spec + - status + - versionDetails + type: object + served: true + storage: true + subresources: {} diff --git a/helm/openebs/charts/cstor/crds/cstorvolumepolicy.yaml b/helm/openebs/charts/cstor/crds/cstorvolumepolicy.yaml new file mode 100644 index 0000000..a706f0b --- /dev/null +++ b/helm/openebs/charts/cstor/crds/cstorvolumepolicy.yaml @@ -0,0 +1,536 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.10.0 + creationTimestamp: null + name: cstorvolumepolicies.cstor.openebs.io +spec: + group: cstor.openebs.io + names: + kind: CStorVolumePolicy + listKind: CStorVolumePolicyList + plural: cstorvolumepolicies + shortNames: + - cvp + singular: cstorvolumepolicy + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + description: CStorVolumePolicy describes a configuration required for cstor + volume resources + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: Spec defines a configuration info of a cstor volume required + to provisione cstor volume resources + properties: + provision: + description: replicaAffinity is set to true then volume replica resources + need to be distributed across the pool instances + properties: + blockSize: + description: BlockSize is the logical block size in multiple of + 512 bytes BlockSize specifies the block size of the volume. + The blocksize cannot be changed once the volume has been written, + so it should be set at volume creation time. The default blocksize + for volumes is 4 Kbytes. Any power of 2 from 512 bytes to 128 + Kbytes is valid. + format: int32 + type: integer + replicaAffinity: + description: replicaAffinity is set to true then volume replica + resources need to be distributed across the cstor pool instances + based on the given topology + type: boolean + required: + - replicaAffinity + type: object + replica: + description: ReplicaSpec represents configuration related to replicas + resources + properties: + compression: + description: The zle compression algorithm compresses runs of + zeros. + type: string + zvolWorkers: + description: IOWorkers represents number of threads that executes + client IOs + type: string + type: object + replicaPoolInfo: + description: 'ReplicaPoolInfo holds the pool information of volume + replicas. Ex: If volume is provisioned on which CStor pool volume + replicas exist' + items: + description: ReplicaPoolInfo represents the pool information of + volume replica + properties: + poolName: + description: PoolName represents the pool name where volume + replica exists + type: string + required: + - poolName + type: object + type: array + target: + description: TargetSpec represents configuration related to cstor + target and its resources + properties: + affinity: + description: PodAffinity if specified, are the target pod's affinities + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to + nodes that satisfy the affinity expressions specified by + this field, but it may choose a node that violates one or + more of the expressions. The node that is most preferred + is the one with the greatest sum of weights, i.e. for each + node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, + etc.), compute a sum by iterating through the elements of + this field and adding "weight" to the sum if the node has + pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied + to the union of the namespaces selected by this + field and the ones listed in the namespaces field. + null selector and null or empty namespaces list + means "this pod's namespace". An empty selector + ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. The + term is applied to the union of the namespaces + listed in this field and the ones selected by + namespaceSelector. null or empty namespaces list + and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey + matches that of any node on which any of the selected + pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the corresponding + podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by this + field are not met at scheduling time, the pod will not be + scheduled onto the node. If the affinity requirements specified + by this field cease to be met at some point during pod execution + (e.g. due to a pod label update), the system may or may + not try to eventually evict the pod from its node. When + there are multiple elements, the lists of nodes corresponding + to each podAffinityTerm are intersected, i.e. all terms + must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not co-located + (anti-affinity) with, where co-located is defined as running + on a node whose value of the label with key + matches that of any node on which a pod of the set of + pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied to the + union of the namespaces selected by this field and + the ones listed in the namespaces field. null selector + and null or empty namespaces list means "this pod's + namespace". An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static list of namespace + names that the term applies to. The term is applied + to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. null or + empty namespaces list and null namespaceSelector means + "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where + co-located is defined as running on a node whose value + of the label with key topologyKey matches that of + any node on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + auxResources: + description: AuxResources are the compute resources required by + the cstor-target pod side car containers. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + luWorkers: + description: IOWorkers sets the number of threads that are working + on above queue + format: int64 + type: integer + monitor: + description: Monitor enables or disables the target exporter sidecar + type: boolean + nodeSelector: + additionalProperties: + type: string + description: NodeSelector is the labels that will be used to select + a node for target pod scheduleing Required field + type: object + priorityClassName: + description: PriorityClassName if specified applies to this target + pod If left empty, no priority class is applied. + type: string + queueDepth: + description: QueueDepth sets the queue size at iSCSI target which + limits the ongoing IO count from client + type: string + replicationFactor: + description: ReplicationFactor represents maximum number of replicas + that are allowed to connect to the target + format: int64 + type: integer + resources: + description: Resources are the compute resources required by the + cstor-target container. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + tolerations: + description: Tolerations, if specified, are the target pod's tolerations + items: + description: The pod this Toleration is attached to tolerates + any taint that matches the triple using + the matching operator . + properties: + effect: + description: Effect indicates the taint effect to match. + Empty means match all taint effects. When specified, allowed + values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Key is the taint key that the toleration applies + to. Empty means match all taint keys. If the key is empty, + operator must be Exists; this combination means to match + all values and all keys. + type: string + operator: + description: Operator represents a key's relationship to + the value. Valid operators are Exists and Equal. Defaults + to Equal. Exists is equivalent to wildcard for value, + so that a pod can tolerate all taints of a particular + category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period of + time the toleration (which must be of effect NoExecute, + otherwise this field is ignored) tolerates the taint. + By default, it is not set, which means tolerate the taint + forever (do not evict). Zero and negative values will + be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration matches + to. If the operator is Exists, the value should be empty, + otherwise just a regular string. + type: string + type: object + type: array + type: object + type: object + status: + description: CStorVolumePolicyStatus is for handling status of CstorVolumePolicy + properties: + phase: + type: string + type: object + required: + - spec + type: object + served: true + storage: true diff --git a/helm/openebs/charts/cstor/crds/cstorvolumereplica.yaml b/helm/openebs/charts/cstor/crds/cstorvolumereplica.yaml new file mode 100644 index 0000000..5ce7957 --- /dev/null +++ b/helm/openebs/charts/cstor/crds/cstorvolumereplica.yaml @@ -0,0 +1,210 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.10.0 + creationTimestamp: null + name: cstorvolumereplicas.cstor.openebs.io +spec: + group: cstor.openebs.io + names: + kind: CStorVolumeReplica + listKind: CStorVolumeReplicaList + plural: cstorvolumereplicas + shortNames: + - cvr + singular: cstorvolumereplica + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: The amount of disk space consumed by a dataset and all its descendents + jsonPath: .status.capacity.total + name: Allocated + type: string + - description: The amount of space that is logically consumed by this dataset + jsonPath: .status.capacity.used + name: Used + type: string + - description: Identifies the current state of the replicas + jsonPath: .status.phase + name: Status + type: string + - description: Age of CStorVolumeReplica + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: CStorVolumeReplica describes a cstor volume resource created + as custom resource + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: CStorVolumeReplicaSpec is the spec for a CStorVolumeReplica + resource + properties: + blockSize: + description: BlockSize is the logical block size in multiple of 512 + bytes BlockSize specifies the block size of the volume. The blocksize + cannot be changed once the volume has been written, so it should + be set at volume creation time. The default blocksize for volumes + is 4 Kbytes. Any power of 2 from 512 bytes to 128 Kbytes is valid. + format: int32 + type: integer + capacity: + description: Represents the actual capacity of the underlying volume + type: string + compression: + description: 'Controls the compression algorithm used for this volumes + examples: on|off|gzip|gzip-N|lz4|lzjb|zle' + type: string + replicaid: + description: ReplicaID is unique number to identify the replica + type: string + targetIP: + description: TargetIP represents iscsi target IP through which replica + cummunicates IO workloads and other volume operations like snapshot + and resize requests + type: string + zvolWorkers: + description: ZvolWorkers represents number of threads that executes + client IOs + type: string + type: object + status: + description: CStorVolumeReplicaStatus is for handling status of cvr. + properties: + capacity: + description: CStorVolumeCapacityDetails represents capacity info of + replica + properties: + total: + description: The amount of space consumed by this volume replica + and all its descendents + type: string + used: + description: The amount of space that is "logically" accessible + by this dataset. The logical space ignores the effect of the + compression and copies properties, giving a quantity closer + to the amount of data that applications see. However, it does + include space consumed by metadata + type: string + required: + - total + - used + type: object + lastTransitionTime: + description: LastTransitionTime refers to the time when the phase + changes + format: date-time + nullable: true + type: string + lastUpdateTime: + description: The last updated time + format: date-time + nullable: true + type: string + message: + description: A human readable message indicating details about the + transition. + type: string + pendingSnapshots: + additionalProperties: + description: CStorSnapshotInfo represents the snapshot information + related to particular snapshot + properties: + logicalReferenced: + description: LogicalReferenced describes the amount of space + that is "logically" accessable by this snapshot. This logical + space ignores the effect of the compression and copies properties, + giving a quantity closer to the amount of data that application + see. It also includes space consumed by metadata. + format: int64 + type: integer + required: + - logicalReferenced + type: object + description: PendingSnapshots contains list of pending snapshots that + are not yet available on this replica + type: object + phase: + description: CStorVolumeReplicaPhase is to holds different phases + of replica + type: string + snapshots: + additionalProperties: + description: CStorSnapshotInfo represents the snapshot information + related to particular snapshot + properties: + logicalReferenced: + description: LogicalReferenced describes the amount of space + that is "logically" accessable by this snapshot. This logical + space ignores the effect of the compression and copies properties, + giving a quantity closer to the amount of data that application + see. It also includes space consumed by metadata. + format: int64 + type: integer + required: + - logicalReferenced + type: object + description: Snapshots contains list of snapshots, and their properties, + created on CVR + type: object + type: object + versionDetails: + description: VersionDetails provides the details for upgrade + properties: + autoUpgrade: + description: If AutoUpgrade is set to true then the resource is upgraded + automatically without any manual steps + type: boolean + desired: + description: Desired is the version that we want to upgrade or the + control plane version + type: string + status: + description: Status gives the status of reconciliation triggered when + the desired and current version are not same + properties: + current: + description: Current is the version of resource + type: string + dependentsUpgraded: + description: DependentsUpgraded gives the details whether all + children of a resource are upgraded to desired version or not + type: boolean + lastUpdateTime: + description: LastUpdateTime is the time the status was last updated + format: date-time + nullable: true + type: string + message: + description: Message is a human readable message if some error + occurs + type: string + reason: + description: Reason is the actual reason for the error state + type: string + state: + description: State is the state of reconciliation + type: string + type: object + type: object + required: + - spec + type: object + served: true + storage: true + subresources: {} diff --git a/helm/openebs/charts/cstor/crds/migrationtask.yaml b/helm/openebs/charts/cstor/crds/migrationtask.yaml new file mode 100644 index 0000000..4dd2e54 --- /dev/null +++ b/helm/openebs/charts/cstor/crds/migrationtask.yaml @@ -0,0 +1,128 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.0 + creationTimestamp: null + name: migrationtasks.openebs.io +spec: + group: openebs.io + names: + kind: MigrationTask + listKind: MigrationTaskList + plural: migrationtasks + shortNames: + - mtask + singular: migrationtask + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: MigrationTask represents an migration task + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: Spec i.e. specifications of the MigrationTask + properties: + cstorPool: + description: MigrateCStorPool contains the details of the cstor pool + to be migrated + properties: + rename: + description: If a CSPC with the same name as SPC already exists + then we can rename SPC during migration using Rename + type: string + spcName: + description: SPCName contains the name of the storage pool claim + to be migrated + type: string + type: object + cstorVolume: + description: MigrateCStorVolume contains the details of the cstor + volume to be migrated + properties: + pvName: + description: PVName contains the name of the pv associated with + the cstor volume to be migrated + type: string + type: object + type: object + status: + description: Status of MigrationTask + properties: + completedTime: + description: CompletedTime of Migrate + format: date-time + nullable: true + type: string + migrationDetailedStatuses: + description: MigrationDetailedStatuses contains the list of statuses + of each step + items: + description: MigrationDetailedStatuses represents the latest available + observations of a MigrationTask current state. + properties: + lastUpdatedAt: + description: LastUpdatedTime of a MigrateStep + format: date-time + nullable: true + type: string + message: + description: A human-readable message indicating details about + why the migrationStep is in this state + type: string + phase: + description: Phase indicates if the MigrateStep is waiting, + errored or completed. + type: string + reason: + description: Reason is a brief CamelCase string that describes + any failure and is meant for machine parsing and tidy display + in the CLI + type: string + startTime: + description: StartTime of a MigrateStep + format: date-time + nullable: true + type: string + step: + type: string + type: object + type: array + phase: + description: Phase indicates if a migrationTask is started, success + or errored + type: string + retries: + description: Retries is the number of times the job attempted to migration + the resource + type: integer + startTime: + description: StartTime of Migrate + format: date-time + nullable: true + type: string + type: object + required: + - spec + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/helm/openebs/charts/cstor/crds/upgradetask.yaml b/helm/openebs/charts/cstor/crds/upgradetask.yaml new file mode 100644 index 0000000..ab35065 --- /dev/null +++ b/helm/openebs/charts/cstor/crds/upgradetask.yaml @@ -0,0 +1,257 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.0 + creationTimestamp: null + name: upgradetasks.openebs.io +spec: + group: openebs.io + names: + kind: UpgradeTask + listKind: UpgradeTaskList + plural: upgradetasks + singular: upgradetask + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: UpgradeTask represents an upgrade task + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: Spec i.e. specifications of the UpgradeTask + properties: + cstorPool: + description: CStorPool contains the details of the cstor pool to be + upgraded + properties: + options: + description: Options can be used to change the default behaviour + of upgrade + properties: + ignoreStepsOnError: + description: IgnoreStepsOnError allows to ignore steps which + failed + items: + type: string + type: array + type: object + poolName: + description: PoolName contains the name of the cstor pool to be + upgraded + type: string + type: object + cstorPoolCluster: + description: CStorPoolCluster contains the details of the storage + pool claim to be upgraded + properties: + cspcName: + description: CSPCName contains the name of the storage pool claim + to be upgraded + type: string + options: + description: Options can be used to change the default behaviour + of upgrade + properties: + ignoreStepsOnError: + description: IgnoreStepsOnError allows to ignore steps which + failed + items: + type: string + type: array + type: object + type: object + cstorPoolInstance: + description: CStorPoolInstance contains the details of the cstor pool + to be upgraded + properties: + cspiName: + description: CSPCName contains the name of the storage pool claim + to be upgraded + type: string + options: + description: Options can be used to change the default behaviour + of upgrade + properties: + ignoreStepsOnError: + description: IgnoreStepsOnError allows to ignore steps which + failed + items: + type: string + type: array + type: object + type: object + cstorVolume: + description: CStorVolume contains the details of the cstor volume + to be upgraded + properties: + options: + description: Options can be used to change the default behaviour + of upgrade + properties: + ignoreStepsOnError: + description: IgnoreStepsOnError allows to ignore steps which + failed + items: + type: string + type: array + type: object + pvName: + description: PVName contains the name of the pv associated with + the cstor volume + type: string + type: object + fromVersion: + description: FromVersion is the current version of the resource. + type: string + imagePrefix: + description: ImagePrefix contains the url prefix of the image url. + This field is optional. If not present upgrade takes the previously + present ImagePrefix. + type: string + imageTag: + description: ImageTag contains the customized tag for ToVersion if + any. This field is optional. If not present upgrade takes the ToVersion + as the ImageTag + type: string + jivaVolume: + description: JivaVolume contains the details of the jiva volume to + be upgraded + properties: + options: + description: Options can be used to change the default behaviour + of upgrade + properties: + ignoreStepsOnError: + description: IgnoreStepsOnError allows to ignore steps which + failed + items: + type: string + type: array + type: object + pvName: + description: PVName contains the name of the pv associated with + the jiva volume + type: string + type: object + options: + description: Options contains the optional flags that can be passed + during upgrade. + properties: + timeout: + description: Timeout is maximum seconds to wait at any given step + in the upgrade + type: integer + type: object + storagePoolClaim: + description: StoragePoolClaim contains the details of the storage + pool claim to be upgraded + properties: + options: + description: Options can be used to change the default behaviour + of upgrade + properties: + ignoreStepsOnError: + description: IgnoreStepsOnError allows to ignore steps which + failed + items: + type: string + type: array + type: object + spcName: + description: SPCName contains the name of the storage pool claim + to be upgraded + type: string + type: object + toVersion: + description: ToVersion is the upgraded version of the resource. It + should be same as the version of control plane components version. + type: string + required: + - fromVersion + - toVersion + type: object + status: + description: Status of UpgradeTask + properties: + completedTime: + description: CompletedTime of Upgrade + format: date-time + nullable: true + type: string + phase: + description: Phase indicates if a upgradeTask is started, success + or errored + type: string + retries: + description: Retries is the number of times the job attempted to upgrade + the resource + type: integer + startTime: + description: StartTime of Upgrade + format: date-time + nullable: true + type: string + upgradeDetailedStatuses: + description: UpgradeDetailedStatuses contains the list of statuses + of each step + items: + description: UpgradeDetailedStatuses represents the latest available + observations of a UpgradeTask current state. + properties: + lastUpdatedAt: + description: LastUpdatedTime of a UpgradeStep + format: date-time + nullable: true + type: string + message: + description: A human-readable message indicating details about + why the upgradeStep is in this state + type: string + phase: + description: Phase indicates if the UpgradeStep is waiting, + errored or completed. + type: string + reason: + description: Reason is a brief CamelCase string that describes + any failure and is meant for machine parsing and tidy display + in the CLI + type: string + startTime: + description: StartTime of a UpgradeStep + format: date-time + nullable: true + type: string + step: + description: UpgradeStep is the current step being performed + for a particular resource upgrade + type: string + type: object + type: array + type: object + required: + - spec + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] +--- diff --git a/helm/openebs/charts/cstor/crds/volumesnapshot.yaml b/helm/openebs/charts/cstor/crds/volumesnapshot.yaml new file mode 100644 index 0000000..3b63996 --- /dev/null +++ b/helm/openebs/charts/cstor/crds/volumesnapshot.yaml @@ -0,0 +1,312 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.11.3 + api-approved.kubernetes.io: "https://github.com/kubernetes-csi/external-snapshotter/pull/814" + creationTimestamp: null + name: volumesnapshots.snapshot.storage.k8s.io +spec: + group: snapshot.storage.k8s.io + names: + kind: VolumeSnapshot + listKind: VolumeSnapshotList + plural: volumesnapshots + shortNames: + - vs + singular: volumesnapshot + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Indicates if the snapshot is ready to be used to restore a volume. + jsonPath: .status.readyToUse + name: ReadyToUse + type: boolean + - description: If a new snapshot needs to be created, this contains the name of + the source PVC from which this snapshot was (or will be) created. + jsonPath: .spec.source.persistentVolumeClaimName + name: SourcePVC + type: string + - description: If a snapshot already exists, this contains the name of the existing + VolumeSnapshotContent object representing the existing snapshot. + jsonPath: .spec.source.volumeSnapshotContentName + name: SourceSnapshotContent + type: string + - description: Represents the minimum size of volume required to rehydrate from + this snapshot. + jsonPath: .status.restoreSize + name: RestoreSize + type: string + - description: The name of the VolumeSnapshotClass requested by the VolumeSnapshot. + jsonPath: .spec.volumeSnapshotClassName + name: SnapshotClass + type: string + - description: Name of the VolumeSnapshotContent object to which the VolumeSnapshot + object intends to bind to. Please note that verification of binding actually + requires checking both VolumeSnapshot and VolumeSnapshotContent to ensure + both are pointing at each other. Binding MUST be verified prior to usage of + this object. + jsonPath: .status.boundVolumeSnapshotContentName + name: SnapshotContent + type: string + - description: Timestamp when the point-in-time snapshot was taken by the underlying + storage system. + jsonPath: .status.creationTime + name: CreationTime + type: date + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: VolumeSnapshot is a user's request for either creating a point-in-time + snapshot of a persistent volume, or binding to a pre-existing snapshot. + 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 + spec: + description: 'spec defines the desired characteristics of a snapshot requested + by a user. More info: https://kubernetes.io/docs/concepts/storage/volume-snapshots#volumesnapshots + Required.' + properties: + source: + description: source specifies where a snapshot will be created from. + This field is immutable after creation. Required. + properties: + persistentVolumeClaimName: + description: persistentVolumeClaimName specifies the name of the + PersistentVolumeClaim object representing the volume from which + a snapshot should be created. This PVC is assumed to be in the + same namespace as the VolumeSnapshot object. This field should + be set if the snapshot does not exists, and needs to be created. + This field is immutable. + type: string + volumeSnapshotContentName: + description: volumeSnapshotContentName specifies the name of a + pre-existing VolumeSnapshotContent object representing an existing + volume snapshot. This field should be set if the snapshot already + exists and only needs a representation in Kubernetes. This field + is immutable. + type: string + type: object + oneOf: + - required: ["persistentVolumeClaimName"] + - required: ["volumeSnapshotContentName"] + volumeSnapshotClassName: + description: 'VolumeSnapshotClassName is the name of the VolumeSnapshotClass + requested by the VolumeSnapshot. VolumeSnapshotClassName may be + left nil to indicate that the default SnapshotClass should be used. + A given cluster may have multiple default Volume SnapshotClasses: + one default per CSI Driver. If a VolumeSnapshot does not specify + a SnapshotClass, VolumeSnapshotSource will be checked to figure + out what the associated CSI Driver is, and the default VolumeSnapshotClass + associated with that CSI Driver will be used. If more than one VolumeSnapshotClass + exist for a given CSI Driver and more than one have been marked + as default, CreateSnapshot will fail and generate an event. Empty + string is not allowed for this field.' + type: string + required: + - source + type: object + status: + description: status represents the current information of a snapshot. + Consumers must verify binding between VolumeSnapshot and VolumeSnapshotContent + objects is successful (by validating that both VolumeSnapshot and VolumeSnapshotContent + point at each other) before using this object. + properties: + boundVolumeSnapshotContentName: + description: 'boundVolumeSnapshotContentName is the name of the VolumeSnapshotContent + object to which this VolumeSnapshot object intends to bind to. If + not specified, it indicates that the VolumeSnapshot object has not + been successfully bound to a VolumeSnapshotContent object yet. NOTE: + To avoid possible security issues, consumers must verify binding + between VolumeSnapshot and VolumeSnapshotContent objects is successful + (by validating that both VolumeSnapshot and VolumeSnapshotContent + point at each other) before using this object.' + type: string + creationTime: + description: creationTime is the timestamp when the point-in-time + snapshot is taken by the underlying storage system. In dynamic snapshot + creation case, this field will be filled in by the snapshot controller + with the "creation_time" value returned from CSI "CreateSnapshot" + gRPC call. For a pre-existing snapshot, this field will be filled + with the "creation_time" value returned from the CSI "ListSnapshots" + gRPC call if the driver supports it. If not specified, it may indicate + that the creation time of the snapshot is unknown. + format: date-time + type: string + error: + description: error is the last observed error during snapshot creation, + if any. This field could be helpful to upper level controllers(i.e., + application controller) to decide whether they should continue on + waiting for the snapshot to be created based on the type of error + reported. The snapshot controller will keep retrying when an error + occurs during the snapshot creation. Upon success, this error field + will be cleared. + properties: + message: + description: 'message is a string detailing the encountered error + during snapshot creation if specified. NOTE: message may be + logged, and it should not contain sensitive information.' + type: string + time: + description: time is the timestamp when the error was encountered. + format: date-time + type: string + type: object + readyToUse: + description: readyToUse indicates if the snapshot is ready to be used + to restore a volume. In dynamic snapshot creation case, this field + will be filled in by the snapshot controller with the "ready_to_use" + value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing + snapshot, this field will be filled with the "ready_to_use" value + returned from the CSI "ListSnapshots" gRPC call if the driver supports + it, otherwise, this field will be set to "True". If not specified, + it means the readiness of a snapshot is unknown. + type: boolean + restoreSize: + type: string + description: restoreSize represents the minimum size of volume required + to create a volume from this snapshot. In dynamic snapshot creation + case, this field will be filled in by the snapshot controller with + the "size_bytes" value returned from CSI "CreateSnapshot" gRPC call. + For a pre-existing snapshot, this field will be filled with the + "size_bytes" value returned from the CSI "ListSnapshots" gRPC call + if the driver supports it. When restoring a volume from this snapshot, + the size of the volume MUST NOT be smaller than the restoreSize + if it is specified, otherwise the restoration will fail. If not + specified, it indicates that the size is unknown. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + volumeGroupSnapshotName: + description: VolumeGroupSnapshotName is the name of the VolumeGroupSnapshot + of which this VolumeSnapshot is a part of. + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} + - additionalPrinterColumns: + - description: Indicates if the snapshot is ready to be used to restore a volume. + jsonPath: .status.readyToUse + name: ReadyToUse + type: boolean + - description: If a new snapshot needs to be created, this contains the name of the source PVC from which this snapshot was (or will be) created. + jsonPath: .spec.source.persistentVolumeClaimName + name: SourcePVC + type: string + - description: If a snapshot already exists, this contains the name of the existing VolumeSnapshotContent object representing the existing snapshot. + jsonPath: .spec.source.volumeSnapshotContentName + name: SourceSnapshotContent + type: string + - description: Represents the minimum size of volume required to rehydrate from this snapshot. + jsonPath: .status.restoreSize + name: RestoreSize + type: string + - description: The name of the VolumeSnapshotClass requested by the VolumeSnapshot. + jsonPath: .spec.volumeSnapshotClassName + name: SnapshotClass + type: string + - description: Name of the VolumeSnapshotContent object to which the VolumeSnapshot object intends to bind to. Please note that verification of binding actually requires checking both VolumeSnapshot and VolumeSnapshotContent to ensure both are pointing at each other. Binding MUST be verified prior to usage of this object. + jsonPath: .status.boundVolumeSnapshotContentName + name: SnapshotContent + type: string + - description: Timestamp when the point-in-time snapshot was taken by the underlying storage system. + jsonPath: .status.creationTime + name: CreationTime + type: date + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + # This indicates the v1beta1 version of the custom resource is deprecated. + # API requests to this version receive a warning in the server response. + deprecated: true + # This overrides the default warning returned to clients making v1beta1 API requests. + deprecationWarning: "snapshot.storage.k8s.io/v1beta1 VolumeSnapshot is deprecated; use snapshot.storage.k8s.io/v1 VolumeSnapshot" + schema: + openAPIV3Schema: + description: VolumeSnapshot is a user's request for either creating a point-in-time snapshot of a persistent volume, or binding to a pre-existing snapshot. + 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 + spec: + description: 'spec defines the desired characteristics of a snapshot requested by a user. More info: https://kubernetes.io/docs/concepts/storage/volume-snapshots#volumesnapshots Required.' + properties: + source: + description: source specifies where a snapshot will be created from. This field is immutable after creation. Required. + properties: + persistentVolumeClaimName: + description: persistentVolumeClaimName specifies the name of the PersistentVolumeClaim object representing the volume from which a snapshot should be created. This PVC is assumed to be in the same namespace as the VolumeSnapshot object. This field should be set if the snapshot does not exists, and needs to be created. This field is immutable. + type: string + volumeSnapshotContentName: + description: volumeSnapshotContentName specifies the name of a pre-existing VolumeSnapshotContent object representing an existing volume snapshot. This field should be set if the snapshot already exists and only needs a representation in Kubernetes. This field is immutable. + type: string + type: object + volumeSnapshotClassName: + description: 'VolumeSnapshotClassName is the name of the VolumeSnapshotClass requested by the VolumeSnapshot. VolumeSnapshotClassName may be left nil to indicate that the default SnapshotClass should be used. A given cluster may have multiple default Volume SnapshotClasses: one default per CSI Driver. If a VolumeSnapshot does not specify a SnapshotClass, VolumeSnapshotSource will be checked to figure out what the associated CSI Driver is, and the default VolumeSnapshotClass associated with that CSI Driver will be used. If more than one VolumeSnapshotClass exist for a given CSI Driver and more than one have been marked as default, CreateSnapshot will fail and generate an event. Empty string is not allowed for this field.' + type: string + required: + - source + type: object + status: + description: status represents the current information of a snapshot. Consumers must verify binding between VolumeSnapshot and VolumeSnapshotContent objects is successful (by validating that both VolumeSnapshot and VolumeSnapshotContent point at each other) before using this object. + properties: + boundVolumeSnapshotContentName: + description: 'boundVolumeSnapshotContentName is the name of the VolumeSnapshotContent object to which this VolumeSnapshot object intends to bind to. If not specified, it indicates that the VolumeSnapshot object has not been successfully bound to a VolumeSnapshotContent object yet. NOTE: To avoid possible security issues, consumers must verify binding between VolumeSnapshot and VolumeSnapshotContent objects is successful (by validating that both VolumeSnapshot and VolumeSnapshotContent point at each other) before using this object.' + type: string + creationTime: + description: creationTime is the timestamp when the point-in-time snapshot is taken by the underlying storage system. In dynamic snapshot creation case, this field will be filled in by the snapshot controller with the "creation_time" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "creation_time" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. If not specified, it may indicate that the creation time of the snapshot is unknown. + format: date-time + type: string + error: + description: error is the last observed error during snapshot creation, if any. This field could be helpful to upper level controllers(i.e., application controller) to decide whether they should continue on waiting for the snapshot to be created based on the type of error reported. The snapshot controller will keep retrying when an error occurs during the snapshot creation. Upon success, this error field will be cleared. + properties: + message: + description: 'message is a string detailing the encountered error during snapshot creation if specified. NOTE: message may be logged, and it should not contain sensitive information.' + type: string + time: + description: time is the timestamp when the error was encountered. + format: date-time + type: string + type: object + readyToUse: + description: readyToUse indicates if the snapshot is ready to be used to restore a volume. In dynamic snapshot creation case, this field will be filled in by the snapshot controller with the "ready_to_use" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "ready_to_use" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it, otherwise, this field will be set to "True". If not specified, it means the readiness of a snapshot is unknown. + type: boolean + restoreSize: + type: string + description: restoreSize represents the minimum size of volume required to create a volume from this snapshot. In dynamic snapshot creation case, this field will be filled in by the snapshot controller with the "size_bytes" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "size_bytes" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. When restoring a volume from this snapshot, the size of the volume MUST NOT be smaller than the restoreSize if it is specified, otherwise the restoration will fail. If not specified, it indicates that the size is unknown. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + required: + - spec + type: object + served: false + storage: false + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] +--- \ No newline at end of file diff --git a/helm/openebs/charts/cstor/crds/volumesnapshotclass.yaml b/helm/openebs/charts/cstor/crds/volumesnapshotclass.yaml new file mode 100644 index 0000000..c509746 --- /dev/null +++ b/helm/openebs/charts/cstor/crds/volumesnapshotclass.yaml @@ -0,0 +1,135 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.11.3 + api-approved.kubernetes.io: "https://github.com/kubernetes-csi/external-snapshotter/pull/814" + creationTimestamp: null + name: volumesnapshotclasses.snapshot.storage.k8s.io +spec: + group: snapshot.storage.k8s.io + names: + kind: VolumeSnapshotClass + listKind: VolumeSnapshotClassList + plural: volumesnapshotclasses + shortNames: + - vsclass + - vsclasses + singular: volumesnapshotclass + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .driver + name: Driver + type: string + - description: Determines whether a VolumeSnapshotContent created through the + VolumeSnapshotClass should be deleted when its bound VolumeSnapshot is deleted. + jsonPath: .deletionPolicy + name: DeletionPolicy + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: VolumeSnapshotClass specifies parameters that a underlying storage + system uses when creating a volume snapshot. A specific VolumeSnapshotClass + is used by specifying its name in a VolumeSnapshot object. VolumeSnapshotClasses + are non-namespaced + 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 + deletionPolicy: + description: deletionPolicy determines whether a VolumeSnapshotContent + created through the VolumeSnapshotClass should be deleted when its bound + VolumeSnapshot is deleted. Supported values are "Retain" and "Delete". + "Retain" means that the VolumeSnapshotContent and its physical snapshot + on underlying storage system are kept. "Delete" means that the VolumeSnapshotContent + and its physical snapshot on underlying storage system are deleted. + Required. + enum: + - Delete + - Retain + type: string + driver: + description: driver is the name of the storage driver that handles this + VolumeSnapshotClass. Required. + 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 + parameters: + additionalProperties: + type: string + description: parameters is a key-value map with storage driver specific + parameters for creating snapshots. These values are opaque to Kubernetes. + type: object + required: + - deletionPolicy + - driver + type: object + served: true + storage: true + subresources: {} + - additionalPrinterColumns: + - jsonPath: .driver + name: Driver + type: string + - description: Determines whether a VolumeSnapshotContent created through the VolumeSnapshotClass should be deleted when its bound VolumeSnapshot is deleted. + jsonPath: .deletionPolicy + name: DeletionPolicy + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + # This indicates the v1beta1 version of the custom resource is deprecated. + # API requests to this version receive a warning in the server response. + deprecated: true + # This overrides the default warning returned to clients making v1beta1 API requests. + deprecationWarning: "snapshot.storage.k8s.io/v1beta1 VolumeSnapshotClass is deprecated; use snapshot.storage.k8s.io/v1 VolumeSnapshotClass" + schema: + openAPIV3Schema: + description: VolumeSnapshotClass specifies parameters that a underlying storage system uses when creating a volume snapshot. A specific VolumeSnapshotClass is used by specifying its name in a VolumeSnapshot object. VolumeSnapshotClasses are non-namespaced + 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 + deletionPolicy: + description: deletionPolicy determines whether a VolumeSnapshotContent created through the VolumeSnapshotClass should be deleted when its bound VolumeSnapshot is deleted. Supported values are "Retain" and "Delete". "Retain" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are kept. "Delete" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are deleted. Required. + enum: + - Delete + - Retain + type: string + driver: + description: driver is the name of the storage driver that handles this VolumeSnapshotClass. Required. + 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 + parameters: + additionalProperties: + type: string + description: parameters is a key-value map with storage driver specific parameters for creating snapshots. These values are opaque to Kubernetes. + type: object + required: + - deletionPolicy + - driver + type: object + served: false + storage: false + subresources: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] +--- \ No newline at end of file diff --git a/helm/openebs/charts/cstor/crds/volumesnapshotcontent.yaml b/helm/openebs/charts/cstor/crds/volumesnapshotcontent.yaml new file mode 100644 index 0000000..4a9f8df --- /dev/null +++ b/helm/openebs/charts/cstor/crds/volumesnapshotcontent.yaml @@ -0,0 +1,402 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.11.3 + api-approved.kubernetes.io: "https://github.com/kubernetes-csi/external-snapshotter/pull/814" + creationTimestamp: null + name: volumesnapshotcontents.snapshot.storage.k8s.io +spec: + group: snapshot.storage.k8s.io + names: + kind: VolumeSnapshotContent + listKind: VolumeSnapshotContentList + plural: volumesnapshotcontents + shortNames: + - vsc + - vscs + singular: volumesnapshotcontent + scope: Cluster + versions: + - additionalPrinterColumns: + - description: Indicates if the snapshot is ready to be used to restore a volume. + jsonPath: .status.readyToUse + name: ReadyToUse + type: boolean + - description: Represents the complete size of the snapshot in bytes + jsonPath: .status.restoreSize + name: RestoreSize + type: integer + - description: Determines whether this VolumeSnapshotContent and its physical + snapshot on the underlying storage system should be deleted when its bound + VolumeSnapshot is deleted. + jsonPath: .spec.deletionPolicy + name: DeletionPolicy + type: string + - description: Name of the CSI driver used to create the physical snapshot on + the underlying storage system. + jsonPath: .spec.driver + name: Driver + type: string + - description: Name of the VolumeSnapshotClass to which this snapshot belongs. + jsonPath: .spec.volumeSnapshotClassName + name: VolumeSnapshotClass + type: string + - description: Name of the VolumeSnapshot object to which this VolumeSnapshotContent + object is bound. + jsonPath: .spec.volumeSnapshotRef.name + name: VolumeSnapshot + type: string + - description: Namespace of the VolumeSnapshot object to which this VolumeSnapshotContent object is bound. + jsonPath: .spec.volumeSnapshotRef.namespace + name: VolumeSnapshotNamespace + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: VolumeSnapshotContent represents the actual "on-disk" snapshot + object in the underlying storage system + 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 + spec: + description: spec defines properties of a VolumeSnapshotContent created + by the underlying storage system. Required. + properties: + deletionPolicy: + description: deletionPolicy determines whether this VolumeSnapshotContent + and its physical snapshot on the underlying storage system should + be deleted when its bound VolumeSnapshot is deleted. Supported values + are "Retain" and "Delete". "Retain" means that the VolumeSnapshotContent + and its physical snapshot on underlying storage system are kept. + "Delete" means that the VolumeSnapshotContent and its physical snapshot + on underlying storage system are deleted. For dynamically provisioned + snapshots, this field will automatically be filled in by the CSI + snapshotter sidecar with the "DeletionPolicy" field defined in the + corresponding VolumeSnapshotClass. For pre-existing snapshots, users + MUST specify this field when creating the VolumeSnapshotContent + object. Required. + enum: + - Delete + - Retain + type: string + driver: + description: driver is the name of the CSI driver used to create the + physical snapshot on the underlying storage system. This MUST be + the same as the name returned by the CSI GetPluginName() call for + that driver. Required. + type: string + source: + description: source specifies whether the snapshot is (or should be) + dynamically provisioned or already exists, and just requires a Kubernetes + object representation. This field is immutable after creation. Required. + properties: + snapshotHandle: + description: snapshotHandle specifies the CSI "snapshot_id" of + a pre-existing snapshot on the underlying storage system for + which a Kubernetes object representation was (or should be) + created. This field is immutable. + type: string + volumeHandle: + description: volumeHandle specifies the CSI "volume_id" of the + volume from which a snapshot should be dynamically taken from. + This field is immutable. + type: string + type: object + oneOf: + - required: ["snapshotHandle"] + - required: ["volumeHandle"] + sourceVolumeMode: + description: SourceVolumeMode is the mode of the volume whose snapshot + is taken. Can be either “Filesystem” or “Block”. If not specified, + it indicates the source volume's mode is unknown. This field is + immutable. This field is an alpha field. + type: string + volumeSnapshotClassName: + description: name of the VolumeSnapshotClass from which this snapshot + was (or will be) created. Note that after provisioning, the VolumeSnapshotClass + may be deleted or recreated with different set of values, and as + such, should not be referenced post-snapshot creation. + type: string + volumeSnapshotRef: + description: volumeSnapshotRef specifies the VolumeSnapshot object + to which this VolumeSnapshotContent object is bound. VolumeSnapshot.Spec.VolumeSnapshotContentName + field must reference to this VolumeSnapshotContent's name for the + bidirectional binding to be valid. For a pre-existing VolumeSnapshotContent + object, name and namespace of the VolumeSnapshot object MUST be + provided for binding to happen. This field is immutable after creation. + Required. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: 'If referring to a piece of an object instead of + an entire object, this string should contain a valid JSON/Go + field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within + a pod, this would take on a value like: "spec.containers{name}" + (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" + (container with index 2 in this pod). This syntax is chosen + only to have some well-defined way of referencing a part of + an object. TODO: this design is not final and this field is + subject to change in the future.' + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: 'Specific resourceVersion to which this reference + is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + x-kubernetes-map-type: atomic + required: + - deletionPolicy + - driver + - source + - volumeSnapshotRef + type: object + status: + description: status represents the current information of a snapshot. + properties: + creationTime: + description: creationTime is the timestamp when the point-in-time + snapshot is taken by the underlying storage system. In dynamic snapshot + creation case, this field will be filled in by the CSI snapshotter + sidecar with the "creation_time" value returned from CSI "CreateSnapshot" + gRPC call. For a pre-existing snapshot, this field will be filled + with the "creation_time" value returned from the CSI "ListSnapshots" + gRPC call if the driver supports it. If not specified, it indicates + the creation time is unknown. The format of this field is a Unix + nanoseconds time encoded as an int64. On Unix, the command `date + +%s%N` returns the current time in nanoseconds since 1970-01-01 + 00:00:00 UTC. + format: int64 + type: integer + error: + description: error is the last observed error during snapshot creation, + if any. Upon success after retry, this error field will be cleared. + properties: + message: + description: 'message is a string detailing the encountered error + during snapshot creation if specified. NOTE: message may be + logged, and it should not contain sensitive information.' + type: string + time: + description: time is the timestamp when the error was encountered. + format: date-time + type: string + type: object + readyToUse: + description: readyToUse indicates if a snapshot is ready to be used + to restore a volume. In dynamic snapshot creation case, this field + will be filled in by the CSI snapshotter sidecar with the "ready_to_use" + value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing + snapshot, this field will be filled with the "ready_to_use" value + returned from the CSI "ListSnapshots" gRPC call if the driver supports + it, otherwise, this field will be set to "True". If not specified, + it means the readiness of a snapshot is unknown. + type: boolean + restoreSize: + description: restoreSize represents the complete size of the snapshot + in bytes. In dynamic snapshot creation case, this field will be + filled in by the CSI snapshotter sidecar with the "size_bytes" value + returned from CSI "CreateSnapshot" gRPC call. For a pre-existing + snapshot, this field will be filled with the "size_bytes" value + returned from the CSI "ListSnapshots" gRPC call if the driver supports + it. When restoring a volume from this snapshot, the size of the + volume MUST NOT be smaller than the restoreSize if it is specified, + otherwise the restoration will fail. If not specified, it indicates + that the size is unknown. + format: int64 + minimum: 0 + type: integer + snapshotHandle: + description: snapshotHandle is the CSI "snapshot_id" of a snapshot + on the underlying storage system. If not specified, it indicates + that dynamic snapshot creation has either failed or it is still + in progress. + type: string + volumeGroupSnapshotContentName: + description: VolumeGroupSnapshotContentName is the name of the VolumeGroupSnapshotContent + of which this VolumeSnapshotContent is a part of. + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} + - additionalPrinterColumns: + - description: Indicates if the snapshot is ready to be used to restore a volume. + jsonPath: .status.readyToUse + name: ReadyToUse + type: boolean + - description: Represents the complete size of the snapshot in bytes + jsonPath: .status.restoreSize + name: RestoreSize + type: integer + - description: Determines whether this VolumeSnapshotContent and its physical snapshot on the underlying storage system should be deleted when its bound VolumeSnapshot is deleted. + jsonPath: .spec.deletionPolicy + name: DeletionPolicy + type: string + - description: Name of the CSI driver used to create the physical snapshot on the underlying storage system. + jsonPath: .spec.driver + name: Driver + type: string + - description: Name of the VolumeSnapshotClass to which this snapshot belongs. + jsonPath: .spec.volumeSnapshotClassName + name: VolumeSnapshotClass + type: string + - description: Name of the VolumeSnapshot object to which this VolumeSnapshotContent object is bound. + jsonPath: .spec.volumeSnapshotRef.name + name: VolumeSnapshot + type: string + - description: Namespace of the VolumeSnapshot object to which this VolumeSnapshotContent object is bound. + jsonPath: .spec.volumeSnapshotRef.namespace + name: VolumeSnapshotNamespace + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + # This indicates the v1beta1 version of the custom resource is deprecated. + # API requests to this version receive a warning in the server response. + deprecated: true + # This overrides the default warning returned to clients making v1beta1 API requests. + deprecationWarning: "snapshot.storage.k8s.io/v1beta1 VolumeSnapshotContent is deprecated; use snapshot.storage.k8s.io/v1 VolumeSnapshotContent" + schema: + openAPIV3Schema: + description: VolumeSnapshotContent represents the actual "on-disk" snapshot object in the underlying storage system + 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 + spec: + description: spec defines properties of a VolumeSnapshotContent created by the underlying storage system. Required. + properties: + deletionPolicy: + description: deletionPolicy determines whether this VolumeSnapshotContent and its physical snapshot on the underlying storage system should be deleted when its bound VolumeSnapshot is deleted. Supported values are "Retain" and "Delete". "Retain" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are kept. "Delete" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are deleted. For dynamically provisioned snapshots, this field will automatically be filled in by the CSI snapshotter sidecar with the "DeletionPolicy" field defined in the corresponding VolumeSnapshotClass. For pre-existing snapshots, users MUST specify this field when creating the VolumeSnapshotContent object. Required. + enum: + - Delete + - Retain + type: string + driver: + description: driver is the name of the CSI driver used to create the physical snapshot on the underlying storage system. This MUST be the same as the name returned by the CSI GetPluginName() call for that driver. Required. + type: string + source: + description: source specifies whether the snapshot is (or should be) dynamically provisioned or already exists, and just requires a Kubernetes object representation. This field is immutable after creation. Required. + properties: + snapshotHandle: + description: snapshotHandle specifies the CSI "snapshot_id" of a pre-existing snapshot on the underlying storage system for which a Kubernetes object representation was (or should be) created. This field is immutable. + type: string + volumeHandle: + description: volumeHandle specifies the CSI "volume_id" of the volume from which a snapshot should be dynamically taken from. This field is immutable. + type: string + type: object + volumeSnapshotClassName: + description: name of the VolumeSnapshotClass from which this snapshot was (or will be) created. Note that after provisioning, the VolumeSnapshotClass may be deleted or recreated with different set of values, and as such, should not be referenced post-snapshot creation. + type: string + volumeSnapshotRef: + description: volumeSnapshotRef specifies the VolumeSnapshot object to which this VolumeSnapshotContent object is bound. VolumeSnapshot.Spec.VolumeSnapshotContentName field must reference to this VolumeSnapshotContent's name for the bidirectional binding to be valid. For a pre-existing VolumeSnapshotContent object, name and namespace of the VolumeSnapshot object MUST be provided for binding to happen. This field is immutable after creation. Required. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: 'If referring to a piece of an object instead of an entire object, this string should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. For example, if the object reference is to a container within a pod, this would take on a value like: "spec.containers{name}" (where "name" refers to the name of the container that triggered the event) or if no container name is specified "spec.containers[2]" (container with index 2 in this pod). This syntax is chosen only to have some well-defined way of referencing a part of an object. TODO: this design is not final and this field is subject to change in the future.' + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: 'Specific resourceVersion to which this reference is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + required: + - deletionPolicy + - driver + - source + - volumeSnapshotRef + type: object + status: + description: status represents the current information of a snapshot. + properties: + creationTime: + description: creationTime is the timestamp when the point-in-time snapshot is taken by the underlying storage system. In dynamic snapshot creation case, this field will be filled in by the CSI snapshotter sidecar with the "creation_time" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "creation_time" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. If not specified, it indicates the creation time is unknown. The format of this field is a Unix nanoseconds time encoded as an int64. On Unix, the command `date +%s%N` returns the current time in nanoseconds since 1970-01-01 00:00:00 UTC. + format: int64 + type: integer + error: + description: error is the last observed error during snapshot creation, if any. Upon success after retry, this error field will be cleared. + properties: + message: + description: 'message is a string detailing the encountered error during snapshot creation if specified. NOTE: message may be logged, and it should not contain sensitive information.' + type: string + time: + description: time is the timestamp when the error was encountered. + format: date-time + type: string + type: object + readyToUse: + description: readyToUse indicates if a snapshot is ready to be used to restore a volume. In dynamic snapshot creation case, this field will be filled in by the CSI snapshotter sidecar with the "ready_to_use" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "ready_to_use" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it, otherwise, this field will be set to "True". If not specified, it means the readiness of a snapshot is unknown. + type: boolean + restoreSize: + description: restoreSize represents the complete size of the snapshot in bytes. In dynamic snapshot creation case, this field will be filled in by the CSI snapshotter sidecar with the "size_bytes" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "size_bytes" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. When restoring a volume from this snapshot, the size of the volume MUST NOT be smaller than the restoreSize if it is specified, otherwise the restoration will fail. If not specified, it indicates that the size is unknown. + format: int64 + minimum: 0 + type: integer + snapshotHandle: + description: snapshotHandle is the CSI "snapshot_id" of a snapshot on the underlying storage system. If not specified, it indicates that dynamic snapshot creation has either failed or it is still in progress. + type: string + type: object + required: + - spec + type: object + served: false + storage: false + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] +--- \ No newline at end of file diff --git a/helm/openebs/charts/cstor/templates/NOTES.txt b/helm/openebs/charts/cstor/templates/NOTES.txt new file mode 100644 index 0000000..1dadf47 --- /dev/null +++ b/helm/openebs/charts/cstor/templates/NOTES.txt @@ -0,0 +1,11 @@ +The OpenEBS cstor has been installed check its status by running: +$ kubectl get pods -n {{ .Release.Namespace }} + +Use `kubectl get bd -n {{ .Release.Namespace }} ` to see the list of +blockdevices attached to the Kubernetes cluster nodes. + +For more information, visit our Slack at https://openebs.io/community or view +the documentation online at http://docs.openebs.io/. + +For more information related to cstor pool and volume provisioning, visit +https://github.com/openebs/cstor-operators/tree/master/docs . diff --git a/helm/openebs/charts/cstor/templates/_helpers.tpl b/helm/openebs/charts/cstor/templates/_helpers.tpl new file mode 100644 index 0000000..7c86f3a --- /dev/null +++ b/helm/openebs/charts/cstor/templates/_helpers.tpl @@ -0,0 +1,217 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "cstor.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 "cstor.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 "cstor.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "cstor.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "cstor.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} + +{{/* +Define meta labels for cstor components +*/}} +{{- define "cstor.common.metaLabels" -}} +chart: {{ template "cstor.chart" . }} +heritage: {{ .Release.Service }} +openebs.io/version: {{ .Values.release.version | quote }} +{{- end -}} + +{{/* +Create match labels for cstor admission server +*/}} +{{- define "cstor.admissionServer.matchLabels" -}} +app: {{ .Values.admissionServer.componentName | quote }} +release: {{ .Release.Name }} +component: {{ .Values.admissionServer.componentName | quote }} +{{- end -}} + +{{/* +Create component labels for cstor admission server +*/}} +{{- define "cstor.admissionServer.componentLabels" -}} +openebs.io/component-name: {{ .Values.admissionServer.componentName | quote }} +{{- end -}} + +{{/* +Create labels for cstor admission server +*/}} +{{- define "cstor.admissionServer.labels" -}} +{{ include "cstor.common.metaLabels" . }} +{{ include "cstor.admissionServer.matchLabels" . }} +{{ include "cstor.admissionServer.componentLabels" . }} +{{- end -}} + +{{/* +Create match labels for cstor cspc operator +*/}} +{{- define "cstor.cspcOperator.matchLabels" -}} +name: {{ .Values.cspcOperator.componentName | quote }} +release: {{ .Release.Name }} +component: {{ .Values.cspcOperator.componentName | quote }} +{{- end -}} + +{{/* +Create component labels cstor cspc operator +*/}} +{{- define "cstor.cspcOperator.componentLabels" -}} +openebs.io/component-name: {{ .Values.cspcOperator.componentName | quote }} +{{- end -}} + + +{{/* +Create labels for cstor cspc operator +*/}} +{{- define "cstor.cspcOperator.labels" -}} +{{ include "cstor.common.metaLabels" . }} +{{ include "cstor.cspcOperator.matchLabels" . }} +{{ include "cstor.cspcOperator.componentLabels" . }} +{{- end -}} + +{{/* +Create match labels for cstor cvc operator +*/}} +{{- define "cstor.cvcOperator.matchLabels" -}} +name: {{ .Values.cvcOperator.componentName | quote }} +release: {{ .Release.Name }} +component: {{ .Values.cvcOperator.componentName | quote }} +{{- end -}} + +{{/* +Create component labels cstor cvc operator +*/}} +{{- define "cstor.cvcOperator.componentLabels" -}} +openebs.io/component-name: {{ .Values.cvcOperator.componentName | quote }} +{{- end -}} + +{{/* +Create component labels cstor cvc operator service +*/}} +{{- define "cstor.cvcOperatorService.componentLabels" -}} +openebs.io/component-name: {{ printf "%s-svc" .Values.cvcOperator.componentName | quote }} +{{- end -}} + + +{{/* +Create labels for cstor cvc operator +*/}} +{{- define "cstor.cvcOperator.labels" -}} +{{ include "cstor.common.metaLabels" . }} +{{ include "cstor.cvcOperator.matchLabels" . }} +{{ include "cstor.cvcOperator.componentLabels" . }} +{{- end -}} + +{{/* +Create labels for cstor cvc operator service +*/}} +{{- define "cstor.cvcOperatorService.labels" -}} +{{ include "cstor.common.metaLabels" . }} +{{ include "cstor.cvcOperator.matchLabels" . }} +{{ include "cstor.cvcOperatorService.componentLabels" . }} +{{- end -}} + +{{/* +Create match labels for cstor csi node operator +*/}} +{{- define "cstor.csiNode.matchLabels" -}} +name: {{ .Values.csiNode.componentName | quote }} +release: {{ .Release.Name }} +component: {{ .Values.csiNode.componentName | quote }} +{{- end -}} + +{{/* +Create component labels cstor csi node operator +*/}} +{{- define "cstor.csiNode.componentLabels" -}} +openebs.io/component-name: {{ .Values.csiNode.componentName | quote }} +{{- end -}} + +{{/* +Create labels for cstor csi node operator +*/}} +{{- define "cstor.csiNode.labels" -}} +{{ include "cstor.common.metaLabels" . }} +{{ include "cstor.csiNode.matchLabels" . }} +{{ include "cstor.csiNode.componentLabels" . }} +{{- end -}} + +{{/* +Create match labels for cstor csi controller +*/}} +{{- define "cstor.csiController.matchLabels" -}} +name: {{ .Values.csiController.componentName | quote }} +release: {{ .Release.Name }} +component: {{ .Values.csiController.componentName | quote }} +{{- end -}} + +{{/* +Create component labels cstor csi controller +*/}} +{{- define "cstor.csiController.componentLabels" -}} +openebs.io/component-name: {{ .Values.csiController.componentName | quote }} +{{- end -}} + +{{/* +Create labels for cstor csi controller +*/}} +{{- define "cstor.csiController.labels" -}} +{{ include "cstor.common.metaLabels" . }} +{{ include "cstor.csiController.matchLabels" . }} +{{ include "cstor.csiController.componentLabels" . }} +{{- end -}} + +{{/* +Create the name of the priority class for csi node plugin +*/}} +{{- define "cstor.csiNode.priorityClassName" -}} +{{- if .Values.csiNode.priorityClass.create }} +{{- printf "%s-%s" .Release.Name .Values.csiNode.priorityClass.name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s" .Values.csiNode.priorityClass.name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} + +{{/* +Create the name of the priority class for csi controller plugin +*/}} +{{- define "cstor.csiController.priorityClassName" -}} +{{- if .Values.csiController.priorityClass.create }} +{{- printf "%s-%s" .Release.Name .Values.csiController.priorityClass.name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s" .Values.csiController.priorityClass.name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} diff --git a/helm/openebs/charts/cstor/templates/admission-server.yaml b/helm/openebs/charts/cstor/templates/admission-server.yaml new file mode 100644 index 0000000..0909c9d --- /dev/null +++ b/helm/openebs/charts/cstor/templates/admission-server.yaml @@ -0,0 +1,59 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "cstor.fullname" . }}-admission-server + {{- with .Values.admissionServer.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "cstor.admissionServer.labels" . | nindent 4 }} +spec: + replicas: {{ .Values.admissionServer.replicas }} + strategy: + type: Recreate + rollingUpdate: null + selector: + matchLabels: + {{- include "cstor.admissionServer.matchLabels" . | nindent 6 }} + template: + metadata: + labels: + {{- include "cstor.admissionServer.labels" . | nindent 8 }} + {{- if .Values.admissionServer.podLabels }} + {{ toYaml .Values.admissionServer.podLabels | nindent 8 }} + {{- end }} + spec: + serviceAccountName: {{ .Values.serviceAccount.cstorOperator.name }} + containers: + - name: {{ template "cstor.fullname" . }}-admission-webhook + image: "{{ .Values.admissionServer.image.registry }}{{ .Values.admissionServer.image.repository }}:{{ .Values.admissionServer.image.tag }}" + imagePullPolicy: {{ .Values.admissionServer.image.pullPolicy }} + resources: +{{ toYaml .Values.admissionServer.resources | indent 12 }} + args: + - -alsologtostderr + - -v=2 + - 2>&1 + env: + - name: OPENEBS_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: ADMISSION_WEBHOOK_FAILURE_POLICY + value: {{ .Values.admissionServer.failurePolicy }} +{{- if .Values.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | indent 2 }} +{{- end }} +{{- if .Values.admissionServer.nodeSelector }} + nodeSelector: +{{ toYaml .Values.admissionServer.nodeSelector | indent 8 }} +{{- end }} +{{- if .Values.admissionServer.securityContext }} + securityContext: +{{ toYaml .Values.admissionServer.securityContext | indent 8 }} +{{- end }} +{{- if .Values.admissionServer.tolerations }} + tolerations: +{{ toYaml .Values.admissionServer.tolerations | indent 8 }} +{{- end }} diff --git a/helm/openebs/charts/cstor/templates/cleanup-webhook.yaml b/helm/openebs/charts/cstor/templates/cleanup-webhook.yaml new file mode 100644 index 0000000..ea1d869 --- /dev/null +++ b/helm/openebs/charts/cstor/templates/cleanup-webhook.yaml @@ -0,0 +1,39 @@ +# HELM first deletes RBAC, then it tries to delete other resources like CSPC and PVC. +# We've got validating webhook on CSPC and PVC. +# But even that the policy of this webhook is Ignore, it fails because the ServiceAccount +# does not have permission to access resources like BDC anymore which are used for validation. +# Therefore we first need to delete webhook so we can delete the rest of the deployments. +{{- $kubeMinor := .Capabilities.KubeVersion.Minor | replace "+" "" }} +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ template "cstor.fullname" . }}-webhook-cleanup + namespace: {{ .Release.Namespace }} + annotations: + "helm.sh/hook": pre-delete + "helm.sh/hook-delete-policy": hook-succeeded + labels: + app: {{ template "cstor.name" . }} +spec: + template: + metadata: + name: {{ template "cstor.fullname" . }}-webhook-cleanup + labels: + app: {{ template "cstor.name" . }} + spec: + serviceAccountName: {{ .Values.serviceAccount.cstorOperator.name }} + containers: + - name: kubectl + {{- /* bitnami maintains an image for all k8s versions */}} + {{- /* see: https://hub.docker.com/r/bitnami/kubectl */}} + {{- if .Values.cleanup.image.tag }} + image: "{{ .Values.cleanup.image.registry }}{{ .Values.cleanup.image.repository }}:{{ .Values.cleanup.image.tag }}" + {{- else }} + image: "{{ .Values.cleanup.image.registry }}{{ .Values.cleanup.image.repository }}:{{ .Capabilities.KubeVersion.Major }}.{{ $kubeMinor }}" + {{- end }} + command: + - /bin/sh + - -c + - > + kubectl delete validatingWebhookConfiguration openebs-cstor-validation-webhook || true; + restartPolicy: OnFailure diff --git a/helm/openebs/charts/cstor/templates/csi-controller-rbac.yaml b/helm/openebs/charts/cstor/templates/csi-controller-rbac.yaml new file mode 100644 index 0000000..a0624e4 --- /dev/null +++ b/helm/openebs/charts/cstor/templates/csi-controller-rbac.yaml @@ -0,0 +1,196 @@ +{{- if .Values.serviceAccount.csiController.create -}} +kind: ServiceAccount +apiVersion: v1 +metadata: + name: {{ .Values.serviceAccount.csiController.name }} + labels: + {{- include "cstor.csiController.labels" . | nindent 4 }} + namespace: {{ .Release.Namespace }} +{{- end }} +{{- if .Values.rbac.create }} +--- +# cstor csi roles and bindings +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: openebs-cstor-csi-snapshotter-binding + labels: + {{- include "cstor.csiController.labels" . | nindent 4 }} +subjects: + - kind: ServiceAccount + name: {{ .Values.serviceAccount.csiController.name }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: openebs-cstor-csi-snapshotter-role + apiGroup: rbac.authorization.k8s.io +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: openebs-cstor-csi-snapshotter-role + labels: + {{- include "cstor.csiController.labels" . | nindent 4 }} +rules: + - apiGroups: [""] + resources: ["persistentvolumes"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["persistentvolumeclaims"] + verbs: ["get", "list", "watch"] + - 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: ["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"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshots"] + verbs: ["get", "list", "watch", "update", "patch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshots/status"] + verbs: ["update"] + - apiGroups: ["coordination.k8s.io"] + resources: ["leases"] + verbs: ["get", "watch", "list", "delete", "update", "create"] + - apiGroups: ["apiextensions.k8s.io"] + resources: ["customresourcedefinitions"] + verbs: ["create", "list", "watch", "delete", "get", "update"] +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: openebs-cstor-csi-provisioner-role + labels: + {{- include "cstor.csiController.labels" . | nindent 4 }} +rules: + - apiGroups: [""] + resources: ["secrets","namespaces"] + verbs: ["get", "list"] + - apiGroups: [ "" ] + resources: [ "pods" ] + verbs: [ "get", "list", "watch" ] + - apiGroups: [""] + resources: ["persistentvolumes", "services"] + verbs: ["get", "list", "watch", "create", "delete", "update", "patch"] + - apiGroups: [""] + resources: ["persistentvolumeclaims"] + verbs: ["get", "list", "watch", "update"] + - apiGroups: [""] + resources: ["persistentvolumeclaims/status"] + verbs: ["update", "patch"] + - apiGroups: ["storage.k8s.io"] + resources: ["storageclasses", "csinodes"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["events"] + verbs: ["list", "watch", "create", "update", "patch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshots"] + verbs: ["get", "list"] + - apiGroups: ["storage.k8s.io"] + resources: ["volumeattachments"] + verbs: ["get", "list", "watch", "create", "delete", "update", "patch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotcontents"] + verbs: ["get", "list"] + - apiGroups: ["coordination.k8s.io"] + resources: ["leases"] + verbs: ["*"] + - apiGroups: ["*"] + resources: ["cstorvolumeattachments", "cstorvolumes","cstorvolumeconfigs"] + verbs: ["*"] +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: openebs-cstor-csi-provisioner-binding + labels: + {{- include "cstor.csiController.labels" . | nindent 4 }} +subjects: + - kind: ServiceAccount + name: {{ .Values.serviceAccount.csiController.name }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: openebs-cstor-csi-provisioner-role + apiGroup: rbac.authorization.k8s.io +--- +############################## CSI- Attacher ####################### +# Attacher must be able to work with PVs, nodes and VolumeAttachments +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: openebs-cstor-csi-attacher-role + labels: + {{- include "cstor.csiController.labels" . | nindent 4 }} +rules: + - apiGroups: [""] + resources: ["persistentvolumes"] + verbs: ["get", "list", "watch", "update"] + - apiGroups: [""] + resources: ["nodes"] + verbs: ["get", "list", "watch"] + - apiGroups: ["csi.storage.k8s.io"] + resources: ["csinodeinfos"] + verbs: ["get", "list", "watch"] + - apiGroups: ["storage.k8s.io"] + resources: ["volumeattachments", "csinodes"] + verbs: ["get", "list", "watch", "update"] + - apiGroups: [ "storage.k8s.io" ] + resources: [ "volumeattachments/status" ] + verbs: [ "patch" ] +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: openebs-cstor-csi-attacher-binding + labels: + {{- include "cstor.csiController.labels" . | nindent 4 }} +subjects: + - kind: ServiceAccount + name: {{ .Values.serviceAccount.csiController.name }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: openebs-cstor-csi-attacher-role + apiGroup: rbac.authorization.k8s.io +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: openebs-cstor-csi-cluster-registrar-role + labels: + {{- include "cstor.csiController.labels" . | nindent 4 }} +rules: + - apiGroups: ["csi.storage.k8s.io"] + resources: ["csidrivers"] + verbs: ["create", "delete"] +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: openebs-cstor-csi-cluster-registrar-binding + labels: + {{- include "cstor.csiController.labels" . | nindent 4 }} +subjects: + - kind: ServiceAccount + name: {{ .Values.serviceAccount.csiController.name }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: openebs-cstor-csi-cluster-registrar-role + apiGroup: rbac.authorization.k8s.io +{{- end }} diff --git a/helm/openebs/charts/cstor/templates/csi-controller.yaml b/helm/openebs/charts/cstor/templates/csi-controller.yaml new file mode 100644 index 0000000..335a056 --- /dev/null +++ b/helm/openebs/charts/cstor/templates/csi-controller.yaml @@ -0,0 +1,137 @@ +kind: StatefulSet +apiVersion: apps/v1 +metadata: + name: {{ template "cstor.fullname" . }}-csi-controller + {{- with .Values.csiController.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "cstor.csiController.labels" . | nindent 4 }} +spec: + selector: + matchLabels: + {{- include "cstor.csiController.matchLabels" . | nindent 6 }} + serviceName: "openebs-csi" + replicas: {{ .Values.csiController.replicas }} + template: + metadata: + labels: + {{- include "cstor.csiController.labels" . | nindent 8 }} + {{- if .Values.csiController.podLabels }} + {{ toYaml .Values.csiController.podLabels | nindent 8 }} + {{- end }} + spec: + priorityClassName: {{ template "cstor.csiController.priorityClassName" . }} + serviceAccountName: {{ .Values.serviceAccount.csiController.name }} + containers: + - name: {{ .Values.csiController.resizer.name }} + image: "{{ .Values.csiController.resizer.image.registry }}{{ .Values.csiController.resizer.image.repository }}:{{ .Values.csiController.resizer.image.tag }}" + resources: +{{ toYaml .Values.csiController.resources | indent 12 }} + args: + - "--v={{ .Values.csiController.resizer.logLevel | default .Values.csiController.logLevel }}" + - "--csi-address=$(ADDRESS)" + - "--leader-election" + env: + - name: ADDRESS + value: /var/lib/csi/sockets/pluginproxy/csi.sock + imagePullPolicy: {{ .Values.csiController.resizer.image.pullPolicy }} + volumeMounts: + - name: socket-dir + mountPath: /var/lib/csi/sockets/pluginproxy/ + - name: {{ .Values.csiController.snapshotter.name }} + image: "{{ .Values.csiController.snapshotter.image.registry }}{{ .Values.csiController.snapshotter.image.repository }}:{{ .Values.csiController.snapshotter.image.tag }}" + args: + - "--csi-address=$(ADDRESS)" + env: + - name: ADDRESS + value: /var/lib/csi/sockets/pluginproxy/csi.sock + imagePullPolicy: {{ .Values.csiController.snapshotter.image.pullPolicy }} + volumeMounts: + - name: socket-dir + mountPath: /var/lib/csi/sockets/pluginproxy/ + - name: {{ .Values.csiController.snapshotController.name }} + image: "{{ .Values.csiController.snapshotController.image.registry }}{{ .Values.csiController.snapshotController.image.repository }}:{{ .Values.csiController.snapshotController.image.tag }}" + args: + - "--v={{ .Values.csiController.snapshotController.logLevel | default .Values.csiController.logLevel }}" + - "--leader-election=false" + imagePullPolicy: {{ .Values.csiController.snapshotController.image.pullPolicy }} + - name: {{ .Values.csiController.provisioner.name }} + image: "{{ .Values.csiController.provisioner.image.registry }}{{ .Values.csiController.provisioner.image.repository }}:{{ .Values.csiController.provisioner.image.tag }}" + imagePullPolicy: {{ .Values.csiController.provisioner.image.pullPolicy }} + args: + - "--csi-address=$(ADDRESS)" + - "--v={{ .Values.csiController.provisioner.logLevel | default .Values.csiController.logLevel }}" + - "--feature-gates=Topology=true" + - "--extra-create-metadata=true" + - "--metrics-address=:22011" + - "--timeout=250s" + - "--default-fstype=ext4" + env: + - name: MY_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: ADDRESS + value: /var/lib/csi/sockets/pluginproxy/csi.sock + volumeMounts: + - name: socket-dir + mountPath: /var/lib/csi/sockets/pluginproxy/ + - name: {{ .Values.csiController.attacher.name }} + image: "{{ .Values.csiController.attacher.image.registry }}{{ .Values.csiController.attacher.image.repository }}:{{ .Values.csiController.attacher.image.tag }}" + imagePullPolicy: {{ .Values.csiController.attacher.image.pullPolicy }} + args: + - "--v={{ .Values.csiController.attacher.logLevel | default .Values.csiController.logLevel }}" + - "--csi-address=$(ADDRESS)" + env: + - name: ADDRESS + value: /var/lib/csi/sockets/pluginproxy/csi.sock + volumeMounts: + - name: socket-dir + mountPath: /var/lib/csi/sockets/pluginproxy/ + - name: {{ .Values.cstorCSIPlugin.name }} + image: "{{ .Values.cstorCSIPlugin.image.registry }}{{ .Values.cstorCSIPlugin.image.repository }}:{{ .Values.cstorCSIPlugin.image.tag }}" + imagePullPolicy: {{ .Values.cstorCSIPlugin.image.pullPolicy }} + env: + - name: OPENEBS_CONTROLLER_DRIVER + value: controller + - name: OPENEBS_CSI_ENDPOINT + value: unix:///var/lib/csi/sockets/pluginproxy/csi.sock + - name: OPENEBS_CSI_API_URL + value: https://openebs.io + # OpenEBS namespace where the openebs cstor operator components + # has been installed + - name: OPENEBS_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: OPENEBS_IO_INSTALLER_TYPE + value: "cstor-helm" + - name: OPENEBS_IO_ENABLE_ANALYTICS + value: "{{ .Values.analytics.enabled }}" + args : + - "--endpoint=$(OPENEBS_CSI_ENDPOINT)" + - "--url=$(OPENEBS_CSI_API_URL)" + - "--plugin=$(OPENEBS_CONTROLLER_DRIVER)" + volumeMounts: + - name: socket-dir + mountPath: /var/lib/csi/sockets/pluginproxy/ + volumes: + - name: socket-dir + emptyDir: {} +{{- if .Values.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | indent 2 }} +{{- end }} +{{- if .Values.csiController.nodeSelector }} + nodeSelector: +{{ toYaml .Values.csiController.nodeSelector | indent 8 }} +{{- end }} +{{- if .Values.csiController.securityContext }} + securityContext: +{{ toYaml .Values.csiController.securityContext | indent 8 }} +{{- end }} +{{- if .Values.csiController.tolerations }} + tolerations: +{{ toYaml .Values.csiController.tolerations | indent 8 }} +{{- end }} diff --git a/helm/openebs/charts/cstor/templates/csi-driver.yaml b/helm/openebs/charts/cstor/templates/csi-driver.yaml new file mode 100644 index 0000000..fbb9b8e --- /dev/null +++ b/helm/openebs/charts/cstor/templates/csi-driver.yaml @@ -0,0 +1,16 @@ +{{- if .Values.csiDriver.create -}} +apiVersion: storage.k8s.io/v1 +kind: CSIDriver +metadata: + name: cstor.csi.openebs.io +spec: + # Supports persistent inline volumes. + volumeLifecycleModes: + - Persistent + # Not yet supported but added just to support upgrade control plane seamlessly + - Ephemeral + # To determine at runtime which mode a volume uses, pod info and its + # "csi.storage.k8s.io/ephemeral" entry are needed. + podInfoOnMount: {{ .Values.csiDriver.podInfoOnMount }} + attachRequired: {{ .Values.csiDriver.attachRequired }} +{{- end }} \ No newline at end of file diff --git a/helm/openebs/charts/cstor/templates/csi-iscsiadm-config.yaml b/helm/openebs/charts/cstor/templates/csi-iscsiadm-config.yaml new file mode 100644 index 0000000..4c134ad --- /dev/null +++ b/helm/openebs/charts/cstor/templates/csi-iscsiadm-config.yaml @@ -0,0 +1,18 @@ +kind: ConfigMap +apiVersion: v1 +metadata: + name: openebs-cstor-csi-iscsiadm +data: + iscsiadm: | + #!/bin/sh + if [ -x /host/sbin/iscsiadm ]; then + chroot /host /sbin/iscsiadm "$@" + elif [ -x /host/usr/local/sbin/iscsiadm ]; then + chroot /host /usr/local/sbin/iscsiadm "$@" + elif [ -x /host/bin/iscsiadm ]; then + chroot /host /bin/iscsiadm "$@" + elif [ -x /host/usr/local/bin/iscsiadm ]; then + chroot /host /usr/local/bin/iscsiadm "$@" + else + chroot /host iscsiadm "$@" + fi diff --git a/helm/openebs/charts/cstor/templates/csi-node-rbac.yaml b/helm/openebs/charts/cstor/templates/csi-node-rbac.yaml new file mode 100644 index 0000000..4af703b --- /dev/null +++ b/helm/openebs/charts/cstor/templates/csi-node-rbac.yaml @@ -0,0 +1,73 @@ +{{- if .Values.serviceAccount.csiNode.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .Values.serviceAccount.csiNode.name }} + labels: + {{- include "cstor.csiNode.labels" . | nindent 4 }} + namespace: {{ .Release.Namespace }} +{{- end }} +{{- if .Values.rbac.create }} +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: openebs-cstor-csi-registrar-role + labels: + {{- include "cstor.csiNode.labels" . | nindent 4 }} +rules: + - apiGroups: [""] + resources: ["events"] + verbs: ["get", "list", "watch", "create", "update", "patch"] + - apiGroups: [""] + resources: ["persistentvolumes", "nodes", "services"] + verbs: ["get", "list", "patch"] + - apiGroups: ["*"] + resources: ["cstorvolumeattachments", "cstorvolumes","cstorvolumeconfigs"] + verbs: ["get", "list", "watch", "create", "update", "delete", "patch"] +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: openebs-cstor-csi-registrar-binding + labels: + {{- include "cstor.csiNode.labels" . | nindent 4 }} +subjects: + - kind: ServiceAccount + name: {{ .Values.serviceAccount.csiNode.name }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: openebs-cstor-csi-registrar-role + apiGroup: rbac.authorization.k8s.io +{{- if .Values.rbac.pspEnabled }} +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: openebs-cstor-csi-node-role + labels: + {{- include "cstor.csiNode.labels" . | nindent 4 }} +rules: +- apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - openebs-cstor-csi-node-psp +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: openebs-cstor-csi-node-binding + labels: + {{- include "cstor.csiNode.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: openebs-cstor-csi-node-role +subjects: + - kind: ServiceAccount + name: {{ .Values.serviceAccount.csiNode.name }} + namespace: {{ $.Release.Namespace }} +{{- end }} +{{- end }} diff --git a/helm/openebs/charts/cstor/templates/csi-node.yaml b/helm/openebs/charts/cstor/templates/csi-node.yaml new file mode 100644 index 0000000..df4c2df --- /dev/null +++ b/helm/openebs/charts/cstor/templates/csi-node.yaml @@ -0,0 +1,143 @@ +kind: DaemonSet +apiVersion: apps/v1 +metadata: + name: {{ template "cstor.fullname" . }}-csi-node + {{- with .Values.csiNode.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "cstor.csiNode.labels" . | nindent 4 }} +spec: + selector: + matchLabels: + {{- include "cstor.csiNode.matchLabels" . | nindent 6 }} + template: + metadata: + labels: + {{- include "cstor.csiNode.labels" . | nindent 8 }} + {{- if .Values.csiNode.podLabels }} + {{ toYaml .Values.csiNode.podLabels | nindent 8 }} + {{- end }} + spec: + priorityClassName: {{ template "cstor.csiNode.priorityClassName" . }} + serviceAccountName: {{ .Values.serviceAccount.csiNode.name }} + hostNetwork: true + containers: + - name: {{ .Values.csiNode.driverRegistrar.name }} + image: "{{ .Values.csiNode.driverRegistrar.image.registry }}{{ .Values.csiNode.driverRegistrar.image.repository }}:{{ .Values.csiNode.driverRegistrar.image.tag }}" + imagePullPolicy: {{ .Values.csiNode.driverRegistrar.image.pullPolicy }} + resources: +{{ toYaml .Values.csiNode.resources | indent 12 }} + args: + - "--v={{ .Values.csiNode.driverRegistrar.logLevel | default .Values.csiNode.logLevel }}" + - "--csi-address=$(ADDRESS)" + - "--kubelet-registration-path=$(DRIVER_REG_SOCK_PATH)" + lifecycle: + preStop: + exec: + command: ["/bin/sh", "-c", "rm -rf /registration/cstor.csi.openebs.io /registration/cstor.csi.openebs.io-reg.sock"] + env: + - name: ADDRESS + value: /plugin/csi.sock + - name: DRIVER_REG_SOCK_PATH + value: {{ .Values.csiNode.kubeletDir }}plugins/cstor.csi.openebs.io/csi.sock + - name: KUBE_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: NODE_DRIVER + value: openebs-cstor-csi + volumeMounts: + - name: plugin-dir + mountPath: /plugin + - name: registration-dir + mountPath: /registration + - name: {{ .Values.cstorCSIPlugin.name }} + securityContext: + privileged: true + allowPrivilegeEscalation: true + image: "{{ .Values.cstorCSIPlugin.image.registry }}{{ .Values.cstorCSIPlugin.image.repository }}:{{ .Values.cstorCSIPlugin.image.tag }}" + imagePullPolicy: {{ .Values.cstorCSIPlugin.image.pullPolicy }} + args: + - "--nodeid=$(OPENEBS_NODE_ID)" + - "--endpoint=$(OPENEBS_CSI_ENDPOINT)" + - "--url=$(OPENEBS_CSI_API_URL)" + - "--plugin=$(OPENEBS_NODE_DRIVER)" + env: + - name: OPENEBS_NODE_ID + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: OPENEBS_CSI_ENDPOINT + value: unix:///plugin/csi.sock + - name: OPENEBS_NODE_DRIVER + value: node + - name: OPENEBS_CSI_API_URL + value: https://openebs.io + # OpenEBS namespace where the openebs cstor operator components + # has been installed + - name: OPENEBS_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + # Enable/Disable auto-remount feature, when volumes + # recovers from the read-only state + - name: REMOUNT + value: "{{ .Values.cstorCSIPlugin.remount }}" + volumeMounts: + - name: plugin-dir + mountPath: /plugin + - name: device-dir + mountPath: /dev + - name: pods-mount-dir + mountPath: {{ .Values.csiNode.kubeletDir }} + # needed so that any mounts setup inside this container are + # propagated back to the host machine. + mountPropagation: "Bidirectional" + - name: host-root + mountPath: /host + mountPropagation: "HostToContainer" + - name: chroot-iscsiadm + mountPath: /sbin/iscsiadm + subPath: iscsiadm + volumes: + - name: device-dir + hostPath: + path: /dev + type: Directory + - name: registration-dir + hostPath: + path: {{ .Values.csiNode.kubeletDir }}plugins_registry/ + type: DirectoryOrCreate + - name: plugin-dir + hostPath: + path: {{ .Values.csiNode.kubeletDir }}plugins/cstor.csi.openebs.io/ + type: DirectoryOrCreate + - name: pods-mount-dir + hostPath: + path: {{ .Values.csiNode.kubeletDir }} + type: Directory + - name: chroot-iscsiadm + configMap: + defaultMode: 0555 + name: openebs-cstor-csi-iscsiadm + - name: host-root + hostPath: + path: / + type: Directory +{{- if .Values.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | indent 2 }} +{{- end }} +{{- if .Values.csiNode.nodeSelector }} + nodeSelector: +{{ toYaml .Values.csiNode.nodeSelector | indent 8 }} +{{- end }} +{{- if .Values.csiNode.securityContext }} + securityContext: +{{ toYaml .Values.csiNode.securityContext | indent 8 }} +{{- end }} +{{- if .Values.csiNode.tolerations }} + tolerations: +{{ toYaml .Values.csiNode.tolerations | indent 8 }} +{{- end }} diff --git a/helm/openebs/charts/cstor/templates/cspc-operator.yaml b/helm/openebs/charts/cstor/templates/cspc-operator.yaml new file mode 100644 index 0000000..7ba61d3 --- /dev/null +++ b/helm/openebs/charts/cstor/templates/cspc-operator.yaml @@ -0,0 +1,90 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "cstor.fullname" . }}-cspc-operator + {{- with .Values.cspcOperator.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "cstor.cspcOperator.labels" . | nindent 4 }} +spec: + selector: + matchLabels: + {{- include "cstor.cspcOperator.matchLabels" . | nindent 6 }} + replicas: {{ .Values.cspcOperator.replicas }} + strategy: + type: Recreate + template: + metadata: + {{- with .Values.cspcOperator.podAnnotations }} + annotations: {{ toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "cstor.cspcOperator.labels" . | nindent 8 }} + {{- if .Values.cspcOperator.podLabels }} + {{ toYaml .Values.cspcOperator.podLabels | nindent 8 }} + {{- end }} + spec: + serviceAccountName: {{ .Values.serviceAccount.cstorOperator.name }} + containers: + - name: {{ template "cstor.fullname" . }}-cspc-operator + imagePullPolicy: {{ .Values.cspcOperator.image.pullPolicy }} + image: "{{ .Values.cspcOperator.image.registry }}{{ .Values.cspcOperator.image.repository }}:{{ .Values.cspcOperator.image.tag }}" + resources: +{{ toYaml .Values.cspcOperator.resources | indent 12 }} + env: + - name: OPENEBS_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: OPENEBS_SERVICEACCOUNT_NAME + valueFrom: + fieldRef: + fieldPath: spec.serviceAccountName + - name: CSPC_OPERATOR_POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name +{{- if .Values.cspcOperator.baseDir }} + # OPENEBS_IO_BASE_DIR is used to configure base directory for openebs on host path. + # Where OpenEBS can store required files. Default base path will be /var/openebs + - name: OPENEBS_IO_BASE_DIR + value: {{ .Values.cspcOperator.baseDir | quote }} +{{- end }} +{{- if .Values.cspcOperator.sparseDir }} + # OPENEBS_IO_CSTOR_POOL_SPARSE_DIR can be used to specify the hostpath + # to be used for saving the shared content between the side cars + # of cstor pool pod. This ENV is also used to indicate the location + # of the sparse devices. + # The default path used is /var/openebs/sparse + - name: OPENEBS_IO_CSTOR_POOL_SPARSE_DIR + value: "{{ .Values.cspcOperator.sparseDir }}" +{{- end }} + - name: OPENEBS_IO_CSPI_MGMT_IMAGE + value: "{{ .Values.cspcOperator.poolManager.image.registry }}{{ .Values.cspcOperator.poolManager.image.repository }}:{{ .Values.cspcOperator.poolManager.image.tag }}" + - name: OPENEBS_IO_CSTOR_POOL_IMAGE + value: "{{ .Values.cspcOperator.cstorPool.image.registry }}{{ .Values.cspcOperator.cstorPool.image.repository }}:{{ .Values.cspcOperator.cstorPool.image.tag }}" + - name: OPENEBS_IO_CSTOR_POOL_EXPORTER_IMAGE + value: "{{ .Values.cspcOperator.cstorPoolExporter.image.registry }}{{ .Values.cspcOperator.cstorPoolExporter.image.repository }}:{{ .Values.cspcOperator.cstorPoolExporter.image.tag }}" + - name: RESYNC_INTERVAL + value: "{{ .Values.cspcOperator.resyncInterval }}" +{{- if .Values.imagePullSecrets }} + - name: OPENEBS_IO_IMAGE_PULL_SECRETS + value: "{{- range $.Values.imagePullSecrets }}{{ .name }},{{- end }}" +{{- end }} +{{- if .Values.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | indent 2 }} +{{- end }} +{{- if .Values.cspcOperator.nodeSelector }} + nodeSelector: +{{ toYaml .Values.cspcOperator.nodeSelector | indent 8 }} +{{- end }} +{{- if .Values.cspcOperator.securityContext }} + securityContext: +{{ toYaml .Values.cspcOperator.securityContext | indent 8 }} +{{- end }} +{{- if .Values.cspcOperator.tolerations }} + tolerations: +{{ toYaml .Values.cspcOperator.tolerations | indent 8 }} +{{- end }} diff --git a/helm/openebs/charts/cstor/templates/cvc-operator-service.yaml b/helm/openebs/charts/cstor/templates/cvc-operator-service.yaml new file mode 100644 index 0000000..2962838 --- /dev/null +++ b/helm/openebs/charts/cstor/templates/cvc-operator-service.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ template "cstor.fullname" . }}-cvc-operator-svc + labels: + {{- include "cstor.cvcOperatorService.labels" . | nindent 4 }} +spec: + ports: + - name: api + port: 5757 + protocol: TCP + targetPort: 5757 + selector: + name: cvc-operator + sessionAffinity: None diff --git a/helm/openebs/charts/cstor/templates/cvc-operator.yaml b/helm/openebs/charts/cstor/templates/cvc-operator.yaml new file mode 100644 index 0000000..22cd81c --- /dev/null +++ b/helm/openebs/charts/cstor/templates/cvc-operator.yaml @@ -0,0 +1,80 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "cstor.fullname" . }}-cvc-operator + {{- with .Values.cvcOperator.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "cstor.cvcOperator.labels" . | nindent 4 }} +spec: + selector: + matchLabels: + {{- include "cstor.cvcOperator.matchLabels" . | nindent 6 }} + replicas: {{ .Values.cvcOperator.replicas }} + strategy: + type: Recreate + template: + metadata: + labels: + {{- include "cstor.cvcOperator.labels" . | nindent 8 }} + {{- if .Values.cvcOperator.podLabels }} + {{ toYaml .Values.cvcOperator.podLabels | nindent 8 }} + {{- end }} + spec: + serviceAccountName: {{ .Values.serviceAccount.cstorOperator.name }} + containers: + - name: {{ template "cstor.fullname" . }}-cvc-operator + imagePullPolicy: {{ .Values.cvcOperator.image.pullPolicy }} + image: "{{ .Values.cvcOperator.image.registry }}{{ .Values.cvcOperator.image.repository }}:{{ .Values.cvcOperator.image.tag }}" + args: + - "--v={{ .Values.cvcOperator.logLevel }}" + - "--leader-election=false" + - "--bind=$(OPENEBS_CVC_POD_IP)" + resources: +{{ toYaml .Values.cvcOperator.resources | indent 12 }} + env: +{{- if .Values.cvcOperator.baseDir }} + # OPENEBS_IO_BASE_DIR is used to configure base directory for openebs on host path. + # Where OpenEBS can store required files. Default base path will be /var/openebs + - name: OPENEBS_IO_BASE_DIR + value: "{{ .Values.cvcOperator.baseDir }}" +{{- end }} + - name: OPENEBS_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: OPENEBS_SERVICEACCOUNT_NAME + valueFrom: + fieldRef: + fieldPath: spec.serviceAccountName + - name: OPENEBS_CVC_POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: OPENEBS_IO_CSTOR_TARGET_IMAGE + value: "{{ .Values.cvcOperator.target.image.registry }}{{ .Values.cvcOperator.target.image.repository }}:{{ .Values.cvcOperator.target.image.tag }}" + - name: OPENEBS_IO_CSTOR_VOLUME_MGMT_IMAGE + value: "{{ .Values.cvcOperator.volumeMgmt.image.registry }}{{ .Values.cvcOperator.volumeMgmt.image.repository }}:{{ .Values.cvcOperator.volumeMgmt.image.tag }}" + - name: OPENEBS_IO_VOLUME_MONITOR_IMAGE + value: "{{ .Values.cvcOperator.volumeExporter.image.registry }}{{ .Values.cvcOperator.volumeExporter.image.repository }}:{{ .Values.cvcOperator.volumeExporter.image.tag }}" +{{- if .Values.imagePullSecrets }} + - name: OPENEBS_IO_IMAGE_PULL_SECRETS + value: "{{- range $.Values.imagePullSecrets }}{{ .name }},{{- end }}" +{{- end }} +{{- if .Values.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | indent 2 }} +{{- end }} +{{- if .Values.cvcOperator.nodeSelector }} + nodeSelector: +{{ toYaml .Values.cvcOperator.nodeSelector | indent 8 }} +{{- end }} +{{- if .Values.cvcOperator.securityContext }} + securityContext: +{{ toYaml .Values.cvcOperator.securityContext | indent 8 }} +{{- end }} +{{- if .Values.cvcOperator.tolerations }} + tolerations: +{{ toYaml .Values.cvcOperator.tolerations | indent 8 }} +{{- end }} diff --git a/helm/openebs/charts/cstor/templates/priority-class.yaml b/helm/openebs/charts/cstor/templates/priority-class.yaml new file mode 100644 index 0000000..3fef025 --- /dev/null +++ b/helm/openebs/charts/cstor/templates/priority-class.yaml @@ -0,0 +1,19 @@ +{{- if .Values.csiController.priorityClass.create }} +apiVersion: scheduling.k8s.io/v1 +kind: PriorityClass +metadata: + name: {{ template "cstor.csiController.priorityClassName" . }} +value: {{ .Values.csiController.priorityClass.value }} +globalDefault: false +description: "This priority class should be used for the CStor CSI driver controller deployment only." +{{- end }} +--- +{{- if .Values.csiNode.priorityClass.create }} +apiVersion: scheduling.k8s.io/v1 +kind: PriorityClass +metadata: + name: {{ template "cstor.csiNode.priorityClassName" . }} +value: {{ .Values.csiNode.priorityClass.value }} +globalDefault: false +description: "This priority class should be used for the CStor CSI driver node deployment only." +{{- end }} \ No newline at end of file diff --git a/helm/openebs/charts/cstor/templates/psp.yaml b/helm/openebs/charts/cstor/templates/psp.yaml new file mode 100644 index 0000000..138b52e --- /dev/null +++ b/helm/openebs/charts/cstor/templates/psp.yaml @@ -0,0 +1,24 @@ +{{- if .Values.rbac.pspEnabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: openebs-cstor-csi-node-psp + labels: + {{- include "cstor.csiNode.labels" . | nindent 4 }} +spec: + privileged: true + allowPrivilegeEscalation: true + allowedCapabilities: ['*'] + volumes: ['*'] + hostNetwork: true + hostIPC: true + hostPID: true + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'RunAsAny' + fsGroup: + rule: 'RunAsAny' +{{- end }} diff --git a/helm/openebs/charts/cstor/templates/rbac.yaml b/helm/openebs/charts/cstor/templates/rbac.yaml new file mode 100644 index 0000000..74845bd --- /dev/null +++ b/helm/openebs/charts/cstor/templates/rbac.yaml @@ -0,0 +1,117 @@ +{{- if .Values.serviceAccount.cstorOperator.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .Values.serviceAccount.cstorOperator.name }} + labels: + {{- include "cstor.common.metaLabels" . | 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: openebs-cstor-operator + {{- with .Values.serviceAccount.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "cstor.common.metaLabels" . | nindent 4 }} +rules: + - apiGroups: ["*"] + resources: ["nodes", "nodes/proxy"] + verbs: ["*"] + - apiGroups: ["*"] + resources: ["namespaces", "services", "pods", "deployments", "deployments/finalizers", "replicationcontrollers", "replicasets", "events", "endpoints", "configmaps", "secrets", "jobs", "cronjobs"] + verbs: ["*"] + - apiGroups: ["*"] + resources: ["statefulsets", "daemonsets"] + verbs: ["*"] + - apiGroups: ["*"] + resources: ["resourcequotas", "limitranges"] + verbs: ["list", "watch"] + - apiGroups: ["*"] + resources: ["certificatesigningrequests"] + verbs: ["list", "watch"] + - apiGroups: ["*"] + resources: ["storageclasses", "persistentvolumeclaims", "persistentvolumes"] + verbs: ["*"] + - apiGroups: ["apiextensions.k8s.io"] + resources: ["customresourcedefinitions"] + verbs: [ "get", "list", "create", "update", "delete", "patch"] + - apiGroups: ["openebs.io"] + resources: ["*"] + verbs: ["*" ] + - apiGroups: ["cstor.openebs.io"] + resources: ["*"] + verbs: ["*" ] + - apiGroups: ["coordination.k8s.io"] + resources: ["leases"] + verbs: ["get", "watch", "list", "delete", "update", "create"] + - apiGroups: ["admissionregistration.k8s.io"] + resources: ["validatingwebhookconfigurations", "mutatingwebhookconfigurations"] + verbs: ["get", "create", "list", "delete", "update", "patch"] + - nonResourceURLs: ["/metrics"] + verbs: ["get"] + - apiGroups: ["*"] + resources: ["upgradetasks","migrationtasks"] + verbs: ["*"] + - apiGroups: ["*"] + resources: ["poddisruptionbudgets"] + verbs: ["get", "list", "create", "delete", "watch"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: openebs-cstor-operator + {{- with .Values.serviceAccount.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "cstor.common.metaLabels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: openebs-cstor-operator +subjects: +- kind: ServiceAccount + name: {{ .Values.serviceAccount.cstorOperator.name }} + namespace: {{ .Release.Namespace }} +--- +# Define Role that allows operations required for migration of snapshots +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: openebs-cstor-migration + labels: + {{- include "cstor.common.metaLabels" . | nindent 4 }} +rules: + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotclasses"] + verbs: ["get", "list"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotcontents"] + verbs: ["create", "get", "list"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshots"] + verbs: ["create", "get", "list"] +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: openebs-cstor-migration + labels: + {{- include "cstor.common.metaLabels" . | nindent 4 }} +subjects: +- kind: ServiceAccount + name: {{ .Values.serviceAccount.cstorOperator.name }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: openebs-cstor-migration + apiGroup: rbac.authorization.k8s.io +{{- end }} diff --git a/helm/openebs/charts/cstor/templates/snapshot-class.yaml b/helm/openebs/charts/cstor/templates/snapshot-class.yaml new file mode 100644 index 0000000..e709b20 --- /dev/null +++ b/helm/openebs/charts/cstor/templates/snapshot-class.yaml @@ -0,0 +1,14 @@ +{{ if or (.Capabilities.APIVersions.Has "snapshot.storage.k8s.io/v1beta1/VolumeSnapshotClass") (.Capabilities.APIVersions.Has "snapshot.storage.k8s.io/v1/VolumeSnapshotClass") }} +kind: VolumeSnapshotClass +apiVersion: {{ if .Capabilities.APIVersions.Has "snapshot.storage.k8s.io/v1beta1/VolumeSnapshotClass" -}} + snapshot.storage.k8s.io/v1beta1 +{{- else -}} + snapshot.storage.k8s.io/v1 +{{- end }} +metadata: + name: csi-cstor-snapshotclass + annotations: + snapshot.storage.kubernetes.io/is-default-class: "true" +driver: cstor.csi.openebs.io +deletionPolicy: Delete +{{- end }} diff --git a/helm/openebs/charts/cstor/values.yaml b/helm/openebs/charts/cstor/values.yaml new file mode 100644 index 0000000..20b2f5a --- /dev/null +++ b/helm/openebs/charts/cstor/values.yaml @@ -0,0 +1,256 @@ +# Default values for cstor-operators. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +release: + version: "3.5.0" + +# If false, openebs NDM sub-chart will not be installed +openebsNDM: + enabled: true + +rbac: + # rbac.create: `true` if rbac resources should be created + create: true + # rbac.pspEnabled: `true` if PodSecurityPolicy resources should be created + pspEnabled: false + +imagePullSecrets: +# - name: "image-pull-secret" + +cspcOperator: + componentName: cspc-operator + poolManager: + image: + registry: + repository: openebs/cstor-pool-manager + tag: 3.5.0 + cstorPool: + image: + registry: + repository: openebs/cstor-pool + tag: 3.5.0 + cstorPoolExporter: + image: + registry: + repository: openebs/m-exporter + tag: 3.5.0 + image: + # Make sure that registry name end with a '/'. + # For example : quay.io/ is a correct value here and quay.io is incorrect + registry: + repository: openebs/cspc-operator + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: 3.5.0 + annotations: {} + resyncInterval: "30" + podAnnotations: {} + podLabels: {} + nodeSelector: {} + tolerations: [] + resources: {} + securityContext: {} + baseDir: "/var/openebs" + sparseDir: "/var/openebs/sparse" + +cvcOperator: + componentName: cvc-operator + target: + image: + registry: + repository: openebs/cstor-istgt + tag: 3.5.0 + volumeMgmt: + image: + registry: + repository: openebs/cstor-volume-manager + tag: 3.5.0 + volumeExporter: + image: + registry: + repository: openebs/m-exporter + tag: 3.5.0 + image: + # Make sure that registry name end with a '/'. + # For example : quay.io/ is a correct value here and quay.io is incorrect + registry: + repository: openebs/cvc-operator + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: 3.5.0 + annotations: {} + resyncInterval: "30" + podAnnotations: {} + podLabels: {} + nodeSelector: {} + tolerations: [] + resources: {} + securityContext: {} + baseDir: "/var/openebs" + logLevel: "2" + +csiController: + priorityClass: + create: true + name: cstor-csi-controller-critical + value: 900000000 + componentName: "openebs-cstor-csi-controller" + logLevel: "5" + resizer: + name: "csi-resizer" + image: + # Make sure that registry name end with a '/'. + # For example : quay.io/ is a correct value here and quay.io is incorrect + registry: registry.k8s.io/ + repository: sig-storage/csi-resizer + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: v1.8.0 + snapshotter: + name: "csi-snapshotter" + image: + # Make sure that registry name end with a '/'. + # For example : quay.io/ is a correct value here and quay.io is incorrect + registry: registry.k8s.io/ + repository: sig-storage/csi-snapshotter + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: v6.2.2 + snapshotController: + name: "snapshot-controller" + image: + # Make sure that registry name end with a '/'. + # For example : quay.io/ is a correct value here and quay.io is incorrect + registry: registry.k8s.io/ + repository: sig-storage/snapshot-controller + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: v6.2.2 + attacher: + name: "csi-attacher" + image: + # Make sure that registry name end with a '/'. + # For example : quay.io/ is a correct value here and quay.io is incorrect + registry: registry.k8s.io/ + repository: sig-storage/csi-attacher + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: v4.3.0 + provisioner: + name: "csi-provisioner" + image: + # Make sure that registry name end with a '/'. + # For example : quay.io/ is a correct value here and quay.io is incorrect + registry: registry.k8s.io/ + repository: sig-storage/csi-provisioner + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: v3.5.0 + annotations: {} + podAnnotations: {} + podLabels: {} + nodeSelector: {} + tolerations: [] + resources: {} + securityContext: {} + +cstorCSIPlugin: + name: cstor-csi-plugin + image: + # Make sure that registry name end with a '/'. + # For example : quay.io/ is a correct value here and quay.io is incorrect + registry: + repository: openebs/cstor-csi-driver + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: 3.5.0 + remount: "true" + +csiNode: + priorityClass: + create: true + name: cstor-csi-node-critical + value: 900001000 + componentName: "openebs-cstor-csi-node" + driverRegistrar: + name: "csi-node-driver-registrar" + image: + registry: registry.k8s.io/ + repository: sig-storage/csi-node-driver-registrar + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: v2.8.0 + logLevel: "5" + updateStrategy: + type: RollingUpdate + annotations: {} + podAnnotations: {} + resources: {} + # limits: + # cpu: 10m + # memory: 32Mi + # requests: + # cpu: 10m + # memory: 32Mi + ## Labels to be added to openebs-cstor-csi-node pods + podLabels: {} + # kubeletDir path can be configured to run on various different k8s distributions like + # microk8s where kubelet root dir is not (/var/lib/kubelet/). For example microk8s, + # we need to change the kubelet directory to `/var/snap/microk8s/common/var/lib/kubelet/` + kubeletDir: "/var/lib/kubelet/" + nodeSelector: {} + tolerations: [] + securityContext: {} + +csiDriver: + create: true + podInfoOnMount: true + attachRequired: false + +admissionServer: + componentName: cstor-admission-webhook + image: + # Make sure that registry name end with a '/'. + # For example : quay.io/ is a correct value here and quay.io is incorrect + registry: + repository: openebs/cstor-webhook + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: 3.5.0 + failurePolicy: "Fail" + annotations: {} + podAnnotations: {} + podLabels: {} + nodeSelector: {} + tolerations: [] + resources: {} + securityContext: {} + +serviceAccount: + # Annotations to add to the service account + annotations: {} + cstorOperator: + create: true + name: openebs-cstor-operator + csiController: + # Specifies whether a service account should be created + create: true + name: openebs-cstor-csi-controller-sa + csiNode: + # Specifies whether a service account should be created + create: true + name: openebs-cstor-csi-node-sa + +analytics: + enabled: true + # Specify in hours the duration after which a ping event needs to be sent. + pingInterval: "24h" + +cleanup: + image: + # Make sure that registry name end with a '/'. + # For example : quay.io/ is a correct value here and quay.io is incorrect + registry: + repository: bitnami/kubectl + tag: diff --git a/helm/openebs/charts/jiva/.helmignore b/helm/openebs/charts/jiva/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/helm/openebs/charts/jiva/.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/helm/openebs/charts/jiva/Chart.lock b/helm/openebs/charts/jiva/Chart.lock new file mode 100644 index 0000000..ab10f2f --- /dev/null +++ b/helm/openebs/charts/jiva/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: localpv-provisioner + repository: https://openebs.github.io/dynamic-localpv-provisioner + version: 3.4.1 +digest: sha256:44aedfe520f39f2587bf3ea06d225f176ee7b56aa6cb5d3e6b2a16545d2d1222 +generated: "2023-09-05T07:30:05.174651007Z" diff --git a/helm/openebs/charts/jiva/Chart.yaml b/helm/openebs/charts/jiva/Chart.yaml new file mode 100644 index 0000000..a0919d4 --- /dev/null +++ b/helm/openebs/charts/jiva/Chart.yaml @@ -0,0 +1,29 @@ +apiVersion: v2 +appVersion: 3.5.0 +dependencies: +- condition: openebsLocalpv.enabled + name: localpv-provisioner + repository: https://openebs.github.io/dynamic-localpv-provisioner + version: 3.4.1 +description: Helm chart for OpenEBS Jiva Operator. Jiva provides highly available + replication block volumes to Kubernetes stateful workloads using the local storage + available on the Kubernetes nodes. +home: http://www.openebs.io/ +icon: https://raw.githubusercontent.com/cncf/artwork/master/projects/openebs/icon/color/openebs-icon-color.png +keywords: +- cloud-native-storage +- block-storage +- iSCSI +- storage +- jiva +- jiva-operator +maintainers: +- email: prateek.pandey@mayadata.io + name: prateekpandey14 +- email: shubham.bajpai@mayadata.io + name: shubham14bajpai +name: jiva +sources: +- https://github.com/openebs/jiva-operator +type: application +version: 3.5.1 diff --git a/helm/openebs/charts/jiva/README.md b/helm/openebs/charts/jiva/README.md new file mode 100644 index 0000000..40724ec --- /dev/null +++ b/helm/openebs/charts/jiva/README.md @@ -0,0 +1,218 @@ + +# OpenEBS Jiva + +[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) +![Release Charts](https://github.com/openebs/jiva-operator/workflows/Release%20Charts/badge.svg?branch=master) +![Chart Lint and Test](https://github.com/openebs/jiva-operator/workflows/Chart%20Lint%20and%20Test/badge.svg) + +OpenEBS Jiva helm chart for Kubernetes. This chart bootstraps OpenEBS jiva operators and csi driver deployment on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager + +**Homepage:** + +## Maintainers + +| Name | Email | Url | +| ---- | ------ | --- | +| prateekpandey14 | prateek.pandey@mayadata.io | | +| shubham14bajpai | shubham.bajpai@mayadata.io | | + +## Get Repo Info + +```console +helm repo add openebs-jiva https://openebs.github.io/jiva-operator +helm repo update +``` + +_See [helm repo](https://helm.sh/docs/helm/helm_repo/) for command documentation._ + +## Install Chart + +Please visit the [link](https://openebs.github.io/jiva-operator) for install instructions via helm3. + +```console +# Helm +helm install [RELEASE_NAME] openebs-jiva/jiva --namespace [NAMESPACE] --create-namespace +``` + +_See [configuration](#configuration) below._ + +_See [helm install](https://helm.sh/docs/helm/helm_install/) for command documentation._ + + +## Dependencies + +By default this chart installs additional, dependent charts: + +| Repository | Name | Version | +|------------|------|---------| +| https://openebs.github.io/dynamic-localpv-provisioner | localpv-provisioner | 3.4.1 | + +**Note:** Find detailed Dynamic LocalPV Provisioner Helm chart configuration options [here](https://github.com/openebs/dynamic-localpv-provisioner/blob/develop/deploy/helm/charts/README.md). + +To disable the dependency during installation, set `openebsLocalpv.enabled` to `false`. + +```console +helm install openebs-jiva/jiva --namespace --create-namespace --set openebsLocalpv.enabled=false +``` + +For more details on dependency see [Jiva chart readme](https://github.com/openebs/jiva-operator/blob/master/deploy/helm/charts/README.md). + +_See [helm dependency](https://helm.sh/docs/helm/helm_dependency/) for command documentation._ + +## Uninstall Chart + +```console +# Helm +helm uninstall [RELEASE_NAME] --namespace [NAMESPACE] +``` + +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._ + +## Upgrading Chart + +```console +# Helm +helm upgrade [RELEASE_NAME] [CHART] --install --namespace [NAMESPACE] +``` + +## Configuration + +The following table lists the configurable parameters of the OpenEBS Jiva chart and their default values. +You can modify different parameters by specifying the desired value in the helm install command by using the `--set` and/or the `--set-string` flag(s). You can modify the parameters of the [Dynamic LocalPV Provisioner chart](https://openebs.github.io/dynamic-localpv-provisioner) by adding `localpv-provisioner` before the desired parameter in the helm install command. + +In the following sample command we modify `csiNode.nodeSelector` from the Jiva chart to only use the NodeSelector label `openebs.io/data-plane=true` to schedule the openebs-jiva-csi-node DaemonSet pods, and we also modify `hostpathClass.basePath` from the localpv-provisioner chart to change the BasePath directory to '/data' used by the openebs-hostpath StorageClass. + +```console +helm install openebs-jiva openebs-jiva/jiva -n openebs --create-namespace \ + --set-string csiNode.nodeSelector."openebs\.io/data-plane"=true \ + --set-string localpv-provisioner.hostpathClass.basePath="/data" +``` + +The Dynamic LocalPV Provisioner helm chart (this is a dependency for the Jiva helm chart) includes the [Node Disk Manager (NDM)](https://openebs.github.io/node-disk-manager/) helm chart. This NDM helm chart is disabled by default. You can enable the NDM chart during installation using flags as shown below: + +```console +helm install openebs-jiva openebs-jiva/jiva -n openebs --create-namespace \ + --set localpv-provisioner.openebsNDM.enabled=true \ + --set localpv-provisioner.deviceClass.enabled=true +``` + +If you have already installed Jiva without NDM, and would like to enable it after installation, use the following command: + +```console +helm upgrade openebs-jiva openebs-jiva/jiva -n openebs \ + --set localpv-provisioner.openebsNDM.enabled=true \ + --set localpv-provisioner.deviceClass.enabled=true +``` + +| Key | Type | Default | Description | +|-----|----------------------|---------------------------------------------------------|-------------| +| csiController.annotations | object | `{}` | CSI controller annotations | +| csiController.attacher.image.pullPolicy | string | `"IfNotPresent"` | CSI attacher image pull policy | +| csiController.attacher.image.registry | string | `"registry.k8s.io/"` | CSI attacher image registry | +| csiController.attacher.image.repository | string | `"sig-storage/csi-attacher"` | CSI attacher image repo | +| csiController.attacher.image.tag | string | `"v4.3.0"` | CSI attacher image tag | +| csiController.attacher.logLevel | string | _unspecified_ | Override CSI attacher container log level (1 = least verbose, 5 = most verbose) | +| csiController.attacher.name | string | `"csi-attacher"` | CSI attacher container name| +| csiController.componentName | string | `""` | CSI controller component name | +| csiController.livenessprobe.image.pullPolicy | string | `"IfNotPresent"` | CSI livenessprobe image pull policy | +| csiController.livenessprobe.image.registry | string | `"registry.k8s.io/"` | CSI livenessprobe image registry | +| csiController.livenessprobe.image.repository | string | `"sig-storage/livenessprobe"` | CSI livenessprobe image repo | +| csiController.livenessprobe.image.tag | string | `"v2.10.0"` | CSI livenessprobe image tag | +| csiController.livenessprobe.name | string | `"liveness-probe"` | CSI livenessprobe container name| +| csiController.logLevel | string | `"5"` | Default log level for all CSI controller containers (1 = least verbose, 5 = most verbose) unless overridden for a specific container | +| csiController.nodeSelector | object | `{}` | CSI controller pod node selector | +| csiController.podAnnotations | object | `{}` | CSI controller pod annotations | +| csiController.provisioner.image.pullPolicy | string | `"IfNotPresent"` | CSI provisioner image pull policy | +| csiController.provisioner.image.registry | string | `"registry.k8s.io/"` | CSI provisioner image pull registry | +| csiController.provisioner.image.repository | string | `"sig-storage/csi-provisioner"` | CSI provisioner image pull repository | +| csiController.provisioner.image.tag | string | `"v3.5.0"` | CSI provisioner image tag | +| csiController.provisioner.logLevel | string | _unspecified_ | Override CSI provisioner container log level (1 = least verbose, 5 = most verbose) | +| csiController.provisioner.name | string | `"csi-provisioner"` | CSI provisioner container name | +| csiController.resizer.image.pullPolicy | string | `"IfNotPresent"` | CSI resizer image pull policy | +| csiController.resizer.image.registry | string | `"registry.k8s.io/"` | CSI resizer image registry | +| csiController.resizer.image.repository | string | `"sig-storage/csi-resizer"` | CSI resizer image repository| +| csiController.resizer.image.tag | string | `"v1.8.0"` | CSI resizer image tag | +| csiController.resizer.logLevel | string | _unspecified_ | Override CSI resizer container log level (1 = least verbose, 5 = most verbose) | +| csiController.resizer.name | string | `"csi-resizer"` | CSI resizer container name | +| csiController.resources | object | `{}` | CSI controller container resources | +| csiController.securityContext | object | `{}` | CSI controller security context | +| csiController.tolerations | list | `[]` | CSI controller pod tolerations | +| csiNode.annotations | object | `{}` | CSI Node annotations | +| csiNode.componentName | string | `"openebs-jiva-csi-node"` | CSI Node component name | +| csiNode.driverRegistrar.image.pullPolicy | string | `"IfNotPresent"` | CSI Node driver registrar image pull policy| +| csiNode.driverRegistrar.image.registry | string | `"registry.k8s.io/"` | CSI Node driver registrar image registry | +| csiNode.driverRegistrar.image.repository | string | `"sig-storage/csi-node-driver-registrar"` | CSI Node driver registrar image repository | +| csiNode.driverRegistrar.image.tag | string | `"v2.8.0"` | CSI Node driver registrar image tag| +| csiNode.driverRegistrar.name | string | `"csi-node-driver-registrar"` | CSI Node driver registrar container name | +| csiNode.driverRegistrar.logLevel | string | _unspecified_ | Override CSI node driver registrar container log level (1 = least verbose, 5 = most verbose) | +| csiNode.kubeletDir | string | `"/var/lib/kubelet/"` | Kubelet root dir | +| csiNode.labels | object | `{}` | CSI Node pod labels | +| csiNode.logLevel | string | `"5"` | Default log level for all CSI node pod containers (1 = least verbose, 5 = most verbose) unless overridden for a specific container | +| csiNode.nodeSelector | object | `{}` | CSI Node pod nodeSelector | +| csiNode.podAnnotations | object | `{}` | CSI Node pod annotations | +| csiNode.resources | object | `{}` | CSI Node pod resources | +| csiNode.securityContext | object | `{}` | CSI Node pod security context | +| csiNode.tolerations | list | `[]` | CSI Node pod tolerations | +| csiNode.updateStrategy.type | string | `"RollingUpdate"` | CSI Node daemonset update strategy | +| csiNode.livenessprobe.image.pullPolicy | string | `"IfNotPresent"` | CSI livenessprobe image pull policy | +| csiNode.livenessprobe.image.registry | string | `"registry.k8s.io/"` | CSI livenessprobe image registry | +| csiNode.livenessprobe.image.repository | string | `"sig-storage/livenessprobe"` | CSI livenessprobe image repo | +| csiNode.livenessprobe.image.tag | string | `"v2.10.0"` | CSI livenessprobe image tag | +| csiNode.livenessprobe.name | string | `"liveness-probe"` | CSI livenessprobe container name| +| defaultPolicy.name | string | `"openebs-jiva-default-policy"` | Default jiva volume policy | +| defaultPolicy.enabled | bool | `true` | Enable default jiva volume policy | +| defaultPolicy.replicaSC | string | `"openebs-hostpath"` | StorageClass used for creating the PVC for the replica STS | +| defaultPolicy.replicas | string | `"3"` | The desired replication factor for the jiva volumes | +| storageClass.name | string | `"openebs-jiva-csi-default"` | Default jiva csi StorageClass | +| storageClass.enabled | bool | `true` | Enable default jiva csi StorageClass | +| storageClass.allowVolumeExpansion | bool | `true` | Enable volume expansion for the Volumes | +| storageClass.reclaimPolicy | string | `"Delete"` | Reclaim Policy for the StorageClass | +| storageClass.isDefaultClass | bool | `false` | Make jiva csi StorageClass as the default StorageClass | +| jivaOperator.annotations | object | `{}` | Jiva operator annotations | +| jivaOperator.componentName | string | `"jiva-operator"` | Jiva operator component name | +| jivaOperator.controller.image.registry | `nil` | Jiva volume controller container image registry | +| jivaOperator.controller.image.repository | `openebs/jiva` | Jiva volume controller container image repository | +| jivaOperator.controller.image.tag | `"3.5.0"` | Jiva volume controller container image tag | +| jivaOperator.exporter.image.registry | `nil` | Jiva volume metrics exporter container image registry | +| jivaOperator.exporter.image.repository | `openebs/m-exporter` | Jiva volume metrics exporter container image repository | +| jivaOperator.exporter.image.tag | `"3.5.0"` | Jiva volume metrics exporter container image tag | +| jivaOperator.image.pullPolicy | string | `"IfNotPresent"` | Jiva operator image pull policy | +| jivaOperator.image.registry | string | `nil` | Jiva operator image registry | +| jivaOperator.image.repository | string | `"openebs/jiva-operator"` | Jiva operator image repository | +| jivaOperator.image.tag | string | `"3.5.0"` | Jiva operator image tag | +| jivaOperator.nodeSelector | object | `{}` | Jiva operator pod nodeSelector| +| jivaOperator.podAnnotations | object | `{}` | Jiva operator pod annotations | +| jivaOperator.replica.image.registry | `nil` | Jiva volume replica container image registry | +| jivaOperator.replica.image.repository | `openebs/jiva` | Jiva volume replica container image repository | +| jivaOperator.replica.image.tag | `"3.5.0"` | Jiva volume replica container image tag | +| jivaOperator.resources | object | `{}` | Jiva operator pod resources | +| jivaOperator.securityContext | object | `{}` | Jiva operator security context | +| jivaOperator.tolerations | list | `[]` | Jiva operator pod tolerations | +| jivaCSIPlugin.image.pullPolicy | string | `"IfNotPresent"` | Jiva CSI driver image pull policy | +| jivaCSIPlugin.image.registry | string | `nil` | Jiva CSI driver image registry | +| jivaCSIPlugin.image.repository | string | `"openebs/jiva-csi"` | Jiva CSI driver image repository | +| jivaCSIPlugin.image.tag | string | `"3.5.0"` | Jiva CSI driver image tag | +| jivaCSIPlugin.name | string | `"jiva-csi-plugin"` | Jiva CSI driver container name | +| jivaCSIPlugin.remount | string | `"true"` | Jiva CSI driver remount feature, enabled by default | +| rbac.create | bool | `true` | Enable RBAC | +| rbac.pspEnabled | bool | `false` | Enable PodSecurityPolicy | +| release.version | string | `"3.5.0"` | Openebs Jiva release version | +| serviceAccount.annotations | object | `{}` | Service Account annotations | +| serviceAccount.csiController.create | bool | `true` | Enable CSI Controller ServiceAccount | +| serviceAccount.csiController.name | string | `"openebs-jiva-csi-controller-sa"` | CSI Controller ServiceAccount name | +| serviceAccount.csiNode.create | bool | `true` | Enable CSI Node ServiceAccount | +| serviceAccount.csiNode.name | string | `"openebs-jiva-csi-node-sa"` | CSI Node ServiceAccount name | +| serviceAccount.jivaOperator.create | bool | `true` | Enable Jiva Operator Node ServiceAccount | +| serviceAccount.jivaOperator.name | string | `"openebs-jiva-operator"` | Jiva Operator ServiceAccount name | + +Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. + +Alternatively, a YAML file that specifies the values for the parameters can be provided while installing the chart. For example, + +```bash +helm install -f values.yaml openebs-jiva/jiva +``` + +> **Tip**: You can use the default [values.yaml](values.yaml) diff --git a/helm/openebs/charts/jiva/charts/localpv-provisioner/.helmignore b/helm/openebs/charts/jiva/charts/localpv-provisioner/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/helm/openebs/charts/jiva/charts/localpv-provisioner/.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/helm/openebs/charts/jiva/charts/localpv-provisioner/Chart.lock b/helm/openebs/charts/jiva/charts/localpv-provisioner/Chart.lock new file mode 100644 index 0000000..4ff3a5c --- /dev/null +++ b/helm/openebs/charts/jiva/charts/localpv-provisioner/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: openebs-ndm + repository: https://openebs.github.io/node-disk-manager + version: 2.1.0 +digest: sha256:47adcc8a92ea7ce83ca7f37f05f9e2f4c10154adc9551bd92e92c1ca5608f131 +generated: "2023-08-16T16:46:46.773916076Z" diff --git a/helm/openebs/charts/jiva/charts/localpv-provisioner/Chart.yaml b/helm/openebs/charts/jiva/charts/localpv-provisioner/Chart.yaml new file mode 100644 index 0000000..4d1e73d --- /dev/null +++ b/helm/openebs/charts/jiva/charts/localpv-provisioner/Chart.yaml @@ -0,0 +1,27 @@ +apiVersion: v2 +appVersion: 3.4.0 +dependencies: +- condition: openebsNDM.enabled + name: openebs-ndm + repository: https://openebs.github.io/node-disk-manager + version: 2.1.0 +description: Helm chart for OpenEBS Dynamic Local PV. For instructions to install + OpenEBS Dynamic Local PV using helm chart, refer to https://openebs.github.io/dynamic-localpv-provisioner/. +home: http://www.openebs.io/ +icon: https://raw.githubusercontent.com/cncf/artwork/master/projects/openebs/icon/color/openebs-icon-color.png +keywords: +- storage +- local +- dynamic-localpv +maintainers: +- email: akhil.mohan@mayadata.io + name: akhilerm +- email: kiran.mova@mayadata.io + name: kiranmova +- email: prateek.pandey@mayadata.io + name: prateekpandey14 +name: localpv-provisioner +sources: +- https://github.com/openebs/dynamic-localpv-provisioner +type: application +version: 3.4.1 diff --git a/helm/openebs/charts/jiva/charts/localpv-provisioner/README.md b/helm/openebs/charts/jiva/charts/localpv-provisioner/README.md new file mode 100644 index 0000000..fe321ca --- /dev/null +++ b/helm/openebs/charts/jiva/charts/localpv-provisioner/README.md @@ -0,0 +1,160 @@ +# OpenEBS LocalPV Provisioner + +[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) +![Chart Lint and Test](https://github.com/openebs/dynamic-localpv-provisioner/workflows/Chart%20Lint%20and%20Test/badge.svg) +![Release Charts](https://github.com/openebs/dynamic-localpv-provisioner/workflows/Release%20Charts/badge.svg?branch=develop) + +A Helm chart for openebs dynamic localpv provisioner. This chart bootstraps OpenEBS Dynamic LocalPV provisioner deployment on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. + + +**Homepage:** + +## Maintainers + +| Name | Email | Url | +| ---- | ------ | --- | +| akhilerm | akhil.mohan@mayadata.io | | +| kiranmova | kiran.mova@mayadata.io | | +| prateekpandey14 | prateek.pandey@mayadata.io | | + + +## Get Repo Info + +```console +helm repo add openebs-localpv https://openebs.github.io/dynamic-localpv-provisioner +helm repo update +``` + +_See [helm repo](https://helm.sh/docs/helm/helm_repo/) for command documentation._ + +## Install Chart + +Please visit the [link](https://openebs.github.io/dynamic-localpv-provisioner/) for install instructions via helm3. + +```console +# Helm +helm install [RELEASE_NAME] openebs-localpv/localpv-provisioner --namespace [NAMESPACE] --create-namespace +``` + +_See [configuration](#configuration) below._ + +_See [helm install](https://helm.sh/docs/helm/helm_install/) for command documentation._ + +## Dependencies + +By default this chart installs additional, dependent charts: + +| Repository | Name | Version | +|------------|------|---------| +| https://openebs.github.io/node-disk-manager | openebs-ndm | 2.1.0 | + +**Note:** Find detailed Node Disk Manager Helm chart configuration options [here](https://github.com/openebs/node-disk-manager/blob/master/deploy/helm/charts/README.md). + + +To disable the dependency during installation, set `openebsNDM.enabled` to `false`. + +_See [helm dependency](https://helm.sh/docs/helm/helm_dependency/) for command documentation._ + +## Uninstall Chart + +```console +# Helm +helm uninstall [RELEASE_NAME] --namespace [NAMESPACE] +``` + +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._ + +## Upgrading Chart + +```console +# Helm +helm upgrade [RELEASE_NAME] [CHART] --install --namespace [NAMESPACE] +``` + + +## Configuration + +The following table lists the configurable parameters of the OpenEBS Dynamic LocalPV Provisioner chart and their default values. + +You can modify different parameters by specifying the desired value in the `helm install` command by using the `--set` and/or the `--set-string` flag(s). You can modify the parameters of the [Node Disk Manager chart](https://openebs.github.io/node-disk-manager) by adding `openebs-ndm` before the desired parameter in the `helm install` command. + +In the following sample command we modify `deviceClass.fsType` from the localpv-provisioner chart and `ndm.nodeSelector` from the openebs-ndm chart to only schedule openebs-ndm DaemonSet pods on nodes labelled with `openebs.io/data-plane=true`. We also enable the 'Use OS-disk' feature gate using the `featureGates.UseOSDisk.enabled` parameter from the openebs-ndm chart. + + +```console +helm install openebs-localpv openebs-localpv/localpv-provisioner --namespace openebs --create-namespace \ + --set-string deviceClass.fsType="xfs" \ + --set-string openebs-ndm.ndm.nodeSelector."openebs\.io/data-plane"=true \ + --set openebs-ndm.featureGates.UseOSDisk.enabled=true +``` + +Sample command to install the provisioner with nodeAffinityLabels "openebs.io/node-affinity-key-1" and "openebs.io/node-affinity-key-2" on the hostpath StorageClass: +```console +helm install openebs-localpv openebs-localpv/localpv-provisioner --namespace openebs --create-namespace \ + --set-string hostpathClass.nodeAffinityLabels="{openebs.io/node-affinity-key-1,openebs.io/node-affinity-key-2}" +``` + +Sample command to install the provisioner with blockDeviceSelectors "openebs.io/block-device-tag=mongo" and "ndm.io/fsType=ext4": +```console +helm install openebs-localpv openebs-localpv/localpv-provisioner --namespace openebs --create-namespace \ + --set-string deviceClass.blockDeviceSelectors."openebs\.io/block-device-tag"="mongo" \ + --set-string deviceClass.blockDeviceSelectors."ndm\.io/fsType"="ext4" +``` + +| Parameter | Description | Default | +| ------------------------------------------- | --------------------------------------------- | ----------------------------------------- | +| `release.version` | LocalPV Provisioner release version | `3.4.0` | +| `analytics.enabled` | Enable sending stats to Google Analytics | `true` | +| `analytics.pingInterval` | Duration(hours) between sending ping stat | `24h` | +| `deviceClass.blockDeviceSelectors` | Label key value pairs based on which BlockDevices on the node will be selected for provisioning | `{}` | +| `deviceClass.enabled` | Enables creation of default Device StorageClass | `true` | +| `deviceClass.fsType` | Filesystem type for openebs-device StorageClass | `"ext4"` | +| `deviceClass.isDefaultClass` | Make openebs-device the default StorageClass | `"false"` | +| `deviceClass.nodeAffinityLabels` | Custom node label(or labels) key to uniquely identify nodes. `kubernetes.io/hostname` is the default label key for node selection. | `[]` | +| `deviceClass.reclaimPolicy` | ReclaimPolicy for Device PVs | `"Delete"` | +| `helperPod.image.registry` | Registry for helper image | `""` | +| `helperPod.image.repository` | Image for helper pod | `"openebs/linux-utils"` | +| `helperPod.image.pullPolicy` | Pull policy for helper pod | `"IfNotPresent"` | +| `helperPod.image.tag` | Image tag for helper image | `3.4.0` | +| `hostpathClass.basePath` | BasePath for openebs-hostpath StorageClass | `"/var/openebs/local"` | +| `hostpathClass.enabled` | Enables creation of default Hostpath StorageClass | `true` | +| `hostpathClass.isDefaultClass` | Make openebs-hostpath the default StorageClass | `"false"` | +| `hostpathClass.nodeAffinityLabels` | Custom node label(or labels) key to uniquely identify nodes. `kubernetes.io/hostname` is the default label key for node selection. | `[]` | +| `hostpathClass.xfsQuota.enabled` | Enable XFS Quota (requires XFS filesystem) | `false` | +| `hostpathClass.ext4Quota.enabled` | Enable EXT4 Quota (requires EXT4 filesystem) | `false` | +| `hostpathClass.reclaimPolicy` | ReclaimPolicy for Hostpath PVs | `"Delete"` | +| `imagePullSecrets` | Provides image pull secrect | `""` | +| `localpv.enabled` | Enable LocalPV Provisioner | `true` | +| `localpv.image.registry` | Registry for LocalPV Provisioner image | `""` | +| `localpv.image.repository` | Image repository for LocalPV Provisioner | `openebs/localpv-provisioner` | +| `localpv.image.pullPolicy` | Image pull policy for LocalPV Provisioner | `IfNotPresent` | +| `localpv.image.tag` | Image tag for LocalPV Provisioner | `3.4.0` | +| `localpv.updateStrategy.type` | Update strategy for LocalPV Provisioner | `RollingUpdate` | +| `localpv.annotations` | Annotations for LocalPV Provisioner metadata | `""` | +| `localpv.podAnnotations` | Annotations for LocalPV Provisioner pods metadata | `""` | +| `localpv.privileged` | Run LocalPV Provisioner with extra privileges | `true` | +| `localpv.resources` | Resource and request and limit for containers | `""` | +| `localpv.podLabels` | Appends labels to the pods | `""` | +| `localpv.nodeSelector` | Nodeselector for LocalPV Provisioner pods | `""` | +| `localpv.tolerations` | LocalPV Provisioner pod toleration values | `""` | +| `localpv.securityContext` | Seurity context for container | `""` | +| `localpv.healthCheck.initialDelaySeconds` | Delay before liveness probe is initiated | `30` | +| `localpv.healthCheck.periodSeconds` | How often to perform the liveness probe | `60` | +| `localpv.replicas` | No. of LocalPV Provisioner replica | `1` | +| `localpv.enableLeaderElection` | Enable leader election | `true` | +| `localpv.affinity` | LocalPV Provisioner pod affinity | `{}` | +| `localpv.waitForBDBindTimeoutRetryCount` | This sets the number of times the provisioner should try with a polling interval of 5 seconds, to get the Blockdevice Name from a BlockDeviceClaim, before the BlockDeviceClaim is deleted. | "12" | +| `openebsNDM.enabled` | Install openebs NDM dependency | `true` | +| `rbac.create` | Enable RBAC Resources | `true` | +| `rbac.pspEnabled` | Create pod security policy resources | `false` | + + +A YAML file that specifies the values for the parameters can be provided while installing the chart. For example, + +```bash +helm install -f values.yaml --namespace openebs openebs-localpv/localpv-provisioner +``` + +> **Tip**: You can use the default [values.yaml](values.yaml) diff --git a/helm/openebs/charts/jiva/charts/localpv-provisioner/charts/openebs-ndm/Chart.yaml b/helm/openebs/charts/jiva/charts/localpv-provisioner/charts/openebs-ndm/Chart.yaml new file mode 100644 index 0000000..53484cd --- /dev/null +++ b/helm/openebs/charts/jiva/charts/localpv-provisioner/charts/openebs-ndm/Chart.yaml @@ -0,0 +1,23 @@ +apiVersion: v2 +appVersion: 2.1.0 +description: Helm chart for OpenEBS Node Disk Manager - a Kubernetes native storage + device management solution. For instructions on how to install, refer to https://openebs.github.io/node-disk-manager/. +home: http://www.openebs.io/ +icon: https://raw.githubusercontent.com/cncf/artwork/master/projects/openebs/icon/color/openebs-icon-color.png +keywords: +- cloud-native-storage +- block-storage +- ndm +- disk-inventory +- storage +maintainers: +- email: akhil.mohan@mayadata.io + name: akhilerm +- email: michaelfornaro@gmail.com + name: xUnholy +- email: prateek.pandey@mayadata.io + name: prateekpandey14 +name: openebs-ndm +sources: +- https://github.com/openebs/node-disk-manager +version: 2.1.0 diff --git a/helm/openebs/charts/jiva/charts/localpv-provisioner/charts/openebs-ndm/README.md b/helm/openebs/charts/jiva/charts/localpv-provisioner/charts/openebs-ndm/README.md new file mode 100644 index 0000000..399a687 --- /dev/null +++ b/helm/openebs/charts/jiva/charts/localpv-provisioner/charts/openebs-ndm/README.md @@ -0,0 +1,93 @@ +## Introduction + +This chart bootstraps OpenEBS NDM deployment on a [Kubernetes](http://kubernetes.io) cluster using the +[Helm](https://helm.sh) package manager. + +## Installation + +You can run OpenEBS NDM on any Kubernetes 1.17+ cluster in a matter of seconds. + +Please visit the [link](https://openebs.github.io/node-disk-manager/) for install instructions via helm3. + +## Configuration + +The following table lists the configurable parameters of the OpenEBS NDM chart and their default values. + +| Parameter | Description | Default | +|-------------------------------------------------------------|-------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------| +| `imagePullSecrets` | Provides image pull secrect | `""` | +| `ndm.enabled` | Enable Node Disk Manager | `true` | +| `ndm.image.registry` | Registry for Node Disk Manager image | `""` | +| `ndm.image.repository` | Image repository for Node Disk Manager | `openebs/node-disk-manager` | +| `ndm.image.pullPolicy` | Image pull policy for Node Disk Manager | `IfNotPresent` | +| `ndm.image.tag` | Image tag for Node Disk Manager | `2.1.0` | +| `ndm.sparse.path` | Directory where Sparse files are created | `/var/openebs/sparse` | +| `ndm.sparse.size` | Size of the sparse file in bytes | `10737418240` | +| `ndm.sparse.count` | Number of sparse files to be created | `0` | +| `ndm.updateStrategy.type` | Update strategy for NDM daemonset | `RollingUpdate` | +| `ndm.annotations` | Annotations for NDM daemonset metadata | `""` | +| `ndm.podAnnotations` | Annotations for NDM daemonset's pods metadata | `""` | +| `ndm.resources` | Resource and request and limit for containers | `""` | +| `ndm.podLabels` | Appends labels to the pods | `""` | +| `ndm.nodeSelector` | Nodeselector for daemonset pods | `""` | +| `ndm.tolerations` | NDM daemonset's pod toleration values | `""` | +| `ndm.securityContext` | Seurity context for container | `""` | +| `ndm.filters.enableOsDiskExcludeFilter` | Enable filters of OS disk exclude | `true` | +| `ndm.filters.osDiskExcludePaths` | Paths/Mountpoints to be excluded by OS Disk Filter | `/,/etc/hosts,/boot` | +| `ndm.filters.enableVendorFilter` | Enable filters of vendors | `true` | +| `ndm.filters.excludeVendors` | Exclude devices with specified vendor | `CLOUDBYT,OpenEBS` | +| `ndm.filters.enablePathFilter` | Enable filters of paths | `true` | +| `ndm.filters.includePaths` | Include devices with specified path patterns | `""` | +| `ndm.filters.excludePaths` | Exclude devices with specified path patterns | `loop,fd0,sr0,/dev/ram,/dev/dm-,/dev/md,/dev/rbd,/dev/zd` | +| `ndm.probes.enableSeachest` | Enable Seachest probe for NDM | `false` | +| `ndm.probes.enableUdevProbe` | Enable Udev probe for NDM | `true` | +| `ndm.probes.enableSmartProbe` | Enable Smart probe for NDM | `true` | +| `ndm.metaConfig.nodeLabelPattern` | Config for adding node labels as BD labels | `kubernetes.io*,beta.kubernetes.io*` | +| `ndm.metaConfig.deviceLabelTypes` | Config for adding device attributes as BD labels | `.spec.details.vendor,.spec.details.model,.spec.details.driveType,.spec.filesystem.fsType` | +| `ndmOperator.enabled` | Enable NDM Operator | `true` | +| `ndmOperator.replica` | Pod replica count for NDM operator | `1` | +| `ndmOperator.upgradeStrategy` | Update strategy NDM operator | `"Recreate"` | +| `ndmOperator.image.registry` | Registry for NDM operator image | `""` | +| `ndmOperator.image.repository` | Image repository for NDM operator | `openebs/node-disk-operator` | +| `ndmOperator.image.pullPolicy` | Image pull policy for NDM operator | `IfNotPresent` | +| `ndmOperator.image.tag` | Image tag for NDM operator | `2.1.0` | +| `ndmOperator.annotations` | Annotations for NDM operator metadata | `""` | +| `ndmOperator.podAnnotations` | Annotations for NDM operator's pods metadata | `""` | +| `ndmOperator.resources` | Resource and request and limit for containers | `""` | +| `ndmOperator.podLabels` | Appends labels to the pods | `""` | +| `ndmOperator.nodeSelector` | Nodeselector for operator pods | `""` | +| `ndmOperator.tolerations` | NDM operator's pod toleration values | `""` | +| `ndmOperator.securityContext` | Security context for container | `""` | +| `ndmExporter.enabled` | Enable NDM Exporters | `false` | +| `ndmExporter.image.registry` | Registry for NDM Exporters image | `""` | +| `ndmExporter.repository` | Image repository for NDM Exporters | `openebs/node-disk-exporter` | +| `ndmExporter.pullPolicy` | Image pull policy for NDM Exporters | `IfNotPresent` | +| `ndmExporter.tag` | Image tag for NDM Exporters | `2.1.0` | +| `ndmExporter.nodeExporter.metricsPort` | The TCP port number used for exposing NDM node exporter metrics | `9101` | +| `ndmExporter.nodeExporter.nodeExporter.nodeSelector` | Node selector for NDM node exporter pods | `9101` | +| `ndmExporter.nodeExporter.nodeExporter.tolerations` | NDM node exporter toleration values | `9101` | +| `ndmExporter.clusterExporter.metricsPort` | The TCP port number used for exposing NDM cluster exporter metrics | `9100` | +| `ndmExporter.clusterExporter.clusterExpoerter.nodeSelector` | Node selector for NDM cluster exporter pod | `9100` | +| `ndmExporter.clusterExporter.clusterExpoerter.tolerations` | NDM cluster exporter toleraion values | `9100` | +| `featureGates.APIService.enabled` | Enable the gRPC API service of NDM | `false` | +| `featureGates.UseOSDisk.enabled` | Enable feature-gate to use free space on OS disk | `false` | +| `featureGates.ChangeDetection.enabled` | Enable feature-gate to detect mountpoint/filesystem/size changes | `false` | +| `featureGates.PartitionTableUUID.enabled` | Enable feature-gate to use partition table UUID instead of creating partition | `true` | +| `helperPod.image.registry` | Registry for helper image | `""` | +| `helperPod.image.repository` | Image for helper pod | `openebs/linux-utils` | +| `helperPod.image.pullPolicy` | Pull policy for helper pod | `IfNotPresent` | +| `helperPod.image.tag` | Image tag for helper image | `3.4.0` | +| `varDirectoryPath.baseDir` | Directory to store debug info and so forth | `/var/openebs` | +| `serviceAccount.create` | Create a service account or not | `true` | +| `serviceAccount.name` | Name for the service account | `true` | + + +Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. + +Alternatively, a YAML file that specifies the values for the parameters can be provided while installing the chart. For example, + +```bash +helm install -f values.yaml ndm/openebs-ndm +``` + +> **Tip**: You can use the default [values.yaml](values.yaml) diff --git a/helm/openebs/charts/jiva/charts/localpv-provisioner/charts/openebs-ndm/crds/blockdevice.yaml b/helm/openebs/charts/jiva/charts/localpv-provisioner/charts/openebs-ndm/crds/blockdevice.yaml new file mode 100644 index 0000000..95f4070 --- /dev/null +++ b/helm/openebs/charts/jiva/charts/localpv-provisioner/charts/openebs-ndm/crds/blockdevice.yaml @@ -0,0 +1,241 @@ + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.5.0 + creationTimestamp: null + name: blockdevices.openebs.io +spec: + group: openebs.io + names: + kind: BlockDevice + listKind: BlockDeviceList + plural: blockdevices + shortNames: + - bd + singular: blockdevice + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.nodeAttributes.nodeName + name: NodeName + type: string + - jsonPath: .spec.path + name: Path + priority: 1 + type: string + - jsonPath: .spec.filesystem.fsType + name: FSType + priority: 1 + type: string + - jsonPath: .spec.capacity.storage + name: Size + type: string + - jsonPath: .status.claimState + name: ClaimState + type: string + - jsonPath: .status.state + name: Status + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: BlockDevice is the Schema for the blockdevices 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: DeviceSpec defines the properties and runtime status of a BlockDevice + properties: + aggregateDevice: + description: AggregateDevice was intended to store the hierarchical information in cases of LVM. However this is currently not implemented and may need to be re-looked into for better design. To be deprecated + type: string + capacity: + description: Capacity + properties: + logicalSectorSize: + description: LogicalSectorSize is blockdevice logical-sector size in bytes + format: int32 + type: integer + physicalSectorSize: + description: PhysicalSectorSize is blockdevice physical-Sector size in bytes + format: int32 + type: integer + storage: + description: Storage is the blockdevice capacity in bytes + format: int64 + type: integer + required: + - storage + type: object + claimRef: + description: ClaimRef is the reference to the BDC which has claimed this BD + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: 'If referring to a piece of an object instead of an entire object, this string should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. For example, if the object reference is to a container within a pod, this would take on a value like: "spec.containers{name}" (where "name" refers to the name of the container that triggered the event) or if no container name is specified "spec.containers[2]" (container with index 2 in this pod). This syntax is chosen only to have some well-defined way of referencing a part of an object. TODO: this design is not final and this field is subject to change in the future.' + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: 'Specific resourceVersion to which this reference is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + details: + description: Details contain static attributes of BD like model,serial, and so forth + properties: + compliance: + description: Compliance is standards/specifications version implemented by device firmware such as SPC-1, SPC-2, etc + type: string + deviceType: + description: DeviceType represents the type of device like sparse, disk, partition, lvm, crypt + enum: + - disk + - partition + - sparse + - loop + - lvm + - crypt + - dm + - mpath + type: string + driveType: + description: DriveType is the type of backing drive, HDD/SSD + enum: + - HDD + - SSD + - Unknown + - "" + type: string + firmwareRevision: + description: FirmwareRevision is the disk firmware revision + type: string + hardwareSectorSize: + description: HardwareSectorSize is the hardware sector size in bytes + format: int32 + type: integer + logicalBlockSize: + description: LogicalBlockSize is the logical block size in bytes reported by /sys/class/block/sda/queue/logical_block_size + format: int32 + type: integer + model: + description: Model is model of disk + type: string + physicalBlockSize: + description: PhysicalBlockSize is the physical block size in bytes reported by /sys/class/block/sda/queue/physical_block_size + format: int32 + type: integer + serial: + description: Serial is serial number of disk + type: string + vendor: + description: Vendor is vendor of disk + type: string + type: object + devlinks: + description: DevLinks contains soft links of a block device like /dev/by-id/... /dev/by-uuid/... + items: + description: DeviceDevLink holds the mapping between type and links like by-id type or by-path type link + properties: + kind: + description: Kind is the type of link like by-id or by-path. + enum: + - by-id + - by-path + type: string + links: + description: Links are the soft links + items: + type: string + type: array + type: object + type: array + filesystem: + description: FileSystem contains mountpoint and filesystem type + properties: + fsType: + description: Type represents the FileSystem type of the block device + type: string + mountPoint: + description: MountPoint represents the mountpoint of the block device. + type: string + type: object + nodeAttributes: + description: NodeAttributes has the details of the node on which BD is attached + properties: + nodeName: + description: NodeName is the name of the Kubernetes node resource on which the device is attached + type: string + type: object + parentDevice: + description: "ParentDevice was intended to store the UUID of the parent Block Device as is the case for partitioned block devices. \n For example: /dev/sda is the parent for /dev/sda1 To be deprecated" + type: string + partitioned: + description: Partitioned represents if BlockDevice has partitions or not (Yes/No) Currently always default to No. To be deprecated + enum: + - "Yes" + - "No" + type: string + path: + description: Path contain devpath (e.g. /dev/sdb) + type: string + required: + - capacity + - devlinks + - nodeAttributes + - path + type: object + status: + description: DeviceStatus defines the observed state of BlockDevice + properties: + claimState: + description: ClaimState represents the claim state of the block device + enum: + - Claimed + - Unclaimed + - Released + type: string + state: + description: State is the current state of the blockdevice (Active/Inactive/Unknown) + enum: + - Active + - Inactive + - Unknown + type: string + required: + - claimState + - state + type: object + type: object + served: true + storage: true + subresources: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/helm/openebs/charts/jiva/charts/localpv-provisioner/charts/openebs-ndm/crds/blockdeviceclaim.yaml b/helm/openebs/charts/jiva/charts/localpv-provisioner/charts/openebs-ndm/crds/blockdeviceclaim.yaml new file mode 100644 index 0000000..81b9a35 --- /dev/null +++ b/helm/openebs/charts/jiva/charts/localpv-provisioner/charts/openebs-ndm/crds/blockdeviceclaim.yaml @@ -0,0 +1,144 @@ + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.5.0 + creationTimestamp: null + name: blockdeviceclaims.openebs.io +spec: + group: openebs.io + names: + kind: BlockDeviceClaim + listKind: BlockDeviceClaimList + plural: blockdeviceclaims + shortNames: + - bdc + singular: blockdeviceclaim + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.blockDeviceName + name: BlockDeviceName + type: string + - jsonPath: .status.phase + name: Phase + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: BlockDeviceClaim is the Schema for the blockdeviceclaims 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: DeviceClaimSpec defines the request details for a BlockDevice + properties: + blockDeviceName: + description: BlockDeviceName is the reference to the block-device backing this claim + type: string + blockDeviceNodeAttributes: + description: BlockDeviceNodeAttributes is the attributes on the node from which a BD should be selected for this claim. It can include nodename, failure domain etc. + properties: + hostName: + description: HostName represents the hostname of the Kubernetes node resource where the BD should be present + type: string + nodeName: + description: NodeName represents the name of the Kubernetes node resource where the BD should be present + type: string + type: object + deviceClaimDetails: + description: Details of the device to be claimed + properties: + allowPartition: + description: AllowPartition represents whether to claim a full block device or a device that is a partition + type: boolean + blockVolumeMode: + description: 'BlockVolumeMode represents whether to claim a device in Block mode or Filesystem mode. These are use cases of BlockVolumeMode: 1) Not specified: VolumeMode check will not be effective 2) VolumeModeBlock: BD should not have any filesystem or mountpoint 3) VolumeModeFileSystem: BD should have a filesystem and mountpoint. If DeviceFormat is specified then the format should match with the FSType in BD' + type: string + formatType: + description: Format of the device required, eg:ext4, xfs + type: string + type: object + deviceType: + description: DeviceType represents the type of drive like SSD, HDD etc., + nullable: true + type: string + hostName: + description: Node name from where blockdevice has to be claimed. To be deprecated. Use NodeAttributes.HostName instead + type: string + resources: + description: Resources will help with placing claims on Capacity, IOPS + properties: + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum resources required. eg: if storage resource of 10G is requested minimum capacity of 10G should be available TODO for validating' + type: object + required: + - requests + type: object + selector: + description: Selector is used to find block devices to be considered for claiming + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + type: object + status: + description: DeviceClaimStatus defines the observed state of BlockDeviceClaim + properties: + phase: + description: Phase represents the current phase of the claim + type: string + required: + - phase + type: object + type: object + served: true + storage: true + subresources: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/helm/openebs/charts/jiva/charts/localpv-provisioner/charts/openebs-ndm/templates/NOTES.txt b/helm/openebs/charts/jiva/charts/localpv-provisioner/charts/openebs-ndm/templates/NOTES.txt new file mode 100644 index 0000000..3c84551 --- /dev/null +++ b/helm/openebs/charts/jiva/charts/localpv-provisioner/charts/openebs-ndm/templates/NOTES.txt @@ -0,0 +1,8 @@ +The OpenEBS Node Disk Manager has been installed. Check its status by running: +$ kubectl get pods -n {{ .Release.Namespace }} + +Use `kubectl get bd -n {{ .Release.Namespace }} ` to see the list of +blockdevices attached to the Kubernetes cluster nodes. + +For more information, visit our Slack at https://openebs.io/community or view +the documentation online at http://docs.openebs.io/. diff --git a/helm/openebs/charts/jiva/charts/localpv-provisioner/charts/openebs-ndm/templates/_helpers.tpl b/helm/openebs/charts/jiva/charts/localpv-provisioner/charts/openebs-ndm/templates/_helpers.tpl new file mode 100644 index 0000000..c975510 --- /dev/null +++ b/helm/openebs/charts/jiva/charts/localpv-provisioner/charts/openebs-ndm/templates/_helpers.tpl @@ -0,0 +1,242 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +This name is used for ndm daemonset +*/}} +{{- define "openebs-ndm.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "openebs-ndm.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified ndm daemonset 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 "openebs-ndm.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains .Release.Name $name }} +{{- $name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{- define "openebs-ndm.operator.name" -}} +{{- $ndmName := default .Chart.Name .Values.ndmOperator.nameOverride | trunc 63 | trimSuffix "-" }} +{{- $componentName := .Values.ndmOperator.name | trunc 63 | trimSuffix "-" }} +{{- printf "%s-%s" $ndmName $componentName | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified ndm operator 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 "openebs-ndm.operator.fullname" -}} +{{- if .Values.ndmOperator.fullnameOverride }} +{{- .Values.ndmOperator.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $ndmOperatorName := include "openebs-ndm.operator.name" .}} + +{{- $name := default $ndmOperatorName .Values.ndmOperator.nameOverride }} +{{- if contains .Release.Name $name }} +{{- $name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{- define "openebs-ndm.cluster-exporter.name" -}} +{{- $ndmName := default .Chart.Name .Values.ndmExporter.clusterExporter.nameOverride | trunc 63 | trimSuffix "-" }} +{{- $componentName := .Values.ndmExporter.clusterExporter.name | trunc 63 | trimSuffix "-" }} +{{- printf "%s-%s" $ndmName $componentName | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified ndm cluster exporter 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 "openebs-ndm.cluster-exporter.fullname" -}} +{{- if .Values.ndmExporter.clusterExporter.fullnameOverride }} +{{- .Values.ndmExporter.clusterExporter.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $ndmClusterExporterName := include "openebs-ndm.cluster-exporter.name" .}} + +{{- $name := default $ndmClusterExporterName .Values.ndmExporter.clusterExporter.nameOverride }} +{{- if contains .Release.Name $name }} +{{- $name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{- define "openebs-ndm.exporter.name" -}} +{{- $ndmName := .Chart.Name | trunc 63 | trimSuffix "-" }} +{{- $componentName := "exporter" | trunc 63 | trimSuffix "-" }} +{{- printf "%s-%s" $ndmName $componentName | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{- define "openebs-ndm.node-exporter.name" -}} +{{- $ndmName := default .Chart.Name .Values.ndmExporter.nodeExporter.nameOverride | trunc 63 | trimSuffix "-" }} +{{- $componentName := .Values.ndmExporter.nodeExporter.name | trunc 63 | trimSuffix "-" }} +{{- printf "%s-%s" $ndmName $componentName | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified ndm node exporter 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 "openebs-ndm.node-exporter.fullname" -}} +{{- if .Values.ndmExporter.nodeExporter.fullnameOverride }} +{{- .Values.ndmExporter.nodeExporter.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $ndmNodeExporterName := include "openebs-ndm.node-exporter.name" .}} + +{{- $name := default $ndmNodeExporterName .Values.ndmExporter.nodeExporter.nameOverride }} +{{- if contains .Release.Name $name }} +{{- $name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "openebs-ndm.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "openebs-ndm.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} + +{{/* +Define meta labels for ndm components +*/}} +{{- define "openebs-ndm.common.metaLabels" -}} +chart: {{ template "openebs-ndm.chart" . }} +heritage: {{ .Release.Service }} +openebs.io/version: {{ .Values.release.version | quote }} +{{- end -}} + + +{{/* +Create match labels for ndm daemonset component +*/}} +{{- define "openebs-ndm.matchLabels" -}} +app: {{ template "openebs-ndm.name" . }} +release: {{ .Release.Name }} +component: {{ .Values.ndm.componentName | quote }} +{{- end -}} + +{{/* +Create component labels for ndm daemonset component +*/}} +{{- define "openebs-ndm.componentLabels" -}} +openebs.io/component-name: {{ .Values.ndm.componentName | quote }} +{{- end -}} + + +{{/* +Create labels for ndm daemonset component +*/}} +{{- define "openebs-ndm.labels" -}} +{{ include "openebs-ndm.common.metaLabels" . }} +{{ include "openebs-ndm.matchLabels" . }} +{{ include "openebs-ndm.componentLabels" . }} +{{- end -}} + +{{/* +Create match labels for ndm operator deployment +*/}} +{{- define "openebs-ndm.operator.matchLabels" -}} +app: {{ template "openebs-ndm.operator.name" . }} +release: {{ .Release.Name }} +component: {{ default (include "openebs-ndm.operator.name" .) .Values.ndmOperator.componentName }} +{{- end -}} + +{{/* +Create component labels for ndm operator component +*/}} +{{- define "openebs-ndm.operator.componentLabels" -}} +openebs.io/component-name: {{ default (include "openebs-ndm.operator.name" .) .Values.ndmOperator.componentName }} +{{- end -}} + + +{{/* +Create labels for ndm operator component +*/}} +{{- define "openebs-ndm.operator.labels" -}} +{{ include "openebs-ndm.common.metaLabels" . }} +{{ include "openebs-ndm.operator.matchLabels" . }} +{{ include "openebs-ndm.operator.componentLabels" . }} +{{- end -}} + +{{/* +Create match labels for ndm cluster exporter deployment +*/}} +{{- define "openebs-ndm.cluster-exporter.matchLabels" -}} +app: {{ template "openebs-ndm.exporter.name" . }} +release: {{ .Release.Name }} +component: {{ default (include "openebs-ndm.cluster-exporter.name" .) .Values.ndmExporter.clusterExporter.componentName }} +{{- end -}} + +{{/* +Create component labels for ndm cluster exporter component +*/}} +{{- define "openebs-ndm.cluster-exporter.componentLabels" -}} +openebs.io/component-name: {{ default (include "openebs-ndm.cluster-exporter.name" .) .Values.ndmExporter.clusterExporter.componentName }} +{{- end -}} + + +{{/* +Create labels for ndm cluster exporter component +*/}} +{{- define "openebs-ndm.cluster-exporter.labels" -}} +{{ include "openebs-ndm.common.metaLabels" . }} +{{ include "openebs-ndm.cluster-exporter.matchLabels" . }} +{{ include "openebs-ndm.cluster-exporter.componentLabels" . }} +{{- end -}} + +{{/* +Create match labels for ndm node exporter deployment +*/}} +{{- define "openebs-ndm.node-exporter.matchLabels" -}} +app: {{ template "openebs-ndm.exporter.name" . }} +release: {{ .Release.Name }} +component: {{ default (include "openebs-ndm.node-exporter.name" .) .Values.ndmExporter.nodeExporter.componentName }} +{{- end -}} + +{{/* +Create component labels for ndm node exporter component +*/}} +{{- define "openebs-ndm.node-exporter.componentLabels" -}} +openebs.io/component-name: {{ default (include "openebs-ndm.node-exporter.name" .) .Values.ndmExporter.nodeExporter.componentName }} +{{- end -}} + + +{{/* +Create labels for ndm cluster node component +*/}} +{{- define "openebs-ndm.node-exporter.labels" -}} +{{ include "openebs-ndm.common.metaLabels" . }} +{{ include "openebs-ndm.node-exporter.matchLabels" . }} +{{ include "openebs-ndm.node-exporter.componentLabels" . }} +{{- end -}} diff --git a/helm/openebs/charts/jiva/charts/localpv-provisioner/charts/openebs-ndm/templates/cluster-exporter-service.yaml b/helm/openebs/charts/jiva/charts/localpv-provisioner/charts/openebs-ndm/templates/cluster-exporter-service.yaml new file mode 100644 index 0000000..719f6b4 --- /dev/null +++ b/helm/openebs/charts/jiva/charts/localpv-provisioner/charts/openebs-ndm/templates/cluster-exporter-service.yaml @@ -0,0 +1,18 @@ +{{- if and .Values.ndmExporter.enabled .Values.ndmExporter.clusterExporter.metricsPort }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "openebs-ndm.cluster-exporter.fullname" . }}-service + labels: + {{- include "openebs-ndm.cluster-exporter.labels" . | nindent 4 }} +spec: + clusterIP: None + ports: + - name: metrics + port: {{ .Values.ndmExporter.clusterExporter.metricsPort }} + targetPort: {{ .Values.ndmExporter.clusterExporter.metricsPort }} + selector: + {{- with .Values.ndmExporter.clusterExporter.podLabels }} + {{ toYaml . }} + {{- end }} + {{- end }} diff --git a/helm/openebs/charts/jiva/charts/localpv-provisioner/charts/openebs-ndm/templates/cluster-exporter.yaml b/helm/openebs/charts/jiva/charts/localpv-provisioner/charts/openebs-ndm/templates/cluster-exporter.yaml new file mode 100644 index 0000000..af8b1e6 --- /dev/null +++ b/helm/openebs/charts/jiva/charts/localpv-provisioner/charts/openebs-ndm/templates/cluster-exporter.yaml @@ -0,0 +1,60 @@ +{{- if .Values.ndmExporter.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "openebs-ndm.cluster-exporter.fullname" . }} + labels: + {{- include "openebs-ndm.cluster-exporter.labels" . | nindent 4 }} +spec: + replicas: 1 + strategy: + type: Recreate + selector: + matchLabels: + {{- include "openebs-ndm.cluster-exporter.matchLabels" . | nindent 6 }} + template: + metadata: + labels: + {{- include "openebs-ndm.cluster-exporter.labels" . | nindent 8 }} + {{- with .Values.ndmExporter.clusterExporter.podLabels }} + {{ toYaml . }} + {{- end }} + spec: + serviceAccountName: {{ template "openebs-ndm.serviceAccountName" . }} + containers: + - name: {{ template "openebs-ndm.cluster-exporter.fullname" . }} + image: "{{ .Values.ndmExporter.image.registry }}{{ .Values.ndmExporter.image.repository }}:{{ .Values.ndmExporter.image.tag }}" + command: + - /usr/local/bin/exporter + args: + - "start" + - "--mode=cluster" + - "--port=$(METRICS_LISTEN_PORT)" + - "--metrics=/metrics" + ports: + - containerPort: {{ .Values.ndmExporter.clusterExporter.metricsPort }} + protocol: TCP + name: metrics + imagePullPolicy: {{ .Values.ndmExporter.image.pullPolicy }} + env: + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + {{- if .Values.ndmExporter.clusterExporter.metricsPort }} + - name: METRICS_LISTEN_PORT + value: :{{ .Values.ndmExporter.clusterExporter.metricsPort }} + {{- end }} +{{- if .Values.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | indent 8 }} +{{- end }} +{{- if .Values.ndmExporter.clusterExporter.nodeSelector }} + nodeSelector: +{{ toYaml .Values.ndmExporter.clusterExporter.nodeSelector | indent 8 }} +{{- end }} +{{- if .Values.ndmExporter.clusterExporter.tolerations }} + tolerations: +{{ toYaml .Values.ndmExporter.clusterExporter.tolerations | indent 8 }} +{{- end }} +{{- end }} diff --git a/helm/openebs/charts/jiva/charts/localpv-provisioner/charts/openebs-ndm/templates/configmap.yaml b/helm/openebs/charts/jiva/charts/localpv-provisioner/charts/openebs-ndm/templates/configmap.yaml new file mode 100644 index 0000000..99b814d --- /dev/null +++ b/helm/openebs/charts/jiva/charts/localpv-provisioner/charts/openebs-ndm/templates/configmap.yaml @@ -0,0 +1,45 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "openebs-ndm.fullname" . }}-config +data: + # node-disk-manager-config contains config of available probes and filters. + # Probes and Filters will initialize with default values if config for that + # filter or probe are not present in configmap + + # udev-probe is default or primary probe it should be enabled to run ndm + # filterconfigs contains configs of filters. To provide a group of include + # and exclude values add it as , separated string + node-disk-manager.config: | + probeconfigs: + - key: udev-probe + name: udev probe + state: {{ .Values.ndm.probes.enableUdevProbe }} + - key: seachest-probe + name: seachest probe + state: {{ .Values.ndm.probes.enableSeachest }} + - key: smart-probe + name: smart probe + state: {{ .Values.ndm.probes.enableSmartProbe }} + filterconfigs: + - key: os-disk-exclude-filter + name: os disk exclude filter + state: {{ .Values.ndm.filters.enableOsDiskExcludeFilter }} + exclude: "{{ .Values.ndm.filters.osDiskExcludePaths }}" + - key: vendor-filter + name: vendor filter + state: {{ .Values.ndm.filters.enableVendorFilter }} + include: "" + exclude: "{{ .Values.ndm.filters.excludeVendors }}" + - key: path-filter + name: path filter + state: {{ .Values.ndm.filters.enablePathFilter }} + include: "{{ .Values.ndm.filters.includePaths }}" + exclude: "{{ .Values.ndm.filters.excludePaths }}" + metaconfigs: + - key: node-labels + name: node labels + pattern: "{{ .Values.ndm.metaConfig.nodeLabelPattern }}" + - key: device-labels + name: device labels + type: "{{ .Values.ndm.metaConfig.deviceLabelTypes }}" diff --git a/helm/openebs/charts/jiva/charts/localpv-provisioner/charts/openebs-ndm/templates/daemonset.yaml b/helm/openebs/charts/jiva/charts/localpv-provisioner/charts/openebs-ndm/templates/daemonset.yaml new file mode 100644 index 0000000..715db87 --- /dev/null +++ b/helm/openebs/charts/jiva/charts/localpv-provisioner/charts/openebs-ndm/templates/daemonset.yaml @@ -0,0 +1,179 @@ +{{- if .Values.ndm.enabled }} +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: {{ template "openebs-ndm.fullname" . }} + {{- with .Values.ndm.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "openebs-ndm.labels" . | nindent 4 }} +spec: + updateStrategy: +{{ toYaml .Values.ndm.updateStrategy | indent 4 }} + selector: + matchLabels: + {{- include "openebs-ndm.matchLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.ndm.podAnnotations }} + annotations: {{ toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "openebs-ndm.labels" . | nindent 8 }} + {{- with .Values.ndm.podLabels}} + {{ toYaml . }} + {{- end}} + spec: + serviceAccountName: {{ template "openebs-ndm.serviceAccountName" . }} +{{- if .Values.featureGates.enabled }} +{{- if .Values.featureGates.APIService.enabled }} + hostPID: true +{{- end}} +{{- end}} + containers: + - name: {{ template "openebs-ndm.name" . }} + image: "{{ .Values.ndm.image.registry }}{{ .Values.ndm.image.repository }}:{{ .Values.ndm.image.tag }}" + args: + - -v=4 +{{- if .Values.featureGates.enabled }} +{{- if .Values.featureGates.GPTBasedUUID.enabled }} + - --feature-gates={{ .Values.featureGates.GPTBasedUUID.featureGateFlag }} +{{- end}} +{{- if .Values.featureGates.APIService.enabled }} + - --feature-gates={{ .Values.featureGates.APIService.featureGateFlag }} + - --api-service-address={{ .Values.featureGates.APIService.address }} +{{- end}} +{{- if .Values.featureGates.UseOSDisk.enabled }} + - --feature-gates={{ .Values.featureGates.UseOSDisk.featureGateFlag }} +{{- end}} +{{- if .Values.featureGates.ChangeDetection.enabled }} + - --feature-gates={{ .Values.featureGates.ChangeDetection.featureGateFlag }} +{{- end}} +{{- if .Values.featureGates.PartitionTableUUID.enabled }} + - --feature-gates={{ .Values.featureGates.PartitionTableUUID.featureGateFlag }} +{{- end}} +{{- end}} + imagePullPolicy: {{ .Values.ndm.image.pullPolicy }} + resources: +{{ toYaml .Values.ndm.resources | indent 12 }} + securityContext: + privileged: true + env: + # namespace in which NDM is installed will be passed to NDM Daemonset + # as environment variable + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + # pass hostname as env variable using downward API to the NDM container + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName +{{- if .Values.ndm.sparse }} +{{- if .Values.ndm.sparse.path }} + # specify the directory where the sparse files need to be created. + # if not specified, then sparse files will not be created. + - name: SPARSE_FILE_DIR + value: "{{ .Values.ndm.sparse.path }}" +{{- end }} +{{- if .Values.ndm.sparse.size }} + # Size(bytes) of the sparse file to be created. + - name: SPARSE_FILE_SIZE + value: "{{ .Values.ndm.sparse.size }}" +{{- end }} +{{- if .Values.ndm.sparse.count }} + # Specify the number of sparse files to be created + - name: SPARSE_FILE_COUNT + value: "{{ .Values.ndm.sparse.count }}" +{{- end }} +{{- end }} + # Process name used for matching is limited to the 15 characters + # present in the pgrep output. + # So fullname can be used here with pgrep (cmd is < 15 chars). + livenessProbe: + exec: + command: + - pgrep + - "ndm" + initialDelaySeconds: {{ .Values.ndm.healthCheck.initialDelaySeconds }} + periodSeconds: {{ .Values.ndm.healthCheck.periodSeconds }} + volumeMounts: + - name: config + mountPath: /host/node-disk-manager.config + subPath: node-disk-manager.config + readOnly: true + - name: udev + mountPath: /run/udev + - name: procmount + mountPath: /host/proc + readOnly: true + - name: devmount + mountPath: /dev + - name: basepath + mountPath: /var/openebs/ndm +{{- if .Values.ndm.sparse }} +{{- if .Values.ndm.sparse.path }} + - name: sparsepath + mountPath: {{ .Values.ndm.sparse.path }} +{{- end }} +{{- end }} + volumes: + - name: config + configMap: + name: {{ include "openebs-ndm.fullname" . }}-config + - name: udev + hostPath: + path: /run/udev + type: Directory + # mount /proc (to access mount file of process 1 of host) inside container + # to read mount-point of disks and partitions + - name: procmount + hostPath: + path: /proc + type: Directory + - name: devmount + # the /dev directory is mounted so that we have access to the devices that + # are connected at runtime of the pod. + hostPath: + path: /dev + type: Directory + - name: basepath + hostPath: + path: "{{ .Values.varDirectoryPath.baseDir }}/ndm" + type: DirectoryOrCreate +{{- if .Values.ndm.sparse }} +{{- if .Values.ndm.sparse.path }} + - name: sparsepath + hostPath: + path: {{ .Values.ndm.sparse.path }} +{{- end }} +{{- end }} + # By default the node-disk-manager will be run on all kubernetes nodes + # If you would like to limit this to only some nodes, say the nodes + # that have storage attached, you could label those node and use + # nodeSelector. + # + # e.g. label the storage nodes with - "openebs.io/nodegroup"="storage-node" + # kubectl label node "openebs.io/nodegroup"="storage-node" + #nodeSelector: + # "openebs.io/nodegroup": "storage-node" +{{- if .Values.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | indent 8 }} +{{- end }} +{{- if .Values.ndm.nodeSelector }} + nodeSelector: +{{ toYaml .Values.ndm.nodeSelector | indent 8 }} +{{- end }} +{{- if .Values.ndm.tolerations }} + tolerations: +{{ toYaml .Values.ndm.tolerations | indent 8 }} +{{- end }} +{{- if .Values.ndm.securityContext }} + securityContext: +{{ toYaml .Values.ndm.securityContext | indent 8 }} +{{- end }} + hostNetwork: true +{{- end }} diff --git a/helm/openebs/charts/jiva/charts/localpv-provisioner/charts/openebs-ndm/templates/deployment.yaml b/helm/openebs/charts/jiva/charts/localpv-provisioner/charts/openebs-ndm/templates/deployment.yaml new file mode 100644 index 0000000..213a861 --- /dev/null +++ b/helm/openebs/charts/jiva/charts/localpv-provisioner/charts/openebs-ndm/templates/deployment.yaml @@ -0,0 +1,87 @@ +{{- if .Values.ndmOperator.enabled }} +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "openebs-ndm.operator.fullname" . }} + {{- with .Values.ndmOperator.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "openebs-ndm.operator.labels" . | nindent 4 }} +spec: + replicas: {{ .Values.ndmOperator.replicas }} + strategy: + type: "Recreate" + rollingUpdate: null + selector: + matchLabels: + {{- include "openebs-ndm.operator.matchLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.ndmOperator.podAnnotations }} + annotations: {{ toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "openebs-ndm.operator.labels" . | nindent 8 }} + {{- with .Values.ndmOperator.podLabels}} + {{ toYaml . }} + {{- end}} + spec: + serviceAccountName: {{ template "openebs-ndm.serviceAccountName" . }} + containers: + - name: {{ template "openebs-ndm.operator.fullname" . }} + image: "{{ .Values.ndmOperator.image.registry }}{{ .Values.ndmOperator.image.repository }}:{{ .Values.ndmOperator.image.tag }}" + imagePullPolicy: {{ .Values.ndmOperator.image.pullPolicy }} + resources: +{{ toYaml .Values.ndmOperator.resources | indent 12 }} + livenessProbe: + httpGet: + path: /healthz + port: 8585 + initialDelaySeconds: {{ .Values.ndmOperator.healthCheck.initialDelaySeconds }} + periodSeconds: {{ .Values.ndmOperator.healthCheck.periodSeconds }} + readinessProbe: + httpGet: + path: /readyz + port: 8585 + initialDelaySeconds: {{ .Values.ndmOperator.readinessCheck.initialDelaySeconds }} + periodSeconds: {{ .Values.ndmOperator.readinessCheck.periodSeconds }} + env: + - name: WATCH_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: SERVICE_ACCOUNT + valueFrom: + fieldRef: + fieldPath: spec.serviceAccountName + - name: OPERATOR_NAME + value: "node-disk-operator" + - name: CLEANUP_JOB_IMAGE + value: "{{ .Values.helperPod.image.registry }}{{ .Values.helperPod.image.repository }}:{{ .Values.helperPod.image.tag }}" +{{- if .Values.imagePullSecrets }} + - name: OPENEBS_IO_IMAGE_PULL_SECRETS + value: "{{- range $index, $secret := .Values.imagePullSecrets}}{{if $index}},{{end}}{{ $secret.name }}{{- end}}" +{{- end }} +{{- if .Values.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | indent 8 }} +{{- end }} +{{- if .Values.ndmOperator.nodeSelector }} + nodeSelector: +{{ toYaml .Values.ndmOperator.nodeSelector | indent 8 }} +{{- end }} +{{- if .Values.ndmOperator.securityContext }} + securityContext: +{{ toYaml .Values.ndmOperator.securityContext | indent 8 }} +{{- end }} +{{- if .Values.ndmOperator.tolerations }} + tolerations: +{{ toYaml .Values.ndmOperator.tolerations | indent 8 }} +{{- end }} +{{- end }} diff --git a/helm/openebs/charts/jiva/charts/localpv-provisioner/charts/openebs-ndm/templates/node-exporter-service.yaml b/helm/openebs/charts/jiva/charts/localpv-provisioner/charts/openebs-ndm/templates/node-exporter-service.yaml new file mode 100644 index 0000000..026b77d --- /dev/null +++ b/helm/openebs/charts/jiva/charts/localpv-provisioner/charts/openebs-ndm/templates/node-exporter-service.yaml @@ -0,0 +1,18 @@ +{{- if and .Values.ndmExporter.enabled .Values.ndmExporter.nodeExporter.metricsPort }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "openebs-ndm.node-exporter.fullname" . }}-service + labels: + {{- include "openebs-ndm.node-exporter.labels" . | nindent 4 }} +spec: + clusterIP: None + ports: + - name: metrics + port: {{ .Values.ndmExporter.nodeExporter.metricsPort }} + targetPort: {{ .Values.ndmExporter.nodeExporter.metricsPort }} + selector: + {{- with .Values.ndmExporter.nodeExporter.podLabels }} + {{ toYaml . }} + {{- end }} + {{- end }} diff --git a/helm/openebs/charts/jiva/charts/localpv-provisioner/charts/openebs-ndm/templates/node-exporter.yaml b/helm/openebs/charts/jiva/charts/localpv-provisioner/charts/openebs-ndm/templates/node-exporter.yaml new file mode 100644 index 0000000..cd5f635 --- /dev/null +++ b/helm/openebs/charts/jiva/charts/localpv-provisioner/charts/openebs-ndm/templates/node-exporter.yaml @@ -0,0 +1,62 @@ +{{- if .Values.ndmExporter.enabled }} +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: {{ template "openebs-ndm.node-exporter.fullname" . }} + labels: + {{- include "openebs-ndm.node-exporter.labels" . | nindent 4 }} +spec: + updateStrategy: + type: RollingUpdate + selector: + matchLabels: + {{- include "openebs-ndm.node-exporter.matchLabels" . | nindent 6 }} + template: + metadata: + labels: + {{- include "openebs-ndm.node-exporter.labels" . | nindent 8 }} + {{- with .Values.ndmExporter.nodeExporter.podLabels }} + {{ toYaml . }} + {{- end }} + spec: + serviceAccountName: {{ template "openebs-ndm.serviceAccountName" . }} + containers: + - name: {{ template "openebs-ndm.node-exporter.fullname" . }} + image: "{{ .Values.ndmExporter.image.registry }}{{ .Values.ndmExporter.image.repository }}:{{ .Values.ndmExporter.image.tag }}" + command: + - /usr/local/bin/exporter + args: + - "start" + - "--mode=node" + - "--port=$(METRICS_LISTEN_PORT)" + - "--metrics=/metrics" + ports: + - containerPort: {{ .Values.ndmExporter.nodeExporter.metricsPort }} + protocol: TCP + name: metrics + imagePullPolicy: {{ .Values.ndmExporter.image.pullPolicy }} + securityContext: + privileged: true + env: + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + {{- if .Values.ndmExporter.nodeExporter.metricsPort }} + - name: METRICS_LISTEN_PORT + value: :{{ .Values.ndmExporter.nodeExporter.metricsPort }} + {{- end }} +{{- if .Values.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | indent 8 }} +{{- end }} +{{- if .Values.ndmExporter.nodeExporter.nodeSelector }} + nodeSelector: +{{ toYaml .Values.ndmExporter.nodeExporter.nodeSelector | indent 8 }} +{{- end }} +{{- if .Values.ndmExporter.nodeExporter.tolerations }} + tolerations: +{{ toYaml .Values.ndmExporter.nodeExporter.tolerations | indent 8 }} +{{- end }} +{{- end }} + diff --git a/helm/openebs/charts/jiva/charts/localpv-provisioner/charts/openebs-ndm/templates/rbac.yaml b/helm/openebs/charts/jiva/charts/localpv-provisioner/charts/openebs-ndm/templates/rbac.yaml new file mode 100644 index 0000000..8e81c49 --- /dev/null +++ b/helm/openebs/charts/jiva/charts/localpv-provisioner/charts/openebs-ndm/templates/rbac.yaml @@ -0,0 +1,44 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "openebs-ndm.serviceAccountName" . }} +{{- end }} +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ include "openebs-ndm.fullname" . }} +rules: + - apiGroups: ["*"] + resources: ["nodes", "pods", "events", "configmaps", "jobs"] + verbs: + - '*' + - apiGroups: ["apiextensions.k8s.io"] + resources: ["customresourcedefinitions"] + verbs: + - '*' + - apiGroups: + - openebs.io + resources: + - blockdevices + - blockdeviceclaims + verbs: + - '*' +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ include "openebs-ndm.fullname" . }} +subjects: + - kind: ServiceAccount + name: {{ include "openebs-ndm.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} + - kind: User + name: system:serviceaccount:default:default + apiGroup: rbac.authorization.k8s.io +roleRef: + kind: ClusterRole + name: {{ include "openebs-ndm.fullname" . }} + apiGroup: rbac.authorization.k8s.io +--- diff --git a/helm/openebs/charts/jiva/charts/localpv-provisioner/charts/openebs-ndm/values.yaml b/helm/openebs/charts/jiva/charts/localpv-provisioner/charts/openebs-ndm/values.yaml new file mode 100644 index 0000000..2548606 --- /dev/null +++ b/helm/openebs/charts/jiva/charts/localpv-provisioner/charts/openebs-ndm/values.yaml @@ -0,0 +1,156 @@ +# Default values for ndm. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. +release: + version: "2.1.0" + +imagePullSecrets: +# - name: "image-pull-secret" + +ndm: + componentName: ndm + enabled: true + image: + # Make sure that registry name end with a '/'. + # For example : quay.io/ is a correct value here and quay.io is incorrect + registry: + repository: openebs/node-disk-manager + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: 2.1.0 + sparse: + path: "/var/openebs/sparse" + size: "10737418240" + count: "0" + updateStrategy: + type: RollingUpdate + annotations: {} + podAnnotations: {} + resources: {} + # limits: + # cpu: 10m + # memory: 32Mi + # requests: + # cpu: 10m + # memory: 32Mi + ## Labels to be added to ndm daemonset pods + podLabels: + name: openebs-ndm + nodeSelector: {} + tolerations: [] + securityContext: {} + filters: + enableOsDiskExcludeFilter: true + osDiskExcludePaths: "/,/etc/hosts,/boot" + enableVendorFilter: true + excludeVendors: "CLOUDBYT,OpenEBS" + enablePathFilter: true + includePaths: "" + excludePaths: "loop,fd0,sr0,/dev/ram,/dev/dm-,/dev/md,/dev/rbd,/dev/zd" + probes: + enableSeachest: false + enableUdevProbe: true + enableSmartProbe: true + metaConfig: + nodeLabelPattern: "" + deviceLabelTypes: "" + healthCheck: + initialDelaySeconds: 30 + periodSeconds: 60 + +ndmOperator: + name: operator + enabled: true + image: + registry: + repository: openebs/node-disk-operator + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: 2.1.0 + podLabels: + name: openebs-ndm-operator + annotations: {} + podAnnotations: {} + nodeSelector: {} + resources: {} + securityContext: {} + tolerations: [] + healthCheck: + initialDelaySeconds: 15 + periodSeconds: 20 + readinessCheck: + initialDelaySeconds: 5 + periodSeconds: 10 + replicas: 1 + upgradeStrategy: Recreate + +ndmExporter: + enabled: false + image: + registry: + repository: openebs/node-disk-exporter + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: 2.1.0 + nodeExporter: + name: node-exporter + podLabels: + name: openebs-ndm-node-exporter + # The TCP port number used for exposing ndm-node-exporter metrics. + # If not set, service will not be created to expose metrics endpoint to serviceMonitor + # and listen-port flag will not be set and container port will be empty. + metricsPort: 9101 + nodeSelector: {} + tolerations: [] + clusterExporter: + name: cluster-exporter + podLabels: + name: openebs-ndm-cluster-exporter + # The TCP port number used for exposing ndm-cluster-exporter metrics. + # If not set, service will not be created to expose metrics endpoint to serviceMonitor + # and listen-port flag will not be set and container port will be empty. + metricsPort: 9100 + nodeSelector: {} + tolerations: [] + +helperPod: + image: + registry: "" + repository: openebs/linux-utils + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: 3.4.0 + +crd: + enableInstall: false + +featureGates: + enabled: true + GPTBasedUUID: + enabled: true + featureGateFlag: "GPTBasedUUID" + APIService: + enabled: false + featureGateFlag: "APIService" + address: "0.0.0.0:9115" + UseOSDisk: + enabled: false + featureGateFlag: "UseOSDisk" + ChangeDetection: + enabled: false + featureGateFlag: "ChangeDetection" + PartitionTableUUID: + enabled: false + featureGateFlag: "PartitionTableUUID" + +# Directory used by the OpenEBS to store debug information and so forth +# that are generated in the course of running OpenEBS containers. +varDirectoryPath: + baseDir: "/var/openebs" + +serviceAccount: + # Specifies whether a service account should be created + create: true + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: openebs-ndm diff --git a/helm/openebs/charts/jiva/charts/localpv-provisioner/templates/NOTES.txt b/helm/openebs/charts/jiva/charts/localpv-provisioner/templates/NOTES.txt new file mode 100644 index 0000000..a82ff98 --- /dev/null +++ b/helm/openebs/charts/jiva/charts/localpv-provisioner/templates/NOTES.txt @@ -0,0 +1,12 @@ +The OpenEBS Dynamic LocalPV Provisioner has been installed. +Check its status by running: +$ kubectl get pods -n {{ .Release.Namespace }} + +Use `kubectl get bd -n {{ .Release.Namespace }}` to list the +blockdevices attached to the Kubernetes cluster nodes. + +Get started with the Dynamic LocalPV Provisioner Quickstart guide at: +https://github.com/openebs/dynamic-localpv-provisioner/blob/develop/docs/quickstart.md + +For more information, visit our Slack at https://openebs.io/community or view +the OpenEBS documentation online at https://openebs.io/docs diff --git a/helm/openebs/charts/jiva/charts/localpv-provisioner/templates/_helpers.tpl b/helm/openebs/charts/jiva/charts/localpv-provisioner/templates/_helpers.tpl new file mode 100644 index 0000000..ea1ce31 --- /dev/null +++ b/helm/openebs/charts/jiva/charts/localpv-provisioner/templates/_helpers.tpl @@ -0,0 +1,79 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "localpv.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create a default fully qualified localpv provisioner 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 "localpv.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 "localpv.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + + +{{/* +Meta labels +*/}} +{{- define "localpv.common.metaLabels" -}} +chart: {{ template "localpv.chart" . }} +heritage: {{ .Release.Service }} +openebs.io/version: {{ .Values.release.version | quote }} +{{- end -}} + +{{/* +Selector labels +*/}} +{{- define "localpv.selectorLabels" -}} +app: {{ template "localpv.name" . }} +release: {{ .Release.Name }} +component: {{ .Values.localpv.name | quote }} +{{- end -}} + +{{/* +Component labels +*/}} +{{- define "localpv.componentLabels" -}} +openebs.io/component-name: openebs-{{ .Values.localpv.name }} +{{- end -}} + +{{/* +Common labels +*/}} +{{- define "localpv.labels" -}} +{{ include "localpv.common.metaLabels" . }} +{{ include "localpv.selectorLabels" . }} +{{ include "localpv.componentLabels" . }} +{{- end -}} + + +{{/* +Create the name of the service account to use +*/}} +{{- define "localpv.serviceAccountName" -}} +{{- if .Values.serviceAccount.create -}} + {{ default (include "localpv.fullname" .) .Values.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.serviceAccount.name }} +{{- end -}} +{{- end -}} diff --git a/helm/openebs/charts/jiva/charts/localpv-provisioner/templates/deployment.yaml b/helm/openebs/charts/jiva/charts/localpv-provisioner/templates/deployment.yaml new file mode 100644 index 0000000..63936f4 --- /dev/null +++ b/helm/openebs/charts/jiva/charts/localpv-provisioner/templates/deployment.yaml @@ -0,0 +1,120 @@ +{{- if .Values.localpv.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "localpv.fullname" . }} + {{- with .Values.localpv.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "localpv.labels" . | nindent 4 }} +spec: + replicas: {{ .Values.localpv.replicas }} + strategy: + type: "Recreate" + rollingUpdate: null + selector: + matchLabels: + {{- include "localpv.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.localpv.podAnnotations }} + annotations: {{ toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "localpv.labels" . | nindent 8 }} + {{- with .Values.localpv.podLabels }} + {{ toYaml . | nindent 8 }} + {{- end }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ template "localpv.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: {{ template "localpv.fullname" . }} + image: "{{ .Values.localpv.image.registry }}{{ .Values.localpv.image.repository }}:{{ .Values.localpv.image.tag }}" + imagePullPolicy: {{ .Values.localpv.image.pullPolicy }} + resources: +{{ toYaml .Values.localpv.resources | indent 10 }} + args: + - "--bd-time-out=$(BDC_BD_BIND_RETRIES)" + env: + # OPENEBS_IO_K8S_MASTER enables openebs provisioner to connect to K8s + # based on this address. This is ignored if empty. + # This is supported for openebs provisioner version 0.5.2 onwards + #- name: OPENEBS_IO_K8S_MASTER + # value: "http://10.128.0.12:8080" + # OPENEBS_IO_KUBE_CONFIG enables openebs provisioner to connect to K8s + # based on this config. This is ignored if empty. + # This is supported for openebs provisioner version 0.5.2 onwards + #- name: OPENEBS_IO_KUBE_CONFIG + # value: "/home/ubuntu/.kube/config" + # This sets the number of times the provisioner should try + # with a polling interval of 5 seconds, to get the Blockdevice + # Name from a BlockDeviceClaim, before the BlockDeviceClaim + # is deleted. E.g. 12 * 5 seconds = 60 seconds timeout + - name: BDC_BD_BIND_RETRIES + value: "{{ .Values.localpv.waitForBDBindTimeoutRetryCount }}" + - name: OPENEBS_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + # OPENEBS_SERVICE_ACCOUNT provides the service account of this pod as + # environment variable + - name: OPENEBS_SERVICE_ACCOUNT + valueFrom: + fieldRef: + fieldPath: spec.serviceAccountName + # OPENEBS_IO_BASE_PATH is the environment variable that provides the + # default base path on the node where host-path PVs will be provisioned. + - name: OPENEBS_IO_ENABLE_ANALYTICS + value: "{{ .Values.analytics.enabled }}" + - name: OPENEBS_IO_BASE_PATH + value: "{{ .Values.localpv.basePath }}" + - name: OPENEBS_IO_HELPER_IMAGE + value: "{{ .Values.helperPod.image.registry }}{{ .Values.helperPod.image.repository }}:{{ .Values.helperPod.image.tag }}" + - name: OPENEBS_IO_INSTALLER_TYPE + value: "localpv-charts-helm" + # LEADER_ELECTION_ENABLED is used to enable/disable leader election. By default + # leader election is enabled. + - name: LEADER_ELECTION_ENABLED + value: "{{ .Values.localpv.enableLeaderElection }}" +{{- if .Values.imagePullSecrets }} + - name: OPENEBS_IO_IMAGE_PULL_SECRETS + value: "{{- range $index, $secret := .Values.imagePullSecrets}}{{if $index}},{{end}}{{ $secret.name }}{{- end}}" +{{- end }} + # Process name used for matching is limited to the 15 characters + # present in the pgrep output. + # So fullname can't be used here with pgrep (>15 chars).A regular expression + # that matches the entire command name has to specified. + # Anchor `^` : matches any string that starts with `provisioner-loc` + # `.*`: matches any string that has `provisioner-loc` followed by zero or more char + livenessProbe: + exec: + command: + - sh + - -c + - test `pgrep -c "^provisioner-loc.*"` = 1 + initialDelaySeconds: {{ .Values.localpv.healthCheck.initialDelaySeconds }} + periodSeconds: {{ .Values.localpv.healthCheck.periodSeconds }} +{{- if .Values.localpv.nodeSelector }} + nodeSelector: +{{ toYaml .Values.localpv.nodeSelector | indent 8 }} +{{- end }} +{{- if .Values.localpv.tolerations }} + tolerations: +{{ toYaml .Values.localpv.tolerations | indent 8 }} +{{- end }} +{{- if .Values.localpv.affinity }} + affinity: +{{ toYaml .Values.localpv.affinity | indent 8 }} +{{- end }} +{{- end }} diff --git a/helm/openebs/charts/jiva/charts/localpv-provisioner/templates/device-class.yaml b/helm/openebs/charts/jiva/charts/localpv-provisioner/templates/device-class.yaml new file mode 100644 index 0000000..35fb94b --- /dev/null +++ b/helm/openebs/charts/jiva/charts/localpv-provisioner/templates/device-class.yaml @@ -0,0 +1,31 @@ +{{- if .Values.deviceClass.enabled }} +apiVersion: storage.k8s.io/v1 +kind: StorageClass +metadata: + name: {{ .Values.deviceClass.name }} + annotations: + openebs.io/cas-type: local + cas.openebs.io/config: | + - name: StorageType + value: "device" +{{- if .Values.deviceClass.fsType }} + - name: FSType + value: {{ .Values.deviceClass.fsType | quote }} +{{- end }} +{{- if .Values.deviceClass.blockDeviceSelectors }} + - name: BlockDeviceSelectors + data: +{{ toYaml .Values.deviceClass.blockDeviceSelectors | indent 10 }} +{{- end }} +{{- if .Values.deviceClass.nodeAffinityLabels }} + - name: NodeAffinityLabels + list: +{{ toYaml .Values.deviceClass.nodeAffinityLabels | indent 10 }} +{{- end }} +{{- if .Values.deviceClass.isDefaultClass }} + storageclass.kubernetes.io/is-default-class: "true" +{{- end }} +provisioner: openebs.io/local +volumeBindingMode: WaitForFirstConsumer +reclaimPolicy: {{ .Values.deviceClass.reclaimPolicy }} +{{- end }} \ No newline at end of file diff --git a/helm/openebs/charts/jiva/charts/localpv-provisioner/templates/hostpath-class.yaml b/helm/openebs/charts/jiva/charts/localpv-provisioner/templates/hostpath-class.yaml new file mode 100644 index 0000000..6dd49d9 --- /dev/null +++ b/helm/openebs/charts/jiva/charts/localpv-provisioner/templates/hostpath-class.yaml @@ -0,0 +1,40 @@ +{{- if .Values.hostpathClass.enabled }} +apiVersion: storage.k8s.io/v1 +kind: StorageClass +metadata: + name: {{ tpl (.Values.hostpathClass.name) .}} + annotations: + openebs.io/cas-type: local + cas.openebs.io/config: | + - name: StorageType + value: "hostpath" +{{- if or .Values.localpv.basePath .Values.hostpathClass.basePath }} + - name: BasePath + value: {{ tpl (.Values.hostpathClass.basePath | default .Values.localpv.basePath | quote) . }} +{{- end }} +{{- if .Values.hostpathClass.nodeAffinityLabels }} + - name: NodeAffinityLabels + list: +{{ toYaml .Values.hostpathClass.nodeAffinityLabels | indent 10 }} +{{- end }} +{{- if .Values.hostpathClass.xfsQuota.enabled }} + - name: XFSQuota + enabled: "{{ .Values.hostpathClass.xfsQuota.enabled }}" + data: + softLimitGrace: "{{ .Values.hostpathClass.xfsQuota.softLimitGrace }}" + hardLimitGrace: "{{ .Values.hostpathClass.xfsQuota.hardLimitGrace }}" +{{- end }} +{{- if .Values.hostpathClass.ext4Quota.enabled }} + - name: EXT4Quota + enabled: "{{ .Values.hostpathClass.ext4Quota.enabled }}" + data: + softLimitGrace: "{{ .Values.hostpathClass.ext4Quota.softLimitGrace }}" + hardLimitGrace: "{{ .Values.hostpathClass.ext4Quota.hardLimitGrace }}" +{{- end }} +{{- if .Values.hostpathClass.isDefaultClass }} + storageclass.kubernetes.io/is-default-class: "true" +{{- end }} +provisioner: openebs.io/local +volumeBindingMode: WaitForFirstConsumer +reclaimPolicy: {{ .Values.hostpathClass.reclaimPolicy }} +{{- end }} diff --git a/helm/openebs/charts/jiva/charts/localpv-provisioner/templates/psp.yaml b/helm/openebs/charts/jiva/charts/localpv-provisioner/templates/psp.yaml new file mode 100644 index 0000000..ec64aad --- /dev/null +++ b/helm/openebs/charts/jiva/charts/localpv-provisioner/templates/psp.yaml @@ -0,0 +1,30 @@ +{{- if .Values.rbac.pspEnabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "localpv.fullname" . }}-psp + {{- with .Values.localpv.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "localpv.labels" . | nindent 4 }} +spec: + privileged: {{ .Values.localpv.privileged }} + allowPrivilegeEscalation: true + allowedCapabilities: ['*'] + volumes: ['*'] + hostNetwork: true + hostPorts: + - min: 0 + max: 65535 + hostIPC: true + hostPID: true + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'RunAsAny' + fsGroup: + rule: 'RunAsAny' +{{- end }} diff --git a/helm/openebs/charts/jiva/charts/localpv-provisioner/templates/rbac.yaml b/helm/openebs/charts/jiva/charts/localpv-provisioner/templates/rbac.yaml new file mode 100644 index 0000000..04cd540 --- /dev/null +++ b/helm/openebs/charts/jiva/charts/localpv-provisioner/templates/rbac.yaml @@ -0,0 +1,99 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "localpv.serviceAccountName" . }} + labels: + {{- include "localpv.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} +{{- if .Values.rbac.create }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "localpv.fullname" . }} + {{- with .Values.localpv.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "localpv.labels" . | nindent 4 }} +rules: +- apiGroups: ["*"] + resources: ["nodes"] + verbs: ["get", "list", "watch"] +- apiGroups: ["*"] + resources: ["namespaces", "pods", "events", "endpoints"] + verbs: ["*"] +- apiGroups: ["*"] + resources: ["resourcequotas", "limitranges"] + verbs: ["list", "watch"] +- apiGroups: ["*"] + resources: ["storageclasses", "persistentvolumeclaims", "persistentvolumes"] + verbs: ["*"] +- apiGroups: ["apiextensions.k8s.io"] + resources: ["customresourcedefinitions"] + verbs: [ "get", "list", "create", "update", "delete", "patch"] +- apiGroups: ["openebs.io"] + resources: [ "*"] + verbs: ["*" ] +- nonResourceURLs: ["/metrics"] + verbs: ["get"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "localpv.fullname" . }} + {{- with .Values.localpv.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "localpv.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "localpv.fullname" . }} +subjects: +- kind: ServiceAccount + name: {{ template "localpv.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +{{- if .Values.rbac.pspEnabled }} +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ template "localpv.fullname" . }}-psp + {{- with .Values.localpv.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "localpv.labels" . | nindent 4 }} +rules: +- apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ template "localpv.fullname" . }}-psp +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "localpv.fullname" . }}-psp + {{- with .Values.localpv.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "localpv.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "localpv.fullname" . }}-psp +subjects: + - kind: ServiceAccount + name: {{ template "localpv.serviceAccountName" . }} + namespace: {{ $.Release.Namespace }} +{{- end }} +{{- end }} diff --git a/helm/openebs/charts/jiva/charts/localpv-provisioner/values.yaml b/helm/openebs/charts/jiva/charts/localpv-provisioner/values.yaml new file mode 100644 index 0000000..d421232 --- /dev/null +++ b/helm/openebs/charts/jiva/charts/localpv-provisioner/values.yaml @@ -0,0 +1,171 @@ +# Default values for localpv. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +release: + version: "3.4.0" + +rbac: + # rbac.create: `true` if rbac resources should be created + create: true + # rbac.pspEnabled: `true` if PodSecurityPolicy resources should be created + pspEnabled: false + +# If false, openebs NDM sub-chart will not be installed +openebsNDM: + enabled: true + +localpv: + name: localpv-provisioner + enabled: true + image: + # Make sure that registry name end with a '/'. + # For example : quay.io/ is a correct value here and quay.io is incorrect + registry: + repository: openebs/provisioner-localpv + tag: 3.4.0 + pullPolicy: IfNotPresent + updateStrategy: + type: RollingUpdate + # If set to false, containers created by the localpv provisioner will run without extra privileges. + privileged: true + annotations: {} + podAnnotations: {} + ## Labels to be added to localpv provisioner deployment pods + podLabels: + name: openebs-localpv-provisioner + healthCheck: + initialDelaySeconds: 30 + periodSeconds: 60 + replicas: 1 + enableLeaderElection: true + basePath: "/var/openebs/local" +# This sets the number of times the provisioner should try +# with a polling interval of 5 seconds, to get the Blockdevice +# Name from a BlockDeviceClaim, before the BlockDeviceClaim +# is deleted. E.g. 12 * 5 seconds = 60 seconds timeout + waitForBDBindTimeoutRetryCount: "12" + 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 + nodeSelector: {} + tolerations: [] + affinity: {} + securityContext: {} + +imagePullSecrets: + # - name: img-pull-secret + +podSecurityContext: {} + # fsGroup: 2000 + +nameOverride: "" +fullnameOverride: "" + +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: + +deviceClass: + # Name of default device StorageClass. + name: openebs-device + # If true, enables creation of the openebs-device StorageClass + enabled: true + # Available reclaim policies: Delete/Retain, defaults: Delete. + reclaimPolicy: Delete + # If true, sets the openebs-device StorageClass as the default StorageClass + isDefaultClass: false + # Custom node affinity label(s) for example "openebs.io/node-affinity-value" + # that will be used instead of hostnames + # This helps in cases where the hostname changes when the node is removed and + # added back with the disks still intact. + # Example: + # nodeAffinityLabels: + # - "openebs.io/node-affinity-key-1" + # - "openebs.io/node-affinity-key-2" + nodeAffinityLabels: [] + # Sets the filesystem to be written to the blockdevice before + # mounting (filesystem volumes) + # This is only usable if the selected BlockDevice does not already + # have a filesystem + # Valid values: "ext4", "xfs" + fsType: "ext4" + # Label block devices in the cluster that you would like the openEBS localPV + # Provisioner to pick up those specific block devices available on the node. + # Set the label key and value as shown in the example below. + # + # To read more: https://github.com/openebs/dynamic-localpv-provisioner/blob/develop/docs/tutorials/device/blockdeviceselectors.md + # + # Example: + # blockDeviceSelectors: + # ndm.io/driveType: "SSD" + # ndm.io/fsType: "none" + blockDeviceSelectors: {} + +hostpathClass: + # Name of the default hostpath StorageClass + name: openebs-hostpath + # If true, enables creation of the openebs-hostpath StorageClass + enabled: true + # Available reclaim policies: Delete/Retain, defaults: Delete. + reclaimPolicy: Delete + # If true, sets the openebs-hostpath StorageClass as the default StorageClass + isDefaultClass: false + # Path on the host where local volumes of this storage class are mounted under. + # NOTE: If not specified, this defaults to the value of localpv.basePath. + basePath: "" + # Custom node affinity label(s) for example "openebs.io/node-affinity-value" + # that will be used instead of hostnames + # This helps in cases where the hostname changes when the node is removed and + # added back with the disks still intact. + # Example: + # nodeAffinityLabels: + # - "openebs.io/node-affinity-key-1" + # - "openebs.io/node-affinity-key-2" + nodeAffinityLabels: [] + # Prerequisite: XFS Quota requires an XFS filesystem mounted with + # the 'pquota' or 'prjquota' mount option. + xfsQuota: + # If true, enables XFS project quota + enabled: false + # Detailed configuration options for XFS project quota. + # If XFS Quota is enabled with the default values, the usage limit + # is set at the storage capacity specified in the PVC. + softLimitGrace: "0%" + hardLimitGrace: "0%" + # Prerequisite: EXT4 Quota requires an EXT4 filesystem mounted with + # the 'prjquota' mount option. + ext4Quota: + # If true, enables XFS project quota + enabled: false + # Detailed configuration options for EXT4 project quota. + # If EXT4 Quota is enabled with the default values, the usage limit + # is set at the storage capacity specified in the PVC. + softLimitGrace: "0%" + hardLimitGrace: "0%" + +helperPod: + image: + registry: "" + repository: openebs/linux-utils + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: 3.4.0 + +analytics: + enabled: true + # Specify in hours the duration after which a ping event needs to be sent. + pingInterval: "24h" diff --git a/helm/openebs/charts/jiva/crds/jivavolumepolicy.yaml b/helm/openebs/charts/jiva/crds/jivavolumepolicy.yaml new file mode 100644 index 0000000..a2c288c --- /dev/null +++ b/helm/openebs/charts/jiva/crds/jivavolumepolicy.yaml @@ -0,0 +1,2974 @@ + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.1 + creationTimestamp: null + name: jivavolumepolicies.openebs.io +spec: + group: openebs.io + names: + kind: JivaVolumePolicy + listKind: JivaVolumePolicyList + plural: jivavolumepolicies + shortNames: + - jvp + singular: jivavolumepolicy + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + description: 'JivaVolumePolicy is the Schema for the jivavolumes API Important: + Run "operator-sdk generate k8s" to regenerate code after modifying this + file' + 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: JivaVolumePolicySpec defines the desired state of JivaVolumePolicy + properties: + priorityClassName: + description: PriorityClassName if specified applies to the pod If + left empty, no priority class is applied. + type: string + replica: + description: ReplicaSpec represents configuration related to replicas + resources + nullable: true + properties: + affinity: + description: Affinity if specified, are the pod's affinities + properties: + nodeAffinity: + description: Describes node affinity scheduling rules for + the pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods + to nodes that satisfy the affinity expressions specified + by this field, but it may choose a node that violates + one or more of the expressions. The node that is most + preferred is the one with the greatest sum of weights, + i.e. for each node that meets all of the scheduling + requirements (resource request, requiredDuringScheduling + affinity expressions, etc.), compute a sum by iterating + through the elements of this field and adding "weight" + to the sum if the node matches the corresponding matchExpressions; + the node(s) with the highest sum are the most preferred. + items: + description: An empty preferred scheduling term matches + all objects with implicit weight 0 (i.e. it's a no-op). + A null preferred scheduling term matches no objects + (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated with + the corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement is + a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement is + a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + description: Weight associated with matching the + corresponding nodeSelectorTerm, in the range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by + this field are not met at scheduling time, the pod will + not be scheduled onto the node. If the affinity requirements + specified by this field cease to be met at some point + during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from + its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector terms. + The terms are ORed. + items: + description: A null or empty node selector term + matches no objects. The requirements of them are + ANDed. The TopologySelectorTerm type implements + a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement is + a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement is + a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + description: Describes pod affinity scheduling rules (e.g. + co-locate this pod in the same node, zone, etc. as some + other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods + to nodes that satisfy the affinity expressions specified + by this field, but it may choose a node that violates + one or more of the expressions. The node that is most + preferred is the one with the greatest sum of weights, + i.e. for each node that meets all of the scheduling + requirements (resource request, requiredDuringScheduling + affinity expressions, etc.), compute a sum by iterating + through the elements of this field and adding "weight" + to the sum if the node has pods which matches the corresponding + podAffinityTerm; the node(s) with the highest sum are + the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies which namespaces + the labelSelector applies to (matches against); + null or empty list means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the + pods matching the labelSelector in the specified + namespaces, where co-located is defined as + running on a node whose value of the label + with key topologyKey matches that of any node + on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the + corresponding podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by + this field are not met at scheduling time, the pod will + not be scheduled onto the node. If the affinity requirements + specified by this field cease to be met at some point + during pod execution (e.g. due to a pod label update), + the system may or may not try to eventually evict the + pod from its node. When there are multiple elements, + the lists of nodes corresponding to each podAffinityTerm + are intersected, i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not + co-located (anti-affinity) with, where co-located + is defined as running on a node whose value of the + label with key matches that of any node + on which a pod of the set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies which namespaces + the labelSelector applies to (matches against); + null or empty list means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey + matches that of any node on which any of the selected + pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules + (e.g. avoid putting this pod in the same node, zone, etc. + as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods + to nodes that satisfy the anti-affinity expressions + specified by this field, but it may choose a node that + violates one or more of the expressions. The node that + is most preferred is the one with the greatest sum of + weights, i.e. for each node that meets all of the scheduling + requirements (resource request, requiredDuringScheduling + anti-affinity expressions, etc.), compute a sum by iterating + through the elements of this field and adding "weight" + to the sum if the node has pods which matches the corresponding + podAffinityTerm; the node(s) with the highest sum are + the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies which namespaces + the labelSelector applies to (matches against); + null or empty list means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the + pods matching the labelSelector in the specified + namespaces, where co-located is defined as + running on a node whose value of the label + with key topologyKey matches that of any node + on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the + corresponding podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the anti-affinity requirements specified + by this field are not met at scheduling time, the pod + will not be scheduled onto the node. If the anti-affinity + requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod + label update), the system may or may not try to eventually + evict the pod from its node. When there are multiple + elements, the lists of nodes corresponding to each podAffinityTerm + are intersected, i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not + co-located (anti-affinity) with, where co-located + is defined as running on a node whose value of the + label with key matches that of any node + on which a pod of the set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies which namespaces + the labelSelector applies to (matches against); + null or empty list means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey + matches that of any node on which any of the selected + pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + nodeSelector: + additionalProperties: + type: string + description: NodeSelector is the labels that will be used to select + a node for pod scheduleing + type: object + resources: + description: Resources are the compute resources required by the + jiva container. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' + type: object + type: object + tolerations: + description: Tolerations, if specified, are the pod's tolerations + items: + description: The pod this Toleration is attached to tolerates + any taint that matches the triple using + the matching operator . + properties: + effect: + description: Effect indicates the taint effect to match. + Empty means match all taint effects. When specified, allowed + values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Key is the taint key that the toleration applies + to. Empty means match all taint keys. If the key is empty, + operator must be Exists; this combination means to match + all values and all keys. + type: string + operator: + description: Operator represents a key's relationship to + the value. Valid operators are Exists and Equal. Defaults + to Equal. Exists is equivalent to wildcard for value, + so that a pod can tolerate all taints of a particular + category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period of + time the toleration (which must be of effect NoExecute, + otherwise this field is ignored) tolerates the taint. + By default, it is not set, which means tolerate the taint + forever (do not evict). Zero and negative values will + be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration matches + to. If the operator is Exists, the value should be empty, + otherwise just a regular string. + type: string + type: object + type: array + type: object + replicaSC: + description: ReplicaSC represents the storage class used for creating + the pvc for the replicas (provisioned by localpv provisioner) + type: string + serviceAccountName: + description: ServiceAccountName can be provided to enable PSP + type: string + target: + description: TargetSpec represents configuration related to jiva target + and its resources + nullable: true + properties: + affinity: + description: Affinity if specified, are the pod's affinities + properties: + nodeAffinity: + description: Describes node affinity scheduling rules for + the pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods + to nodes that satisfy the affinity expressions specified + by this field, but it may choose a node that violates + one or more of the expressions. The node that is most + preferred is the one with the greatest sum of weights, + i.e. for each node that meets all of the scheduling + requirements (resource request, requiredDuringScheduling + affinity expressions, etc.), compute a sum by iterating + through the elements of this field and adding "weight" + to the sum if the node matches the corresponding matchExpressions; + the node(s) with the highest sum are the most preferred. + items: + description: An empty preferred scheduling term matches + all objects with implicit weight 0 (i.e. it's a no-op). + A null preferred scheduling term matches no objects + (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated with + the corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement is + a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement is + a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + description: Weight associated with matching the + corresponding nodeSelectorTerm, in the range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by + this field are not met at scheduling time, the pod will + not be scheduled onto the node. If the affinity requirements + specified by this field cease to be met at some point + during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from + its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector terms. + The terms are ORed. + items: + description: A null or empty node selector term + matches no objects. The requirements of them are + ANDed. The TopologySelectorTerm type implements + a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement is + a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement is + a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + description: Describes pod affinity scheduling rules (e.g. + co-locate this pod in the same node, zone, etc. as some + other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods + to nodes that satisfy the affinity expressions specified + by this field, but it may choose a node that violates + one or more of the expressions. The node that is most + preferred is the one with the greatest sum of weights, + i.e. for each node that meets all of the scheduling + requirements (resource request, requiredDuringScheduling + affinity expressions, etc.), compute a sum by iterating + through the elements of this field and adding "weight" + to the sum if the node has pods which matches the corresponding + podAffinityTerm; the node(s) with the highest sum are + the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies which namespaces + the labelSelector applies to (matches against); + null or empty list means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the + pods matching the labelSelector in the specified + namespaces, where co-located is defined as + running on a node whose value of the label + with key topologyKey matches that of any node + on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the + corresponding podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by + this field are not met at scheduling time, the pod will + not be scheduled onto the node. If the affinity requirements + specified by this field cease to be met at some point + during pod execution (e.g. due to a pod label update), + the system may or may not try to eventually evict the + pod from its node. When there are multiple elements, + the lists of nodes corresponding to each podAffinityTerm + are intersected, i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not + co-located (anti-affinity) with, where co-located + is defined as running on a node whose value of the + label with key matches that of any node + on which a pod of the set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies which namespaces + the labelSelector applies to (matches against); + null or empty list means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey + matches that of any node on which any of the selected + pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules + (e.g. avoid putting this pod in the same node, zone, etc. + as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods + to nodes that satisfy the anti-affinity expressions + specified by this field, but it may choose a node that + violates one or more of the expressions. The node that + is most preferred is the one with the greatest sum of + weights, i.e. for each node that meets all of the scheduling + requirements (resource request, requiredDuringScheduling + anti-affinity expressions, etc.), compute a sum by iterating + through the elements of this field and adding "weight" + to the sum if the node has pods which matches the corresponding + podAffinityTerm; the node(s) with the highest sum are + the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies which namespaces + the labelSelector applies to (matches against); + null or empty list means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the + pods matching the labelSelector in the specified + namespaces, where co-located is defined as + running on a node whose value of the label + with key topologyKey matches that of any node + on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the + corresponding podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the anti-affinity requirements specified + by this field are not met at scheduling time, the pod + will not be scheduled onto the node. If the anti-affinity + requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod + label update), the system may or may not try to eventually + evict the pod from its node. When there are multiple + elements, the lists of nodes corresponding to each podAffinityTerm + are intersected, i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not + co-located (anti-affinity) with, where co-located + is defined as running on a node whose value of the + label with key matches that of any node + on which a pod of the set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies which namespaces + the labelSelector applies to (matches against); + null or empty list means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey + matches that of any node on which any of the selected + pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + auxResources: + description: AuxResources are the compute resources required by + the jiva-target pod side car containers. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' + type: object + type: object + disableMonitor: + description: DisableMonitor will not attach prometheus exporter + sidecar to jiva volume target. + type: boolean + nodeSelector: + additionalProperties: + type: string + description: NodeSelector is the labels that will be used to select + a node for pod scheduleing + type: object + replicationFactor: + description: ReplicationFactor represents maximum number of replicas + that are allowed to connect to the target + type: integer + resources: + description: Resources are the compute resources required by the + jiva container. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' + type: object + type: object + tolerations: + description: Tolerations, if specified, are the pod's tolerations + items: + description: The pod this Toleration is attached to tolerates + any taint that matches the triple using + the matching operator . + properties: + effect: + description: Effect indicates the taint effect to match. + Empty means match all taint effects. When specified, allowed + values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Key is the taint key that the toleration applies + to. Empty means match all taint keys. If the key is empty, + operator must be Exists; this combination means to match + all values and all keys. + type: string + operator: + description: Operator represents a key's relationship to + the value. Valid operators are Exists and Equal. Defaults + to Equal. Exists is equivalent to wildcard for value, + so that a pod can tolerate all taints of a particular + category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period of + time the toleration (which must be of effect NoExecute, + otherwise this field is ignored) tolerates the taint. + By default, it is not set, which means tolerate the taint + forever (do not evict). Zero and negative values will + be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration matches + to. If the operator is Exists, the value should be empty, + otherwise just a regular string. + type: string + type: object + type: array + type: object + type: object + status: + description: JivaVolumePolicyStatus is for handling status of JivaVolumePolicy + properties: + phase: + type: string + required: + - phase + type: object + type: object + served: true + storage: true + - name: v1alpha1 + schema: + openAPIV3Schema: + description: 'JivaVolumePolicy is the Schema for the jivavolumes API Important: + Run "operator-sdk generate k8s" to regenerate code after modifying this + file' + 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: JivaVolumePolicySpec defines the desired state of JivaVolumePolicy + properties: + priorityClassName: + description: PriorityClassName if specified applies to the pod If + left empty, no priority class is applied. + type: string + replica: + description: ReplicaSpec represents configuration related to replicas + resources + nullable: true + properties: + affinity: + description: Affinity if specified, are the pod's affinities + properties: + nodeAffinity: + description: Describes node affinity scheduling rules for + the pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods + to nodes that satisfy the affinity expressions specified + by this field, but it may choose a node that violates + one or more of the expressions. The node that is most + preferred is the one with the greatest sum of weights, + i.e. for each node that meets all of the scheduling + requirements (resource request, requiredDuringScheduling + affinity expressions, etc.), compute a sum by iterating + through the elements of this field and adding "weight" + to the sum if the node matches the corresponding matchExpressions; + the node(s) with the highest sum are the most preferred. + items: + description: An empty preferred scheduling term matches + all objects with implicit weight 0 (i.e. it's a no-op). + A null preferred scheduling term matches no objects + (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated with + the corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement is + a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement is + a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + description: Weight associated with matching the + corresponding nodeSelectorTerm, in the range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by + this field are not met at scheduling time, the pod will + not be scheduled onto the node. If the affinity requirements + specified by this field cease to be met at some point + during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from + its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector terms. + The terms are ORed. + items: + description: A null or empty node selector term + matches no objects. The requirements of them are + ANDed. The TopologySelectorTerm type implements + a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement is + a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement is + a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + description: Describes pod affinity scheduling rules (e.g. + co-locate this pod in the same node, zone, etc. as some + other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods + to nodes that satisfy the affinity expressions specified + by this field, but it may choose a node that violates + one or more of the expressions. The node that is most + preferred is the one with the greatest sum of weights, + i.e. for each node that meets all of the scheduling + requirements (resource request, requiredDuringScheduling + affinity expressions, etc.), compute a sum by iterating + through the elements of this field and adding "weight" + to the sum if the node has pods which matches the corresponding + podAffinityTerm; the node(s) with the highest sum are + the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies which namespaces + the labelSelector applies to (matches against); + null or empty list means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the + pods matching the labelSelector in the specified + namespaces, where co-located is defined as + running on a node whose value of the label + with key topologyKey matches that of any node + on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the + corresponding podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by + this field are not met at scheduling time, the pod will + not be scheduled onto the node. If the affinity requirements + specified by this field cease to be met at some point + during pod execution (e.g. due to a pod label update), + the system may or may not try to eventually evict the + pod from its node. When there are multiple elements, + the lists of nodes corresponding to each podAffinityTerm + are intersected, i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not + co-located (anti-affinity) with, where co-located + is defined as running on a node whose value of the + label with key matches that of any node + on which a pod of the set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies which namespaces + the labelSelector applies to (matches against); + null or empty list means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey + matches that of any node on which any of the selected + pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules + (e.g. avoid putting this pod in the same node, zone, etc. + as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods + to nodes that satisfy the anti-affinity expressions + specified by this field, but it may choose a node that + violates one or more of the expressions. The node that + is most preferred is the one with the greatest sum of + weights, i.e. for each node that meets all of the scheduling + requirements (resource request, requiredDuringScheduling + anti-affinity expressions, etc.), compute a sum by iterating + through the elements of this field and adding "weight" + to the sum if the node has pods which matches the corresponding + podAffinityTerm; the node(s) with the highest sum are + the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies which namespaces + the labelSelector applies to (matches against); + null or empty list means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the + pods matching the labelSelector in the specified + namespaces, where co-located is defined as + running on a node whose value of the label + with key topologyKey matches that of any node + on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the + corresponding podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the anti-affinity requirements specified + by this field are not met at scheduling time, the pod + will not be scheduled onto the node. If the anti-affinity + requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod + label update), the system may or may not try to eventually + evict the pod from its node. When there are multiple + elements, the lists of nodes corresponding to each podAffinityTerm + are intersected, i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not + co-located (anti-affinity) with, where co-located + is defined as running on a node whose value of the + label with key matches that of any node + on which a pod of the set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies which namespaces + the labelSelector applies to (matches against); + null or empty list means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey + matches that of any node on which any of the selected + pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + nodeSelector: + additionalProperties: + type: string + description: NodeSelector is the labels that will be used to select + a node for pod scheduleing + type: object + resources: + description: Resources are the compute resources required by the + jiva container. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' + type: object + type: object + tolerations: + description: Tolerations, if specified, are the pod's tolerations + items: + description: The pod this Toleration is attached to tolerates + any taint that matches the triple using + the matching operator . + properties: + effect: + description: Effect indicates the taint effect to match. + Empty means match all taint effects. When specified, allowed + values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Key is the taint key that the toleration applies + to. Empty means match all taint keys. If the key is empty, + operator must be Exists; this combination means to match + all values and all keys. + type: string + operator: + description: Operator represents a key's relationship to + the value. Valid operators are Exists and Equal. Defaults + to Equal. Exists is equivalent to wildcard for value, + so that a pod can tolerate all taints of a particular + category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period of + time the toleration (which must be of effect NoExecute, + otherwise this field is ignored) tolerates the taint. + By default, it is not set, which means tolerate the taint + forever (do not evict). Zero and negative values will + be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration matches + to. If the operator is Exists, the value should be empty, + otherwise just a regular string. + type: string + type: object + type: array + type: object + replicaSC: + description: ReplicaSC represents the storage class used for creating + the pvc for the replicas (provisioned by localpv provisioner) + type: string + serviceAccountName: + description: ServiceAccountName can be provided to enable PSP + type: string + target: + description: TargetSpec represents configuration related to jiva target + and its resources + nullable: true + properties: + affinity: + description: Affinity if specified, are the pod's affinities + properties: + nodeAffinity: + description: Describes node affinity scheduling rules for + the pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods + to nodes that satisfy the affinity expressions specified + by this field, but it may choose a node that violates + one or more of the expressions. The node that is most + preferred is the one with the greatest sum of weights, + i.e. for each node that meets all of the scheduling + requirements (resource request, requiredDuringScheduling + affinity expressions, etc.), compute a sum by iterating + through the elements of this field and adding "weight" + to the sum if the node matches the corresponding matchExpressions; + the node(s) with the highest sum are the most preferred. + items: + description: An empty preferred scheduling term matches + all objects with implicit weight 0 (i.e. it's a no-op). + A null preferred scheduling term matches no objects + (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated with + the corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement is + a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement is + a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + description: Weight associated with matching the + corresponding nodeSelectorTerm, in the range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by + this field are not met at scheduling time, the pod will + not be scheduled onto the node. If the affinity requirements + specified by this field cease to be met at some point + during pod execution (e.g. due to an update), the system + may or may not try to eventually evict the pod from + its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector terms. + The terms are ORed. + items: + description: A null or empty node selector term + matches no objects. The requirements of them are + ANDed. The TopologySelectorTerm type implements + a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement is + a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement is + a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, the + values array must be non-empty. If the + operator is Exists or DoesNotExist, + the values array must be empty. If the + operator is Gt or Lt, the values array + must have a single element, which will + be interpreted as an integer. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + description: Describes pod affinity scheduling rules (e.g. + co-locate this pod in the same node, zone, etc. as some + other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods + to nodes that satisfy the affinity expressions specified + by this field, but it may choose a node that violates + one or more of the expressions. The node that is most + preferred is the one with the greatest sum of weights, + i.e. for each node that meets all of the scheduling + requirements (resource request, requiredDuringScheduling + affinity expressions, etc.), compute a sum by iterating + through the elements of this field and adding "weight" + to the sum if the node has pods which matches the corresponding + podAffinityTerm; the node(s) with the highest sum are + the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies which namespaces + the labelSelector applies to (matches against); + null or empty list means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the + pods matching the labelSelector in the specified + namespaces, where co-located is defined as + running on a node whose value of the label + with key topologyKey matches that of any node + on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the + corresponding podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by + this field are not met at scheduling time, the pod will + not be scheduled onto the node. If the affinity requirements + specified by this field cease to be met at some point + during pod execution (e.g. due to a pod label update), + the system may or may not try to eventually evict the + pod from its node. When there are multiple elements, + the lists of nodes corresponding to each podAffinityTerm + are intersected, i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not + co-located (anti-affinity) with, where co-located + is defined as running on a node whose value of the + label with key matches that of any node + on which a pod of the set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies which namespaces + the labelSelector applies to (matches against); + null or empty list means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey + matches that of any node on which any of the selected + pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules + (e.g. avoid putting this pod in the same node, zone, etc. + as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods + to nodes that satisfy the anti-affinity expressions + specified by this field, but it may choose a node that + violates one or more of the expressions. The node that + is most preferred is the one with the greatest sum of + weights, i.e. for each node that meets all of the scheduling + requirements (resource request, requiredDuringScheduling + anti-affinity expressions, etc.), compute a sum by iterating + through the elements of this field and adding "weight" + to the sum if the node has pods which matches the corresponding + podAffinityTerm; the node(s) with the highest sum are + the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies which namespaces + the labelSelector applies to (matches against); + null or empty list means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the + pods matching the labelSelector in the specified + namespaces, where co-located is defined as + running on a node whose value of the label + with key topologyKey matches that of any node + on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the + corresponding podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the anti-affinity requirements specified + by this field are not met at scheduling time, the pod + will not be scheduled onto the node. If the anti-affinity + requirements specified by this field cease to be met + at some point during pod execution (e.g. due to a pod + label update), the system may or may not try to eventually + evict the pod from its node. When there are multiple + elements, the lists of nodes corresponding to each podAffinityTerm + are intersected, i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not + co-located (anti-affinity) with, where co-located + is defined as running on a node whose value of the + label with key matches that of any node + on which a pod of the set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies which namespaces + the labelSelector applies to (matches against); + null or empty list means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey + matches that of any node on which any of the selected + pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + auxResources: + description: AuxResources are the compute resources required by + the jiva-target pod side car containers. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' + type: object + type: object + disableMonitor: + description: DisableMonitor will not attach prometheus exporter + sidecar to jiva volume target. + type: boolean + nodeSelector: + additionalProperties: + type: string + description: NodeSelector is the labels that will be used to select + a node for pod scheduleing + type: object + replicationFactor: + description: ReplicationFactor represents maximum number of replicas + that are allowed to connect to the target + type: integer + resources: + description: Resources are the compute resources required by the + jiva container. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' + type: object + type: object + tolerations: + description: Tolerations, if specified, are the pod's tolerations + items: + description: The pod this Toleration is attached to tolerates + any taint that matches the triple using + the matching operator . + properties: + effect: + description: Effect indicates the taint effect to match. + Empty means match all taint effects. When specified, allowed + values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Key is the taint key that the toleration applies + to. Empty means match all taint keys. If the key is empty, + operator must be Exists; this combination means to match + all values and all keys. + type: string + operator: + description: Operator represents a key's relationship to + the value. Valid operators are Exists and Equal. Defaults + to Equal. Exists is equivalent to wildcard for value, + so that a pod can tolerate all taints of a particular + category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period of + time the toleration (which must be of effect NoExecute, + otherwise this field is ignored) tolerates the taint. + By default, it is not set, which means tolerate the taint + forever (do not evict). Zero and negative values will + be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration matches + to. If the operator is Exists, the value should be empty, + otherwise just a regular string. + type: string + type: object + type: array + type: object + type: object + status: + description: JivaVolumePolicyStatus is for handling status of JivaVolumePolicy + properties: + phase: + type: string + required: + - phase + type: object + type: object + served: true + storage: false +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/helm/openebs/charts/jiva/crds/jivavolumes.yaml b/helm/openebs/charts/jiva/crds/jivavolumes.yaml new file mode 100644 index 0000000..8aff71f --- /dev/null +++ b/helm/openebs/charts/jiva/crds/jivavolumes.yaml @@ -0,0 +1,3300 @@ + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.1 + creationTimestamp: null + name: jivavolumes.openebs.io +spec: + group: openebs.io + names: + kind: JivaVolume + listKind: JivaVolumeList + plural: jivavolumes + shortNames: + - jv + singular: jivavolume + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .status.replicaCount + name: ReplicaCount + type: string + - jsonPath: .status.phase + name: Phase + type: string + - jsonPath: .status.status + name: Status + type: string + name: v1 + schema: + openAPIV3Schema: + description: 'JivaVolume is the Schema for the jivavolumes API Important: + Run "operator-sdk generate k8s" to regenerate code after modifying this + file' + 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: JivaVolumeSpec defines the desired state of JivaVolume + properties: + accessType: + description: AccessType can be specified as Block or Mount type + type: string + capacity: + type: string + desiredReplicationFactor: + type: integer + iscsiSpec: + nullable: true + properties: + iqn: + type: string + targetIP: + type: string + targetPort: + format: int32 + type: integer + type: object + mountInfo: + nullable: true + properties: + devicePath: + type: string + fsType: + type: string + stagingPath: + description: StagingPath is the path provided by K8s during NodeStageVolume + rpc call, where volume is mounted globally. + type: string + targetPath: + description: TargetPath is the path provided by K8s during NodePublishVolume + rpc call where bind mount happens. + type: string + type: object + policy: + description: Policy is the configuration used for creating target + and replica pods during volume provisioning + nullable: true + properties: + priorityClassName: + description: PriorityClassName if specified applies to the pod + If left empty, no priority class is applied. + type: string + replica: + description: ReplicaSpec represents configuration related to replicas + resources + nullable: true + properties: + affinity: + description: Affinity if specified, are the pod's affinities + properties: + nodeAffinity: + description: Describes node affinity scheduling rules + for the pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule + pods to nodes that satisfy the affinity expressions + specified by this field, but it may choose a node + that violates one or more of the expressions. The + node that is most preferred is the one with the + greatest sum of weights, i.e. for each node that + meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, + etc.), compute a sum by iterating through the elements + of this field and adding "weight" to the sum if + the node matches the corresponding matchExpressions; + the node(s) with the highest sum are the most preferred. + items: + description: An empty preferred scheduling term + matches all objects with implicit weight 0 (i.e. + it's a no-op). A null preferred scheduling term + matches no objects (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated + with the corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: The label key that the + selector applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. + If the operator is Gt or Lt, the + values array must have a single + element, which will be interpreted + as an integer. This array is replaced + during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: The label key that the + selector applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. + If the operator is Gt or Lt, the + values array must have a single + element, which will be interpreted + as an integer. This array is replaced + during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + description: Weight associated with matching + the corresponding nodeSelectorTerm, in the + range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified + by this field are not met at scheduling time, the + pod will not be scheduled onto the node. If the + affinity requirements specified by this field cease + to be met at some point during pod execution (e.g. + due to an update), the system may or may not try + to eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector + terms. The terms are ORed. + items: + description: A null or empty node selector term + matches no objects. The requirements of them + are ANDed. The TopologySelectorTerm type implements + a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: The label key that the + selector applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. + If the operator is Gt or Lt, the + values array must have a single + element, which will be interpreted + as an integer. This array is replaced + during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: The label key that the + selector applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. + If the operator is Gt or Lt, the + values array must have a single + element, which will be interpreted + as an integer. This array is replaced + during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + description: Describes pod affinity scheduling rules (e.g. + co-locate this pod in the same node, zone, etc. as some + other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule + pods to nodes that satisfy the affinity expressions + specified by this field, but it may choose a node + that violates one or more of the expressions. The + node that is most preferred is the one with the + greatest sum of weights, i.e. for each node that + meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, + etc.), compute a sum by iterating through the elements + of this field and adding "weight" to the sum if + the node has pods which matches the corresponding + podAffinityTerm; the node(s) with the highest sum + are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, + associated with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of + resources, in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: operator represents + a key's relationship to a set + of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array + of string values. If the operator + is In or NotIn, the values array + must be non-empty. If the operator + is Exists or DoesNotExist, the + values array must be empty. + This array is replaced during + a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of + {key,value} pairs. A single {key,value} + in the matchLabels map is equivalent + to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are + ANDed. + type: object + type: object + namespaces: + description: namespaces specifies which + namespaces the labelSelector applies to + (matches against); null or empty list + means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located + (affinity) or not co-located (anti-affinity) + with the pods matching the labelSelector + in the specified namespaces, where co-located + is defined as running on a node whose + value of the label with key topologyKey + matches that of any node on which any + of the selected pods is running. Empty + topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching + the corresponding podAffinityTerm, in the + range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified + by this field are not met at scheduling time, the + pod will not be scheduled onto the node. If the + affinity requirements specified by this field cease + to be met at some point during pod execution (e.g. + due to a pod label update), the system may or may + not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes + corresponding to each podAffinityTerm are intersected, + i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those + matching the labelSelector relative to the given + namespace(s)) that this pod should be co-located + (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node + whose value of the label with key + matches that of any node on which a pod of the + set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies which namespaces + the labelSelector applies to (matches against); + null or empty list means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the + pods matching the labelSelector in the specified + namespaces, where co-located is defined as + running on a node whose value of the label + with key topologyKey matches that of any node + on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules + (e.g. avoid putting this pod in the same node, zone, + etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule + pods to nodes that satisfy the anti-affinity expressions + specified by this field, but it may choose a node + that violates one or more of the expressions. The + node that is most preferred is the one with the + greatest sum of weights, i.e. for each node that + meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity + expressions, etc.), compute a sum by iterating through + the elements of this field and adding "weight" to + the sum if the node has pods which matches the corresponding + podAffinityTerm; the node(s) with the highest sum + are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, + associated with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of + resources, in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: operator represents + a key's relationship to a set + of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array + of string values. If the operator + is In or NotIn, the values array + must be non-empty. If the operator + is Exists or DoesNotExist, the + values array must be empty. + This array is replaced during + a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of + {key,value} pairs. A single {key,value} + in the matchLabels map is equivalent + to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are + ANDed. + type: object + type: object + namespaces: + description: namespaces specifies which + namespaces the labelSelector applies to + (matches against); null or empty list + means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located + (affinity) or not co-located (anti-affinity) + with the pods matching the labelSelector + in the specified namespaces, where co-located + is defined as running on a node whose + value of the label with key topologyKey + matches that of any node on which any + of the selected pods is running. Empty + topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching + the corresponding podAffinityTerm, in the + range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the anti-affinity requirements specified + by this field are not met at scheduling time, the + pod will not be scheduled onto the node. If the + anti-affinity requirements specified by this field + cease to be met at some point during pod execution + (e.g. due to a pod label update), the system may + or may not try to eventually evict the pod from + its node. When there are multiple elements, the + lists of nodes corresponding to each podAffinityTerm + are intersected, i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those + matching the labelSelector relative to the given + namespace(s)) that this pod should be co-located + (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node + whose value of the label with key + matches that of any node on which a pod of the + set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies which namespaces + the labelSelector applies to (matches against); + null or empty list means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the + pods matching the labelSelector in the specified + namespaces, where co-located is defined as + running on a node whose value of the label + with key topologyKey matches that of any node + on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + nodeSelector: + additionalProperties: + type: string + description: NodeSelector is the labels that will be used + to select a node for pod scheduleing + type: object + resources: + description: Resources are the compute resources required + by the jiva container. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of + compute resources required. If Requests is omitted for + a container, it defaults to Limits if that is explicitly + specified, otherwise to an implementation-defined value. + More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' + type: object + type: object + tolerations: + description: Tolerations, if specified, are the pod's tolerations + items: + description: The pod this Toleration is attached to tolerates + any taint that matches the triple using + the matching operator . + properties: + effect: + description: Effect indicates the taint effect to match. + Empty means match all taint effects. When specified, + allowed values are NoSchedule, PreferNoSchedule and + NoExecute. + type: string + key: + description: Key is the taint key that the toleration + applies to. Empty means match all taint keys. If the + key is empty, operator must be Exists; this combination + means to match all values and all keys. + type: string + operator: + description: Operator represents a key's relationship + to the value. Valid operators are Exists and Equal. + Defaults to Equal. Exists is equivalent to wildcard + for value, so that a pod can tolerate all taints of + a particular category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period + of time the toleration (which must be of effect NoExecute, + otherwise this field is ignored) tolerates the taint. + By default, it is not set, which means tolerate the + taint forever (do not evict). Zero and negative values + will be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration + matches to. If the operator is Exists, the value should + be empty, otherwise just a regular string. + type: string + type: object + type: array + type: object + replicaSC: + description: ReplicaSC represents the storage class used for creating + the pvc for the replicas (provisioned by localpv provisioner) + type: string + serviceAccountName: + description: ServiceAccountName can be provided to enable PSP + type: string + target: + description: TargetSpec represents configuration related to jiva + target and its resources + nullable: true + properties: + affinity: + description: Affinity if specified, are the pod's affinities + properties: + nodeAffinity: + description: Describes node affinity scheduling rules + for the pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule + pods to nodes that satisfy the affinity expressions + specified by this field, but it may choose a node + that violates one or more of the expressions. The + node that is most preferred is the one with the + greatest sum of weights, i.e. for each node that + meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, + etc.), compute a sum by iterating through the elements + of this field and adding "weight" to the sum if + the node matches the corresponding matchExpressions; + the node(s) with the highest sum are the most preferred. + items: + description: An empty preferred scheduling term + matches all objects with implicit weight 0 (i.e. + it's a no-op). A null preferred scheduling term + matches no objects (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated + with the corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: The label key that the + selector applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. + If the operator is Gt or Lt, the + values array must have a single + element, which will be interpreted + as an integer. This array is replaced + during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: The label key that the + selector applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. + If the operator is Gt or Lt, the + values array must have a single + element, which will be interpreted + as an integer. This array is replaced + during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + description: Weight associated with matching + the corresponding nodeSelectorTerm, in the + range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified + by this field are not met at scheduling time, the + pod will not be scheduled onto the node. If the + affinity requirements specified by this field cease + to be met at some point during pod execution (e.g. + due to an update), the system may or may not try + to eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector + terms. The terms are ORed. + items: + description: A null or empty node selector term + matches no objects. The requirements of them + are ANDed. The TopologySelectorTerm type implements + a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: The label key that the + selector applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. + If the operator is Gt or Lt, the + values array must have a single + element, which will be interpreted + as an integer. This array is replaced + during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: The label key that the + selector applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. + If the operator is Gt or Lt, the + values array must have a single + element, which will be interpreted + as an integer. This array is replaced + during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + description: Describes pod affinity scheduling rules (e.g. + co-locate this pod in the same node, zone, etc. as some + other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule + pods to nodes that satisfy the affinity expressions + specified by this field, but it may choose a node + that violates one or more of the expressions. The + node that is most preferred is the one with the + greatest sum of weights, i.e. for each node that + meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, + etc.), compute a sum by iterating through the elements + of this field and adding "weight" to the sum if + the node has pods which matches the corresponding + podAffinityTerm; the node(s) with the highest sum + are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, + associated with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of + resources, in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: operator represents + a key's relationship to a set + of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array + of string values. If the operator + is In or NotIn, the values array + must be non-empty. If the operator + is Exists or DoesNotExist, the + values array must be empty. + This array is replaced during + a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of + {key,value} pairs. A single {key,value} + in the matchLabels map is equivalent + to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are + ANDed. + type: object + type: object + namespaces: + description: namespaces specifies which + namespaces the labelSelector applies to + (matches against); null or empty list + means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located + (affinity) or not co-located (anti-affinity) + with the pods matching the labelSelector + in the specified namespaces, where co-located + is defined as running on a node whose + value of the label with key topologyKey + matches that of any node on which any + of the selected pods is running. Empty + topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching + the corresponding podAffinityTerm, in the + range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified + by this field are not met at scheduling time, the + pod will not be scheduled onto the node. If the + affinity requirements specified by this field cease + to be met at some point during pod execution (e.g. + due to a pod label update), the system may or may + not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes + corresponding to each podAffinityTerm are intersected, + i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those + matching the labelSelector relative to the given + namespace(s)) that this pod should be co-located + (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node + whose value of the label with key + matches that of any node on which a pod of the + set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies which namespaces + the labelSelector applies to (matches against); + null or empty list means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the + pods matching the labelSelector in the specified + namespaces, where co-located is defined as + running on a node whose value of the label + with key topologyKey matches that of any node + on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules + (e.g. avoid putting this pod in the same node, zone, + etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule + pods to nodes that satisfy the anti-affinity expressions + specified by this field, but it may choose a node + that violates one or more of the expressions. The + node that is most preferred is the one with the + greatest sum of weights, i.e. for each node that + meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity + expressions, etc.), compute a sum by iterating through + the elements of this field and adding "weight" to + the sum if the node has pods which matches the corresponding + podAffinityTerm; the node(s) with the highest sum + are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, + associated with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of + resources, in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: operator represents + a key's relationship to a set + of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array + of string values. If the operator + is In or NotIn, the values array + must be non-empty. If the operator + is Exists or DoesNotExist, the + values array must be empty. + This array is replaced during + a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of + {key,value} pairs. A single {key,value} + in the matchLabels map is equivalent + to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are + ANDed. + type: object + type: object + namespaces: + description: namespaces specifies which + namespaces the labelSelector applies to + (matches against); null or empty list + means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located + (affinity) or not co-located (anti-affinity) + with the pods matching the labelSelector + in the specified namespaces, where co-located + is defined as running on a node whose + value of the label with key topologyKey + matches that of any node on which any + of the selected pods is running. Empty + topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching + the corresponding podAffinityTerm, in the + range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the anti-affinity requirements specified + by this field are not met at scheduling time, the + pod will not be scheduled onto the node. If the + anti-affinity requirements specified by this field + cease to be met at some point during pod execution + (e.g. due to a pod label update), the system may + or may not try to eventually evict the pod from + its node. When there are multiple elements, the + lists of nodes corresponding to each podAffinityTerm + are intersected, i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those + matching the labelSelector relative to the given + namespace(s)) that this pod should be co-located + (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node + whose value of the label with key + matches that of any node on which a pod of the + set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies which namespaces + the labelSelector applies to (matches against); + null or empty list means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the + pods matching the labelSelector in the specified + namespaces, where co-located is defined as + running on a node whose value of the label + with key topologyKey matches that of any node + on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + auxResources: + description: AuxResources are the compute resources required + by the jiva-target pod side car containers. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of + compute resources required. If Requests is omitted for + a container, it defaults to Limits if that is explicitly + specified, otherwise to an implementation-defined value. + More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' + type: object + type: object + disableMonitor: + description: DisableMonitor will not attach prometheus exporter + sidecar to jiva volume target. + type: boolean + nodeSelector: + additionalProperties: + type: string + description: NodeSelector is the labels that will be used + to select a node for pod scheduleing + type: object + replicationFactor: + description: ReplicationFactor represents maximum number of + replicas that are allowed to connect to the target + type: integer + resources: + description: Resources are the compute resources required + by the jiva container. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of + compute resources required. If Requests is omitted for + a container, it defaults to Limits if that is explicitly + specified, otherwise to an implementation-defined value. + More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' + type: object + type: object + tolerations: + description: Tolerations, if specified, are the pod's tolerations + items: + description: The pod this Toleration is attached to tolerates + any taint that matches the triple using + the matching operator . + properties: + effect: + description: Effect indicates the taint effect to match. + Empty means match all taint effects. When specified, + allowed values are NoSchedule, PreferNoSchedule and + NoExecute. + type: string + key: + description: Key is the taint key that the toleration + applies to. Empty means match all taint keys. If the + key is empty, operator must be Exists; this combination + means to match all values and all keys. + type: string + operator: + description: Operator represents a key's relationship + to the value. Valid operators are Exists and Equal. + Defaults to Equal. Exists is equivalent to wildcard + for value, so that a pod can tolerate all taints of + a particular category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period + of time the toleration (which must be of effect NoExecute, + otherwise this field is ignored) tolerates the taint. + By default, it is not set, which means tolerate the + taint forever (do not evict). Zero and negative values + will be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration + matches to. If the operator is Exists, the value should + be empty, otherwise just a regular string. + type: string + type: object + type: array + type: object + type: object + pv: + type: string + required: + - accessType + - capacity + - pv + type: object + status: + description: JivaVolumeStatus defines the observed state of JivaVolume + properties: + phase: + description: Phase represents the current phase of JivaVolume. + type: string + replicaCount: + type: integer + replicaStatus: + items: + description: ReplicaStatus stores the status of replicas + properties: + address: + type: string + mode: + type: string + type: object + nullable: true + type: array + status: + type: string + type: object + versionDetails: + description: VersionDetails provides the details for upgrade + properties: + autoUpgrade: + description: If AutoUpgrade is set to true then the resource is upgraded + automatically without any manual steps + type: boolean + desired: + description: Desired is the version that we want to upgrade or the + control plane version + type: string + status: + description: Status gives the status of reconciliation triggered when + the desired and current version are not same + properties: + current: + description: Current is the version of resource + type: string + dependentsUpgraded: + description: DependentsUpgraded gives the details whether all + children of a resource are upgraded to desired version or not + type: boolean + lastUpdateTime: + description: LastUpdateTime is the time the status was last updated + format: date-time + nullable: true + type: string + message: + description: Message is a human readable message if some error + occurs + type: string + reason: + description: Reason is the actual reason for the error state + type: string + state: + description: State is the state of reconciliation + type: string + type: object + type: object + type: object + served: true + storage: true + subresources: {} + - additionalPrinterColumns: + - jsonPath: .status.replicaCount + name: ReplicaCount + type: string + - jsonPath: .status.phase + name: Phase + type: string + - jsonPath: .status.status + name: Status + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + description: 'JivaVolume is the Schema for the jivavolumes API Important: + Run "operator-sdk generate k8s" to regenerate code after modifying this + file' + 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: JivaVolumeSpec defines the desired state of JivaVolume + properties: + accessType: + description: AccessType can be specified as Block or Mount type + type: string + capacity: + type: string + desiredReplicationFactor: + type: integer + iscsiSpec: + nullable: true + properties: + iqn: + type: string + targetIP: + type: string + targetPort: + format: int32 + type: integer + type: object + mountInfo: + nullable: true + properties: + devicePath: + type: string + fsType: + type: string + stagingPath: + description: StagingPath is the path provided by K8s during NodeStageVolume + rpc call, where volume is mounted globally. + type: string + targetPath: + description: TargetPath is the path provided by K8s during NodePublishVolume + rpc call where bind mount happens. + type: string + type: object + policy: + description: Policy is the configuration used for creating target + and replica pods during volume provisioning + nullable: true + properties: + priorityClassName: + description: PriorityClassName if specified applies to the pod + If left empty, no priority class is applied. + type: string + replica: + description: ReplicaSpec represents configuration related to replicas + resources + nullable: true + properties: + affinity: + description: Affinity if specified, are the pod's affinities + properties: + nodeAffinity: + description: Describes node affinity scheduling rules + for the pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule + pods to nodes that satisfy the affinity expressions + specified by this field, but it may choose a node + that violates one or more of the expressions. The + node that is most preferred is the one with the + greatest sum of weights, i.e. for each node that + meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, + etc.), compute a sum by iterating through the elements + of this field and adding "weight" to the sum if + the node matches the corresponding matchExpressions; + the node(s) with the highest sum are the most preferred. + items: + description: An empty preferred scheduling term + matches all objects with implicit weight 0 (i.e. + it's a no-op). A null preferred scheduling term + matches no objects (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated + with the corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: The label key that the + selector applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. + If the operator is Gt or Lt, the + values array must have a single + element, which will be interpreted + as an integer. This array is replaced + during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: The label key that the + selector applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. + If the operator is Gt or Lt, the + values array must have a single + element, which will be interpreted + as an integer. This array is replaced + during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + description: Weight associated with matching + the corresponding nodeSelectorTerm, in the + range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified + by this field are not met at scheduling time, the + pod will not be scheduled onto the node. If the + affinity requirements specified by this field cease + to be met at some point during pod execution (e.g. + due to an update), the system may or may not try + to eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector + terms. The terms are ORed. + items: + description: A null or empty node selector term + matches no objects. The requirements of them + are ANDed. The TopologySelectorTerm type implements + a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: The label key that the + selector applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. + If the operator is Gt or Lt, the + values array must have a single + element, which will be interpreted + as an integer. This array is replaced + during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: The label key that the + selector applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. + If the operator is Gt or Lt, the + values array must have a single + element, which will be interpreted + as an integer. This array is replaced + during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + description: Describes pod affinity scheduling rules (e.g. + co-locate this pod in the same node, zone, etc. as some + other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule + pods to nodes that satisfy the affinity expressions + specified by this field, but it may choose a node + that violates one or more of the expressions. The + node that is most preferred is the one with the + greatest sum of weights, i.e. for each node that + meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, + etc.), compute a sum by iterating through the elements + of this field and adding "weight" to the sum if + the node has pods which matches the corresponding + podAffinityTerm; the node(s) with the highest sum + are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, + associated with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of + resources, in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: operator represents + a key's relationship to a set + of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array + of string values. If the operator + is In or NotIn, the values array + must be non-empty. If the operator + is Exists or DoesNotExist, the + values array must be empty. + This array is replaced during + a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of + {key,value} pairs. A single {key,value} + in the matchLabels map is equivalent + to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are + ANDed. + type: object + type: object + namespaces: + description: namespaces specifies which + namespaces the labelSelector applies to + (matches against); null or empty list + means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located + (affinity) or not co-located (anti-affinity) + with the pods matching the labelSelector + in the specified namespaces, where co-located + is defined as running on a node whose + value of the label with key topologyKey + matches that of any node on which any + of the selected pods is running. Empty + topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching + the corresponding podAffinityTerm, in the + range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified + by this field are not met at scheduling time, the + pod will not be scheduled onto the node. If the + affinity requirements specified by this field cease + to be met at some point during pod execution (e.g. + due to a pod label update), the system may or may + not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes + corresponding to each podAffinityTerm are intersected, + i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those + matching the labelSelector relative to the given + namespace(s)) that this pod should be co-located + (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node + whose value of the label with key + matches that of any node on which a pod of the + set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies which namespaces + the labelSelector applies to (matches against); + null or empty list means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the + pods matching the labelSelector in the specified + namespaces, where co-located is defined as + running on a node whose value of the label + with key topologyKey matches that of any node + on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules + (e.g. avoid putting this pod in the same node, zone, + etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule + pods to nodes that satisfy the anti-affinity expressions + specified by this field, but it may choose a node + that violates one or more of the expressions. The + node that is most preferred is the one with the + greatest sum of weights, i.e. for each node that + meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity + expressions, etc.), compute a sum by iterating through + the elements of this field and adding "weight" to + the sum if the node has pods which matches the corresponding + podAffinityTerm; the node(s) with the highest sum + are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, + associated with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of + resources, in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: operator represents + a key's relationship to a set + of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array + of string values. If the operator + is In or NotIn, the values array + must be non-empty. If the operator + is Exists or DoesNotExist, the + values array must be empty. + This array is replaced during + a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of + {key,value} pairs. A single {key,value} + in the matchLabels map is equivalent + to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are + ANDed. + type: object + type: object + namespaces: + description: namespaces specifies which + namespaces the labelSelector applies to + (matches against); null or empty list + means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located + (affinity) or not co-located (anti-affinity) + with the pods matching the labelSelector + in the specified namespaces, where co-located + is defined as running on a node whose + value of the label with key topologyKey + matches that of any node on which any + of the selected pods is running. Empty + topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching + the corresponding podAffinityTerm, in the + range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the anti-affinity requirements specified + by this field are not met at scheduling time, the + pod will not be scheduled onto the node. If the + anti-affinity requirements specified by this field + cease to be met at some point during pod execution + (e.g. due to a pod label update), the system may + or may not try to eventually evict the pod from + its node. When there are multiple elements, the + lists of nodes corresponding to each podAffinityTerm + are intersected, i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those + matching the labelSelector relative to the given + namespace(s)) that this pod should be co-located + (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node + whose value of the label with key + matches that of any node on which a pod of the + set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies which namespaces + the labelSelector applies to (matches against); + null or empty list means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the + pods matching the labelSelector in the specified + namespaces, where co-located is defined as + running on a node whose value of the label + with key topologyKey matches that of any node + on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + nodeSelector: + additionalProperties: + type: string + description: NodeSelector is the labels that will be used + to select a node for pod scheduleing + type: object + resources: + description: Resources are the compute resources required + by the jiva container. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of + compute resources required. If Requests is omitted for + a container, it defaults to Limits if that is explicitly + specified, otherwise to an implementation-defined value. + More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' + type: object + type: object + tolerations: + description: Tolerations, if specified, are the pod's tolerations + items: + description: The pod this Toleration is attached to tolerates + any taint that matches the triple using + the matching operator . + properties: + effect: + description: Effect indicates the taint effect to match. + Empty means match all taint effects. When specified, + allowed values are NoSchedule, PreferNoSchedule and + NoExecute. + type: string + key: + description: Key is the taint key that the toleration + applies to. Empty means match all taint keys. If the + key is empty, operator must be Exists; this combination + means to match all values and all keys. + type: string + operator: + description: Operator represents a key's relationship + to the value. Valid operators are Exists and Equal. + Defaults to Equal. Exists is equivalent to wildcard + for value, so that a pod can tolerate all taints of + a particular category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period + of time the toleration (which must be of effect NoExecute, + otherwise this field is ignored) tolerates the taint. + By default, it is not set, which means tolerate the + taint forever (do not evict). Zero and negative values + will be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration + matches to. If the operator is Exists, the value should + be empty, otherwise just a regular string. + type: string + type: object + type: array + type: object + replicaSC: + description: ReplicaSC represents the storage class used for creating + the pvc for the replicas (provisioned by localpv provisioner) + type: string + serviceAccountName: + description: ServiceAccountName can be provided to enable PSP + type: string + target: + description: TargetSpec represents configuration related to jiva + target and its resources + nullable: true + properties: + affinity: + description: Affinity if specified, are the pod's affinities + properties: + nodeAffinity: + description: Describes node affinity scheduling rules + for the pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule + pods to nodes that satisfy the affinity expressions + specified by this field, but it may choose a node + that violates one or more of the expressions. The + node that is most preferred is the one with the + greatest sum of weights, i.e. for each node that + meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, + etc.), compute a sum by iterating through the elements + of this field and adding "weight" to the sum if + the node matches the corresponding matchExpressions; + the node(s) with the highest sum are the most preferred. + items: + description: An empty preferred scheduling term + matches all objects with implicit weight 0 (i.e. + it's a no-op). A null preferred scheduling term + matches no objects (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated + with the corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: The label key that the + selector applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. + If the operator is Gt or Lt, the + values array must have a single + element, which will be interpreted + as an integer. This array is replaced + during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: The label key that the + selector applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. + If the operator is Gt or Lt, the + values array must have a single + element, which will be interpreted + as an integer. This array is replaced + during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + description: Weight associated with matching + the corresponding nodeSelectorTerm, in the + range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified + by this field are not met at scheduling time, the + pod will not be scheduled onto the node. If the + affinity requirements specified by this field cease + to be met at some point during pod execution (e.g. + due to an update), the system may or may not try + to eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector + terms. The terms are ORed. + items: + description: A null or empty node selector term + matches no objects. The requirements of them + are ANDed. The TopologySelectorTerm type implements + a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: The label key that the + selector applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. + If the operator is Gt or Lt, the + values array must have a single + element, which will be interpreted + as an integer. This array is replaced + during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: The label key that the + selector applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators + are In, NotIn, Exists, DoesNotExist. + Gt, and Lt. + type: string + values: + description: An array of string values. + If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. + If the operator is Gt or Lt, the + values array must have a single + element, which will be interpreted + as an integer. This array is replaced + during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + description: Describes pod affinity scheduling rules (e.g. + co-locate this pod in the same node, zone, etc. as some + other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule + pods to nodes that satisfy the affinity expressions + specified by this field, but it may choose a node + that violates one or more of the expressions. The + node that is most preferred is the one with the + greatest sum of weights, i.e. for each node that + meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, + etc.), compute a sum by iterating through the elements + of this field and adding "weight" to the sum if + the node has pods which matches the corresponding + podAffinityTerm; the node(s) with the highest sum + are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, + associated with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of + resources, in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: operator represents + a key's relationship to a set + of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array + of string values. If the operator + is In or NotIn, the values array + must be non-empty. If the operator + is Exists or DoesNotExist, the + values array must be empty. + This array is replaced during + a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of + {key,value} pairs. A single {key,value} + in the matchLabels map is equivalent + to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are + ANDed. + type: object + type: object + namespaces: + description: namespaces specifies which + namespaces the labelSelector applies to + (matches against); null or empty list + means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located + (affinity) or not co-located (anti-affinity) + with the pods matching the labelSelector + in the specified namespaces, where co-located + is defined as running on a node whose + value of the label with key topologyKey + matches that of any node on which any + of the selected pods is running. Empty + topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching + the corresponding podAffinityTerm, in the + range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified + by this field are not met at scheduling time, the + pod will not be scheduled onto the node. If the + affinity requirements specified by this field cease + to be met at some point during pod execution (e.g. + due to a pod label update), the system may or may + not try to eventually evict the pod from its node. + When there are multiple elements, the lists of nodes + corresponding to each podAffinityTerm are intersected, + i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those + matching the labelSelector relative to the given + namespace(s)) that this pod should be co-located + (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node + whose value of the label with key + matches that of any node on which a pod of the + set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies which namespaces + the labelSelector applies to (matches against); + null or empty list means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the + pods matching the labelSelector in the specified + namespaces, where co-located is defined as + running on a node whose value of the label + with key topologyKey matches that of any node + on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules + (e.g. avoid putting this pod in the same node, zone, + etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule + pods to nodes that satisfy the anti-affinity expressions + specified by this field, but it may choose a node + that violates one or more of the expressions. The + node that is most preferred is the one with the + greatest sum of weights, i.e. for each node that + meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity + expressions, etc.), compute a sum by iterating through + the elements of this field and adding "weight" to + the sum if the node has pods which matches the corresponding + podAffinityTerm; the node(s) with the highest sum + are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred + node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, + associated with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of + resources, in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: operator represents + a key's relationship to a set + of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array + of string values. If the operator + is In or NotIn, the values array + must be non-empty. If the operator + is Exists or DoesNotExist, the + values array must be empty. + This array is replaced during + a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of + {key,value} pairs. A single {key,value} + in the matchLabels map is equivalent + to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are + ANDed. + type: object + type: object + namespaces: + description: namespaces specifies which + namespaces the labelSelector applies to + (matches against); null or empty list + means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located + (affinity) or not co-located (anti-affinity) + with the pods matching the labelSelector + in the specified namespaces, where co-located + is defined as running on a node whose + value of the label with key topologyKey + matches that of any node on which any + of the selected pods is running. Empty + topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching + the corresponding podAffinityTerm, in the + range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the anti-affinity requirements specified + by this field are not met at scheduling time, the + pod will not be scheduled onto the node. If the + anti-affinity requirements specified by this field + cease to be met at some point during pod execution + (e.g. due to a pod label update), the system may + or may not try to eventually evict the pod from + its node. When there are multiple elements, the + lists of nodes corresponding to each podAffinityTerm + are intersected, i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those + matching the labelSelector relative to the given + namespace(s)) that this pod should be co-located + (affinity) or not co-located (anti-affinity) with, + where co-located is defined as running on a node + whose value of the label with key + matches that of any node on which a pod of the + set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The requirements + are ANDed. + items: + description: A label selector requirement + is a selector that contains values, + a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key + that the selector applies to. + type: string + operator: + description: operator represents a + key's relationship to a set of values. + Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of + string values. If the operator is + In or NotIn, the values array must + be non-empty. If the operator is + Exists or DoesNotExist, the values + array must be empty. This array + is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator + is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies which namespaces + the labelSelector applies to (matches against); + null or empty list means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the + pods matching the labelSelector in the specified + namespaces, where co-located is defined as + running on a node whose value of the label + with key topologyKey matches that of any node + on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + auxResources: + description: AuxResources are the compute resources required + by the jiva-target pod side car containers. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of + compute resources required. If Requests is omitted for + a container, it defaults to Limits if that is explicitly + specified, otherwise to an implementation-defined value. + More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' + type: object + type: object + disableMonitor: + description: DisableMonitor will not attach prometheus exporter + sidecar to jiva volume target. + type: boolean + nodeSelector: + additionalProperties: + type: string + description: NodeSelector is the labels that will be used + to select a node for pod scheduleing + type: object + replicationFactor: + description: ReplicationFactor represents maximum number of + replicas that are allowed to connect to the target + type: integer + resources: + description: Resources are the compute resources required + by the jiva container. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of + compute resources required. If Requests is omitted for + a container, it defaults to Limits if that is explicitly + specified, otherwise to an implementation-defined value. + More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' + type: object + type: object + tolerations: + description: Tolerations, if specified, are the pod's tolerations + items: + description: The pod this Toleration is attached to tolerates + any taint that matches the triple using + the matching operator . + properties: + effect: + description: Effect indicates the taint effect to match. + Empty means match all taint effects. When specified, + allowed values are NoSchedule, PreferNoSchedule and + NoExecute. + type: string + key: + description: Key is the taint key that the toleration + applies to. Empty means match all taint keys. If the + key is empty, operator must be Exists; this combination + means to match all values and all keys. + type: string + operator: + description: Operator represents a key's relationship + to the value. Valid operators are Exists and Equal. + Defaults to Equal. Exists is equivalent to wildcard + for value, so that a pod can tolerate all taints of + a particular category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period + of time the toleration (which must be of effect NoExecute, + otherwise this field is ignored) tolerates the taint. + By default, it is not set, which means tolerate the + taint forever (do not evict). Zero and negative values + will be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration + matches to. If the operator is Exists, the value should + be empty, otherwise just a regular string. + type: string + type: object + type: array + type: object + type: object + pv: + type: string + required: + - accessType + - capacity + - pv + type: object + status: + description: JivaVolumeStatus defines the observed state of JivaVolume + properties: + phase: + description: Phase represents the current phase of JivaVolume. + type: string + replicaCount: + type: integer + replicaStatus: + items: + description: ReplicaStatus stores the status of replicas + properties: + address: + type: string + mode: + type: string + type: object + nullable: true + type: array + status: + type: string + type: object + versionDetails: + description: VersionDetails provides the details for upgrade + properties: + autoUpgrade: + description: If AutoUpgrade is set to true then the resource is upgraded + automatically without any manual steps + type: boolean + desired: + description: Desired is the version that we want to upgrade or the + control plane version + type: string + status: + description: Status gives the status of reconciliation triggered when + the desired and current version are not same + properties: + current: + description: Current is the version of resource + type: string + dependentsUpgraded: + description: DependentsUpgraded gives the details whether all + children of a resource are upgraded to desired version or not + type: boolean + lastUpdateTime: + description: LastUpdateTime is the time the status was last updated + format: date-time + nullable: true + type: string + message: + description: Message is a human readable message if some error + occurs + type: string + reason: + description: Reason is the actual reason for the error state + type: string + state: + description: State is the state of reconciliation + type: string + type: object + type: object + type: object + served: true + storage: false + subresources: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/helm/openebs/charts/jiva/crds/upgradetask.yaml b/helm/openebs/charts/jiva/crds/upgradetask.yaml new file mode 100644 index 0000000..ab35065 --- /dev/null +++ b/helm/openebs/charts/jiva/crds/upgradetask.yaml @@ -0,0 +1,257 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.0 + creationTimestamp: null + name: upgradetasks.openebs.io +spec: + group: openebs.io + names: + kind: UpgradeTask + listKind: UpgradeTaskList + plural: upgradetasks + singular: upgradetask + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: UpgradeTask represents an upgrade task + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: Spec i.e. specifications of the UpgradeTask + properties: + cstorPool: + description: CStorPool contains the details of the cstor pool to be + upgraded + properties: + options: + description: Options can be used to change the default behaviour + of upgrade + properties: + ignoreStepsOnError: + description: IgnoreStepsOnError allows to ignore steps which + failed + items: + type: string + type: array + type: object + poolName: + description: PoolName contains the name of the cstor pool to be + upgraded + type: string + type: object + cstorPoolCluster: + description: CStorPoolCluster contains the details of the storage + pool claim to be upgraded + properties: + cspcName: + description: CSPCName contains the name of the storage pool claim + to be upgraded + type: string + options: + description: Options can be used to change the default behaviour + of upgrade + properties: + ignoreStepsOnError: + description: IgnoreStepsOnError allows to ignore steps which + failed + items: + type: string + type: array + type: object + type: object + cstorPoolInstance: + description: CStorPoolInstance contains the details of the cstor pool + to be upgraded + properties: + cspiName: + description: CSPCName contains the name of the storage pool claim + to be upgraded + type: string + options: + description: Options can be used to change the default behaviour + of upgrade + properties: + ignoreStepsOnError: + description: IgnoreStepsOnError allows to ignore steps which + failed + items: + type: string + type: array + type: object + type: object + cstorVolume: + description: CStorVolume contains the details of the cstor volume + to be upgraded + properties: + options: + description: Options can be used to change the default behaviour + of upgrade + properties: + ignoreStepsOnError: + description: IgnoreStepsOnError allows to ignore steps which + failed + items: + type: string + type: array + type: object + pvName: + description: PVName contains the name of the pv associated with + the cstor volume + type: string + type: object + fromVersion: + description: FromVersion is the current version of the resource. + type: string + imagePrefix: + description: ImagePrefix contains the url prefix of the image url. + This field is optional. If not present upgrade takes the previously + present ImagePrefix. + type: string + imageTag: + description: ImageTag contains the customized tag for ToVersion if + any. This field is optional. If not present upgrade takes the ToVersion + as the ImageTag + type: string + jivaVolume: + description: JivaVolume contains the details of the jiva volume to + be upgraded + properties: + options: + description: Options can be used to change the default behaviour + of upgrade + properties: + ignoreStepsOnError: + description: IgnoreStepsOnError allows to ignore steps which + failed + items: + type: string + type: array + type: object + pvName: + description: PVName contains the name of the pv associated with + the jiva volume + type: string + type: object + options: + description: Options contains the optional flags that can be passed + during upgrade. + properties: + timeout: + description: Timeout is maximum seconds to wait at any given step + in the upgrade + type: integer + type: object + storagePoolClaim: + description: StoragePoolClaim contains the details of the storage + pool claim to be upgraded + properties: + options: + description: Options can be used to change the default behaviour + of upgrade + properties: + ignoreStepsOnError: + description: IgnoreStepsOnError allows to ignore steps which + failed + items: + type: string + type: array + type: object + spcName: + description: SPCName contains the name of the storage pool claim + to be upgraded + type: string + type: object + toVersion: + description: ToVersion is the upgraded version of the resource. It + should be same as the version of control plane components version. + type: string + required: + - fromVersion + - toVersion + type: object + status: + description: Status of UpgradeTask + properties: + completedTime: + description: CompletedTime of Upgrade + format: date-time + nullable: true + type: string + phase: + description: Phase indicates if a upgradeTask is started, success + or errored + type: string + retries: + description: Retries is the number of times the job attempted to upgrade + the resource + type: integer + startTime: + description: StartTime of Upgrade + format: date-time + nullable: true + type: string + upgradeDetailedStatuses: + description: UpgradeDetailedStatuses contains the list of statuses + of each step + items: + description: UpgradeDetailedStatuses represents the latest available + observations of a UpgradeTask current state. + properties: + lastUpdatedAt: + description: LastUpdatedTime of a UpgradeStep + format: date-time + nullable: true + type: string + message: + description: A human-readable message indicating details about + why the upgradeStep is in this state + type: string + phase: + description: Phase indicates if the UpgradeStep is waiting, + errored or completed. + type: string + reason: + description: Reason is a brief CamelCase string that describes + any failure and is meant for machine parsing and tidy display + in the CLI + type: string + startTime: + description: StartTime of a UpgradeStep + format: date-time + nullable: true + type: string + step: + description: UpgradeStep is the current step being performed + for a particular resource upgrade + type: string + type: object + type: array + type: object + required: + - spec + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] +--- diff --git a/helm/openebs/charts/jiva/templates/NOTES.txt b/helm/openebs/charts/jiva/templates/NOTES.txt new file mode 100644 index 0000000..de04887 --- /dev/null +++ b/helm/openebs/charts/jiva/templates/NOTES.txt @@ -0,0 +1,8 @@ +The OpenEBS jiva has been installed check its status by running: +$ kubectl get pods -n {{ .Release.Namespace }} + +For more information, visit our Slack at https://openebs.io/community or view +the documentation online at http://docs.openebs.io/. + +For more information related to jiva volume provisioning, visit +https://github.com/openebs/jiva-operator/tree/master/docs . diff --git a/helm/openebs/charts/jiva/templates/_helpers.tpl b/helm/openebs/charts/jiva/templates/_helpers.tpl new file mode 100644 index 0000000..88fed2e --- /dev/null +++ b/helm/openebs/charts/jiva/templates/_helpers.tpl @@ -0,0 +1,150 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "jiva.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 "jiva.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 "jiva.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "jiva.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "jiva.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} + +{{/* +Define meta labels for jiva components +*/}} +{{- define "jiva.common.metaLabels" -}} +chart: {{ template "jiva.chart" . }} +heritage: {{ .Release.Service }} +openebs.io/version: {{ .Values.release.version | quote }} +{{- end -}} + +{{/* +Create match labels for jiva operator +*/}} +{{- define "jiva.operator.matchLabels" -}} +name: {{ .Values.jivaOperator.componentName | quote }} +release: {{ .Release.Name }} +component: {{ .Values.jivaOperator.componentName | quote }} +{{- end -}} + +{{/* +Create component labels jiva operator +*/}} +{{- define "jiva.operator.componentLabels" -}} +openebs.io/component-name: {{ .Values.jivaOperator.componentName | quote }} +{{- end -}} + + +{{/* +Create labels for jiva operator +*/}} +{{- define "jiva.operator.labels" -}} +{{ include "jiva.common.metaLabels" . }} +{{ include "jiva.operator.matchLabels" . }} +{{ include "jiva.operator.componentLabels" . }} +{{- end -}} + +{{/* +Create match labels for jiva csi node operator +*/}} +{{- define "jiva.csiNode.matchLabels" -}} +name: {{ .Values.csiNode.componentName | quote }} +release: {{ .Release.Name }} +component: {{ .Values.csiNode.componentName | quote }} +{{- end -}} + +{{/* +Create component labels jiva csi node operator +*/}} +{{- define "jiva.csiNode.componentLabels" -}} +openebs.io/component-name: {{ .Values.csiNode.componentName | quote }} +{{- end -}} + +{{/* +Create labels for jiva csi node operator +*/}} +{{- define "jiva.csiNode.labels" -}} +{{ include "jiva.common.metaLabels" . }} +{{ include "jiva.csiNode.matchLabels" . }} +{{ include "jiva.csiNode.componentLabels" . }} +{{- end -}} + +{{/* +Create match labels for jiva csi controller +*/}} +{{- define "jiva.csiController.matchLabels" -}} +name: {{ .Values.csiController.componentName | quote }} +release: {{ .Release.Name }} +component: {{ .Values.csiController.componentName | quote }} +{{- end -}} + +{{/* +Create component labels jiva csi controller +*/}} +{{- define "jiva.csiController.componentLabels" -}} +openebs.io/component-name: {{ .Values.csiController.componentName | quote }} +{{- end -}} + +{{/* +Create labels for jiva csi controller +*/}} +{{- define "jiva.csiController.labels" -}} +{{ include "jiva.common.metaLabels" . }} +{{ include "jiva.csiController.matchLabels" . }} +{{ include "jiva.csiController.componentLabels" . }} +{{- end -}} + +{{/* +Create the name of the priority class for csi node plugin +*/}} +{{- define "jiva.csiNode.priorityClassName" -}} +{{- if .Values.csiNode.priorityClass.create }} +{{- printf "%s-%s" .Release.Name .Values.csiNode.priorityClass.name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s" .Values.csiNode.priorityClass.name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} + +{{/* +Create the name of the priority class for csi controller plugin +*/}} +{{- define "jiva.csiController.priorityClassName" -}} +{{- if .Values.csiController.priorityClass.create }} +{{- printf "%s-%s" .Release.Name .Values.csiController.priorityClass.name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s" .Values.csiController.priorityClass.name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} diff --git a/helm/openebs/charts/jiva/templates/csi-controller-rbac.yaml b/helm/openebs/charts/jiva/templates/csi-controller-rbac.yaml new file mode 100644 index 0000000..c19db64 --- /dev/null +++ b/helm/openebs/charts/jiva/templates/csi-controller-rbac.yaml @@ -0,0 +1,196 @@ +{{- if .Values.serviceAccount.csiController.create -}} +kind: ServiceAccount +apiVersion: v1 +metadata: + name: {{ .Values.serviceAccount.csiController.name }} + labels: + {{- include "jiva.csiController.labels" . | nindent 4 }} + namespace: {{ .Release.Namespace }} +{{- end }} +{{- if .Values.rbac.create }} +--- +# jiva csi roles and bindings +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: openebs-jiva-csi-snapshotter-binding + labels: + {{- include "jiva.csiController.labels" . | nindent 4 }} +subjects: + - kind: ServiceAccount + name: {{ .Values.serviceAccount.csiController.name }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: openebs-jiva-csi-snapshotter-role + apiGroup: rbac.authorization.k8s.io +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: openebs-jiva-csi-snapshotter-role + labels: + {{- include "jiva.csiController.labels" . | nindent 4 }} +rules: + - apiGroups: [""] + resources: ["persistentvolumes"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["persistentvolumeclaims"] + verbs: ["get", "list", "watch"] + - 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: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotclasses"] + verbs: ["get", "list", "watch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotcontents"] + verbs: ["create", "get", "list", "watch", "update", "delete"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotcontents/status"] + verbs: ["update"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshots"] + verbs: ["get", "list", "watch", "update"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshots/status"] + verbs: ["update"] + - apiGroups: ["coordination.k8s.io"] + resources: ["leases"] + verbs: ["get", "watch", "list", "delete", "update", "create"] + - apiGroups: ["apiextensions.k8s.io"] + resources: ["customresourcedefinitions"] + verbs: ["create", "list", "watch", "delete", "get", "update"] +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: openebs-jiva-csi-provisioner-role + labels: + {{- include "jiva.csiController.labels" . | nindent 4 }} +rules: + - apiGroups: [""] + resources: ["secrets","namespaces"] + verbs: ["get", "list"] + - apiGroups: [ "" ] + resources: [ "pods" ] + verbs: [ "get", "list", "watch" ] + - apiGroups: [""] + resources: ["persistentvolumes", "services"] + verbs: ["get", "list", "watch", "create", "delete", "update", "patch"] + - apiGroups: [""] + resources: ["persistentvolumeclaims"] + verbs: ["get", "list", "watch", "update"] + - apiGroups: [""] + resources: ["persistentvolumeclaims/status"] + verbs: ["update", "patch"] + - apiGroups: ["storage.k8s.io"] + resources: ["storageclasses", "csinodes"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["events"] + verbs: ["list", "watch", "create", "update", "patch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshots"] + verbs: ["get", "list"] + - apiGroups: ["storage.k8s.io"] + resources: ["volumeattachments"] + verbs: ["get", "list", "watch", "create", "delete", "update", "patch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotcontents"] + verbs: ["get", "list"] + - apiGroups: ["coordination.k8s.io"] + resources: ["leases"] + verbs: ["*"] + - apiGroups: ["*"] + resources: ["jivavolumeattachments", "jivavolumes","jivavolumeconfigs"] + verbs: ["*"] +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: openebs-jiva-csi-provisioner-binding + labels: + {{- include "jiva.csiController.labels" . | nindent 4 }} +subjects: + - kind: ServiceAccount + name: {{ .Values.serviceAccount.csiController.name }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: openebs-jiva-csi-provisioner-role + apiGroup: rbac.authorization.k8s.io +--- +############################## CSI- Attacher ####################### +# Attacher must be able to work with PVs, nodes and VolumeAttachments +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: openebs-jiva-csi-attacher-role + labels: + {{- include "jiva.csiController.labels" . | nindent 4 }} +rules: + - apiGroups: [""] + resources: ["persistentvolumes"] + verbs: ["get", "list", "watch", "update"] + - apiGroups: [""] + resources: ["nodes"] + verbs: ["get", "list", "watch"] + - apiGroups: ["csi.storage.k8s.io"] + resources: ["csinodeinfos"] + verbs: ["get", "list", "watch"] + - apiGroups: ["storage.k8s.io"] + resources: ["volumeattachments", "csinodes"] + verbs: ["get", "list", "watch", "update"] + - apiGroups: [ "storage.k8s.io" ] + resources: [ "volumeattachments/status" ] + verbs: [ "patch" ] +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: openebs-jiva-csi-attacher-binding + labels: + {{- include "jiva.csiController.labels" . | nindent 4 }} +subjects: + - kind: ServiceAccount + name: {{ .Values.serviceAccount.csiController.name }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: openebs-jiva-csi-attacher-role + apiGroup: rbac.authorization.k8s.io +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: openebs-jiva-csi-cluster-registrar-role + labels: + {{- include "jiva.csiController.labels" . | nindent 4 }} +rules: + - apiGroups: ["csi.storage.k8s.io"] + resources: ["csidrivers"] + verbs: ["create", "delete"] +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: openebs-jiva-csi-cluster-registrar-binding + labels: + {{- include "jiva.csiController.labels" . | nindent 4 }} +subjects: + - kind: ServiceAccount + name: {{ .Values.serviceAccount.csiController.name }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: openebs-jiva-csi-cluster-registrar-role + apiGroup: rbac.authorization.k8s.io +{{- end }} diff --git a/helm/openebs/charts/jiva/templates/csi-controller.yaml b/helm/openebs/charts/jiva/templates/csi-controller.yaml new file mode 100644 index 0000000..062a0b6 --- /dev/null +++ b/helm/openebs/charts/jiva/templates/csi-controller.yaml @@ -0,0 +1,134 @@ +kind: StatefulSet +apiVersion: apps/v1 +metadata: + name: {{ template "jiva.fullname" . }}-csi-controller + {{- with .Values.csiController.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "jiva.csiController.labels" . | nindent 4 }} +spec: + selector: + matchLabels: + {{- include "jiva.csiController.matchLabels" . | nindent 6 }} + serviceName: "openebs-csi" + replicas: {{ .Values.csiController.replicas }} + template: + metadata: + labels: + {{- include "jiva.csiController.labels" . | nindent 8 }} + {{- if .Values.csiController.podLabels }} + {{ toYaml .Values.csiController.podLabels | nindent 8 }} + {{- end }} + spec: + priorityClassName: {{ template "jiva.csiController.priorityClassName" . }} + serviceAccountName: {{ .Values.serviceAccount.csiController.name }} + containers: + - name: {{ .Values.csiController.resizer.name }} + image: "{{ .Values.csiController.resizer.image.registry }}{{ .Values.csiController.resizer.image.repository }}:{{ .Values.csiController.resizer.image.tag }}" + resources: +{{ toYaml .Values.csiController.resources | indent 12 }} + args: + - "--v={{ .Values.csiController.resizer.logLevel | default .Values.csiController.logLevel }}" + - "--csi-address=$(ADDRESS)" + - "--leader-election" + env: + - name: ADDRESS + value: /var/lib/csi/sockets/pluginproxy/csi.sock + imagePullPolicy: {{ .Values.csiController.resizer.image.pullPolicy }} + volumeMounts: + - name: socket-dir + mountPath: /var/lib/csi/sockets/pluginproxy/ + - name: {{ .Values.csiController.provisioner.name }} + image: "{{ .Values.csiController.provisioner.image.registry }}{{ .Values.csiController.provisioner.image.repository }}:{{ .Values.csiController.provisioner.image.tag }}" + imagePullPolicy: {{ .Values.csiController.provisioner.image.pullPolicy }} + args: + - "--csi-address=$(ADDRESS)" + - "--v={{ .Values.csiController.provisioner.logLevel | default .Values.csiController.logLevel }}" + - "--feature-gates=Topology=true" + - "--extra-create-metadata=true" + - "--metrics-address=:22011" + - "--timeout=250s" + - "--default-fstype=ext4" + env: + - name: MY_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: ADDRESS + value: /var/lib/csi/sockets/pluginproxy/csi.sock + volumeMounts: + - name: socket-dir + mountPath: /var/lib/csi/sockets/pluginproxy/ + - name: {{ .Values.csiController.attacher.name }} + image: "{{ .Values.csiController.attacher.image.registry }}{{ .Values.csiController.attacher.image.repository }}:{{ .Values.csiController.attacher.image.tag }}" + imagePullPolicy: {{ .Values.csiController.attacher.image.pullPolicy }} + args: + - "--v={{ .Values.csiController.attacher.logLevel | default .Values.csiController.logLevel }}" + - "--csi-address=$(ADDRESS)" + env: + - name: ADDRESS + value: /var/lib/csi/sockets/pluginproxy/csi.sock + volumeMounts: + - name: socket-dir + mountPath: /var/lib/csi/sockets/pluginproxy/ + - name: {{ .Values.jivaCSIPlugin.name }} + image: "{{ .Values.jivaCSIPlugin.image.registry }}{{ .Values.jivaCSIPlugin.image.repository }}:{{ .Values.jivaCSIPlugin.image.tag }}" + imagePullPolicy: {{ .Values.jivaCSIPlugin.image.pullPolicy }} + env: + - name: OPENEBS_JIVA_CSI_CONTROLLER + value: controller + - name: OPENEBS_JIVA_CSI_ENDPOINT + value: unix:///var/lib/csi/sockets/pluginproxy/csi.sock + - name: OPENEBS_CSI_API_URL + value: https://openebs.io + - name: OPENEBS_NODEID + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: spec.nodeName + # OpenEBS namespace where the openebs jiva operator components + # has been installed + - name: OPENEBS_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: OPENEBS_IO_INSTALLER_TYPE + value: "jiva-helm" + - name: OPENEBS_IO_ENABLE_ANALYTICS + value: "{{ .Values.analytics.enabled }}" + args : + - "--endpoint=$(OPENEBS_JIVA_CSI_ENDPOINT)" + - "--plugin=$(OPENEBS_JIVA_CSI_CONTROLLER)" + - "--name=jiva.csi.openebs.io" + - "--nodeid=$(OPENEBS_NODEID)" + volumeMounts: + - name: socket-dir + mountPath: /var/lib/csi/sockets/pluginproxy/ + - name: {{ .Values.csiController.livenessprobe.name }} + image: "{{ .Values.csiController.livenessprobe.image.registry }}{{ .Values.csiController.livenessprobe.image.repository }}:{{ .Values.csiController.livenessprobe.image.tag }}" + imagePullPolicy: {{ .Values.csiController.livenessprobe.image.pullPolicy }} + args: + - "--csi-address=/csi/csi.sock" + volumeMounts: + - mountPath: /csi + name: socket-dir + volumes: + - name: socket-dir + emptyDir: {} +{{- if .Values.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | nindent 8 }} +{{- end }} +{{- if .Values.csiController.nodeSelector }} + nodeSelector: +{{ toYaml .Values.csiController.nodeSelector | indent 8 }} +{{- end }} +{{- if .Values.csiController.securityContext }} + securityContext: +{{ toYaml .Values.csiController.securityContext | indent 8 }} +{{- end }} +{{- if .Values.csiController.tolerations }} + tolerations: +{{ toYaml .Values.csiController.tolerations | indent 8 }} +{{- end }} diff --git a/helm/openebs/charts/jiva/templates/csi-driver.yaml b/helm/openebs/charts/jiva/templates/csi-driver.yaml new file mode 100644 index 0000000..04bd6e3 --- /dev/null +++ b/helm/openebs/charts/jiva/templates/csi-driver.yaml @@ -0,0 +1,9 @@ +{{- if .Values.csiDriver.create -}} +apiVersion: storage.k8s.io/v1 +kind: CSIDriver +metadata: + name: jiva.csi.openebs.io +spec: + podInfoOnMount: {{ .Values.csiDriver.podInfoOnMount }} + attachRequired: {{ .Values.csiDriver.attachRequired }} +{{- end }} diff --git a/helm/openebs/charts/jiva/templates/csi-iscsiadm-config.yaml b/helm/openebs/charts/jiva/templates/csi-iscsiadm-config.yaml new file mode 100644 index 0000000..f25f155 --- /dev/null +++ b/helm/openebs/charts/jiva/templates/csi-iscsiadm-config.yaml @@ -0,0 +1,18 @@ +kind: ConfigMap +apiVersion: v1 +metadata: + name: openebs-jiva-csi-iscsiadm +data: + iscsiadm: | + #!/bin/sh + if [ -x /host/sbin/iscsiadm ]; then + chroot /host /sbin/iscsiadm "$@" + elif [ -x /host/usr/local/sbin/iscsiadm ]; then + chroot /host /usr/local/sbin/iscsiadm "$@" + elif [ -x /host/bin/iscsiadm ]; then + chroot /host /bin/iscsiadm "$@" + elif [ -x /host/usr/local/bin/iscsiadm ]; then + chroot /host /usr/local/bin/iscsiadm "$@" + else + chroot /host iscsiadm "$@" + fi diff --git a/helm/openebs/charts/jiva/templates/csi-node-rbac.yaml b/helm/openebs/charts/jiva/templates/csi-node-rbac.yaml new file mode 100644 index 0000000..68e33fe --- /dev/null +++ b/helm/openebs/charts/jiva/templates/csi-node-rbac.yaml @@ -0,0 +1,43 @@ +{{- if .Values.serviceAccount.csiNode.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .Values.serviceAccount.csiNode.name }} + labels: + {{- include "jiva.csiNode.labels" . | nindent 4 }} + namespace: {{ .Release.Namespace }} +{{- end }} +{{- if .Values.rbac.create }} +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: openebs-jiva-csi-registrar-role + labels: + {{- include "jiva.csiNode.labels" . | nindent 4 }} +rules: + - apiGroups: [""] + resources: ["events"] + verbs: ["get", "list", "watch", "create", "update", "patch"] + - apiGroups: [""] + resources: ["persistentvolumes", "nodes", "services"] + verbs: ["get", "list", "patch"] + - apiGroups: ["*"] + resources: ["jivavolumes"] + verbs: ["get", "list", "watch", "create", "update", "delete", "patch"] +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: openebs-jiva-csi-registrar-binding + labels: + {{- include "jiva.csiNode.labels" . | nindent 4 }} +subjects: + - kind: ServiceAccount + name: {{ .Values.serviceAccount.csiNode.name }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: openebs-jiva-csi-registrar-role + apiGroup: rbac.authorization.k8s.io +{{- end }} diff --git a/helm/openebs/charts/jiva/templates/csi-node.yaml b/helm/openebs/charts/jiva/templates/csi-node.yaml new file mode 100644 index 0000000..23c73e7 --- /dev/null +++ b/helm/openebs/charts/jiva/templates/csi-node.yaml @@ -0,0 +1,165 @@ +kind: DaemonSet +apiVersion: apps/v1 +metadata: + name: {{ template "jiva.fullname" . }}-csi-node + {{- with .Values.csiNode.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "jiva.csiNode.labels" . | nindent 4 }} +spec: + selector: + matchLabels: + {{- include "jiva.csiNode.matchLabels" . | nindent 6 }} + template: + metadata: + labels: + {{- include "jiva.csiNode.labels" . | nindent 8 }} + {{- if .Values.csiNode.podLabels }} + {{ toYaml .Values.csiNode.podLabels | nindent 8 }} + {{- end }} + spec: + priorityClassName: {{ template "jiva.csiNode.priorityClassName" . }} + serviceAccountName: {{ .Values.serviceAccount.csiNode.name }} + hostNetwork: true + containers: + - name: {{ .Values.csiNode.driverRegistrar.name }} + image: "{{ .Values.csiNode.driverRegistrar.image.registry }}{{ .Values.csiNode.driverRegistrar.image.repository }}:{{ .Values.csiNode.driverRegistrar.image.tag }}" + imagePullPolicy: {{ .Values.csiNode.driverRegistrar.image.pullPolicy }} + resources: +{{ toYaml .Values.csiNode.resources | indent 12 }} + args: + - "--v={{ .Values.csiNode.driverRegistrar.logLevel | default .Values.csiNode.logLevel }}" + - "--csi-address=$(ADDRESS)" + - "--kubelet-registration-path=$(DRIVER_REG_SOCK_PATH)" + lifecycle: + preStop: + exec: + command: ["/bin/sh", "-c", "rm -rf /registration/jiva.csi.openebs.io /registration/jiva.csi.openebs.io-reg.sock"] + env: + - name: ADDRESS + value: /plugin/csi.sock + - name: DRIVER_REG_SOCK_PATH + value: {{ .Values.csiNode.kubeletDir }}plugins/jiva.csi.openebs.io/csi.sock + - name: KUBE_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: NODE_DRIVER + value: openebs-jiva-csi + volumeMounts: + - name: plugin-dir + mountPath: /plugin + - name: registration-dir + mountPath: /registration + - name: {{ .Values.jivaCSIPlugin.name }} + securityContext: + privileged: true + allowPrivilegeEscalation: true + image: "{{ .Values.jivaCSIPlugin.image.registry }}{{ .Values.jivaCSIPlugin.image.repository }}:{{ .Values.jivaCSIPlugin.image.tag }}" + imagePullPolicy: {{ .Values.jivaCSIPlugin.image.pullPolicy }} + args: + - "--name=jiva.csi.openebs.io" + - "--nodeid=$(OPENEBS_NODE_ID)" + - "--endpoint=$(OPENEBS_CSI_ENDPOINT)" + - "--plugin=$(OPENEBS_NODE_DRIVER)" + # enableiscsidebug is used to enable debug logs for iscsi operations + - "--enableiscsidebug=true" + # logging level for klog library used in k8s packages + #- "--v=5" + # retrycount is the max number of retries per nodeStaging rpc + # request on a timeout of 5 sec + # This count has been set to 20 for sanity test cases as it takes + # time in minikube + - "--retrycount=20" + # metricsBindAddress is the TCP address that the controller should bind to + # for serving prometheus metrics. By default the address is set to localhost:9505. + # The address can be configured to any desired address. + # Remove the flag to disable prometheus metrics. + - "--metricsBindAddress=:9505" + env: + - name: OPENEBS_NODE_ID + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: OPENEBS_CSI_ENDPOINT + value: unix:///plugin/csi.sock + - name: OPENEBS_NODE_DRIVER + value: node + - name: OPENEBS_CSI_API_URL + value: https://openebs.io + # OpenEBS namespace where the openebs jiva operator components + # has been installed + - name: OPENEBS_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + # Enable/Disable auto-remount feature, when volumes + # recovers form the read-only state + - name: REMOUNT + value: "{{ .Values.jivaCSIPlugin.remount }}" + volumeMounts: + - name: plugin-dir + mountPath: /plugin + - name: device-dir + mountPath: /dev + - name: pods-mount-dir + mountPath: {{ .Values.csiNode.kubeletDir }} + # needed so that any mounts setup inside this container are + # propagated back to the host machine. + mountPropagation: "Bidirectional" + - name: host-root + mountPath: /host + mountPropagation: "HostToContainer" + - name: chroot-iscsiadm + mountPath: /sbin/iscsiadm + subPath: iscsiadm + - name: {{ .Values.csiNode.livenessprobe.name }} + image: "{{ .Values.csiNode.livenessprobe.image.registry }}{{ .Values.csiNode.livenessprobe.image.repository }}:{{ .Values.csiNode.livenessprobe.image.tag }}" + imagePullPolicy: {{ .Values.csiNode.livenessprobe.image.pullPolicy }} + args: + - "--csi-address=/plugin/csi.sock" + volumeMounts: + - mountPath: /plugin + name: plugin-dir + volumes: + - name: device-dir + hostPath: + path: /dev + type: Directory + - name: registration-dir + hostPath: + path: {{ .Values.csiNode.kubeletDir }}plugins_registry/ + type: DirectoryOrCreate + - name: plugin-dir + hostPath: + path: {{ .Values.csiNode.kubeletDir }}plugins/jiva.csi.openebs.io/ + type: DirectoryOrCreate + - name: pods-mount-dir + hostPath: + path: {{ .Values.csiNode.kubeletDir }} + type: Directory + - name: chroot-iscsiadm + configMap: + defaultMode: 0555 + name: openebs-jiva-csi-iscsiadm + - name: host-root + hostPath: + path: / + type: Directory +{{- if .Values.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | nindent 8 }} +{{- end }} +{{- if .Values.csiNode.nodeSelector }} + nodeSelector: +{{ toYaml .Values.csiNode.nodeSelector | indent 8 }} +{{- end }} +{{- if .Values.csiNode.securityContext }} + securityContext: +{{ toYaml .Values.csiNode.securityContext | indent 8 }} +{{- end }} +{{- if .Values.csiNode.tolerations }} + tolerations: +{{ toYaml .Values.csiNode.tolerations | indent 8 }} +{{- end }} diff --git a/helm/openebs/charts/jiva/templates/default-policy.yaml b/helm/openebs/charts/jiva/templates/default-policy.yaml new file mode 100644 index 0000000..ae6d4de --- /dev/null +++ b/helm/openebs/charts/jiva/templates/default-policy.yaml @@ -0,0 +1,10 @@ +{{- if .Values.defaultPolicy.enabled }} +apiVersion: openebs.io/v1alpha1 +kind: JivaVolumePolicy +metadata: + name: {{ .Values.defaultPolicy.name }} +spec: + replicaSC: {{ .Values.defaultPolicy.replicaSC }} + target: + replicationFactor: {{ .Values.defaultPolicy.replicas }} +{{- end }} diff --git a/helm/openebs/charts/jiva/templates/default-storageclass.yaml b/helm/openebs/charts/jiva/templates/default-storageclass.yaml new file mode 100644 index 0000000..d80fabd --- /dev/null +++ b/helm/openebs/charts/jiva/templates/default-storageclass.yaml @@ -0,0 +1,17 @@ +{{- if .Values.storageClass.enabled }} +apiVersion: storage.k8s.io/v1 +kind: StorageClass +metadata: + name: {{ .Values.storageClass.name }} + annotations: +{{- if .Values.storageClass.isDefaultClass }} + storageclass.kubernetes.io/is-default-class: "true" +{{- end }} +provisioner: jiva.csi.openebs.io +volumeBindingMode: Immediate +allowVolumeExpansion: {{ .Values.storageClass.allowVolumeExpansion }} +reclaimPolicy: {{ .Values.storageClass.reclaimPolicy }} +parameters: + cas-type: "jiva" + policy: {{ .Values.defaultPolicy.name }} +{{- end }} diff --git a/helm/openebs/charts/jiva/templates/jiva-operator-rbac.yaml b/helm/openebs/charts/jiva/templates/jiva-operator-rbac.yaml new file mode 100644 index 0000000..4c5b5e8 --- /dev/null +++ b/helm/openebs/charts/jiva/templates/jiva-operator-rbac.yaml @@ -0,0 +1,103 @@ +{{- if .Values.serviceAccount.jivaOperator.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .Values.serviceAccount.jivaOperator.name }} + labels: + {{- include "jiva.common.metaLabels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} +{{- if .Values.rbac.create }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: jiva-operator +rules: +- apiGroups: + - "" + resources: + - pods + - services + - services/finalizers + - endpoints + - persistentvolumes + - persistentvolumeclaims + - events + - configmaps + - secrets + verbs: + - '*' +- apiGroups: + - apps + resources: + - deployments + - daemonsets + - replicasets + - statefulsets + verbs: + - '*' +- apiGroups: + - monitoring.coreos.com + resources: + - servicemonitors + verbs: + - get + - create +- apiGroups: + - apps + resourceNames: + - jiva-operator + resources: + - deployments/finalizers + verbs: + - update +- apiGroups: + - "" + resources: + - nodes + verbs: + - get + - list + - watch +- apiGroups: + - apps + resources: + - replicasets + verbs: + - get +- apiGroups: + - policy + resources: + - poddisruptionbudgets + verbs: + - '*' +- apiGroups: + - openebs.io + resources: + - '*' + verbs: + - '*' +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: openebs-jiva-operator + {{- with .Values.serviceAccount.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "jiva.common.metaLabels" . | nindent 4 }} +subjects: +- kind: ServiceAccount + name: {{ .Values.serviceAccount.jivaOperator.name }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: jiva-operator + apiGroup: rbac.authorization.k8s.io +{{- end }} + diff --git a/helm/openebs/charts/jiva/templates/jiva-operator.yaml b/helm/openebs/charts/jiva/templates/jiva-operator.yaml new file mode 100644 index 0000000..ba7a815 --- /dev/null +++ b/helm/openebs/charts/jiva/templates/jiva-operator.yaml @@ -0,0 +1,74 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "jiva.fullname" . }}-operator + {{- with .Values.jivaOperator.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "jiva.operator.labels" . | nindent 4 }} +spec: + selector: + matchLabels: + {{- include "jiva.operator.matchLabels" . | nindent 6 }} + replicas: {{ .Values.jivaOperator.replicas }} + strategy: + type: Recreate + template: + metadata: + labels: + {{- include "jiva.operator.labels" . | nindent 8 }} + {{- if .Values.jivaOperator.podLabels }} + {{ toYaml .Values.jivaOperator.podLabels | nindent 8 }} + {{- end }} + spec: + serviceAccountName: {{ .Values.serviceAccount.jivaOperator.name }} + containers: + - name: {{ template "jiva.fullname" . }}-operator + imagePullPolicy: {{ .Values.jivaOperator.image.pullPolicy }} + image: "{{ .Values.jivaOperator.image.registry }}{{ .Values.jivaOperator.image.repository }}:{{ .Values.jivaOperator.image.tag }}" + command: + - jiva-operator + resources: +{{ toYaml .Values.jivaOperator.resources | indent 12 }} + env: + - name: OPENEBS_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: OPERATOR_NAME + value: "jiva-operator" + - name: OPENEBS_SERVICEACCOUNT_NAME + valueFrom: + fieldRef: + fieldPath: spec.serviceAccountName + - name: OPENEBS_IO_JIVA_CONTROLLER_IMAGE + value: "{{ .Values.jivaOperator.controller.image.registry }}{{ .Values.jivaOperator.controller.image.repository }}:{{ .Values.jivaOperator.controller.image.tag }}" + - name: OPENEBS_IO_JIVA_REPLICA_IMAGE + value: "{{ .Values.jivaOperator.replica.image.registry }}{{ .Values.jivaOperator.replica.image.repository }}:{{ .Values.jivaOperator.replica.image.tag }}" + - name: OPENEBS_IO_MAYA_EXPORTER_IMAGE + value: "{{ .Values.jivaOperator.exporter.image.registry }}{{ .Values.jivaOperator.exporter.image.repository }}:{{ .Values.jivaOperator.exporter.image.tag }}" +{{- if .Values.imagePullSecrets }} + - name: OPENEBS_IO_IMAGE_PULL_SECRETS + value: "{{- range $.Values.imagePullSecrets }}{{ .name }},{{- end }}" +{{- end }} +{{- if .Values.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | nindent 8 }} +{{- end }} +{{- if .Values.jivaOperator.nodeSelector }} + nodeSelector: +{{ toYaml .Values.jivaOperator.nodeSelector | indent 8 }} +{{- end }} +{{- if .Values.jivaOperator.securityContext }} + securityContext: +{{ toYaml .Values.jivaOperator.securityContext | indent 8 }} +{{- end }} +{{- if .Values.jivaOperator.tolerations }} + tolerations: +{{ toYaml .Values.jivaOperator.tolerations | indent 8 }} +{{- end }} diff --git a/helm/openebs/charts/jiva/templates/priority-class.yaml b/helm/openebs/charts/jiva/templates/priority-class.yaml new file mode 100644 index 0000000..0b0d325 --- /dev/null +++ b/helm/openebs/charts/jiva/templates/priority-class.yaml @@ -0,0 +1,19 @@ +{{- if .Values.csiController.priorityClass.create }} +apiVersion: scheduling.k8s.io/v1 +kind: PriorityClass +metadata: + name: {{ template "jiva.csiController.priorityClassName" . }} +value: {{ .Values.csiController.priorityClass.value }} +globalDefault: false +description: "This priority class should be used for the OpenEBS CSI driver controller deployment only." +{{- end }} +--- +{{- if .Values.csiNode.priorityClass.create }} +apiVersion: scheduling.k8s.io/v1 +kind: PriorityClass +metadata: + name: {{ template "jiva.csiNode.priorityClassName" . }} +value: {{ .Values.csiNode.priorityClass.value }} +globalDefault: false +description: "This priority class should be used for the OpenEBS CSI driver node deployment only." +{{- end }} diff --git a/helm/openebs/charts/jiva/templates/psp.yaml b/helm/openebs/charts/jiva/templates/psp.yaml new file mode 100644 index 0000000..a8bfc3e --- /dev/null +++ b/helm/openebs/charts/jiva/templates/psp.yaml @@ -0,0 +1,27 @@ +{{- if .Values.rbac.pspEnabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "jiva.fullname" . }}-psp + {{- with .Values.csiNode.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "jiva.csiNode.labels" . | nindent 4 }} +spec: + privileged: true + allowPrivilegeEscalation: true + allowedCapabilities: ['*'] + volumes: ['*'] + hostNetwork: true + hostIPC: true + hostPID: true + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'RunAsAny' + fsGroup: + rule: 'RunAsAny' +{{- end }} diff --git a/helm/openebs/charts/jiva/values.yaml b/helm/openebs/charts/jiva/values.yaml new file mode 100644 index 0000000..fe9c175 --- /dev/null +++ b/helm/openebs/charts/jiva/values.yaml @@ -0,0 +1,225 @@ +# Default values for jiva-operator. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +release: + version: "3.4.0" + + +# If false, openebs localpv sub-chart will not be installed +openebsLocalpv: + enabled: true + +rbac: + # rbac.create: `true` if rbac resources should be created + create: true + # rbac.pspEnabled: `true` if PodSecurityPolicy resources should be created + pspEnabled: false + +imagePullSecrets: +# - name: "image-pull-secret" + +jivaOperator: + componentName: "jiva-operator" + controller: + image: + registry: + repository: openebs/jiva + tag: 3.4.0 + replica: + image: + registry: + repository: openebs/jiva + tag: 3.4.0 + exporter: + image: + registry: + repository: openebs/m-exporter + tag: 3.4.0 + image: + # Make sure that registry name end with a '/'. + # For example : quay.io/ is a correct value here and quay.io is incorrect + registry: + repository: openebs/jiva-operator + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: 3.4.0 + annotations: {} + resyncInterval: "30" + podAnnotations: {} + podLabels: {} + nodeSelector: {} + tolerations: [] + resources: {} + securityContext: {} + + +csiController: + priorityClass: + create: true + name: jiva-csi-controller-critical + value: 900000000 + componentName: "openebs-jiva-csi-controller" + logLevel: "5" + attacher: + name: "csi-attacher" + image: + # Make sure that registry name end with a '/'. + # For example : quay.io/ is a correct value here and quay.io is incorrect + registry: registry.k8s.io/ + repository: sig-storage/csi-attacher + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: v4.3.0 + livenessprobe: + name: "liveness-probe" + image: + # Make sure that registry name end with a '/'. + # For example : quay.io/ is a correct value here and quay.io is incorrect + registry: registry.k8s.io/ + repository: sig-storage/livenessprobe + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: v2.10.0 + provisioner: + name: "csi-provisioner" + image: + # Make sure that registry name end with a '/'. + # For example : quay.io/ is a correct value here and quay.io is incorrect + registry: registry.k8s.io/ + repository: sig-storage/csi-provisioner + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: v3.5.0 + resizer: + name: "csi-resizer" + image: + # Make sure that registry name end with a '/'. + # For example : quay.io/ is a correct value here and quay.io is incorrect + registry: registry.k8s.io/ + repository: sig-storage/csi-resizer + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: v1.8.0 + annotations: {} + podAnnotations: {} + podLabels: {} + nodeSelector: {} + tolerations: [] + resources: {} + securityContext: {} + +jivaCSIPlugin: + name: jiva-csi-plugin + image: + # Make sure that registry name end with a '/'. + # For example : quay.io/ is a correct value here and quay.io is incorrect + registry: + repository: openebs/jiva-csi + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: 3.4.0 + remount: "true" + +csiNode: + priorityClass: + create: true + name: jiva-csi-node-critical + value: 900001000 + componentName: "openebs-jiva-csi-node" + logLevel: "5" + driverRegistrar: + name: "csi-node-driver-registrar" + image: + registry: registry.k8s.io/ + repository: sig-storage/csi-node-driver-registrar + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: v2.8.0 + livenessprobe: + name: "liveness-probe" + image: + # Make sure that registry name end with a '/'. + # For example : quay.io/ is a correct value here and quay.io is incorrect + registry: registry.k8s.io/ + repository: sig-storage/livenessprobe + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: v2.10.0 + updateStrategy: + type: RollingUpdate + annotations: {} + podAnnotations: {} + resources: {} + # limits: + # cpu: 10m + # memory: 32Mi + # requests: + # cpu: 10m + # memory: 32Mi + ## Labels to be added to openebs-jiva-csi-node pods + podLabels: {} + # kubeletDir path can be configured to run on various different k8s distributions like + # microk8s where kubelet root dir is not (/var/lib/kubelet/). For example microk8s, + # we need to change the kubelet directory to `/var/snap/microk8s/common/var/lib/kubelet/` + kubeletDir: "/var/lib/kubelet/" + nodeSelector: {} + tolerations: [] + securityContext: {} + +csiDriver: + create: true + podInfoOnMount: true + attachRequired: false + +serviceAccount: + # Annotations to add to the service account + annotations: {} + jivaOperator: + create: true + name: openebs-jiva-operator + csiController: + # Specifies whether a service account should be created + create: true + name: openebs-jiva-csi-controller-sa + csiNode: + # Specifies whether a service account should be created + create: true + name: openebs-jiva-csi-node-sa + +storageClass: + # Name of the default StorageClass + name: openebs-jiva-csi-default + # If true, enables creation of the openebs-jiva-csi-default StorageClass + enabled: true + # Available reclaim policies: Delete/Retain, defaults: Delete. + reclaimPolicy: Delete + # If true, sets the openebs-jiva-csi-default StorageClass as the + # default kubernetes StorageClass for the cluster + isDefaultClass: false + # If true, allows resize of the volumes + allowVolumeExpansion: true + +defaultPolicy: + # Name of the default default JivaVolumePolicy + name: openebs-jiva-default-policy + # If true, enables creation of the openebs-jiva-default-policy JivaVolumePolicy + enabled: true + # replicaSC represents the storage class used for creating + # the pvc for the replica sts provisioned by localpv provisioner + replicaSC: openebs-hostpath + # replicas represent the desired replication factor for the jiva volume + replicas: 3 + +analytics: + enabled: true + # Specify in hours the duration after which a ping event needs to be sent. + pingInterval: "24h" + +localpv-provisioner: + # Disable installation of node-disk-manager components by default + openebsNDM: + enabled: false + # Disable openebs-device deviceClass by default. + deviceClass: + enabled: false diff --git a/helm/openebs/charts/localpv-provisioner/.helmignore b/helm/openebs/charts/localpv-provisioner/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/helm/openebs/charts/localpv-provisioner/.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/helm/openebs/charts/localpv-provisioner/Chart.lock b/helm/openebs/charts/localpv-provisioner/Chart.lock new file mode 100644 index 0000000..4ff3a5c --- /dev/null +++ b/helm/openebs/charts/localpv-provisioner/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: openebs-ndm + repository: https://openebs.github.io/node-disk-manager + version: 2.1.0 +digest: sha256:47adcc8a92ea7ce83ca7f37f05f9e2f4c10154adc9551bd92e92c1ca5608f131 +generated: "2023-08-16T16:46:46.773916076Z" diff --git a/helm/openebs/charts/localpv-provisioner/Chart.yaml b/helm/openebs/charts/localpv-provisioner/Chart.yaml new file mode 100644 index 0000000..4d1e73d --- /dev/null +++ b/helm/openebs/charts/localpv-provisioner/Chart.yaml @@ -0,0 +1,27 @@ +apiVersion: v2 +appVersion: 3.4.0 +dependencies: +- condition: openebsNDM.enabled + name: openebs-ndm + repository: https://openebs.github.io/node-disk-manager + version: 2.1.0 +description: Helm chart for OpenEBS Dynamic Local PV. For instructions to install + OpenEBS Dynamic Local PV using helm chart, refer to https://openebs.github.io/dynamic-localpv-provisioner/. +home: http://www.openebs.io/ +icon: https://raw.githubusercontent.com/cncf/artwork/master/projects/openebs/icon/color/openebs-icon-color.png +keywords: +- storage +- local +- dynamic-localpv +maintainers: +- email: akhil.mohan@mayadata.io + name: akhilerm +- email: kiran.mova@mayadata.io + name: kiranmova +- email: prateek.pandey@mayadata.io + name: prateekpandey14 +name: localpv-provisioner +sources: +- https://github.com/openebs/dynamic-localpv-provisioner +type: application +version: 3.4.1 diff --git a/helm/openebs/charts/localpv-provisioner/README.md b/helm/openebs/charts/localpv-provisioner/README.md new file mode 100644 index 0000000..fe321ca --- /dev/null +++ b/helm/openebs/charts/localpv-provisioner/README.md @@ -0,0 +1,160 @@ +# OpenEBS LocalPV Provisioner + +[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) +![Chart Lint and Test](https://github.com/openebs/dynamic-localpv-provisioner/workflows/Chart%20Lint%20and%20Test/badge.svg) +![Release Charts](https://github.com/openebs/dynamic-localpv-provisioner/workflows/Release%20Charts/badge.svg?branch=develop) + +A Helm chart for openebs dynamic localpv provisioner. This chart bootstraps OpenEBS Dynamic LocalPV provisioner deployment on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. + + +**Homepage:** + +## Maintainers + +| Name | Email | Url | +| ---- | ------ | --- | +| akhilerm | akhil.mohan@mayadata.io | | +| kiranmova | kiran.mova@mayadata.io | | +| prateekpandey14 | prateek.pandey@mayadata.io | | + + +## Get Repo Info + +```console +helm repo add openebs-localpv https://openebs.github.io/dynamic-localpv-provisioner +helm repo update +``` + +_See [helm repo](https://helm.sh/docs/helm/helm_repo/) for command documentation._ + +## Install Chart + +Please visit the [link](https://openebs.github.io/dynamic-localpv-provisioner/) for install instructions via helm3. + +```console +# Helm +helm install [RELEASE_NAME] openebs-localpv/localpv-provisioner --namespace [NAMESPACE] --create-namespace +``` + +_See [configuration](#configuration) below._ + +_See [helm install](https://helm.sh/docs/helm/helm_install/) for command documentation._ + +## Dependencies + +By default this chart installs additional, dependent charts: + +| Repository | Name | Version | +|------------|------|---------| +| https://openebs.github.io/node-disk-manager | openebs-ndm | 2.1.0 | + +**Note:** Find detailed Node Disk Manager Helm chart configuration options [here](https://github.com/openebs/node-disk-manager/blob/master/deploy/helm/charts/README.md). + + +To disable the dependency during installation, set `openebsNDM.enabled` to `false`. + +_See [helm dependency](https://helm.sh/docs/helm/helm_dependency/) for command documentation._ + +## Uninstall Chart + +```console +# Helm +helm uninstall [RELEASE_NAME] --namespace [NAMESPACE] +``` + +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._ + +## Upgrading Chart + +```console +# Helm +helm upgrade [RELEASE_NAME] [CHART] --install --namespace [NAMESPACE] +``` + + +## Configuration + +The following table lists the configurable parameters of the OpenEBS Dynamic LocalPV Provisioner chart and their default values. + +You can modify different parameters by specifying the desired value in the `helm install` command by using the `--set` and/or the `--set-string` flag(s). You can modify the parameters of the [Node Disk Manager chart](https://openebs.github.io/node-disk-manager) by adding `openebs-ndm` before the desired parameter in the `helm install` command. + +In the following sample command we modify `deviceClass.fsType` from the localpv-provisioner chart and `ndm.nodeSelector` from the openebs-ndm chart to only schedule openebs-ndm DaemonSet pods on nodes labelled with `openebs.io/data-plane=true`. We also enable the 'Use OS-disk' feature gate using the `featureGates.UseOSDisk.enabled` parameter from the openebs-ndm chart. + + +```console +helm install openebs-localpv openebs-localpv/localpv-provisioner --namespace openebs --create-namespace \ + --set-string deviceClass.fsType="xfs" \ + --set-string openebs-ndm.ndm.nodeSelector."openebs\.io/data-plane"=true \ + --set openebs-ndm.featureGates.UseOSDisk.enabled=true +``` + +Sample command to install the provisioner with nodeAffinityLabels "openebs.io/node-affinity-key-1" and "openebs.io/node-affinity-key-2" on the hostpath StorageClass: +```console +helm install openebs-localpv openebs-localpv/localpv-provisioner --namespace openebs --create-namespace \ + --set-string hostpathClass.nodeAffinityLabels="{openebs.io/node-affinity-key-1,openebs.io/node-affinity-key-2}" +``` + +Sample command to install the provisioner with blockDeviceSelectors "openebs.io/block-device-tag=mongo" and "ndm.io/fsType=ext4": +```console +helm install openebs-localpv openebs-localpv/localpv-provisioner --namespace openebs --create-namespace \ + --set-string deviceClass.blockDeviceSelectors."openebs\.io/block-device-tag"="mongo" \ + --set-string deviceClass.blockDeviceSelectors."ndm\.io/fsType"="ext4" +``` + +| Parameter | Description | Default | +| ------------------------------------------- | --------------------------------------------- | ----------------------------------------- | +| `release.version` | LocalPV Provisioner release version | `3.4.0` | +| `analytics.enabled` | Enable sending stats to Google Analytics | `true` | +| `analytics.pingInterval` | Duration(hours) between sending ping stat | `24h` | +| `deviceClass.blockDeviceSelectors` | Label key value pairs based on which BlockDevices on the node will be selected for provisioning | `{}` | +| `deviceClass.enabled` | Enables creation of default Device StorageClass | `true` | +| `deviceClass.fsType` | Filesystem type for openebs-device StorageClass | `"ext4"` | +| `deviceClass.isDefaultClass` | Make openebs-device the default StorageClass | `"false"` | +| `deviceClass.nodeAffinityLabels` | Custom node label(or labels) key to uniquely identify nodes. `kubernetes.io/hostname` is the default label key for node selection. | `[]` | +| `deviceClass.reclaimPolicy` | ReclaimPolicy for Device PVs | `"Delete"` | +| `helperPod.image.registry` | Registry for helper image | `""` | +| `helperPod.image.repository` | Image for helper pod | `"openebs/linux-utils"` | +| `helperPod.image.pullPolicy` | Pull policy for helper pod | `"IfNotPresent"` | +| `helperPod.image.tag` | Image tag for helper image | `3.4.0` | +| `hostpathClass.basePath` | BasePath for openebs-hostpath StorageClass | `"/var/openebs/local"` | +| `hostpathClass.enabled` | Enables creation of default Hostpath StorageClass | `true` | +| `hostpathClass.isDefaultClass` | Make openebs-hostpath the default StorageClass | `"false"` | +| `hostpathClass.nodeAffinityLabels` | Custom node label(or labels) key to uniquely identify nodes. `kubernetes.io/hostname` is the default label key for node selection. | `[]` | +| `hostpathClass.xfsQuota.enabled` | Enable XFS Quota (requires XFS filesystem) | `false` | +| `hostpathClass.ext4Quota.enabled` | Enable EXT4 Quota (requires EXT4 filesystem) | `false` | +| `hostpathClass.reclaimPolicy` | ReclaimPolicy for Hostpath PVs | `"Delete"` | +| `imagePullSecrets` | Provides image pull secrect | `""` | +| `localpv.enabled` | Enable LocalPV Provisioner | `true` | +| `localpv.image.registry` | Registry for LocalPV Provisioner image | `""` | +| `localpv.image.repository` | Image repository for LocalPV Provisioner | `openebs/localpv-provisioner` | +| `localpv.image.pullPolicy` | Image pull policy for LocalPV Provisioner | `IfNotPresent` | +| `localpv.image.tag` | Image tag for LocalPV Provisioner | `3.4.0` | +| `localpv.updateStrategy.type` | Update strategy for LocalPV Provisioner | `RollingUpdate` | +| `localpv.annotations` | Annotations for LocalPV Provisioner metadata | `""` | +| `localpv.podAnnotations` | Annotations for LocalPV Provisioner pods metadata | `""` | +| `localpv.privileged` | Run LocalPV Provisioner with extra privileges | `true` | +| `localpv.resources` | Resource and request and limit for containers | `""` | +| `localpv.podLabels` | Appends labels to the pods | `""` | +| `localpv.nodeSelector` | Nodeselector for LocalPV Provisioner pods | `""` | +| `localpv.tolerations` | LocalPV Provisioner pod toleration values | `""` | +| `localpv.securityContext` | Seurity context for container | `""` | +| `localpv.healthCheck.initialDelaySeconds` | Delay before liveness probe is initiated | `30` | +| `localpv.healthCheck.periodSeconds` | How often to perform the liveness probe | `60` | +| `localpv.replicas` | No. of LocalPV Provisioner replica | `1` | +| `localpv.enableLeaderElection` | Enable leader election | `true` | +| `localpv.affinity` | LocalPV Provisioner pod affinity | `{}` | +| `localpv.waitForBDBindTimeoutRetryCount` | This sets the number of times the provisioner should try with a polling interval of 5 seconds, to get the Blockdevice Name from a BlockDeviceClaim, before the BlockDeviceClaim is deleted. | "12" | +| `openebsNDM.enabled` | Install openebs NDM dependency | `true` | +| `rbac.create` | Enable RBAC Resources | `true` | +| `rbac.pspEnabled` | Create pod security policy resources | `false` | + + +A YAML file that specifies the values for the parameters can be provided while installing the chart. For example, + +```bash +helm install -f values.yaml --namespace openebs openebs-localpv/localpv-provisioner +``` + +> **Tip**: You can use the default [values.yaml](values.yaml) diff --git a/helm/openebs/charts/localpv-provisioner/charts/openebs-ndm/Chart.yaml b/helm/openebs/charts/localpv-provisioner/charts/openebs-ndm/Chart.yaml new file mode 100644 index 0000000..53484cd --- /dev/null +++ b/helm/openebs/charts/localpv-provisioner/charts/openebs-ndm/Chart.yaml @@ -0,0 +1,23 @@ +apiVersion: v2 +appVersion: 2.1.0 +description: Helm chart for OpenEBS Node Disk Manager - a Kubernetes native storage + device management solution. For instructions on how to install, refer to https://openebs.github.io/node-disk-manager/. +home: http://www.openebs.io/ +icon: https://raw.githubusercontent.com/cncf/artwork/master/projects/openebs/icon/color/openebs-icon-color.png +keywords: +- cloud-native-storage +- block-storage +- ndm +- disk-inventory +- storage +maintainers: +- email: akhil.mohan@mayadata.io + name: akhilerm +- email: michaelfornaro@gmail.com + name: xUnholy +- email: prateek.pandey@mayadata.io + name: prateekpandey14 +name: openebs-ndm +sources: +- https://github.com/openebs/node-disk-manager +version: 2.1.0 diff --git a/helm/openebs/charts/localpv-provisioner/charts/openebs-ndm/README.md b/helm/openebs/charts/localpv-provisioner/charts/openebs-ndm/README.md new file mode 100644 index 0000000..399a687 --- /dev/null +++ b/helm/openebs/charts/localpv-provisioner/charts/openebs-ndm/README.md @@ -0,0 +1,93 @@ +## Introduction + +This chart bootstraps OpenEBS NDM deployment on a [Kubernetes](http://kubernetes.io) cluster using the +[Helm](https://helm.sh) package manager. + +## Installation + +You can run OpenEBS NDM on any Kubernetes 1.17+ cluster in a matter of seconds. + +Please visit the [link](https://openebs.github.io/node-disk-manager/) for install instructions via helm3. + +## Configuration + +The following table lists the configurable parameters of the OpenEBS NDM chart and their default values. + +| Parameter | Description | Default | +|-------------------------------------------------------------|-------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------| +| `imagePullSecrets` | Provides image pull secrect | `""` | +| `ndm.enabled` | Enable Node Disk Manager | `true` | +| `ndm.image.registry` | Registry for Node Disk Manager image | `""` | +| `ndm.image.repository` | Image repository for Node Disk Manager | `openebs/node-disk-manager` | +| `ndm.image.pullPolicy` | Image pull policy for Node Disk Manager | `IfNotPresent` | +| `ndm.image.tag` | Image tag for Node Disk Manager | `2.1.0` | +| `ndm.sparse.path` | Directory where Sparse files are created | `/var/openebs/sparse` | +| `ndm.sparse.size` | Size of the sparse file in bytes | `10737418240` | +| `ndm.sparse.count` | Number of sparse files to be created | `0` | +| `ndm.updateStrategy.type` | Update strategy for NDM daemonset | `RollingUpdate` | +| `ndm.annotations` | Annotations for NDM daemonset metadata | `""` | +| `ndm.podAnnotations` | Annotations for NDM daemonset's pods metadata | `""` | +| `ndm.resources` | Resource and request and limit for containers | `""` | +| `ndm.podLabels` | Appends labels to the pods | `""` | +| `ndm.nodeSelector` | Nodeselector for daemonset pods | `""` | +| `ndm.tolerations` | NDM daemonset's pod toleration values | `""` | +| `ndm.securityContext` | Seurity context for container | `""` | +| `ndm.filters.enableOsDiskExcludeFilter` | Enable filters of OS disk exclude | `true` | +| `ndm.filters.osDiskExcludePaths` | Paths/Mountpoints to be excluded by OS Disk Filter | `/,/etc/hosts,/boot` | +| `ndm.filters.enableVendorFilter` | Enable filters of vendors | `true` | +| `ndm.filters.excludeVendors` | Exclude devices with specified vendor | `CLOUDBYT,OpenEBS` | +| `ndm.filters.enablePathFilter` | Enable filters of paths | `true` | +| `ndm.filters.includePaths` | Include devices with specified path patterns | `""` | +| `ndm.filters.excludePaths` | Exclude devices with specified path patterns | `loop,fd0,sr0,/dev/ram,/dev/dm-,/dev/md,/dev/rbd,/dev/zd` | +| `ndm.probes.enableSeachest` | Enable Seachest probe for NDM | `false` | +| `ndm.probes.enableUdevProbe` | Enable Udev probe for NDM | `true` | +| `ndm.probes.enableSmartProbe` | Enable Smart probe for NDM | `true` | +| `ndm.metaConfig.nodeLabelPattern` | Config for adding node labels as BD labels | `kubernetes.io*,beta.kubernetes.io*` | +| `ndm.metaConfig.deviceLabelTypes` | Config for adding device attributes as BD labels | `.spec.details.vendor,.spec.details.model,.spec.details.driveType,.spec.filesystem.fsType` | +| `ndmOperator.enabled` | Enable NDM Operator | `true` | +| `ndmOperator.replica` | Pod replica count for NDM operator | `1` | +| `ndmOperator.upgradeStrategy` | Update strategy NDM operator | `"Recreate"` | +| `ndmOperator.image.registry` | Registry for NDM operator image | `""` | +| `ndmOperator.image.repository` | Image repository for NDM operator | `openebs/node-disk-operator` | +| `ndmOperator.image.pullPolicy` | Image pull policy for NDM operator | `IfNotPresent` | +| `ndmOperator.image.tag` | Image tag for NDM operator | `2.1.0` | +| `ndmOperator.annotations` | Annotations for NDM operator metadata | `""` | +| `ndmOperator.podAnnotations` | Annotations for NDM operator's pods metadata | `""` | +| `ndmOperator.resources` | Resource and request and limit for containers | `""` | +| `ndmOperator.podLabels` | Appends labels to the pods | `""` | +| `ndmOperator.nodeSelector` | Nodeselector for operator pods | `""` | +| `ndmOperator.tolerations` | NDM operator's pod toleration values | `""` | +| `ndmOperator.securityContext` | Security context for container | `""` | +| `ndmExporter.enabled` | Enable NDM Exporters | `false` | +| `ndmExporter.image.registry` | Registry for NDM Exporters image | `""` | +| `ndmExporter.repository` | Image repository for NDM Exporters | `openebs/node-disk-exporter` | +| `ndmExporter.pullPolicy` | Image pull policy for NDM Exporters | `IfNotPresent` | +| `ndmExporter.tag` | Image tag for NDM Exporters | `2.1.0` | +| `ndmExporter.nodeExporter.metricsPort` | The TCP port number used for exposing NDM node exporter metrics | `9101` | +| `ndmExporter.nodeExporter.nodeExporter.nodeSelector` | Node selector for NDM node exporter pods | `9101` | +| `ndmExporter.nodeExporter.nodeExporter.tolerations` | NDM node exporter toleration values | `9101` | +| `ndmExporter.clusterExporter.metricsPort` | The TCP port number used for exposing NDM cluster exporter metrics | `9100` | +| `ndmExporter.clusterExporter.clusterExpoerter.nodeSelector` | Node selector for NDM cluster exporter pod | `9100` | +| `ndmExporter.clusterExporter.clusterExpoerter.tolerations` | NDM cluster exporter toleraion values | `9100` | +| `featureGates.APIService.enabled` | Enable the gRPC API service of NDM | `false` | +| `featureGates.UseOSDisk.enabled` | Enable feature-gate to use free space on OS disk | `false` | +| `featureGates.ChangeDetection.enabled` | Enable feature-gate to detect mountpoint/filesystem/size changes | `false` | +| `featureGates.PartitionTableUUID.enabled` | Enable feature-gate to use partition table UUID instead of creating partition | `true` | +| `helperPod.image.registry` | Registry for helper image | `""` | +| `helperPod.image.repository` | Image for helper pod | `openebs/linux-utils` | +| `helperPod.image.pullPolicy` | Pull policy for helper pod | `IfNotPresent` | +| `helperPod.image.tag` | Image tag for helper image | `3.4.0` | +| `varDirectoryPath.baseDir` | Directory to store debug info and so forth | `/var/openebs` | +| `serviceAccount.create` | Create a service account or not | `true` | +| `serviceAccount.name` | Name for the service account | `true` | + + +Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. + +Alternatively, a YAML file that specifies the values for the parameters can be provided while installing the chart. For example, + +```bash +helm install -f values.yaml ndm/openebs-ndm +``` + +> **Tip**: You can use the default [values.yaml](values.yaml) diff --git a/helm/openebs/charts/localpv-provisioner/charts/openebs-ndm/crds/blockdevice.yaml b/helm/openebs/charts/localpv-provisioner/charts/openebs-ndm/crds/blockdevice.yaml new file mode 100644 index 0000000..95f4070 --- /dev/null +++ b/helm/openebs/charts/localpv-provisioner/charts/openebs-ndm/crds/blockdevice.yaml @@ -0,0 +1,241 @@ + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.5.0 + creationTimestamp: null + name: blockdevices.openebs.io +spec: + group: openebs.io + names: + kind: BlockDevice + listKind: BlockDeviceList + plural: blockdevices + shortNames: + - bd + singular: blockdevice + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.nodeAttributes.nodeName + name: NodeName + type: string + - jsonPath: .spec.path + name: Path + priority: 1 + type: string + - jsonPath: .spec.filesystem.fsType + name: FSType + priority: 1 + type: string + - jsonPath: .spec.capacity.storage + name: Size + type: string + - jsonPath: .status.claimState + name: ClaimState + type: string + - jsonPath: .status.state + name: Status + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: BlockDevice is the Schema for the blockdevices 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: DeviceSpec defines the properties and runtime status of a BlockDevice + properties: + aggregateDevice: + description: AggregateDevice was intended to store the hierarchical information in cases of LVM. However this is currently not implemented and may need to be re-looked into for better design. To be deprecated + type: string + capacity: + description: Capacity + properties: + logicalSectorSize: + description: LogicalSectorSize is blockdevice logical-sector size in bytes + format: int32 + type: integer + physicalSectorSize: + description: PhysicalSectorSize is blockdevice physical-Sector size in bytes + format: int32 + type: integer + storage: + description: Storage is the blockdevice capacity in bytes + format: int64 + type: integer + required: + - storage + type: object + claimRef: + description: ClaimRef is the reference to the BDC which has claimed this BD + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: 'If referring to a piece of an object instead of an entire object, this string should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. For example, if the object reference is to a container within a pod, this would take on a value like: "spec.containers{name}" (where "name" refers to the name of the container that triggered the event) or if no container name is specified "spec.containers[2]" (container with index 2 in this pod). This syntax is chosen only to have some well-defined way of referencing a part of an object. TODO: this design is not final and this field is subject to change in the future.' + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: 'Specific resourceVersion to which this reference is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + details: + description: Details contain static attributes of BD like model,serial, and so forth + properties: + compliance: + description: Compliance is standards/specifications version implemented by device firmware such as SPC-1, SPC-2, etc + type: string + deviceType: + description: DeviceType represents the type of device like sparse, disk, partition, lvm, crypt + enum: + - disk + - partition + - sparse + - loop + - lvm + - crypt + - dm + - mpath + type: string + driveType: + description: DriveType is the type of backing drive, HDD/SSD + enum: + - HDD + - SSD + - Unknown + - "" + type: string + firmwareRevision: + description: FirmwareRevision is the disk firmware revision + type: string + hardwareSectorSize: + description: HardwareSectorSize is the hardware sector size in bytes + format: int32 + type: integer + logicalBlockSize: + description: LogicalBlockSize is the logical block size in bytes reported by /sys/class/block/sda/queue/logical_block_size + format: int32 + type: integer + model: + description: Model is model of disk + type: string + physicalBlockSize: + description: PhysicalBlockSize is the physical block size in bytes reported by /sys/class/block/sda/queue/physical_block_size + format: int32 + type: integer + serial: + description: Serial is serial number of disk + type: string + vendor: + description: Vendor is vendor of disk + type: string + type: object + devlinks: + description: DevLinks contains soft links of a block device like /dev/by-id/... /dev/by-uuid/... + items: + description: DeviceDevLink holds the mapping between type and links like by-id type or by-path type link + properties: + kind: + description: Kind is the type of link like by-id or by-path. + enum: + - by-id + - by-path + type: string + links: + description: Links are the soft links + items: + type: string + type: array + type: object + type: array + filesystem: + description: FileSystem contains mountpoint and filesystem type + properties: + fsType: + description: Type represents the FileSystem type of the block device + type: string + mountPoint: + description: MountPoint represents the mountpoint of the block device. + type: string + type: object + nodeAttributes: + description: NodeAttributes has the details of the node on which BD is attached + properties: + nodeName: + description: NodeName is the name of the Kubernetes node resource on which the device is attached + type: string + type: object + parentDevice: + description: "ParentDevice was intended to store the UUID of the parent Block Device as is the case for partitioned block devices. \n For example: /dev/sda is the parent for /dev/sda1 To be deprecated" + type: string + partitioned: + description: Partitioned represents if BlockDevice has partitions or not (Yes/No) Currently always default to No. To be deprecated + enum: + - "Yes" + - "No" + type: string + path: + description: Path contain devpath (e.g. /dev/sdb) + type: string + required: + - capacity + - devlinks + - nodeAttributes + - path + type: object + status: + description: DeviceStatus defines the observed state of BlockDevice + properties: + claimState: + description: ClaimState represents the claim state of the block device + enum: + - Claimed + - Unclaimed + - Released + type: string + state: + description: State is the current state of the blockdevice (Active/Inactive/Unknown) + enum: + - Active + - Inactive + - Unknown + type: string + required: + - claimState + - state + type: object + type: object + served: true + storage: true + subresources: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/helm/openebs/charts/localpv-provisioner/charts/openebs-ndm/crds/blockdeviceclaim.yaml b/helm/openebs/charts/localpv-provisioner/charts/openebs-ndm/crds/blockdeviceclaim.yaml new file mode 100644 index 0000000..81b9a35 --- /dev/null +++ b/helm/openebs/charts/localpv-provisioner/charts/openebs-ndm/crds/blockdeviceclaim.yaml @@ -0,0 +1,144 @@ + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.5.0 + creationTimestamp: null + name: blockdeviceclaims.openebs.io +spec: + group: openebs.io + names: + kind: BlockDeviceClaim + listKind: BlockDeviceClaimList + plural: blockdeviceclaims + shortNames: + - bdc + singular: blockdeviceclaim + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.blockDeviceName + name: BlockDeviceName + type: string + - jsonPath: .status.phase + name: Phase + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: BlockDeviceClaim is the Schema for the blockdeviceclaims 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: DeviceClaimSpec defines the request details for a BlockDevice + properties: + blockDeviceName: + description: BlockDeviceName is the reference to the block-device backing this claim + type: string + blockDeviceNodeAttributes: + description: BlockDeviceNodeAttributes is the attributes on the node from which a BD should be selected for this claim. It can include nodename, failure domain etc. + properties: + hostName: + description: HostName represents the hostname of the Kubernetes node resource where the BD should be present + type: string + nodeName: + description: NodeName represents the name of the Kubernetes node resource where the BD should be present + type: string + type: object + deviceClaimDetails: + description: Details of the device to be claimed + properties: + allowPartition: + description: AllowPartition represents whether to claim a full block device or a device that is a partition + type: boolean + blockVolumeMode: + description: 'BlockVolumeMode represents whether to claim a device in Block mode or Filesystem mode. These are use cases of BlockVolumeMode: 1) Not specified: VolumeMode check will not be effective 2) VolumeModeBlock: BD should not have any filesystem or mountpoint 3) VolumeModeFileSystem: BD should have a filesystem and mountpoint. If DeviceFormat is specified then the format should match with the FSType in BD' + type: string + formatType: + description: Format of the device required, eg:ext4, xfs + type: string + type: object + deviceType: + description: DeviceType represents the type of drive like SSD, HDD etc., + nullable: true + type: string + hostName: + description: Node name from where blockdevice has to be claimed. To be deprecated. Use NodeAttributes.HostName instead + type: string + resources: + description: Resources will help with placing claims on Capacity, IOPS + properties: + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum resources required. eg: if storage resource of 10G is requested minimum capacity of 10G should be available TODO for validating' + type: object + required: + - requests + type: object + selector: + description: Selector is used to find block devices to be considered for claiming + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + type: object + status: + description: DeviceClaimStatus defines the observed state of BlockDeviceClaim + properties: + phase: + description: Phase represents the current phase of the claim + type: string + required: + - phase + type: object + type: object + served: true + storage: true + subresources: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/helm/openebs/charts/localpv-provisioner/charts/openebs-ndm/templates/NOTES.txt b/helm/openebs/charts/localpv-provisioner/charts/openebs-ndm/templates/NOTES.txt new file mode 100644 index 0000000..3c84551 --- /dev/null +++ b/helm/openebs/charts/localpv-provisioner/charts/openebs-ndm/templates/NOTES.txt @@ -0,0 +1,8 @@ +The OpenEBS Node Disk Manager has been installed. Check its status by running: +$ kubectl get pods -n {{ .Release.Namespace }} + +Use `kubectl get bd -n {{ .Release.Namespace }} ` to see the list of +blockdevices attached to the Kubernetes cluster nodes. + +For more information, visit our Slack at https://openebs.io/community or view +the documentation online at http://docs.openebs.io/. diff --git a/helm/openebs/charts/localpv-provisioner/charts/openebs-ndm/templates/_helpers.tpl b/helm/openebs/charts/localpv-provisioner/charts/openebs-ndm/templates/_helpers.tpl new file mode 100644 index 0000000..c975510 --- /dev/null +++ b/helm/openebs/charts/localpv-provisioner/charts/openebs-ndm/templates/_helpers.tpl @@ -0,0 +1,242 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +This name is used for ndm daemonset +*/}} +{{- define "openebs-ndm.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "openebs-ndm.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified ndm daemonset 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 "openebs-ndm.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains .Release.Name $name }} +{{- $name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{- define "openebs-ndm.operator.name" -}} +{{- $ndmName := default .Chart.Name .Values.ndmOperator.nameOverride | trunc 63 | trimSuffix "-" }} +{{- $componentName := .Values.ndmOperator.name | trunc 63 | trimSuffix "-" }} +{{- printf "%s-%s" $ndmName $componentName | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified ndm operator 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 "openebs-ndm.operator.fullname" -}} +{{- if .Values.ndmOperator.fullnameOverride }} +{{- .Values.ndmOperator.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $ndmOperatorName := include "openebs-ndm.operator.name" .}} + +{{- $name := default $ndmOperatorName .Values.ndmOperator.nameOverride }} +{{- if contains .Release.Name $name }} +{{- $name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{- define "openebs-ndm.cluster-exporter.name" -}} +{{- $ndmName := default .Chart.Name .Values.ndmExporter.clusterExporter.nameOverride | trunc 63 | trimSuffix "-" }} +{{- $componentName := .Values.ndmExporter.clusterExporter.name | trunc 63 | trimSuffix "-" }} +{{- printf "%s-%s" $ndmName $componentName | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified ndm cluster exporter 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 "openebs-ndm.cluster-exporter.fullname" -}} +{{- if .Values.ndmExporter.clusterExporter.fullnameOverride }} +{{- .Values.ndmExporter.clusterExporter.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $ndmClusterExporterName := include "openebs-ndm.cluster-exporter.name" .}} + +{{- $name := default $ndmClusterExporterName .Values.ndmExporter.clusterExporter.nameOverride }} +{{- if contains .Release.Name $name }} +{{- $name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{- define "openebs-ndm.exporter.name" -}} +{{- $ndmName := .Chart.Name | trunc 63 | trimSuffix "-" }} +{{- $componentName := "exporter" | trunc 63 | trimSuffix "-" }} +{{- printf "%s-%s" $ndmName $componentName | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{- define "openebs-ndm.node-exporter.name" -}} +{{- $ndmName := default .Chart.Name .Values.ndmExporter.nodeExporter.nameOverride | trunc 63 | trimSuffix "-" }} +{{- $componentName := .Values.ndmExporter.nodeExporter.name | trunc 63 | trimSuffix "-" }} +{{- printf "%s-%s" $ndmName $componentName | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified ndm node exporter 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 "openebs-ndm.node-exporter.fullname" -}} +{{- if .Values.ndmExporter.nodeExporter.fullnameOverride }} +{{- .Values.ndmExporter.nodeExporter.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $ndmNodeExporterName := include "openebs-ndm.node-exporter.name" .}} + +{{- $name := default $ndmNodeExporterName .Values.ndmExporter.nodeExporter.nameOverride }} +{{- if contains .Release.Name $name }} +{{- $name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "openebs-ndm.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "openebs-ndm.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} + +{{/* +Define meta labels for ndm components +*/}} +{{- define "openebs-ndm.common.metaLabels" -}} +chart: {{ template "openebs-ndm.chart" . }} +heritage: {{ .Release.Service }} +openebs.io/version: {{ .Values.release.version | quote }} +{{- end -}} + + +{{/* +Create match labels for ndm daemonset component +*/}} +{{- define "openebs-ndm.matchLabels" -}} +app: {{ template "openebs-ndm.name" . }} +release: {{ .Release.Name }} +component: {{ .Values.ndm.componentName | quote }} +{{- end -}} + +{{/* +Create component labels for ndm daemonset component +*/}} +{{- define "openebs-ndm.componentLabels" -}} +openebs.io/component-name: {{ .Values.ndm.componentName | quote }} +{{- end -}} + + +{{/* +Create labels for ndm daemonset component +*/}} +{{- define "openebs-ndm.labels" -}} +{{ include "openebs-ndm.common.metaLabels" . }} +{{ include "openebs-ndm.matchLabels" . }} +{{ include "openebs-ndm.componentLabels" . }} +{{- end -}} + +{{/* +Create match labels for ndm operator deployment +*/}} +{{- define "openebs-ndm.operator.matchLabels" -}} +app: {{ template "openebs-ndm.operator.name" . }} +release: {{ .Release.Name }} +component: {{ default (include "openebs-ndm.operator.name" .) .Values.ndmOperator.componentName }} +{{- end -}} + +{{/* +Create component labels for ndm operator component +*/}} +{{- define "openebs-ndm.operator.componentLabels" -}} +openebs.io/component-name: {{ default (include "openebs-ndm.operator.name" .) .Values.ndmOperator.componentName }} +{{- end -}} + + +{{/* +Create labels for ndm operator component +*/}} +{{- define "openebs-ndm.operator.labels" -}} +{{ include "openebs-ndm.common.metaLabels" . }} +{{ include "openebs-ndm.operator.matchLabels" . }} +{{ include "openebs-ndm.operator.componentLabels" . }} +{{- end -}} + +{{/* +Create match labels for ndm cluster exporter deployment +*/}} +{{- define "openebs-ndm.cluster-exporter.matchLabels" -}} +app: {{ template "openebs-ndm.exporter.name" . }} +release: {{ .Release.Name }} +component: {{ default (include "openebs-ndm.cluster-exporter.name" .) .Values.ndmExporter.clusterExporter.componentName }} +{{- end -}} + +{{/* +Create component labels for ndm cluster exporter component +*/}} +{{- define "openebs-ndm.cluster-exporter.componentLabels" -}} +openebs.io/component-name: {{ default (include "openebs-ndm.cluster-exporter.name" .) .Values.ndmExporter.clusterExporter.componentName }} +{{- end -}} + + +{{/* +Create labels for ndm cluster exporter component +*/}} +{{- define "openebs-ndm.cluster-exporter.labels" -}} +{{ include "openebs-ndm.common.metaLabels" . }} +{{ include "openebs-ndm.cluster-exporter.matchLabels" . }} +{{ include "openebs-ndm.cluster-exporter.componentLabels" . }} +{{- end -}} + +{{/* +Create match labels for ndm node exporter deployment +*/}} +{{- define "openebs-ndm.node-exporter.matchLabels" -}} +app: {{ template "openebs-ndm.exporter.name" . }} +release: {{ .Release.Name }} +component: {{ default (include "openebs-ndm.node-exporter.name" .) .Values.ndmExporter.nodeExporter.componentName }} +{{- end -}} + +{{/* +Create component labels for ndm node exporter component +*/}} +{{- define "openebs-ndm.node-exporter.componentLabels" -}} +openebs.io/component-name: {{ default (include "openebs-ndm.node-exporter.name" .) .Values.ndmExporter.nodeExporter.componentName }} +{{- end -}} + + +{{/* +Create labels for ndm cluster node component +*/}} +{{- define "openebs-ndm.node-exporter.labels" -}} +{{ include "openebs-ndm.common.metaLabels" . }} +{{ include "openebs-ndm.node-exporter.matchLabels" . }} +{{ include "openebs-ndm.node-exporter.componentLabels" . }} +{{- end -}} diff --git a/helm/openebs/charts/localpv-provisioner/charts/openebs-ndm/templates/cluster-exporter-service.yaml b/helm/openebs/charts/localpv-provisioner/charts/openebs-ndm/templates/cluster-exporter-service.yaml new file mode 100644 index 0000000..719f6b4 --- /dev/null +++ b/helm/openebs/charts/localpv-provisioner/charts/openebs-ndm/templates/cluster-exporter-service.yaml @@ -0,0 +1,18 @@ +{{- if and .Values.ndmExporter.enabled .Values.ndmExporter.clusterExporter.metricsPort }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "openebs-ndm.cluster-exporter.fullname" . }}-service + labels: + {{- include "openebs-ndm.cluster-exporter.labels" . | nindent 4 }} +spec: + clusterIP: None + ports: + - name: metrics + port: {{ .Values.ndmExporter.clusterExporter.metricsPort }} + targetPort: {{ .Values.ndmExporter.clusterExporter.metricsPort }} + selector: + {{- with .Values.ndmExporter.clusterExporter.podLabels }} + {{ toYaml . }} + {{- end }} + {{- end }} diff --git a/helm/openebs/charts/localpv-provisioner/charts/openebs-ndm/templates/cluster-exporter.yaml b/helm/openebs/charts/localpv-provisioner/charts/openebs-ndm/templates/cluster-exporter.yaml new file mode 100644 index 0000000..af8b1e6 --- /dev/null +++ b/helm/openebs/charts/localpv-provisioner/charts/openebs-ndm/templates/cluster-exporter.yaml @@ -0,0 +1,60 @@ +{{- if .Values.ndmExporter.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "openebs-ndm.cluster-exporter.fullname" . }} + labels: + {{- include "openebs-ndm.cluster-exporter.labels" . | nindent 4 }} +spec: + replicas: 1 + strategy: + type: Recreate + selector: + matchLabels: + {{- include "openebs-ndm.cluster-exporter.matchLabels" . | nindent 6 }} + template: + metadata: + labels: + {{- include "openebs-ndm.cluster-exporter.labels" . | nindent 8 }} + {{- with .Values.ndmExporter.clusterExporter.podLabels }} + {{ toYaml . }} + {{- end }} + spec: + serviceAccountName: {{ template "openebs-ndm.serviceAccountName" . }} + containers: + - name: {{ template "openebs-ndm.cluster-exporter.fullname" . }} + image: "{{ .Values.ndmExporter.image.registry }}{{ .Values.ndmExporter.image.repository }}:{{ .Values.ndmExporter.image.tag }}" + command: + - /usr/local/bin/exporter + args: + - "start" + - "--mode=cluster" + - "--port=$(METRICS_LISTEN_PORT)" + - "--metrics=/metrics" + ports: + - containerPort: {{ .Values.ndmExporter.clusterExporter.metricsPort }} + protocol: TCP + name: metrics + imagePullPolicy: {{ .Values.ndmExporter.image.pullPolicy }} + env: + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + {{- if .Values.ndmExporter.clusterExporter.metricsPort }} + - name: METRICS_LISTEN_PORT + value: :{{ .Values.ndmExporter.clusterExporter.metricsPort }} + {{- end }} +{{- if .Values.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | indent 8 }} +{{- end }} +{{- if .Values.ndmExporter.clusterExporter.nodeSelector }} + nodeSelector: +{{ toYaml .Values.ndmExporter.clusterExporter.nodeSelector | indent 8 }} +{{- end }} +{{- if .Values.ndmExporter.clusterExporter.tolerations }} + tolerations: +{{ toYaml .Values.ndmExporter.clusterExporter.tolerations | indent 8 }} +{{- end }} +{{- end }} diff --git a/helm/openebs/charts/localpv-provisioner/charts/openebs-ndm/templates/configmap.yaml b/helm/openebs/charts/localpv-provisioner/charts/openebs-ndm/templates/configmap.yaml new file mode 100644 index 0000000..99b814d --- /dev/null +++ b/helm/openebs/charts/localpv-provisioner/charts/openebs-ndm/templates/configmap.yaml @@ -0,0 +1,45 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "openebs-ndm.fullname" . }}-config +data: + # node-disk-manager-config contains config of available probes and filters. + # Probes and Filters will initialize with default values if config for that + # filter or probe are not present in configmap + + # udev-probe is default or primary probe it should be enabled to run ndm + # filterconfigs contains configs of filters. To provide a group of include + # and exclude values add it as , separated string + node-disk-manager.config: | + probeconfigs: + - key: udev-probe + name: udev probe + state: {{ .Values.ndm.probes.enableUdevProbe }} + - key: seachest-probe + name: seachest probe + state: {{ .Values.ndm.probes.enableSeachest }} + - key: smart-probe + name: smart probe + state: {{ .Values.ndm.probes.enableSmartProbe }} + filterconfigs: + - key: os-disk-exclude-filter + name: os disk exclude filter + state: {{ .Values.ndm.filters.enableOsDiskExcludeFilter }} + exclude: "{{ .Values.ndm.filters.osDiskExcludePaths }}" + - key: vendor-filter + name: vendor filter + state: {{ .Values.ndm.filters.enableVendorFilter }} + include: "" + exclude: "{{ .Values.ndm.filters.excludeVendors }}" + - key: path-filter + name: path filter + state: {{ .Values.ndm.filters.enablePathFilter }} + include: "{{ .Values.ndm.filters.includePaths }}" + exclude: "{{ .Values.ndm.filters.excludePaths }}" + metaconfigs: + - key: node-labels + name: node labels + pattern: "{{ .Values.ndm.metaConfig.nodeLabelPattern }}" + - key: device-labels + name: device labels + type: "{{ .Values.ndm.metaConfig.deviceLabelTypes }}" diff --git a/helm/openebs/charts/localpv-provisioner/charts/openebs-ndm/templates/daemonset.yaml b/helm/openebs/charts/localpv-provisioner/charts/openebs-ndm/templates/daemonset.yaml new file mode 100644 index 0000000..715db87 --- /dev/null +++ b/helm/openebs/charts/localpv-provisioner/charts/openebs-ndm/templates/daemonset.yaml @@ -0,0 +1,179 @@ +{{- if .Values.ndm.enabled }} +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: {{ template "openebs-ndm.fullname" . }} + {{- with .Values.ndm.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "openebs-ndm.labels" . | nindent 4 }} +spec: + updateStrategy: +{{ toYaml .Values.ndm.updateStrategy | indent 4 }} + selector: + matchLabels: + {{- include "openebs-ndm.matchLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.ndm.podAnnotations }} + annotations: {{ toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "openebs-ndm.labels" . | nindent 8 }} + {{- with .Values.ndm.podLabels}} + {{ toYaml . }} + {{- end}} + spec: + serviceAccountName: {{ template "openebs-ndm.serviceAccountName" . }} +{{- if .Values.featureGates.enabled }} +{{- if .Values.featureGates.APIService.enabled }} + hostPID: true +{{- end}} +{{- end}} + containers: + - name: {{ template "openebs-ndm.name" . }} + image: "{{ .Values.ndm.image.registry }}{{ .Values.ndm.image.repository }}:{{ .Values.ndm.image.tag }}" + args: + - -v=4 +{{- if .Values.featureGates.enabled }} +{{- if .Values.featureGates.GPTBasedUUID.enabled }} + - --feature-gates={{ .Values.featureGates.GPTBasedUUID.featureGateFlag }} +{{- end}} +{{- if .Values.featureGates.APIService.enabled }} + - --feature-gates={{ .Values.featureGates.APIService.featureGateFlag }} + - --api-service-address={{ .Values.featureGates.APIService.address }} +{{- end}} +{{- if .Values.featureGates.UseOSDisk.enabled }} + - --feature-gates={{ .Values.featureGates.UseOSDisk.featureGateFlag }} +{{- end}} +{{- if .Values.featureGates.ChangeDetection.enabled }} + - --feature-gates={{ .Values.featureGates.ChangeDetection.featureGateFlag }} +{{- end}} +{{- if .Values.featureGates.PartitionTableUUID.enabled }} + - --feature-gates={{ .Values.featureGates.PartitionTableUUID.featureGateFlag }} +{{- end}} +{{- end}} + imagePullPolicy: {{ .Values.ndm.image.pullPolicy }} + resources: +{{ toYaml .Values.ndm.resources | indent 12 }} + securityContext: + privileged: true + env: + # namespace in which NDM is installed will be passed to NDM Daemonset + # as environment variable + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + # pass hostname as env variable using downward API to the NDM container + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName +{{- if .Values.ndm.sparse }} +{{- if .Values.ndm.sparse.path }} + # specify the directory where the sparse files need to be created. + # if not specified, then sparse files will not be created. + - name: SPARSE_FILE_DIR + value: "{{ .Values.ndm.sparse.path }}" +{{- end }} +{{- if .Values.ndm.sparse.size }} + # Size(bytes) of the sparse file to be created. + - name: SPARSE_FILE_SIZE + value: "{{ .Values.ndm.sparse.size }}" +{{- end }} +{{- if .Values.ndm.sparse.count }} + # Specify the number of sparse files to be created + - name: SPARSE_FILE_COUNT + value: "{{ .Values.ndm.sparse.count }}" +{{- end }} +{{- end }} + # Process name used for matching is limited to the 15 characters + # present in the pgrep output. + # So fullname can be used here with pgrep (cmd is < 15 chars). + livenessProbe: + exec: + command: + - pgrep + - "ndm" + initialDelaySeconds: {{ .Values.ndm.healthCheck.initialDelaySeconds }} + periodSeconds: {{ .Values.ndm.healthCheck.periodSeconds }} + volumeMounts: + - name: config + mountPath: /host/node-disk-manager.config + subPath: node-disk-manager.config + readOnly: true + - name: udev + mountPath: /run/udev + - name: procmount + mountPath: /host/proc + readOnly: true + - name: devmount + mountPath: /dev + - name: basepath + mountPath: /var/openebs/ndm +{{- if .Values.ndm.sparse }} +{{- if .Values.ndm.sparse.path }} + - name: sparsepath + mountPath: {{ .Values.ndm.sparse.path }} +{{- end }} +{{- end }} + volumes: + - name: config + configMap: + name: {{ include "openebs-ndm.fullname" . }}-config + - name: udev + hostPath: + path: /run/udev + type: Directory + # mount /proc (to access mount file of process 1 of host) inside container + # to read mount-point of disks and partitions + - name: procmount + hostPath: + path: /proc + type: Directory + - name: devmount + # the /dev directory is mounted so that we have access to the devices that + # are connected at runtime of the pod. + hostPath: + path: /dev + type: Directory + - name: basepath + hostPath: + path: "{{ .Values.varDirectoryPath.baseDir }}/ndm" + type: DirectoryOrCreate +{{- if .Values.ndm.sparse }} +{{- if .Values.ndm.sparse.path }} + - name: sparsepath + hostPath: + path: {{ .Values.ndm.sparse.path }} +{{- end }} +{{- end }} + # By default the node-disk-manager will be run on all kubernetes nodes + # If you would like to limit this to only some nodes, say the nodes + # that have storage attached, you could label those node and use + # nodeSelector. + # + # e.g. label the storage nodes with - "openebs.io/nodegroup"="storage-node" + # kubectl label node "openebs.io/nodegroup"="storage-node" + #nodeSelector: + # "openebs.io/nodegroup": "storage-node" +{{- if .Values.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | indent 8 }} +{{- end }} +{{- if .Values.ndm.nodeSelector }} + nodeSelector: +{{ toYaml .Values.ndm.nodeSelector | indent 8 }} +{{- end }} +{{- if .Values.ndm.tolerations }} + tolerations: +{{ toYaml .Values.ndm.tolerations | indent 8 }} +{{- end }} +{{- if .Values.ndm.securityContext }} + securityContext: +{{ toYaml .Values.ndm.securityContext | indent 8 }} +{{- end }} + hostNetwork: true +{{- end }} diff --git a/helm/openebs/charts/localpv-provisioner/charts/openebs-ndm/templates/deployment.yaml b/helm/openebs/charts/localpv-provisioner/charts/openebs-ndm/templates/deployment.yaml new file mode 100644 index 0000000..213a861 --- /dev/null +++ b/helm/openebs/charts/localpv-provisioner/charts/openebs-ndm/templates/deployment.yaml @@ -0,0 +1,87 @@ +{{- if .Values.ndmOperator.enabled }} +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "openebs-ndm.operator.fullname" . }} + {{- with .Values.ndmOperator.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "openebs-ndm.operator.labels" . | nindent 4 }} +spec: + replicas: {{ .Values.ndmOperator.replicas }} + strategy: + type: "Recreate" + rollingUpdate: null + selector: + matchLabels: + {{- include "openebs-ndm.operator.matchLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.ndmOperator.podAnnotations }} + annotations: {{ toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "openebs-ndm.operator.labels" . | nindent 8 }} + {{- with .Values.ndmOperator.podLabels}} + {{ toYaml . }} + {{- end}} + spec: + serviceAccountName: {{ template "openebs-ndm.serviceAccountName" . }} + containers: + - name: {{ template "openebs-ndm.operator.fullname" . }} + image: "{{ .Values.ndmOperator.image.registry }}{{ .Values.ndmOperator.image.repository }}:{{ .Values.ndmOperator.image.tag }}" + imagePullPolicy: {{ .Values.ndmOperator.image.pullPolicy }} + resources: +{{ toYaml .Values.ndmOperator.resources | indent 12 }} + livenessProbe: + httpGet: + path: /healthz + port: 8585 + initialDelaySeconds: {{ .Values.ndmOperator.healthCheck.initialDelaySeconds }} + periodSeconds: {{ .Values.ndmOperator.healthCheck.periodSeconds }} + readinessProbe: + httpGet: + path: /readyz + port: 8585 + initialDelaySeconds: {{ .Values.ndmOperator.readinessCheck.initialDelaySeconds }} + periodSeconds: {{ .Values.ndmOperator.readinessCheck.periodSeconds }} + env: + - name: WATCH_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: SERVICE_ACCOUNT + valueFrom: + fieldRef: + fieldPath: spec.serviceAccountName + - name: OPERATOR_NAME + value: "node-disk-operator" + - name: CLEANUP_JOB_IMAGE + value: "{{ .Values.helperPod.image.registry }}{{ .Values.helperPod.image.repository }}:{{ .Values.helperPod.image.tag }}" +{{- if .Values.imagePullSecrets }} + - name: OPENEBS_IO_IMAGE_PULL_SECRETS + value: "{{- range $index, $secret := .Values.imagePullSecrets}}{{if $index}},{{end}}{{ $secret.name }}{{- end}}" +{{- end }} +{{- if .Values.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | indent 8 }} +{{- end }} +{{- if .Values.ndmOperator.nodeSelector }} + nodeSelector: +{{ toYaml .Values.ndmOperator.nodeSelector | indent 8 }} +{{- end }} +{{- if .Values.ndmOperator.securityContext }} + securityContext: +{{ toYaml .Values.ndmOperator.securityContext | indent 8 }} +{{- end }} +{{- if .Values.ndmOperator.tolerations }} + tolerations: +{{ toYaml .Values.ndmOperator.tolerations | indent 8 }} +{{- end }} +{{- end }} diff --git a/helm/openebs/charts/localpv-provisioner/charts/openebs-ndm/templates/node-exporter-service.yaml b/helm/openebs/charts/localpv-provisioner/charts/openebs-ndm/templates/node-exporter-service.yaml new file mode 100644 index 0000000..026b77d --- /dev/null +++ b/helm/openebs/charts/localpv-provisioner/charts/openebs-ndm/templates/node-exporter-service.yaml @@ -0,0 +1,18 @@ +{{- if and .Values.ndmExporter.enabled .Values.ndmExporter.nodeExporter.metricsPort }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "openebs-ndm.node-exporter.fullname" . }}-service + labels: + {{- include "openebs-ndm.node-exporter.labels" . | nindent 4 }} +spec: + clusterIP: None + ports: + - name: metrics + port: {{ .Values.ndmExporter.nodeExporter.metricsPort }} + targetPort: {{ .Values.ndmExporter.nodeExporter.metricsPort }} + selector: + {{- with .Values.ndmExporter.nodeExporter.podLabels }} + {{ toYaml . }} + {{- end }} + {{- end }} diff --git a/helm/openebs/charts/localpv-provisioner/charts/openebs-ndm/templates/node-exporter.yaml b/helm/openebs/charts/localpv-provisioner/charts/openebs-ndm/templates/node-exporter.yaml new file mode 100644 index 0000000..cd5f635 --- /dev/null +++ b/helm/openebs/charts/localpv-provisioner/charts/openebs-ndm/templates/node-exporter.yaml @@ -0,0 +1,62 @@ +{{- if .Values.ndmExporter.enabled }} +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: {{ template "openebs-ndm.node-exporter.fullname" . }} + labels: + {{- include "openebs-ndm.node-exporter.labels" . | nindent 4 }} +spec: + updateStrategy: + type: RollingUpdate + selector: + matchLabels: + {{- include "openebs-ndm.node-exporter.matchLabels" . | nindent 6 }} + template: + metadata: + labels: + {{- include "openebs-ndm.node-exporter.labels" . | nindent 8 }} + {{- with .Values.ndmExporter.nodeExporter.podLabels }} + {{ toYaml . }} + {{- end }} + spec: + serviceAccountName: {{ template "openebs-ndm.serviceAccountName" . }} + containers: + - name: {{ template "openebs-ndm.node-exporter.fullname" . }} + image: "{{ .Values.ndmExporter.image.registry }}{{ .Values.ndmExporter.image.repository }}:{{ .Values.ndmExporter.image.tag }}" + command: + - /usr/local/bin/exporter + args: + - "start" + - "--mode=node" + - "--port=$(METRICS_LISTEN_PORT)" + - "--metrics=/metrics" + ports: + - containerPort: {{ .Values.ndmExporter.nodeExporter.metricsPort }} + protocol: TCP + name: metrics + imagePullPolicy: {{ .Values.ndmExporter.image.pullPolicy }} + securityContext: + privileged: true + env: + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + {{- if .Values.ndmExporter.nodeExporter.metricsPort }} + - name: METRICS_LISTEN_PORT + value: :{{ .Values.ndmExporter.nodeExporter.metricsPort }} + {{- end }} +{{- if .Values.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | indent 8 }} +{{- end }} +{{- if .Values.ndmExporter.nodeExporter.nodeSelector }} + nodeSelector: +{{ toYaml .Values.ndmExporter.nodeExporter.nodeSelector | indent 8 }} +{{- end }} +{{- if .Values.ndmExporter.nodeExporter.tolerations }} + tolerations: +{{ toYaml .Values.ndmExporter.nodeExporter.tolerations | indent 8 }} +{{- end }} +{{- end }} + diff --git a/helm/openebs/charts/localpv-provisioner/charts/openebs-ndm/templates/rbac.yaml b/helm/openebs/charts/localpv-provisioner/charts/openebs-ndm/templates/rbac.yaml new file mode 100644 index 0000000..8e81c49 --- /dev/null +++ b/helm/openebs/charts/localpv-provisioner/charts/openebs-ndm/templates/rbac.yaml @@ -0,0 +1,44 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "openebs-ndm.serviceAccountName" . }} +{{- end }} +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ include "openebs-ndm.fullname" . }} +rules: + - apiGroups: ["*"] + resources: ["nodes", "pods", "events", "configmaps", "jobs"] + verbs: + - '*' + - apiGroups: ["apiextensions.k8s.io"] + resources: ["customresourcedefinitions"] + verbs: + - '*' + - apiGroups: + - openebs.io + resources: + - blockdevices + - blockdeviceclaims + verbs: + - '*' +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ include "openebs-ndm.fullname" . }} +subjects: + - kind: ServiceAccount + name: {{ include "openebs-ndm.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} + - kind: User + name: system:serviceaccount:default:default + apiGroup: rbac.authorization.k8s.io +roleRef: + kind: ClusterRole + name: {{ include "openebs-ndm.fullname" . }} + apiGroup: rbac.authorization.k8s.io +--- diff --git a/helm/openebs/charts/localpv-provisioner/charts/openebs-ndm/values.yaml b/helm/openebs/charts/localpv-provisioner/charts/openebs-ndm/values.yaml new file mode 100644 index 0000000..2548606 --- /dev/null +++ b/helm/openebs/charts/localpv-provisioner/charts/openebs-ndm/values.yaml @@ -0,0 +1,156 @@ +# Default values for ndm. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. +release: + version: "2.1.0" + +imagePullSecrets: +# - name: "image-pull-secret" + +ndm: + componentName: ndm + enabled: true + image: + # Make sure that registry name end with a '/'. + # For example : quay.io/ is a correct value here and quay.io is incorrect + registry: + repository: openebs/node-disk-manager + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: 2.1.0 + sparse: + path: "/var/openebs/sparse" + size: "10737418240" + count: "0" + updateStrategy: + type: RollingUpdate + annotations: {} + podAnnotations: {} + resources: {} + # limits: + # cpu: 10m + # memory: 32Mi + # requests: + # cpu: 10m + # memory: 32Mi + ## Labels to be added to ndm daemonset pods + podLabels: + name: openebs-ndm + nodeSelector: {} + tolerations: [] + securityContext: {} + filters: + enableOsDiskExcludeFilter: true + osDiskExcludePaths: "/,/etc/hosts,/boot" + enableVendorFilter: true + excludeVendors: "CLOUDBYT,OpenEBS" + enablePathFilter: true + includePaths: "" + excludePaths: "loop,fd0,sr0,/dev/ram,/dev/dm-,/dev/md,/dev/rbd,/dev/zd" + probes: + enableSeachest: false + enableUdevProbe: true + enableSmartProbe: true + metaConfig: + nodeLabelPattern: "" + deviceLabelTypes: "" + healthCheck: + initialDelaySeconds: 30 + periodSeconds: 60 + +ndmOperator: + name: operator + enabled: true + image: + registry: + repository: openebs/node-disk-operator + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: 2.1.0 + podLabels: + name: openebs-ndm-operator + annotations: {} + podAnnotations: {} + nodeSelector: {} + resources: {} + securityContext: {} + tolerations: [] + healthCheck: + initialDelaySeconds: 15 + periodSeconds: 20 + readinessCheck: + initialDelaySeconds: 5 + periodSeconds: 10 + replicas: 1 + upgradeStrategy: Recreate + +ndmExporter: + enabled: false + image: + registry: + repository: openebs/node-disk-exporter + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: 2.1.0 + nodeExporter: + name: node-exporter + podLabels: + name: openebs-ndm-node-exporter + # The TCP port number used for exposing ndm-node-exporter metrics. + # If not set, service will not be created to expose metrics endpoint to serviceMonitor + # and listen-port flag will not be set and container port will be empty. + metricsPort: 9101 + nodeSelector: {} + tolerations: [] + clusterExporter: + name: cluster-exporter + podLabels: + name: openebs-ndm-cluster-exporter + # The TCP port number used for exposing ndm-cluster-exporter metrics. + # If not set, service will not be created to expose metrics endpoint to serviceMonitor + # and listen-port flag will not be set and container port will be empty. + metricsPort: 9100 + nodeSelector: {} + tolerations: [] + +helperPod: + image: + registry: "" + repository: openebs/linux-utils + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: 3.4.0 + +crd: + enableInstall: false + +featureGates: + enabled: true + GPTBasedUUID: + enabled: true + featureGateFlag: "GPTBasedUUID" + APIService: + enabled: false + featureGateFlag: "APIService" + address: "0.0.0.0:9115" + UseOSDisk: + enabled: false + featureGateFlag: "UseOSDisk" + ChangeDetection: + enabled: false + featureGateFlag: "ChangeDetection" + PartitionTableUUID: + enabled: false + featureGateFlag: "PartitionTableUUID" + +# Directory used by the OpenEBS to store debug information and so forth +# that are generated in the course of running OpenEBS containers. +varDirectoryPath: + baseDir: "/var/openebs" + +serviceAccount: + # Specifies whether a service account should be created + create: true + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: openebs-ndm diff --git a/helm/openebs/charts/localpv-provisioner/templates/NOTES.txt b/helm/openebs/charts/localpv-provisioner/templates/NOTES.txt new file mode 100644 index 0000000..a82ff98 --- /dev/null +++ b/helm/openebs/charts/localpv-provisioner/templates/NOTES.txt @@ -0,0 +1,12 @@ +The OpenEBS Dynamic LocalPV Provisioner has been installed. +Check its status by running: +$ kubectl get pods -n {{ .Release.Namespace }} + +Use `kubectl get bd -n {{ .Release.Namespace }}` to list the +blockdevices attached to the Kubernetes cluster nodes. + +Get started with the Dynamic LocalPV Provisioner Quickstart guide at: +https://github.com/openebs/dynamic-localpv-provisioner/blob/develop/docs/quickstart.md + +For more information, visit our Slack at https://openebs.io/community or view +the OpenEBS documentation online at https://openebs.io/docs diff --git a/helm/openebs/charts/localpv-provisioner/templates/_helpers.tpl b/helm/openebs/charts/localpv-provisioner/templates/_helpers.tpl new file mode 100644 index 0000000..ea1ce31 --- /dev/null +++ b/helm/openebs/charts/localpv-provisioner/templates/_helpers.tpl @@ -0,0 +1,79 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "localpv.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create a default fully qualified localpv provisioner 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 "localpv.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 "localpv.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + + +{{/* +Meta labels +*/}} +{{- define "localpv.common.metaLabels" -}} +chart: {{ template "localpv.chart" . }} +heritage: {{ .Release.Service }} +openebs.io/version: {{ .Values.release.version | quote }} +{{- end -}} + +{{/* +Selector labels +*/}} +{{- define "localpv.selectorLabels" -}} +app: {{ template "localpv.name" . }} +release: {{ .Release.Name }} +component: {{ .Values.localpv.name | quote }} +{{- end -}} + +{{/* +Component labels +*/}} +{{- define "localpv.componentLabels" -}} +openebs.io/component-name: openebs-{{ .Values.localpv.name }} +{{- end -}} + +{{/* +Common labels +*/}} +{{- define "localpv.labels" -}} +{{ include "localpv.common.metaLabels" . }} +{{ include "localpv.selectorLabels" . }} +{{ include "localpv.componentLabels" . }} +{{- end -}} + + +{{/* +Create the name of the service account to use +*/}} +{{- define "localpv.serviceAccountName" -}} +{{- if .Values.serviceAccount.create -}} + {{ default (include "localpv.fullname" .) .Values.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.serviceAccount.name }} +{{- end -}} +{{- end -}} diff --git a/helm/openebs/charts/localpv-provisioner/templates/deployment.yaml b/helm/openebs/charts/localpv-provisioner/templates/deployment.yaml new file mode 100644 index 0000000..63936f4 --- /dev/null +++ b/helm/openebs/charts/localpv-provisioner/templates/deployment.yaml @@ -0,0 +1,120 @@ +{{- if .Values.localpv.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "localpv.fullname" . }} + {{- with .Values.localpv.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "localpv.labels" . | nindent 4 }} +spec: + replicas: {{ .Values.localpv.replicas }} + strategy: + type: "Recreate" + rollingUpdate: null + selector: + matchLabels: + {{- include "localpv.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.localpv.podAnnotations }} + annotations: {{ toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "localpv.labels" . | nindent 8 }} + {{- with .Values.localpv.podLabels }} + {{ toYaml . | nindent 8 }} + {{- end }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ template "localpv.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: {{ template "localpv.fullname" . }} + image: "{{ .Values.localpv.image.registry }}{{ .Values.localpv.image.repository }}:{{ .Values.localpv.image.tag }}" + imagePullPolicy: {{ .Values.localpv.image.pullPolicy }} + resources: +{{ toYaml .Values.localpv.resources | indent 10 }} + args: + - "--bd-time-out=$(BDC_BD_BIND_RETRIES)" + env: + # OPENEBS_IO_K8S_MASTER enables openebs provisioner to connect to K8s + # based on this address. This is ignored if empty. + # This is supported for openebs provisioner version 0.5.2 onwards + #- name: OPENEBS_IO_K8S_MASTER + # value: "http://10.128.0.12:8080" + # OPENEBS_IO_KUBE_CONFIG enables openebs provisioner to connect to K8s + # based on this config. This is ignored if empty. + # This is supported for openebs provisioner version 0.5.2 onwards + #- name: OPENEBS_IO_KUBE_CONFIG + # value: "/home/ubuntu/.kube/config" + # This sets the number of times the provisioner should try + # with a polling interval of 5 seconds, to get the Blockdevice + # Name from a BlockDeviceClaim, before the BlockDeviceClaim + # is deleted. E.g. 12 * 5 seconds = 60 seconds timeout + - name: BDC_BD_BIND_RETRIES + value: "{{ .Values.localpv.waitForBDBindTimeoutRetryCount }}" + - name: OPENEBS_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + # OPENEBS_SERVICE_ACCOUNT provides the service account of this pod as + # environment variable + - name: OPENEBS_SERVICE_ACCOUNT + valueFrom: + fieldRef: + fieldPath: spec.serviceAccountName + # OPENEBS_IO_BASE_PATH is the environment variable that provides the + # default base path on the node where host-path PVs will be provisioned. + - name: OPENEBS_IO_ENABLE_ANALYTICS + value: "{{ .Values.analytics.enabled }}" + - name: OPENEBS_IO_BASE_PATH + value: "{{ .Values.localpv.basePath }}" + - name: OPENEBS_IO_HELPER_IMAGE + value: "{{ .Values.helperPod.image.registry }}{{ .Values.helperPod.image.repository }}:{{ .Values.helperPod.image.tag }}" + - name: OPENEBS_IO_INSTALLER_TYPE + value: "localpv-charts-helm" + # LEADER_ELECTION_ENABLED is used to enable/disable leader election. By default + # leader election is enabled. + - name: LEADER_ELECTION_ENABLED + value: "{{ .Values.localpv.enableLeaderElection }}" +{{- if .Values.imagePullSecrets }} + - name: OPENEBS_IO_IMAGE_PULL_SECRETS + value: "{{- range $index, $secret := .Values.imagePullSecrets}}{{if $index}},{{end}}{{ $secret.name }}{{- end}}" +{{- end }} + # Process name used for matching is limited to the 15 characters + # present in the pgrep output. + # So fullname can't be used here with pgrep (>15 chars).A regular expression + # that matches the entire command name has to specified. + # Anchor `^` : matches any string that starts with `provisioner-loc` + # `.*`: matches any string that has `provisioner-loc` followed by zero or more char + livenessProbe: + exec: + command: + - sh + - -c + - test `pgrep -c "^provisioner-loc.*"` = 1 + initialDelaySeconds: {{ .Values.localpv.healthCheck.initialDelaySeconds }} + periodSeconds: {{ .Values.localpv.healthCheck.periodSeconds }} +{{- if .Values.localpv.nodeSelector }} + nodeSelector: +{{ toYaml .Values.localpv.nodeSelector | indent 8 }} +{{- end }} +{{- if .Values.localpv.tolerations }} + tolerations: +{{ toYaml .Values.localpv.tolerations | indent 8 }} +{{- end }} +{{- if .Values.localpv.affinity }} + affinity: +{{ toYaml .Values.localpv.affinity | indent 8 }} +{{- end }} +{{- end }} diff --git a/helm/openebs/charts/localpv-provisioner/templates/device-class.yaml b/helm/openebs/charts/localpv-provisioner/templates/device-class.yaml new file mode 100644 index 0000000..35fb94b --- /dev/null +++ b/helm/openebs/charts/localpv-provisioner/templates/device-class.yaml @@ -0,0 +1,31 @@ +{{- if .Values.deviceClass.enabled }} +apiVersion: storage.k8s.io/v1 +kind: StorageClass +metadata: + name: {{ .Values.deviceClass.name }} + annotations: + openebs.io/cas-type: local + cas.openebs.io/config: | + - name: StorageType + value: "device" +{{- if .Values.deviceClass.fsType }} + - name: FSType + value: {{ .Values.deviceClass.fsType | quote }} +{{- end }} +{{- if .Values.deviceClass.blockDeviceSelectors }} + - name: BlockDeviceSelectors + data: +{{ toYaml .Values.deviceClass.blockDeviceSelectors | indent 10 }} +{{- end }} +{{- if .Values.deviceClass.nodeAffinityLabels }} + - name: NodeAffinityLabels + list: +{{ toYaml .Values.deviceClass.nodeAffinityLabels | indent 10 }} +{{- end }} +{{- if .Values.deviceClass.isDefaultClass }} + storageclass.kubernetes.io/is-default-class: "true" +{{- end }} +provisioner: openebs.io/local +volumeBindingMode: WaitForFirstConsumer +reclaimPolicy: {{ .Values.deviceClass.reclaimPolicy }} +{{- end }} \ No newline at end of file diff --git a/helm/openebs/charts/localpv-provisioner/templates/hostpath-class.yaml b/helm/openebs/charts/localpv-provisioner/templates/hostpath-class.yaml new file mode 100644 index 0000000..6dd49d9 --- /dev/null +++ b/helm/openebs/charts/localpv-provisioner/templates/hostpath-class.yaml @@ -0,0 +1,40 @@ +{{- if .Values.hostpathClass.enabled }} +apiVersion: storage.k8s.io/v1 +kind: StorageClass +metadata: + name: {{ tpl (.Values.hostpathClass.name) .}} + annotations: + openebs.io/cas-type: local + cas.openebs.io/config: | + - name: StorageType + value: "hostpath" +{{- if or .Values.localpv.basePath .Values.hostpathClass.basePath }} + - name: BasePath + value: {{ tpl (.Values.hostpathClass.basePath | default .Values.localpv.basePath | quote) . }} +{{- end }} +{{- if .Values.hostpathClass.nodeAffinityLabels }} + - name: NodeAffinityLabels + list: +{{ toYaml .Values.hostpathClass.nodeAffinityLabels | indent 10 }} +{{- end }} +{{- if .Values.hostpathClass.xfsQuota.enabled }} + - name: XFSQuota + enabled: "{{ .Values.hostpathClass.xfsQuota.enabled }}" + data: + softLimitGrace: "{{ .Values.hostpathClass.xfsQuota.softLimitGrace }}" + hardLimitGrace: "{{ .Values.hostpathClass.xfsQuota.hardLimitGrace }}" +{{- end }} +{{- if .Values.hostpathClass.ext4Quota.enabled }} + - name: EXT4Quota + enabled: "{{ .Values.hostpathClass.ext4Quota.enabled }}" + data: + softLimitGrace: "{{ .Values.hostpathClass.ext4Quota.softLimitGrace }}" + hardLimitGrace: "{{ .Values.hostpathClass.ext4Quota.hardLimitGrace }}" +{{- end }} +{{- if .Values.hostpathClass.isDefaultClass }} + storageclass.kubernetes.io/is-default-class: "true" +{{- end }} +provisioner: openebs.io/local +volumeBindingMode: WaitForFirstConsumer +reclaimPolicy: {{ .Values.hostpathClass.reclaimPolicy }} +{{- end }} diff --git a/helm/openebs/charts/localpv-provisioner/templates/psp.yaml b/helm/openebs/charts/localpv-provisioner/templates/psp.yaml new file mode 100644 index 0000000..ec64aad --- /dev/null +++ b/helm/openebs/charts/localpv-provisioner/templates/psp.yaml @@ -0,0 +1,30 @@ +{{- if .Values.rbac.pspEnabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "localpv.fullname" . }}-psp + {{- with .Values.localpv.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "localpv.labels" . | nindent 4 }} +spec: + privileged: {{ .Values.localpv.privileged }} + allowPrivilegeEscalation: true + allowedCapabilities: ['*'] + volumes: ['*'] + hostNetwork: true + hostPorts: + - min: 0 + max: 65535 + hostIPC: true + hostPID: true + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'RunAsAny' + fsGroup: + rule: 'RunAsAny' +{{- end }} diff --git a/helm/openebs/charts/localpv-provisioner/templates/rbac.yaml b/helm/openebs/charts/localpv-provisioner/templates/rbac.yaml new file mode 100644 index 0000000..04cd540 --- /dev/null +++ b/helm/openebs/charts/localpv-provisioner/templates/rbac.yaml @@ -0,0 +1,99 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "localpv.serviceAccountName" . }} + labels: + {{- include "localpv.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} +{{- if .Values.rbac.create }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "localpv.fullname" . }} + {{- with .Values.localpv.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "localpv.labels" . | nindent 4 }} +rules: +- apiGroups: ["*"] + resources: ["nodes"] + verbs: ["get", "list", "watch"] +- apiGroups: ["*"] + resources: ["namespaces", "pods", "events", "endpoints"] + verbs: ["*"] +- apiGroups: ["*"] + resources: ["resourcequotas", "limitranges"] + verbs: ["list", "watch"] +- apiGroups: ["*"] + resources: ["storageclasses", "persistentvolumeclaims", "persistentvolumes"] + verbs: ["*"] +- apiGroups: ["apiextensions.k8s.io"] + resources: ["customresourcedefinitions"] + verbs: [ "get", "list", "create", "update", "delete", "patch"] +- apiGroups: ["openebs.io"] + resources: [ "*"] + verbs: ["*" ] +- nonResourceURLs: ["/metrics"] + verbs: ["get"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "localpv.fullname" . }} + {{- with .Values.localpv.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "localpv.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "localpv.fullname" . }} +subjects: +- kind: ServiceAccount + name: {{ template "localpv.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +{{- if .Values.rbac.pspEnabled }} +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ template "localpv.fullname" . }}-psp + {{- with .Values.localpv.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "localpv.labels" . | nindent 4 }} +rules: +- apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ template "localpv.fullname" . }}-psp +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "localpv.fullname" . }}-psp + {{- with .Values.localpv.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "localpv.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "localpv.fullname" . }}-psp +subjects: + - kind: ServiceAccount + name: {{ template "localpv.serviceAccountName" . }} + namespace: {{ $.Release.Namespace }} +{{- end }} +{{- end }} diff --git a/helm/openebs/charts/localpv-provisioner/values.yaml b/helm/openebs/charts/localpv-provisioner/values.yaml new file mode 100644 index 0000000..d421232 --- /dev/null +++ b/helm/openebs/charts/localpv-provisioner/values.yaml @@ -0,0 +1,171 @@ +# Default values for localpv. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +release: + version: "3.4.0" + +rbac: + # rbac.create: `true` if rbac resources should be created + create: true + # rbac.pspEnabled: `true` if PodSecurityPolicy resources should be created + pspEnabled: false + +# If false, openebs NDM sub-chart will not be installed +openebsNDM: + enabled: true + +localpv: + name: localpv-provisioner + enabled: true + image: + # Make sure that registry name end with a '/'. + # For example : quay.io/ is a correct value here and quay.io is incorrect + registry: + repository: openebs/provisioner-localpv + tag: 3.4.0 + pullPolicy: IfNotPresent + updateStrategy: + type: RollingUpdate + # If set to false, containers created by the localpv provisioner will run without extra privileges. + privileged: true + annotations: {} + podAnnotations: {} + ## Labels to be added to localpv provisioner deployment pods + podLabels: + name: openebs-localpv-provisioner + healthCheck: + initialDelaySeconds: 30 + periodSeconds: 60 + replicas: 1 + enableLeaderElection: true + basePath: "/var/openebs/local" +# This sets the number of times the provisioner should try +# with a polling interval of 5 seconds, to get the Blockdevice +# Name from a BlockDeviceClaim, before the BlockDeviceClaim +# is deleted. E.g. 12 * 5 seconds = 60 seconds timeout + waitForBDBindTimeoutRetryCount: "12" + 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 + nodeSelector: {} + tolerations: [] + affinity: {} + securityContext: {} + +imagePullSecrets: + # - name: img-pull-secret + +podSecurityContext: {} + # fsGroup: 2000 + +nameOverride: "" +fullnameOverride: "" + +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: + +deviceClass: + # Name of default device StorageClass. + name: openebs-device + # If true, enables creation of the openebs-device StorageClass + enabled: true + # Available reclaim policies: Delete/Retain, defaults: Delete. + reclaimPolicy: Delete + # If true, sets the openebs-device StorageClass as the default StorageClass + isDefaultClass: false + # Custom node affinity label(s) for example "openebs.io/node-affinity-value" + # that will be used instead of hostnames + # This helps in cases where the hostname changes when the node is removed and + # added back with the disks still intact. + # Example: + # nodeAffinityLabels: + # - "openebs.io/node-affinity-key-1" + # - "openebs.io/node-affinity-key-2" + nodeAffinityLabels: [] + # Sets the filesystem to be written to the blockdevice before + # mounting (filesystem volumes) + # This is only usable if the selected BlockDevice does not already + # have a filesystem + # Valid values: "ext4", "xfs" + fsType: "ext4" + # Label block devices in the cluster that you would like the openEBS localPV + # Provisioner to pick up those specific block devices available on the node. + # Set the label key and value as shown in the example below. + # + # To read more: https://github.com/openebs/dynamic-localpv-provisioner/blob/develop/docs/tutorials/device/blockdeviceselectors.md + # + # Example: + # blockDeviceSelectors: + # ndm.io/driveType: "SSD" + # ndm.io/fsType: "none" + blockDeviceSelectors: {} + +hostpathClass: + # Name of the default hostpath StorageClass + name: openebs-hostpath + # If true, enables creation of the openebs-hostpath StorageClass + enabled: true + # Available reclaim policies: Delete/Retain, defaults: Delete. + reclaimPolicy: Delete + # If true, sets the openebs-hostpath StorageClass as the default StorageClass + isDefaultClass: false + # Path on the host where local volumes of this storage class are mounted under. + # NOTE: If not specified, this defaults to the value of localpv.basePath. + basePath: "" + # Custom node affinity label(s) for example "openebs.io/node-affinity-value" + # that will be used instead of hostnames + # This helps in cases where the hostname changes when the node is removed and + # added back with the disks still intact. + # Example: + # nodeAffinityLabels: + # - "openebs.io/node-affinity-key-1" + # - "openebs.io/node-affinity-key-2" + nodeAffinityLabels: [] + # Prerequisite: XFS Quota requires an XFS filesystem mounted with + # the 'pquota' or 'prjquota' mount option. + xfsQuota: + # If true, enables XFS project quota + enabled: false + # Detailed configuration options for XFS project quota. + # If XFS Quota is enabled with the default values, the usage limit + # is set at the storage capacity specified in the PVC. + softLimitGrace: "0%" + hardLimitGrace: "0%" + # Prerequisite: EXT4 Quota requires an EXT4 filesystem mounted with + # the 'prjquota' mount option. + ext4Quota: + # If true, enables XFS project quota + enabled: false + # Detailed configuration options for EXT4 project quota. + # If EXT4 Quota is enabled with the default values, the usage limit + # is set at the storage capacity specified in the PVC. + softLimitGrace: "0%" + hardLimitGrace: "0%" + +helperPod: + image: + registry: "" + repository: openebs/linux-utils + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: 3.4.0 + +analytics: + enabled: true + # Specify in hours the duration after which a ping event needs to be sent. + pingInterval: "24h" diff --git a/helm/openebs/charts/lvm-localpv/.helmignore b/helm/openebs/charts/lvm-localpv/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/helm/openebs/charts/lvm-localpv/.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/helm/openebs/charts/lvm-localpv/Chart.yaml b/helm/openebs/charts/lvm-localpv/Chart.yaml new file mode 100644 index 0000000..05e861b --- /dev/null +++ b/helm/openebs/charts/lvm-localpv/Chart.yaml @@ -0,0 +1,23 @@ +apiVersion: v2 +appVersion: 1.3.0 +description: CSI Driver for dynamic provisioning of LVM Persistent Local Volumes. +home: https://openebs.io/ +icon: https://raw.githubusercontent.com/cncf/artwork/master/projects/openebs/icon/color/openebs-icon-color.png +keywords: +- cloud-native-storage +- block-storage +- filesystem +- LVM +- Local Persistent Volumes +- storage +maintainers: +- email: prateek.pandey@mayadata.io + name: prateekpandey14 +- email: pawan@mayadata.io + name: pawanpraka1 +- email: yashpal.c1995@gmail.com + name: iyashu +name: lvm-localpv +sources: +- https://github.com/openebs/lvm-localpv +version: 1.3.0 diff --git a/helm/openebs/charts/lvm-localpv/README.md b/helm/openebs/charts/lvm-localpv/README.md new file mode 100644 index 0000000..239c8c3 --- /dev/null +++ b/helm/openebs/charts/lvm-localpv/README.md @@ -0,0 +1,160 @@ + +# OpenEBS LocalPV Provisioner + +[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) +![Chart Lint and Test](https://github.com/openebs/lvm-localpv/workflows/Chart%20Lint%20and%20Test/badge.svg) +![Release Charts](https://github.com/openebs/lvm-localpv/workflows/Release%20Charts/badge.svg?branch=develop) + +A Helm chart for openebs lvm localpv provisioner. This chart bootstraps OpenEBS LVM LocalPV provisioner deployment on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. + + +**Homepage:** + +## Maintainers + +| Name | Email | Url | +| ---- | ------ | --- | +| pawanpraka1 | pawan@mayadata.io | | +| prateekpandey14 | prateek.pandey@mayadata.io | | +| iyashu | yashpal.c1995@gmail.com | | + + +## Get Repo Info + +```console +helm repo add openebs-lvmlocalpv https://openebs.github.io/lvm-localpv +helm repo update +``` + +_See [helm repo](https://helm.sh/docs/helm/helm_repo/) for command documentation._ + +## Install Chart + +Please visit the [link](https://openebs.github.io/lvm-localpv/) for install instructions via helm3. + +```console +# Helm +$ helm install [RELEASE_NAME] openebs-lvmlocalpv/lvm-localpv --namespace [NAMESPACE] +``` + +
+ Click here if you're using MicroK8s. + + ```console + microk8s helm3 install [RELEASE_NAME] openebs-lvmlocalpv/lvm-localpv --namespace [NAMESPACE] --set-string lvmNode.kubeletDir="/var/snap/microk8s/common/var/lib/kubelet/" + ``` +
+ + +**Note:** If moving from the operator to helm +- Make sure the namespace provided in the helm install command is same as `LVM_NAMESPACE` (by default it is `openebs`) env in the controller statefulset. +- Before installing, clean up the stale statefulset and daemonset from `kube-system` namespace using the below commands +```sh +kubectl delete sts openebs-lvm-controller -n kube-system +kubectl delete ds openebs-lvm-node -n kube-system +``` + + +_See [configuration](#configuration) below._ + +_See [helm install](https://helm.sh/docs/helm/helm_install/) for command documentation._ + +## Uninstall Chart + +```console +# Helm +$ helm uninstall [RELEASE_NAME] +``` + +This removes all the Kubernetes components associated with the chart and deletes the release. + +_See [helm uninstall](https://helm.sh/docs/helm/helm_uninstall/) for command documentation._ + +## Upgrading Chart + +```console +# Helm +$ helm upgrade [RELEASE_NAME] [CHART] --install --namespace [NAMESPACE] +``` + +## Configuration + +The following table lists the configurable parameters of the OpenEBS LVM Localpv chart and their default values. + +```console +helm install openebs-lvmlocalpv openebs-lvmlocalpv/lvm-localpv --namespace openebs --create-namespace +``` +
+ Click here if you're using MicroK8s. + + If you are using MicroK8s, it is necessary to add the following flag: + + ```console + --set-string lvmNode.kubeletDir="/var/snap/microk8s/common/var/lib/kubelet/" + ``` +
+ +| Parameter | Description | Default | +|-----------------------------------------------------|----------------------------------------------------------------------------------|-----------------------------------------| +| `imagePullSecrets` | Provides image pull secrect | `""` | +| `lvmPlugin.image.registry` | Registry for openebs-lvm-plugin image | `""` | +| `lvmPlugin.image.repository` | Image repository for openebs-lvm-plugin | `openebs/lvm-driver` | +| `lvmPlugin.image.pullPolicy` | Image pull policy for openebs-lvm-plugin | `IfNotPresent` | +| `lvmPlugin.image.tag` | Image tag for openebs-lvm-plugin | `1.3.0` | +| `lvmPlugin.metricsPort` | The TCP port number used for exposing lvm-metrics | `9500` | +| `lvmPlugin.allowedTopologies` | The comma seperated list of allowed node topologies | `kubernetes.io/hostname,` | +| `lvmNode.driverRegistrar.image.registry` | Registry for csi-node-driver-registrar image | `registry.k8s.io/` | +| `lvmNode.driverRegistrar.image.repository` | Image repository for csi-node-driver-registrar | `sig-storage/csi-node-driver-registrar` | +| `lvmNode.driverRegistrar.image.pullPolicy` | Image pull policy for csi-node-driver-registrar | `IfNotPresent` | +| `lvmNode.driverRegistrar.image.tag` | Image tag for csi-node-driver-registrar | `v2.8.0` | +| `lvmNode.updateStrategy.type` | Update strategy for lvmnode daemonset | `RollingUpdate` | +| `lvmNode.kubeletDir` | Kubelet mount point for lvmnode daemonset | `"/var/lib/kubelet/"` | +| `lvmNode.annotations` | Annotations for lvmnode daemonset metadata | `""` | +| `lvmNode.podAnnotations` | Annotations for lvmnode daemonset's pods metadata | `""` | +| `lvmNode.resources` | Resource and request and limit for lvmnode daemonset containers | `""` | +| `lvmNode.labels` | Labels for lvmnode daemonset metadata | `""` | +| `lvmNode.podLabels` | Appends labels to the lvmnode daemonset pods | `""` | +| `lvmNode.nodeSelector` | Nodeselector for lvmnode daemonset pods | `""` | +| `lvmNode.tolerations` | lvmnode daemonset's pod toleration values | `""` | +| `lvmNode.securityContext` | Security context for lvmnode daemonset container | `""` | +| `lvmController.resizer.image.registry` | Registry for csi-resizer image | `registry.k8s.io/` | +| `lvmController.resizer.image.repository` | Image repository for csi-resizer | `sig-storage/csi-resizer` | +| `lvmController.resizer.image.pullPolicy` | Image pull policy for csi-resizer | `IfNotPresent` | +| `lvmController.resizer.image.tag` | Image tag for csi-resizer | `v1.8.0` | +| `lvmController.snapshotter.image.registry` | Registry for csi-snapshotter image | `registry.k8s.io/` | +| `lvmController.snapshotter.image.repository` | Image repository for csi-snapshotter | `sig-storage/csi-snapshotter` | +| `lvmController.snapshotter.image.pullPolicy` | Image pull policy for csi-snapshotter | `IfNotPresent` | +| `lvmController.snapshotter.image.tag` | Image tag for csi-snapshotter | `v6.2.2` | +| `lvmController.snapshotController.image.registry` | Registry for snapshot-controller image | `registry.k8s.io/` | +| `lvmController.snapshotController.image.repository` | Image repository for snapshot-controller | `sig-storage/snapshot-controller` | +| `lvmController.snapshotController.image.pullPolicy` | Image pull policy for snapshot-controller | `IfNotPresent` | +| `lvmController.snapshotController.image.tag` | Image tag for snapshot-controller | `v6.2.2` | +| `lvmController.provisioner.image.registry` | Registry for csi-provisioner image | `registry.k8s.io/` | +| `lvmController.provisioner.image.repository` | Image repository for csi-provisioner | `sig-storage/csi-provisioner` | +| `lvmController.provisioner.image.pullPolicy` | Image pull policy for csi-provisioner | `IfNotPresent` | +| `lvmController.provisioner.image.tag` | Image tag for csi-provisioner | `v3.5.0` | +| `lvmController.updateStrategy.type` | Update strategy for lvm localpv controller statefulset | `RollingUpdate` | +| `lvmController.annotations` | Annotations for lvm localpv controller statefulset metadata | `""` | +| `lvmController.podAnnotations` | Annotations for lvm localpv controller statefulset's pods metadata | `""` | +| `lvmController.resources` | Resource and request and limit for lvm localpv controller statefulset containers | `""` | +| `lvmController.labels` | Labels for lvm localpv controller statefulset metadata | `""` | +| `lvmController.podLabels` | Appends labels to the lvm localpv controller statefulset pods | `""` | +| `lvmController.nodeSelector` | Nodeselector for lvm localpv controller statefulset pods | `""` | +| `lvmController.tolerations` | lvm localpv controller statefulset's pod toleration values | `""` | +| `lvmController.securityContext` | Seurity context for lvm localpv controller statefulset container | `""` | +| `rbac.pspEnabled` | Enable PodSecurityPolicy | `false` | +| `serviceAccount.lvmNode.create` | Create a service account for lvmnode or not | `true` | +| `serviceAccount.lvmNode.name` | Name for the lvmnode service account | `openebs-lvm-node-sa` | +| `serviceAccount.lvmController.create` | Create a service account for lvm localpv controller or not | `true` | +| `serviceAccount.lvmController.name` | Name for the lvm localpv controller service account | `openebs-lvm-controller-sa` | +| `analytics.enabled` | Enable or Disable google analytics for the controller | `true` | + +Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. + +Alternatively, a YAML file that specifies the values for the parameters can be provided while installing the chart. For example, + +```bash +helm install -f values.yaml openebs/lvm-localpv +``` + +> **Tip**: You can use the default [values.yaml](values.yaml) diff --git a/helm/openebs/charts/lvm-localpv/crds/lvmnode.yaml b/helm/openebs/charts/lvm-localpv/crds/lvmnode.yaml new file mode 100644 index 0000000..cf32139 --- /dev/null +++ b/helm/openebs/charts/lvm-localpv/crds/lvmnode.yaml @@ -0,0 +1,177 @@ + + +############################################## +########### ############ +########### LVMNode CRD ############ +########### ############ +############################################## + +# LVMNode CRD is autogenerated via `make manifests` command. +# Do the modification in the code and run the `make manifests` command +# to generate the CRD definition + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.0 + creationTimestamp: null + name: lvmnodes.local.openebs.io +spec: + group: local.openebs.io + names: + kind: LVMNode + listKind: LVMNodeList + plural: lvmnodes + shortNames: + - lvmnode + singular: lvmnode + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: LVMNode records information about all lvm volume groups available + in a node. In general, the openebs node-agent creates the LVMNode object + & periodically synchronizing the volume groups available in the node. LVMNode + has an owner reference pointing to the corresponding node object. + 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 + volumeGroups: + items: + description: VolumeGroup specifies attributes of a given vg exists on + node. + properties: + allocationPolicy: + description: 'AllocationPolicy indicates the volume group allocation + policy. AllocationPolicy has the following mapping between int + and string for its value: [-1: "", 0: "normal", 1: "contiguous", + 2: "cling", 3: "anywhere", 4: "inherited"]' + type: integer + free: + anyOf: + - type: integer + - type: string + description: Free specifies the available capacity of volume group. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + lvCount: + description: LVCount denotes total number of logical volumes in + volume group. + format: int32 + minimum: 0 + type: integer + maxLv: + description: MaxLV denotes maximum number of logical volumes allowed + in volume group or 0 if unlimited. + format: int32 + type: integer + maxPv: + description: MaxPV denotes maximum number of physical volumes allowed + in volume group or 0 if unlimited. + format: int32 + type: integer + metadataCount: + description: MetadataCount denotes number of metadata areas on the + volume group. + format: int32 + type: integer + metadataFree: + anyOf: + - type: integer + - type: string + description: MetadataFree specifies the available metadata area + space for the volume group + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + metadataSize: + anyOf: + - type: integer + - type: string + description: MetadataSize specifies size of smallest metadata area + for the volume group + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + metadataUsedCount: + description: MetadataUsedCount denotes number of used metadata areas + in volume group + format: int32 + type: integer + missingPvCount: + description: MissingPVCount denotes number of physical volumes in + volume group which are missing. + format: int32 + type: integer + name: + description: Name of the lvm volume group. + minLength: 1 + type: string + permissions: + description: 'Permission indicates the volume group permission which + can be writable or read-only. Permission has the following mapping + between int and string for its value: [-1: "", 0: "writeable", + 1: "read-only"]' + type: integer + pvCount: + description: PVCount denotes total number of physical volumes constituting + the volume group. + format: int32 + minimum: 0 + type: integer + size: + anyOf: + - type: integer + - type: string + description: Size specifies the total size of volume group. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + snapCount: + description: SnapCount denotes number of snapshots in volume group. + format: int32 + type: integer + uuid: + description: UUID denotes a unique identity of a lvm volume group. + minLength: 1 + type: string + required: + - allocationPolicy + - free + - lvCount + - maxLv + - maxPv + - metadataCount + - metadataFree + - metadataSize + - metadataUsedCount + - missingPvCount + - name + - permissions + - pvCount + - size + - snapCount + - uuid + type: object + type: array + required: + - volumeGroups + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/helm/openebs/charts/lvm-localpv/crds/lvmsnapshot.yaml b/helm/openebs/charts/lvm-localpv/crds/lvmsnapshot.yaml new file mode 100644 index 0000000..2dc5164 --- /dev/null +++ b/helm/openebs/charts/lvm-localpv/crds/lvmsnapshot.yaml @@ -0,0 +1,85 @@ + + +############################################## +########### ############ +########### LVMSnapshot CRD ############ +########### ############ +############################################## + +# LVMSnapshot CRD is autogenerated via `make manifests` command. +# Do the modification in the code and run the `make manifests` command +# to generate the CRD definition + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.0 + creationTimestamp: null + name: lvmsnapshots.local.openebs.io +spec: + group: local.openebs.io + names: + kind: LVMSnapshot + listKind: LVMSnapshotList + plural: lvmsnapshots + singular: lvmsnapshot + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: LVMSnapshot represents an LVM Snapshot of the lvm volume + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: LVMSnapshotSpec defines LVMSnapshot spec + properties: + ownerNodeID: + description: OwnerNodeID is the Node ID where the volume group is + present which is where the snapshot has been provisioned. OwnerNodeID + can not be edited after the snapshot has been provisioned. + minLength: 1 + type: string + snapSize: + description: SnapSize specifies the space reserved for the snapshot + type: string + volGroup: + description: VolGroup specifies the name of the volume group where + the snapshot has been created. + type: string + required: + - ownerNodeID + - volGroup + type: object + status: + description: SnapStatus string that reflects if the snapshot was created + successfully + properties: + state: + type: string + type: object + required: + - spec + - status + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/helm/openebs/charts/lvm-localpv/crds/lvmvolume.yaml b/helm/openebs/charts/lvm-localpv/crds/lvmvolume.yaml new file mode 100644 index 0000000..61b7812 --- /dev/null +++ b/helm/openebs/charts/lvm-localpv/crds/lvmvolume.yaml @@ -0,0 +1,153 @@ + + +############################################## +########### ############ +########### LVMVolume CRD ############ +########### ############ +############################################## + +# LVMVolume CRD is autogenerated via `make manifests` command. +# Do the modification in the code and run the `make manifests` command +# to generate the CRD definition + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.0 + creationTimestamp: null + name: lvmvolumes.local.openebs.io +spec: + group: local.openebs.io + names: + kind: LVMVolume + listKind: LVMVolumeList + plural: lvmvolumes + shortNames: + - lvmvol + singular: lvmvolume + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: volume group where the volume is created + jsonPath: .spec.volGroup + name: VolGroup + type: string + - description: Node where the volume is created + jsonPath: .spec.ownerNodeID + name: Node + type: string + - description: Size of the volume + jsonPath: .spec.capacity + name: Size + type: string + - description: Status of the volume + jsonPath: .status.state + name: Status + type: string + - description: Age of the volume + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: LVMVolume represents a LVM based volume + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: VolumeInfo defines LVM info + properties: + capacity: + description: Capacity of the volume + minLength: 1 + type: string + ownerNodeID: + description: OwnerNodeID is the Node ID where the volume group is + present which is where the volume has been provisioned. OwnerNodeID + can not be edited after the volume has been provisioned. + minLength: 1 + type: string + shared: + description: Shared specifies whether the volume can be shared among + multiple pods. If it is not set to "yes", then the LVM LocalPV Driver + will not allow the volumes to be mounted by more than one pods. + enum: + - "yes" + - "no" + type: string + thinProvision: + description: ThinProvision specifies whether logical volumes can be + thinly provisioned. If it is set to "yes", then the LVM LocalPV + Driver will create thinProvision i.e. logical volumes that are larger + than the available extents. + enum: + - "yes" + - "no" + type: string + vgPattern: + description: VgPattern specifies the regex to choose volume groups + where volume needs to be created. + type: string + volGroup: + description: VolGroup specifies the name of the volume group where + the volume has been created. + type: string + required: + - capacity + - ownerNodeID + - vgPattern + - volGroup + type: object + status: + description: VolStatus string that specifies the current state of the + volume provisioning request. + properties: + error: + description: Error denotes the error occurred during provisioning/expanding + a volume. Error field should only be set when State becomes Failed. + properties: + code: + description: VolumeErrorCode represents the error code to represent + specific class of errors. + type: string + message: + type: string + type: object + state: + description: State specifies the current state of the volume provisioning + request. The state "Pending" means that the volume creation request + has not processed yet. The state "Ready" means that the volume has + been created and it is ready for the use. "Failed" means that volume + provisioning has been failed and will not be retried by node agent + controller. + enum: + - Pending + - Ready + - Failed + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/helm/openebs/charts/lvm-localpv/templates/NOTES.txt b/helm/openebs/charts/lvm-localpv/templates/NOTES.txt new file mode 100644 index 0000000..cc5aaf6 --- /dev/null +++ b/helm/openebs/charts/lvm-localpv/templates/NOTES.txt @@ -0,0 +1,5 @@ +The OpenEBS LVM LocalPV has been installed. Check its status by running: +$ kubectl get pods -n {{ .Release.Namespace }} -l role=openebs-lvm + +For more information, visit our Slack at https://openebs.io/community or view +the documentation online at http://docs.openebs.io/. diff --git a/helm/openebs/charts/lvm-localpv/templates/_helpers.tpl b/helm/openebs/charts/lvm-localpv/templates/_helpers.tpl new file mode 100644 index 0000000..6251921 --- /dev/null +++ b/helm/openebs/charts/lvm-localpv/templates/_helpers.tpl @@ -0,0 +1,138 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "lvmlocalpv.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create a default fully qualified localpv provisioner 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 "lvmlocalpv.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 "lvmlocalpv.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + + +{{/* +Create the name of the service account for controller +*/}} +{{- define "lvmlocalpv.lvmController.serviceAccountName" -}} +{{- if .Values.serviceAccount.lvmController.create }} +{{- default (include "lvmlocalpv.fullname" .) .Values.serviceAccount.lvmController.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.lvmController.name }} +{{- end -}} +{{- end -}} + +{{/* +Create the name of the service account to use +*/}} +{{- define "lvmlocalpv.lvmNode.serviceAccountName" -}} +{{- if .Values.serviceAccount.lvmNode.create }} +{{- default (include "lvmlocalpv.fullname" .) .Values.serviceAccount.lvmNode.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.lvmNode.name }} +{{- end -}} +{{- end -}} + +{{/* +Define meta labels for openebs lvm-localpv components +*/}} +{{- define "lvmlocalpv.common.metaLabels" -}} +chart: {{ template "lvmlocalpv.chart" . }} +heritage: {{ .Release.Service }} +openebs.io/version: {{ .Values.release.version | quote }} +role: {{ .Values.role | quote }} +{{- end -}} + +{{/* +Create match labels for openebs lvm-localpv controller +*/}} +{{- define "lvmlocalpv.lvmController.matchLabels" -}} +app: {{ .Values.lvmController.componentName | quote }} +release: {{ .Release.Name }} +component: {{ .Values.lvmController.componentName | quote }} +{{- end -}} + +{{/* +Create component labels for lvmlocalpv controller +*/}} +{{- define "lvmlocalpv.lvmController.componentLabels" -}} +openebs.io/component-name: {{ .Values.lvmController.componentName | quote }} +{{- end -}} + + +{{/* +Create labels for openebs lvm-localpv controller +*/}} +{{- define "lvmlocalpv.lvmController.labels" -}} +{{ include "lvmlocalpv.common.metaLabels" . }} +{{ include "lvmlocalpv.lvmController.matchLabels" . }} +{{ include "lvmlocalpv.lvmController.componentLabels" . }} +{{- end -}} + +{{/* +Create match labels for openebs lvm-localpv node daemon +*/}} +{{- define "lvmlocalpv.lvmNode.matchLabels" -}} +name: {{ .Values.lvmNode.componentName | quote }} +release: {{ .Release.Name }} +{{- end -}} + +{{/* +Create component labels openebs lvm-localpv node daemon +*/}} +{{- define "lvmlocalpv.lvmNode.componentLabels" -}} +openebs.io/component-name: {{ .Values.lvmNode.componentName | quote }} +{{- end -}} + + +{{/* +Create labels for openebs lvm-localpv node daemon +*/}} +{{- define "lvmlocalpv.lvmNode.labels" -}} +{{ include "lvmlocalpv.common.metaLabels" . }} +{{ include "lvmlocalpv.lvmNode.matchLabels" . }} +{{ include "lvmlocalpv.lvmNode.componentLabels" . }} +{{- end -}} + +{{/* +Create the name of the priority class for csi node plugin +*/}} +{{- define "lvmlocalpv.lvmNode.priorityClassName" -}} +{{- if .Values.lvmNode.priorityClass.create }} +{{- printf "%s-%s" .Release.Name .Values.lvmNode.priorityClass.name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s" .Values.lvmNode.priorityClass.name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} + +{{/* +Create the name of the priority class for csi controller plugin +*/}} +{{- define "lvmlocalpv.lvmController.priorityClassName" -}} +{{- if .Values.lvmController.priorityClass.create }} +{{- printf "%s-%s" .Release.Name .Values.lvmController.priorityClass.name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s" .Values.lvmController.priorityClass.name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} diff --git a/helm/openebs/charts/lvm-localpv/templates/csidriver.yaml b/helm/openebs/charts/lvm-localpv/templates/csidriver.yaml new file mode 100644 index 0000000..5eeac54 --- /dev/null +++ b/helm/openebs/charts/lvm-localpv/templates/csidriver.yaml @@ -0,0 +1,10 @@ +# Create the CSI Driver object +apiVersion: storage.k8s.io/v1 +kind: CSIDriver +metadata: + name: local.csi.openebs.io +spec: + # do not require volumeattachment + attachRequired: false + podInfoOnMount: true + storageCapacity: {{ .Values.storageCapacity }} diff --git a/helm/openebs/charts/lvm-localpv/templates/lvm-controller.yaml b/helm/openebs/charts/lvm-localpv/templates/lvm-controller.yaml new file mode 100644 index 0000000..b502997 --- /dev/null +++ b/helm/openebs/charts/lvm-localpv/templates/lvm-controller.yaml @@ -0,0 +1,159 @@ +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ template "lvmlocalpv.fullname" . }}-controller + {{- with .Values.lvmController.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "lvmlocalpv.lvmController.labels" . | nindent 4 }} +spec: + selector: + matchLabels: + {{- include "lvmlocalpv.lvmController.matchLabels" . | nindent 6 }} + serviceName: "{{ .Values.lvmController.serviceName }}" + replicas: {{ .Values.lvmController.replicas }} + template: + metadata: + {{- with .Values.lvmController.podAnnotations }} + annotations: {{ toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "lvmlocalpv.lvmController.labels" . | nindent 8 }} + {{- with .Values.lvmController.podLabels}} + {{ toYaml . | nindent 8 }} + {{- end}} + spec: + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: app + operator: In + values: + - openebs-lvm-controller + topologyKey: "kubernetes.io/hostname" +{{- if .Values.lvmController.priorityClass.create }} + priorityClassName: {{ template "lvmlocalpv.lvmController.priorityClassName" . }} +{{- end }} + serviceAccountName: {{ .Values.serviceAccount.lvmController.name }} + containers: + - name: {{ .Values.lvmController.resizer.name }} + image: "{{ .Values.lvmController.resizer.image.registry }}{{ .Values.lvmController.resizer.image.repository }}:{{ .Values.lvmController.resizer.image.tag }}" + args: + - "--v={{ .Values.lvmController.logLevel }}" + - "--csi-address=$(ADDRESS)" + {{- if gt (int .Values.lvmController.replicas) 1 }} + - "--leader-election" + {{- end }} + env: + - name: ADDRESS + value: /var/lib/csi/sockets/pluginproxy/csi.sock + imagePullPolicy: {{ .Values.lvmController.resizer.image.pullPolicy }} + volumeMounts: + - name: socket-dir + mountPath: /var/lib/csi/sockets/pluginproxy/ + resources: + {{- toYaml .Values.lvmController.resources | nindent 12 }} + - name: {{ .Values.lvmController.snapshotter.name }} + image: "{{ .Values.lvmController.snapshotter.image.registry }}{{ .Values.lvmController.snapshotter.image.repository }}:{{ .Values.lvmController.snapshotter.image.tag }}" + imagePullPolicy: {{ .Values.lvmController.snapshotter.image.pullPolicy }} + args: + - "--csi-address=$(ADDRESS)" + {{- if gt (int .Values.lvmController.replicas) 1 }} + - "--leader-election" + {{- end }} + env: + - name: ADDRESS + value: /var/lib/csi/sockets/pluginproxy/csi.sock + volumeMounts: + - name: socket-dir + mountPath: /var/lib/csi/sockets/pluginproxy/ + resources: + {{- toYaml .Values.lvmController.resources | nindent 12 }} + - name: {{ .Values.lvmController.snapshotController.name }} + image: "{{ .Values.lvmController.snapshotController.image.registry }}{{ .Values.lvmController.snapshotController.image.repository }}:{{ .Values.lvmController.snapshotController.image.tag }}" + args: + - "--v={{ .Values.lvmController.logLevel }}" + {{- if gt (int .Values.lvmController.replicas) 1 }} + - "--leader-election=true" + {{- end }} + imagePullPolicy: {{ .Values.lvmController.snapshotController.image.pullPolicy }} + resources: + {{- toYaml .Values.lvmController.resources | nindent 12 }} + - name: {{ .Values.lvmController.provisioner.name }} + image: "{{ .Values.lvmController.provisioner.image.registry }}{{ .Values.lvmController.provisioner.image.repository }}:{{ .Values.lvmController.provisioner.image.tag }}" + imagePullPolicy: {{ .Values.lvmController.provisioner.image.pullPolicy }} + args: + - "--csi-address=$(ADDRESS)" + - "--v={{ .Values.lvmController.logLevel }}" + - "--feature-gates=Topology=true" + - "--strict-topology" + {{- if gt (int .Values.lvmController.replicas) 1 }} + - "--leader-election" + {{- end }} + - "--enable-capacity={{ .Values.storageCapacity }}" + - "--extra-create-metadata=true" + - "--default-fstype=ext4" + env: + - name: ADDRESS + value: /var/lib/csi/sockets/pluginproxy/csi.sock + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + volumeMounts: + - name: socket-dir + mountPath: /var/lib/csi/sockets/pluginproxy/ + resources: + {{- toYaml .Values.lvmController.resources | nindent 12 }} + - name: {{ .Values.lvmPlugin.name }} + image: "{{ .Values.lvmPlugin.image.registry }}{{ .Values.lvmPlugin.image.repository }}:{{ .Values.lvmPlugin.image.tag }}" + imagePullPolicy: {{ .Values.lvmPlugin.image.pullPolicy }} + env: + - name: OPENEBS_CONTROLLER_DRIVER + value: controller + - name: OPENEBS_CSI_ENDPOINT + value: unix:///var/lib/csi/sockets/pluginproxy/csi.sock + - name: LVM_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: OPENEBS_IO_INSTALLER_TYPE + value: "lvm-localpv-helm" + - name: OPENEBS_IO_ENABLE_ANALYTICS + value: "{{ .Values.analytics.enabled }}" + args : + - "--endpoint=$(OPENEBS_CSI_ENDPOINT)" + - "--plugin=$(OPENEBS_CONTROLLER_DRIVER)" + - "--kube-api-qps={{ .Values.lvmController.kubeClientRateLimiter.qps }}" + - "--kube-api-burst={{ .Values.lvmController.kubeClientRateLimiter.burst }}" + volumeMounts: + - name: socket-dir + mountPath: /var/lib/csi/sockets/pluginproxy/ + resources: + {{- toYaml .Values.lvmController.resources | nindent 12 }} + volumes: + - name: socket-dir + emptyDir: {} +{{- if .Values.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | indent 8 }} +{{- end }} +{{- if .Values.lvmController.nodeSelector }} + nodeSelector: +{{ toYaml .Values.lvmController.nodeSelector | indent 8 }} +{{- end }} +{{- if .Values.lvmController.securityContext }} + securityContext: +{{ toYaml .Values.lvmController.securityContext | indent 8 }} +{{- end }} +{{- if .Values.lvmController.tolerations }} + tolerations: +{{ toYaml .Values.lvmController.tolerations | indent 8 }} +{{- end }} diff --git a/helm/openebs/charts/lvm-localpv/templates/lvm-node-service.yaml b/helm/openebs/charts/lvm-localpv/templates/lvm-node-service.yaml new file mode 100644 index 0000000..34c1977 --- /dev/null +++ b/helm/openebs/charts/lvm-localpv/templates/lvm-node-service.yaml @@ -0,0 +1,18 @@ +{{- if .Values.lvmPlugin.metricsPort }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "lvmlocalpv.fullname" . }}-node-service + labels: + {{- include "lvmlocalpv.lvmNode.labels" . | nindent 4 }} +spec: + clusterIP: None + ports: + - name: metrics + port: {{ .Values.lvmPlugin.metricsPort }} + targetPort: {{ .Values.lvmPlugin.metricsPort }} + selector: + {{- with .Values.lvmNode.podLabels }} + {{ toYaml . }} + {{- end }} +{{- end }} diff --git a/helm/openebs/charts/lvm-localpv/templates/lvm-node.yaml b/helm/openebs/charts/lvm-localpv/templates/lvm-node.yaml new file mode 100644 index 0000000..13e6b19 --- /dev/null +++ b/helm/openebs/charts/lvm-localpv/templates/lvm-node.yaml @@ -0,0 +1,158 @@ +kind: DaemonSet +apiVersion: apps/v1 +metadata: + name: {{ template "lvmlocalpv.fullname" . }}-node + {{- with .Values.lvmNode.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "lvmlocalpv.lvmNode.labels" . | nindent 4 }} +spec: + selector: + matchLabels: + {{- include "lvmlocalpv.lvmNode.matchLabels" . | nindent 6 }} + updateStrategy: + rollingUpdate: + maxUnavailable: 100% + type: RollingUpdate + template: + metadata: + {{- with .Values.lvmNode.podAnnotations }} + annotations: {{ toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "lvmlocalpv.lvmNode.labels" . | nindent 8 }} + {{- with .Values.lvmNode.podLabels}} + {{ toYaml . | nindent 8 }} + {{- end}} + spec: +{{- if .Values.lvmNode.priorityClass.create }} + priorityClassName: {{ template "lvmlocalpv.lvmNode.priorityClassName" . }} +{{- end }} + serviceAccountName: {{ .Values.serviceAccount.lvmNode.name }} + hostNetwork: true + containers: + - name: {{ .Values.lvmNode.driverRegistrar.name }} + image: "{{ .Values.lvmNode.driverRegistrar.image.registry }}{{ .Values.lvmNode.driverRegistrar.image.repository }}:{{ .Values.lvmNode.driverRegistrar.image.tag }}" + imagePullPolicy: {{ .Values.lvmNode.driverRegistrar.image.pullPolicy }} + args: + - "--v={{ .Values.lvmNode.logLevel }}" + - "--csi-address=$(ADDRESS)" + - "--kubelet-registration-path=$(DRIVER_REG_SOCK_PATH)" + lifecycle: + preStop: + exec: + command: ["/bin/sh", "-c", "rm -rf /registration/lvm-localpv /registration/lvm-localpv-reg.sock"] + env: + - name: ADDRESS + value: /plugin/csi.sock + - name: DRIVER_REG_SOCK_PATH + value: {{ .Values.lvmNode.kubeletDir }}plugins/lvm-localpv/csi.sock + - name: KUBE_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: NODE_DRIVER + value: openebs-lvm + volumeMounts: + - name: plugin-dir + mountPath: /plugin + - name: registration-dir + mountPath: /registration + resources: + {{- toYaml .Values.lvmNode.resources | nindent 12 }} + - name: {{ .Values.lvmPlugin.name }} + securityContext: + privileged: true + allowPrivilegeEscalation: true + image: "{{ .Values.lvmPlugin.image.registry }}{{ .Values.lvmPlugin.image.repository }}:{{ .Values.lvmPlugin.image.tag }}" + imagePullPolicy: {{ .Values.lvmPlugin.image.pullPolicy }} + args: + - "--nodeid=$(OPENEBS_NODE_ID)" + - "--endpoint=$(OPENEBS_CSI_ENDPOINT)" + - "--plugin=$(OPENEBS_NODE_DRIVER)" + - "--kube-api-qps={{ .Values.lvmNode.kubeClientRateLimiter.qps }}" + - "--kube-api-burst={{ .Values.lvmNode.kubeClientRateLimiter.burst }}" + {{- if .Values.lvmPlugin.ioLimits.enabled }} + - "--setiolimits" + - "--container-runtime=$(CONTAINER_RUNTIME)" + - "--riops-per-gb=$(RIOPS_PER_GB)" + - "--wiops-per-gb=$(WIOPS_PER_GB)" + {{- end }} + {{- if .Values.lvmPlugin.metricsPort }} + - "--listen-address=$(METRICS_LISTEN_ADDRESS)" + {{- end }} + env: + - name: OPENEBS_NODE_ID + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: OPENEBS_CSI_ENDPOINT + value: unix:///plugin/csi.sock + - name: OPENEBS_NODE_DRIVER + value: agent + - name: LVM_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + {{- if .Values.lvmPlugin.ioLimits.enabled }} + - name: CONTAINER_RUNTIME + value: {{ .Values.lvmPlugin.ioLimits.containerRuntime }} + - name: RIOPS_PER_GB + value: {{ .Values.lvmPlugin.ioLimits.readIopsPerGB }} + - name: WIOPS_PER_GB + value: {{ .Values.lvmPlugin.ioLimits.writeIopsPerGB }} + {{- end }} + {{- if .Values.lvmPlugin.metricsPort }} + - name: METRICS_LISTEN_ADDRESS + value: :{{ .Values.lvmPlugin.metricsPort }} + {{- end }} + {{- if .Values.lvmPlugin.allowedTopologies }} + - name: ALLOWED_TOPOLOGIES + value: {{ .Values.lvmPlugin.allowedTopologies }} + {{- end }} + volumeMounts: + - name: plugin-dir + mountPath: /plugin + - name: device-dir + mountPath: /dev + - name: pods-mount-dir + mountPath: {{ .Values.lvmNode.kubeletDir }} + # needed so that any mounts setup inside this container are + # propagated back to the host machine. + mountPropagation: "Bidirectional" + resources: + {{- toYaml .Values.lvmNode.resources | nindent 12 }} + volumes: + - name: device-dir + hostPath: + path: /dev + type: Directory + - name: registration-dir + hostPath: + path: {{ .Values.lvmNode.kubeletDir }}plugins_registry/ + type: DirectoryOrCreate + - name: plugin-dir + hostPath: + path: {{ .Values.lvmNode.kubeletDir }}plugins/lvm-localpv/ + type: DirectoryOrCreate + - name: pods-mount-dir + hostPath: + path: {{ .Values.lvmNode.kubeletDir }} + type: Directory +{{- if .Values.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | indent 8 }} +{{- end }} +{{- if .Values.lvmNode.nodeSelector }} + nodeSelector: +{{ toYaml .Values.lvmNode.nodeSelector | indent 8 }} +{{- end }} +{{- if .Values.lvmNode.securityContext }} + securityContext: +{{ toYaml .Values.lvmNode.securityContext | indent 8 }} +{{- end }} +{{- if .Values.lvmNode.tolerations }} + tolerations: +{{ toYaml .Values.lvmNode.tolerations | indent 8 }} +{{- end }} diff --git a/helm/openebs/charts/lvm-localpv/templates/priority-class.yaml b/helm/openebs/charts/lvm-localpv/templates/priority-class.yaml new file mode 100644 index 0000000..44552ab --- /dev/null +++ b/helm/openebs/charts/lvm-localpv/templates/priority-class.yaml @@ -0,0 +1,19 @@ +{{- if .Values.lvmController.priorityClass.create }} +apiVersion: scheduling.k8s.io/v1 +kind: PriorityClass +metadata: + name: {{ template "lvmlocalpv.lvmController.priorityClassName" . }} +value: 900000000 +globalDefault: false +description: "This priority class should be used for the CStor CSI driver controller deployment only." +{{- end }} +--- +{{- if .Values.lvmNode.priorityClass.create }} +apiVersion: scheduling.k8s.io/v1 +kind: PriorityClass +metadata: + name: {{ template "lvmlocalpv.lvmNode.priorityClassName" . }} +value: 900001000 +globalDefault: false +description: "This priority class should be used for the CStor CSI driver node deployment only." +{{- end }} diff --git a/helm/openebs/charts/lvm-localpv/templates/psp.yaml b/helm/openebs/charts/lvm-localpv/templates/psp.yaml new file mode 100644 index 0000000..7472d7c --- /dev/null +++ b/helm/openebs/charts/lvm-localpv/templates/psp.yaml @@ -0,0 +1,24 @@ +{{- if .Values.rbac.pspEnabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: openebs-lvm-node-psp + labels: + {{- include "lvmlocalpv.lvmNode.labels" . | nindent 4 }} +spec: + privileged: true + allowPrivilegeEscalation: true + allowedCapabilities: ['*'] + volumes: ['*'] + hostNetwork: true + hostIPC: true + hostPID: true + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'RunAsAny' + fsGroup: + rule: 'RunAsAny' +{{- end }} diff --git a/helm/openebs/charts/lvm-localpv/templates/rbac.yaml b/helm/openebs/charts/lvm-localpv/templates/rbac.yaml new file mode 100644 index 0000000..2d87a9d --- /dev/null +++ b/helm/openebs/charts/lvm-localpv/templates/rbac.yaml @@ -0,0 +1,197 @@ +{{- if .Values.serviceAccount.lvmController.create -}} +kind: ServiceAccount +apiVersion: v1 +metadata: + name: {{ .Values.serviceAccount.lvmController.name }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "lvmlocalpv.lvmController.labels" . | nindent 4 }} +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: openebs-lvm-provisioner-role + labels: + {{- include "lvmlocalpv.lvmController.labels" . | nindent 4 }} +rules: + - apiGroups: [""] + resources: ["secrets"] + verbs: ["get", "list"] + - apiGroups: [""] + resources: ["namespaces"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["persistentvolumes", "services"] + verbs: ["get", "list", "watch", "create", "delete", "update", "patch"] + - apiGroups: [""] + resources: ["persistentvolumeclaims"] + verbs: ["get", "list", "watch", "update"] + - apiGroups: [""] + resources: ["persistentvolumeclaims/status"] + verbs: ["update", "patch"] + - apiGroups: ["storage.k8s.io"] + resources: ["storageclasses", "csinodes"] + verbs: ["get", "list", "watch"] + - apiGroups: [ "storage.k8s.io" ] + resources: [ "csistoragecapacities"] + verbs: ["*"] + - apiGroups: [""] + resources: ["events"] + verbs: ["list", "watch", "create", "update", "patch"] + - apiGroups: ["coordination.k8s.io"] + resources: ["leases"] + verbs: ["get", "watch", "list", "delete", "update", "create"] + - apiGroups: [""] + resources: ["nodes"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["pods"] + verbs: ["get", "list", "watch", "update", "patch"] + - apiGroups: ["local.openebs.io"] + resources: ["lvmvolumes", "lvmsnapshots", "lvmnodes"] + verbs: ["*"] +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: openebs-lvm-provisioner-binding + labels: + {{- include "lvmlocalpv.lvmController.labels" . | nindent 4 }} +subjects: + - kind: ServiceAccount + name: {{ .Values.serviceAccount.lvmController.name }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: openebs-lvm-provisioner-role + apiGroup: rbac.authorization.k8s.io +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: openebs-lvm-snapshotter-role + labels: + {{- include "lvmlocalpv.lvmController.labels" . | nindent 4 }} +rules: + - apiGroups: [""] + resources: ["persistentvolumes"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["persistentvolumeclaims"] + verbs: ["get", "list", "watch"] + - 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: ["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"] + verbs: ["get", "list", "watch", "update", "patch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotcontents/status"] + verbs: ["update"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshots/status"] + verbs: ["update"] + - apiGroups: ["apiextensions.k8s.io"] + resources: ["customresourcedefinitions"] + verbs: ["create", "list", "watch", "delete"] +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: openebs-lvm-snapshotter-binding + labels: + {{- include "lvmlocalpv.lvmController.labels" . | nindent 4 }} +subjects: + - kind: ServiceAccount + name: {{ .Values.serviceAccount.lvmController.name }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: openebs-lvm-snapshotter-role + apiGroup: rbac.authorization.k8s.io +--- +{{- end }} +{{- if .Values.serviceAccount.lvmNode.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .Values.serviceAccount.lvmNode.name }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "lvmlocalpv.lvmNode.labels" . | nindent 4 }} +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: openebs-lvm-driver-registrar-role + labels: + {{- include "lvmlocalpv.lvmNode.labels" . | nindent 4 }} +rules: + - apiGroups: [""] + resources: ["events"] + verbs: ["get", "list", "watch", "create", "update", "patch"] + - apiGroups: [""] + resources: ["persistentvolumes", "nodes", "services"] + verbs: ["get", "list"] + - apiGroups: ["local.openebs.io"] + resources: ["lvmvolumes", "lvmsnapshots", "lvmnodes"] + verbs: ["get", "list", "watch", "create", "update", "patch"] +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: openebs-lvm-driver-registrar-binding + labels: + {{- include "lvmlocalpv.lvmNode.labels" . | nindent 4 }} +subjects: + - kind: ServiceAccount + name: {{ .Values.serviceAccount.lvmNode.name }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: openebs-lvm-driver-registrar-role + apiGroup: rbac.authorization.k8s.io + +{{- if .Values.rbac.pspEnabled }} +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: openebs-lvm-node-role + labels: + {{- include "lvmlocalpv.lvmNode.labels" . | nindent 4 }} +rules: +- apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - openebs-lvm-node-psp +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: openebs-lvm-node-binding + labels: + {{- include "lvmlocalpv.lvmNode.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: openebs-lvm-node-role +subjects: + - kind: ServiceAccount + name: {{ .Values.serviceAccount.lvmNode.name }} + namespace: {{ $.Release.Namespace }} +{{- end }} +{{- end }} diff --git a/helm/openebs/charts/lvm-localpv/templates/volumesnapshotclasses-crd.yaml b/helm/openebs/charts/lvm-localpv/templates/volumesnapshotclasses-crd.yaml new file mode 100644 index 0000000..5c89653 --- /dev/null +++ b/helm/openebs/charts/lvm-localpv/templates/volumesnapshotclasses-crd.yaml @@ -0,0 +1,136 @@ +{{- if .Values.crd.volumeSnapshot }} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.11.3 + api-approved.kubernetes.io: "https://github.com/kubernetes-csi/external-snapshotter/pull/814" + creationTimestamp: null + name: volumesnapshotclasses.snapshot.storage.k8s.io +spec: + group: snapshot.storage.k8s.io + names: + kind: VolumeSnapshotClass + listKind: VolumeSnapshotClassList + plural: volumesnapshotclasses + shortNames: + - vsclass + - vsclasses + singular: volumesnapshotclass + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .driver + name: Driver + type: string + - description: Determines whether a VolumeSnapshotContent created through the + VolumeSnapshotClass should be deleted when its bound VolumeSnapshot is deleted. + jsonPath: .deletionPolicy + name: DeletionPolicy + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: VolumeSnapshotClass specifies parameters that a underlying storage + system uses when creating a volume snapshot. A specific VolumeSnapshotClass + is used by specifying its name in a VolumeSnapshot object. VolumeSnapshotClasses + are non-namespaced + 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 + deletionPolicy: + description: deletionPolicy determines whether a VolumeSnapshotContent + created through the VolumeSnapshotClass should be deleted when its bound + VolumeSnapshot is deleted. Supported values are "Retain" and "Delete". + "Retain" means that the VolumeSnapshotContent and its physical snapshot + on underlying storage system are kept. "Delete" means that the VolumeSnapshotContent + and its physical snapshot on underlying storage system are deleted. + Required. + enum: + - Delete + - Retain + type: string + driver: + description: driver is the name of the storage driver that handles this + VolumeSnapshotClass. Required. + 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 + parameters: + additionalProperties: + type: string + description: parameters is a key-value map with storage driver specific + parameters for creating snapshots. These values are opaque to Kubernetes. + type: object + required: + - deletionPolicy + - driver + type: object + served: true + storage: true + subresources: {} + - additionalPrinterColumns: + - jsonPath: .driver + name: Driver + type: string + - description: Determines whether a VolumeSnapshotContent created through the VolumeSnapshotClass should be deleted when its bound VolumeSnapshot is deleted. + jsonPath: .deletionPolicy + name: DeletionPolicy + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + # This indicates the v1beta1 version of the custom resource is deprecated. + # API requests to this version receive a warning in the server response. + deprecated: true + # This overrides the default warning returned to clients making v1beta1 API requests. + deprecationWarning: "snapshot.storage.k8s.io/v1beta1 VolumeSnapshotClass is deprecated; use snapshot.storage.k8s.io/v1 VolumeSnapshotClass" + schema: + openAPIV3Schema: + description: VolumeSnapshotClass specifies parameters that a underlying storage system uses when creating a volume snapshot. A specific VolumeSnapshotClass is used by specifying its name in a VolumeSnapshot object. VolumeSnapshotClasses are non-namespaced + 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 + deletionPolicy: + description: deletionPolicy determines whether a VolumeSnapshotContent created through the VolumeSnapshotClass should be deleted when its bound VolumeSnapshot is deleted. Supported values are "Retain" and "Delete". "Retain" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are kept. "Delete" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are deleted. Required. + enum: + - Delete + - Retain + type: string + driver: + description: driver is the name of the storage driver that handles this VolumeSnapshotClass. Required. + 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 + parameters: + additionalProperties: + type: string + description: parameters is a key-value map with storage driver specific parameters for creating snapshots. These values are opaque to Kubernetes. + type: object + required: + - deletionPolicy + - driver + type: object + served: false + storage: false + subresources: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] +{{- end }} diff --git a/helm/openebs/charts/lvm-localpv/templates/volumesnapshotcontents-crd.yaml b/helm/openebs/charts/lvm-localpv/templates/volumesnapshotcontents-crd.yaml new file mode 100644 index 0000000..7c4ec07 --- /dev/null +++ b/helm/openebs/charts/lvm-localpv/templates/volumesnapshotcontents-crd.yaml @@ -0,0 +1,403 @@ +{{- if .Values.crd.volumeSnapshot }} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.11.3 + api-approved.kubernetes.io: "https://github.com/kubernetes-csi/external-snapshotter/pull/814" + creationTimestamp: null + name: volumesnapshotcontents.snapshot.storage.k8s.io +spec: + group: snapshot.storage.k8s.io + names: + kind: VolumeSnapshotContent + listKind: VolumeSnapshotContentList + plural: volumesnapshotcontents + shortNames: + - vsc + - vscs + singular: volumesnapshotcontent + scope: Cluster + versions: + - additionalPrinterColumns: + - description: Indicates if the snapshot is ready to be used to restore a volume. + jsonPath: .status.readyToUse + name: ReadyToUse + type: boolean + - description: Represents the complete size of the snapshot in bytes + jsonPath: .status.restoreSize + name: RestoreSize + type: integer + - description: Determines whether this VolumeSnapshotContent and its physical + snapshot on the underlying storage system should be deleted when its bound + VolumeSnapshot is deleted. + jsonPath: .spec.deletionPolicy + name: DeletionPolicy + type: string + - description: Name of the CSI driver used to create the physical snapshot on + the underlying storage system. + jsonPath: .spec.driver + name: Driver + type: string + - description: Name of the VolumeSnapshotClass to which this snapshot belongs. + jsonPath: .spec.volumeSnapshotClassName + name: VolumeSnapshotClass + type: string + - description: Name of the VolumeSnapshot object to which this VolumeSnapshotContent + object is bound. + jsonPath: .spec.volumeSnapshotRef.name + name: VolumeSnapshot + type: string + - description: Namespace of the VolumeSnapshot object to which this VolumeSnapshotContent object is bound. + jsonPath: .spec.volumeSnapshotRef.namespace + name: VolumeSnapshotNamespace + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: VolumeSnapshotContent represents the actual "on-disk" snapshot + object in the underlying storage system + 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 + spec: + description: spec defines properties of a VolumeSnapshotContent created + by the underlying storage system. Required. + properties: + deletionPolicy: + description: deletionPolicy determines whether this VolumeSnapshotContent + and its physical snapshot on the underlying storage system should + be deleted when its bound VolumeSnapshot is deleted. Supported values + are "Retain" and "Delete". "Retain" means that the VolumeSnapshotContent + and its physical snapshot on underlying storage system are kept. + "Delete" means that the VolumeSnapshotContent and its physical snapshot + on underlying storage system are deleted. For dynamically provisioned + snapshots, this field will automatically be filled in by the CSI + snapshotter sidecar with the "DeletionPolicy" field defined in the + corresponding VolumeSnapshotClass. For pre-existing snapshots, users + MUST specify this field when creating the VolumeSnapshotContent + object. Required. + enum: + - Delete + - Retain + type: string + driver: + description: driver is the name of the CSI driver used to create the + physical snapshot on the underlying storage system. This MUST be + the same as the name returned by the CSI GetPluginName() call for + that driver. Required. + type: string + source: + description: source specifies whether the snapshot is (or should be) + dynamically provisioned or already exists, and just requires a Kubernetes + object representation. This field is immutable after creation. Required. + properties: + snapshotHandle: + description: snapshotHandle specifies the CSI "snapshot_id" of + a pre-existing snapshot on the underlying storage system for + which a Kubernetes object representation was (or should be) + created. This field is immutable. + type: string + volumeHandle: + description: volumeHandle specifies the CSI "volume_id" of the + volume from which a snapshot should be dynamically taken from. + This field is immutable. + type: string + type: object + oneOf: + - required: [ "snapshotHandle" ] + - required: [ "volumeHandle" ] + sourceVolumeMode: + description: SourceVolumeMode is the mode of the volume whose snapshot + is taken. Can be either “Filesystem” or “Block”. If not specified, + it indicates the source volume's mode is unknown. This field is + immutable. This field is an alpha field. + type: string + volumeSnapshotClassName: + description: name of the VolumeSnapshotClass from which this snapshot + was (or will be) created. Note that after provisioning, the VolumeSnapshotClass + may be deleted or recreated with different set of values, and as + such, should not be referenced post-snapshot creation. + type: string + volumeSnapshotRef: + description: volumeSnapshotRef specifies the VolumeSnapshot object + to which this VolumeSnapshotContent object is bound. VolumeSnapshot.Spec.VolumeSnapshotContentName + field must reference to this VolumeSnapshotContent's name for the + bidirectional binding to be valid. For a pre-existing VolumeSnapshotContent + object, name and namespace of the VolumeSnapshot object MUST be + provided for binding to happen. This field is immutable after creation. + Required. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: 'If referring to a piece of an object instead of + an entire object, this string should contain a valid JSON/Go + field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within + a pod, this would take on a value like: "spec.containers{name}" + (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" + (container with index 2 in this pod). This syntax is chosen + only to have some well-defined way of referencing a part of + an object. TODO: this design is not final and this field is + subject to change in the future.' + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: 'Specific resourceVersion to which this reference + is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + x-kubernetes-map-type: atomic + required: + - deletionPolicy + - driver + - source + - volumeSnapshotRef + type: object + status: + description: status represents the current information of a snapshot. + properties: + creationTime: + description: creationTime is the timestamp when the point-in-time + snapshot is taken by the underlying storage system. In dynamic snapshot + creation case, this field will be filled in by the CSI snapshotter + sidecar with the "creation_time" value returned from CSI "CreateSnapshot" + gRPC call. For a pre-existing snapshot, this field will be filled + with the "creation_time" value returned from the CSI "ListSnapshots" + gRPC call if the driver supports it. If not specified, it indicates + the creation time is unknown. The format of this field is a Unix + nanoseconds time encoded as an int64. On Unix, the command `date + +%s%N` returns the current time in nanoseconds since 1970-01-01 + 00:00:00 UTC. + format: int64 + type: integer + error: + description: error is the last observed error during snapshot creation, + if any. Upon success after retry, this error field will be cleared. + properties: + message: + description: 'message is a string detailing the encountered error + during snapshot creation if specified. NOTE: message may be + logged, and it should not contain sensitive information.' + type: string + time: + description: time is the timestamp when the error was encountered. + format: date-time + type: string + type: object + readyToUse: + description: readyToUse indicates if a snapshot is ready to be used + to restore a volume. In dynamic snapshot creation case, this field + will be filled in by the CSI snapshotter sidecar with the "ready_to_use" + value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing + snapshot, this field will be filled with the "ready_to_use" value + returned from the CSI "ListSnapshots" gRPC call if the driver supports + it, otherwise, this field will be set to "True". If not specified, + it means the readiness of a snapshot is unknown. + type: boolean + restoreSize: + description: restoreSize represents the complete size of the snapshot + in bytes. In dynamic snapshot creation case, this field will be + filled in by the CSI snapshotter sidecar with the "size_bytes" value + returned from CSI "CreateSnapshot" gRPC call. For a pre-existing + snapshot, this field will be filled with the "size_bytes" value + returned from the CSI "ListSnapshots" gRPC call if the driver supports + it. When restoring a volume from this snapshot, the size of the + volume MUST NOT be smaller than the restoreSize if it is specified, + otherwise the restoration will fail. If not specified, it indicates + that the size is unknown. + format: int64 + minimum: 0 + type: integer + snapshotHandle: + description: snapshotHandle is the CSI "snapshot_id" of a snapshot + on the underlying storage system. If not specified, it indicates + that dynamic snapshot creation has either failed or it is still + in progress. + type: string + volumeGroupSnapshotContentName: + description: VolumeGroupSnapshotContentName is the name of the VolumeGroupSnapshotContent + of which this VolumeSnapshotContent is a part of. + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: { } + - additionalPrinterColumns: + - description: Indicates if the snapshot is ready to be used to restore a volume. + jsonPath: .status.readyToUse + name: ReadyToUse + type: boolean + - description: Represents the complete size of the snapshot in bytes + jsonPath: .status.restoreSize + name: RestoreSize + type: integer + - description: Determines whether this VolumeSnapshotContent and its physical snapshot on the underlying storage system should be deleted when its bound VolumeSnapshot is deleted. + jsonPath: .spec.deletionPolicy + name: DeletionPolicy + type: string + - description: Name of the CSI driver used to create the physical snapshot on the underlying storage system. + jsonPath: .spec.driver + name: Driver + type: string + - description: Name of the VolumeSnapshotClass to which this snapshot belongs. + jsonPath: .spec.volumeSnapshotClassName + name: VolumeSnapshotClass + type: string + - description: Name of the VolumeSnapshot object to which this VolumeSnapshotContent object is bound. + jsonPath: .spec.volumeSnapshotRef.name + name: VolumeSnapshot + type: string + - description: Namespace of the VolumeSnapshot object to which this VolumeSnapshotContent object is bound. + jsonPath: .spec.volumeSnapshotRef.namespace + name: VolumeSnapshotNamespace + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + # This indicates the v1beta1 version of the custom resource is deprecated. + # API requests to this version receive a warning in the server response. + deprecated: true + # This overrides the default warning returned to clients making v1beta1 API requests. + deprecationWarning: "snapshot.storage.k8s.io/v1beta1 VolumeSnapshotContent is deprecated; use snapshot.storage.k8s.io/v1 VolumeSnapshotContent" + schema: + openAPIV3Schema: + description: VolumeSnapshotContent represents the actual "on-disk" snapshot object in the underlying storage system + 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 + spec: + description: spec defines properties of a VolumeSnapshotContent created by the underlying storage system. Required. + properties: + deletionPolicy: + description: deletionPolicy determines whether this VolumeSnapshotContent and its physical snapshot on the underlying storage system should be deleted when its bound VolumeSnapshot is deleted. Supported values are "Retain" and "Delete". "Retain" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are kept. "Delete" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are deleted. For dynamically provisioned snapshots, this field will automatically be filled in by the CSI snapshotter sidecar with the "DeletionPolicy" field defined in the corresponding VolumeSnapshotClass. For pre-existing snapshots, users MUST specify this field when creating the VolumeSnapshotContent object. Required. + enum: + - Delete + - Retain + type: string + driver: + description: driver is the name of the CSI driver used to create the physical snapshot on the underlying storage system. This MUST be the same as the name returned by the CSI GetPluginName() call for that driver. Required. + type: string + source: + description: source specifies whether the snapshot is (or should be) dynamically provisioned or already exists, and just requires a Kubernetes object representation. This field is immutable after creation. Required. + properties: + snapshotHandle: + description: snapshotHandle specifies the CSI "snapshot_id" of a pre-existing snapshot on the underlying storage system for which a Kubernetes object representation was (or should be) created. This field is immutable. + type: string + volumeHandle: + description: volumeHandle specifies the CSI "volume_id" of the volume from which a snapshot should be dynamically taken from. This field is immutable. + type: string + type: object + volumeSnapshotClassName: + description: name of the VolumeSnapshotClass from which this snapshot was (or will be) created. Note that after provisioning, the VolumeSnapshotClass may be deleted or recreated with different set of values, and as such, should not be referenced post-snapshot creation. + type: string + volumeSnapshotRef: + description: volumeSnapshotRef specifies the VolumeSnapshot object to which this VolumeSnapshotContent object is bound. VolumeSnapshot.Spec.VolumeSnapshotContentName field must reference to this VolumeSnapshotContent's name for the bidirectional binding to be valid. For a pre-existing VolumeSnapshotContent object, name and namespace of the VolumeSnapshot object MUST be provided for binding to happen. This field is immutable after creation. Required. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: 'If referring to a piece of an object instead of an entire object, this string should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. For example, if the object reference is to a container within a pod, this would take on a value like: "spec.containers{name}" (where "name" refers to the name of the container that triggered the event) or if no container name is specified "spec.containers[2]" (container with index 2 in this pod). This syntax is chosen only to have some well-defined way of referencing a part of an object. TODO: this design is not final and this field is subject to change in the future.' + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: 'Specific resourceVersion to which this reference is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + required: + - deletionPolicy + - driver + - source + - volumeSnapshotRef + type: object + status: + description: status represents the current information of a snapshot. + properties: + creationTime: + description: creationTime is the timestamp when the point-in-time snapshot is taken by the underlying storage system. In dynamic snapshot creation case, this field will be filled in by the CSI snapshotter sidecar with the "creation_time" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "creation_time" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. If not specified, it indicates the creation time is unknown. The format of this field is a Unix nanoseconds time encoded as an int64. On Unix, the command `date +%s%N` returns the current time in nanoseconds since 1970-01-01 00:00:00 UTC. + format: int64 + type: integer + error: + description: error is the last observed error during snapshot creation, if any. Upon success after retry, this error field will be cleared. + properties: + message: + description: 'message is a string detailing the encountered error during snapshot creation if specified. NOTE: message may be logged, and it should not contain sensitive information.' + type: string + time: + description: time is the timestamp when the error was encountered. + format: date-time + type: string + type: object + readyToUse: + description: readyToUse indicates if a snapshot is ready to be used to restore a volume. In dynamic snapshot creation case, this field will be filled in by the CSI snapshotter sidecar with the "ready_to_use" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "ready_to_use" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it, otherwise, this field will be set to "True". If not specified, it means the readiness of a snapshot is unknown. + type: boolean + restoreSize: + description: restoreSize represents the complete size of the snapshot in bytes. In dynamic snapshot creation case, this field will be filled in by the CSI snapshotter sidecar with the "size_bytes" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "size_bytes" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. When restoring a volume from this snapshot, the size of the volume MUST NOT be smaller than the restoreSize if it is specified, otherwise the restoration will fail. If not specified, it indicates that the size is unknown. + format: int64 + minimum: 0 + type: integer + snapshotHandle: + description: snapshotHandle is the CSI "snapshot_id" of a snapshot on the underlying storage system. If not specified, it indicates that dynamic snapshot creation has either failed or it is still in progress. + type: string + type: object + required: + - spec + type: object + served: false + storage: false + subresources: + status: { } +status: + acceptedNames: + kind: "" + plural: "" + conditions: [ ] + storedVersions: [ ] +{{- end }} diff --git a/helm/openebs/charts/lvm-localpv/templates/volumesnapshots-crd.yaml b/helm/openebs/charts/lvm-localpv/templates/volumesnapshots-crd.yaml new file mode 100644 index 0000000..b303fa9 --- /dev/null +++ b/helm/openebs/charts/lvm-localpv/templates/volumesnapshots-crd.yaml @@ -0,0 +1,314 @@ +{{- if .Values.crd.volumeSnapshot }} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.11.3 + api-approved.kubernetes.io: "https://github.com/kubernetes-csi/external-snapshotter/pull/814" + creationTimestamp: null + name: volumesnapshots.snapshot.storage.k8s.io +spec: + group: snapshot.storage.k8s.io + names: + kind: VolumeSnapshot + listKind: VolumeSnapshotList + plural: volumesnapshots + shortNames: + - vs + singular: volumesnapshot + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Indicates if the snapshot is ready to be used to restore a volume. + jsonPath: .status.readyToUse + name: ReadyToUse + type: boolean + - description: If a new snapshot needs to be created, this contains the name of + the source PVC from which this snapshot was (or will be) created. + jsonPath: .spec.source.persistentVolumeClaimName + name: SourcePVC + type: string + - description: If a snapshot already exists, this contains the name of the existing + VolumeSnapshotContent object representing the existing snapshot. + jsonPath: .spec.source.volumeSnapshotContentName + name: SourceSnapshotContent + type: string + - description: Represents the minimum size of volume required to rehydrate from + this snapshot. + jsonPath: .status.restoreSize + name: RestoreSize + type: string + - description: The name of the VolumeSnapshotClass requested by the VolumeSnapshot. + jsonPath: .spec.volumeSnapshotClassName + name: SnapshotClass + type: string + - description: Name of the VolumeSnapshotContent object to which the VolumeSnapshot + object intends to bind to. Please note that verification of binding actually + requires checking both VolumeSnapshot and VolumeSnapshotContent to ensure + both are pointing at each other. Binding MUST be verified prior to usage of + this object. + jsonPath: .status.boundVolumeSnapshotContentName + name: SnapshotContent + type: string + - description: Timestamp when the point-in-time snapshot was taken by the underlying + storage system. + jsonPath: .status.creationTime + name: CreationTime + type: date + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: VolumeSnapshot is a user's request for either creating a point-in-time + snapshot of a persistent volume, or binding to a pre-existing snapshot. + 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 + spec: + description: 'spec defines the desired characteristics of a snapshot requested + by a user. More info: https://kubernetes.io/docs/concepts/storage/volume-snapshots#volumesnapshots + Required.' + properties: + source: + description: source specifies where a snapshot will be created from. + This field is immutable after creation. Required. + properties: + persistentVolumeClaimName: + description: persistentVolumeClaimName specifies the name of the + PersistentVolumeClaim object representing the volume from which + a snapshot should be created. This PVC is assumed to be in the + same namespace as the VolumeSnapshot object. This field should + be set if the snapshot does not exists, and needs to be created. + This field is immutable. + type: string + volumeSnapshotContentName: + description: volumeSnapshotContentName specifies the name of a + pre-existing VolumeSnapshotContent object representing an existing + volume snapshot. This field should be set if the snapshot already + exists and only needs a representation in Kubernetes. This field + is immutable. + type: string + type: object + oneOf: + - required: ["persistentVolumeClaimName"] + - required: ["volumeSnapshotContentName"] + volumeSnapshotClassName: + description: 'VolumeSnapshotClassName is the name of the VolumeSnapshotClass + requested by the VolumeSnapshot. VolumeSnapshotClassName may be + left nil to indicate that the default SnapshotClass should be used. + A given cluster may have multiple default Volume SnapshotClasses: + one default per CSI Driver. If a VolumeSnapshot does not specify + a SnapshotClass, VolumeSnapshotSource will be checked to figure + out what the associated CSI Driver is, and the default VolumeSnapshotClass + associated with that CSI Driver will be used. If more than one VolumeSnapshotClass + exist for a given CSI Driver and more than one have been marked + as default, CreateSnapshot will fail and generate an event. Empty + string is not allowed for this field.' + type: string + required: + - source + type: object + status: + description: status represents the current information of a snapshot. + Consumers must verify binding between VolumeSnapshot and VolumeSnapshotContent + objects is successful (by validating that both VolumeSnapshot and VolumeSnapshotContent + point at each other) before using this object. + properties: + boundVolumeSnapshotContentName: + description: 'boundVolumeSnapshotContentName is the name of the VolumeSnapshotContent + object to which this VolumeSnapshot object intends to bind to. If + not specified, it indicates that the VolumeSnapshot object has not + been successfully bound to a VolumeSnapshotContent object yet. NOTE: + To avoid possible security issues, consumers must verify binding + between VolumeSnapshot and VolumeSnapshotContent objects is successful + (by validating that both VolumeSnapshot and VolumeSnapshotContent + point at each other) before using this object.' + type: string + creationTime: + description: creationTime is the timestamp when the point-in-time + snapshot is taken by the underlying storage system. In dynamic snapshot + creation case, this field will be filled in by the snapshot controller + with the "creation_time" value returned from CSI "CreateSnapshot" + gRPC call. For a pre-existing snapshot, this field will be filled + with the "creation_time" value returned from the CSI "ListSnapshots" + gRPC call if the driver supports it. If not specified, it may indicate + that the creation time of the snapshot is unknown. + format: date-time + type: string + error: + description: error is the last observed error during snapshot creation, + if any. This field could be helpful to upper level controllers(i.e., + application controller) to decide whether they should continue on + waiting for the snapshot to be created based on the type of error + reported. The snapshot controller will keep retrying when an error + occurs during the snapshot creation. Upon success, this error field + will be cleared. + properties: + message: + description: 'message is a string detailing the encountered error + during snapshot creation if specified. NOTE: message may be + logged, and it should not contain sensitive information.' + type: string + time: + description: time is the timestamp when the error was encountered. + format: date-time + type: string + type: object + readyToUse: + description: readyToUse indicates if the snapshot is ready to be used + to restore a volume. In dynamic snapshot creation case, this field + will be filled in by the snapshot controller with the "ready_to_use" + value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing + snapshot, this field will be filled with the "ready_to_use" value + returned from the CSI "ListSnapshots" gRPC call if the driver supports + it, otherwise, this field will be set to "True". If not specified, + it means the readiness of a snapshot is unknown. + type: boolean + restoreSize: + type: string + description: restoreSize represents the minimum size of volume required + to create a volume from this snapshot. In dynamic snapshot creation + case, this field will be filled in by the snapshot controller with + the "size_bytes" value returned from CSI "CreateSnapshot" gRPC call. + For a pre-existing snapshot, this field will be filled with the + "size_bytes" value returned from the CSI "ListSnapshots" gRPC call + if the driver supports it. When restoring a volume from this snapshot, + the size of the volume MUST NOT be smaller than the restoreSize + if it is specified, otherwise the restoration will fail. If not + specified, it indicates that the size is unknown. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + volumeGroupSnapshotName: + description: VolumeGroupSnapshotName is the name of the VolumeGroupSnapshot + of which this VolumeSnapshot is a part of. + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} + - additionalPrinterColumns: + - description: Indicates if the snapshot is ready to be used to restore a volume. + jsonPath: .status.readyToUse + name: ReadyToUse + type: boolean + - description: If a new snapshot needs to be created, this contains the name of the source PVC from which this snapshot was (or will be) created. + jsonPath: .spec.source.persistentVolumeClaimName + name: SourcePVC + type: string + - description: If a snapshot already exists, this contains the name of the existing VolumeSnapshotContent object representing the existing snapshot. + jsonPath: .spec.source.volumeSnapshotContentName + name: SourceSnapshotContent + type: string + - description: Represents the minimum size of volume required to rehydrate from this snapshot. + jsonPath: .status.restoreSize + name: RestoreSize + type: string + - description: The name of the VolumeSnapshotClass requested by the VolumeSnapshot. + jsonPath: .spec.volumeSnapshotClassName + name: SnapshotClass + type: string + - description: Name of the VolumeSnapshotContent object to which the VolumeSnapshot object intends to bind to. Please note that verification of binding actually requires checking both VolumeSnapshot and VolumeSnapshotContent to ensure both are pointing at each other. Binding MUST be verified prior to usage of this object. + jsonPath: .status.boundVolumeSnapshotContentName + name: SnapshotContent + type: string + - description: Timestamp when the point-in-time snapshot was taken by the underlying storage system. + jsonPath: .status.creationTime + name: CreationTime + type: date + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + # This indicates the v1beta1 version of the custom resource is deprecated. + # API requests to this version receive a warning in the server response. + deprecated: true + # This overrides the default warning returned to clients making v1beta1 API requests. + deprecationWarning: "snapshot.storage.k8s.io/v1beta1 VolumeSnapshot is deprecated; use snapshot.storage.k8s.io/v1 VolumeSnapshot" + schema: + openAPIV3Schema: + description: VolumeSnapshot is a user's request for either creating a point-in-time snapshot of a persistent volume, or binding to a pre-existing snapshot. + 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 + spec: + description: 'spec defines the desired characteristics of a snapshot requested by a user. More info: https://kubernetes.io/docs/concepts/storage/volume-snapshots#volumesnapshots Required.' + properties: + source: + description: source specifies where a snapshot will be created from. This field is immutable after creation. Required. + properties: + persistentVolumeClaimName: + description: persistentVolumeClaimName specifies the name of the PersistentVolumeClaim object representing the volume from which a snapshot should be created. This PVC is assumed to be in the same namespace as the VolumeSnapshot object. This field should be set if the snapshot does not exists, and needs to be created. This field is immutable. + type: string + volumeSnapshotContentName: + description: volumeSnapshotContentName specifies the name of a pre-existing VolumeSnapshotContent object representing an existing volume snapshot. This field should be set if the snapshot already exists and only needs a representation in Kubernetes. This field is immutable. + type: string + type: object + volumeSnapshotClassName: + description: 'VolumeSnapshotClassName is the name of the VolumeSnapshotClass requested by the VolumeSnapshot. VolumeSnapshotClassName may be left nil to indicate that the default SnapshotClass should be used. A given cluster may have multiple default Volume SnapshotClasses: one default per CSI Driver. If a VolumeSnapshot does not specify a SnapshotClass, VolumeSnapshotSource will be checked to figure out what the associated CSI Driver is, and the default VolumeSnapshotClass associated with that CSI Driver will be used. If more than one VolumeSnapshotClass exist for a given CSI Driver and more than one have been marked as default, CreateSnapshot will fail and generate an event. Empty string is not allowed for this field.' + type: string + required: + - source + type: object + status: + description: status represents the current information of a snapshot. Consumers must verify binding between VolumeSnapshot and VolumeSnapshotContent objects is successful (by validating that both VolumeSnapshot and VolumeSnapshotContent point at each other) before using this object. + properties: + boundVolumeSnapshotContentName: + description: 'boundVolumeSnapshotContentName is the name of the VolumeSnapshotContent object to which this VolumeSnapshot object intends to bind to. If not specified, it indicates that the VolumeSnapshot object has not been successfully bound to a VolumeSnapshotContent object yet. NOTE: To avoid possible security issues, consumers must verify binding between VolumeSnapshot and VolumeSnapshotContent objects is successful (by validating that both VolumeSnapshot and VolumeSnapshotContent point at each other) before using this object.' + type: string + creationTime: + description: creationTime is the timestamp when the point-in-time snapshot is taken by the underlying storage system. In dynamic snapshot creation case, this field will be filled in by the snapshot controller with the "creation_time" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "creation_time" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. If not specified, it may indicate that the creation time of the snapshot is unknown. + format: date-time + type: string + error: + description: error is the last observed error during snapshot creation, if any. This field could be helpful to upper level controllers(i.e., application controller) to decide whether they should continue on waiting for the snapshot to be created based on the type of error reported. The snapshot controller will keep retrying when an error occurs during the snapshot creation. Upon success, this error field will be cleared. + properties: + message: + description: 'message is a string detailing the encountered error during snapshot creation if specified. NOTE: message may be logged, and it should not contain sensitive information.' + type: string + time: + description: time is the timestamp when the error was encountered. + format: date-time + type: string + type: object + readyToUse: + description: readyToUse indicates if the snapshot is ready to be used to restore a volume. In dynamic snapshot creation case, this field will be filled in by the snapshot controller with the "ready_to_use" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "ready_to_use" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it, otherwise, this field will be set to "True". If not specified, it means the readiness of a snapshot is unknown. + type: boolean + restoreSize: + type: string + description: restoreSize represents the minimum size of volume required to create a volume from this snapshot. In dynamic snapshot creation case, this field will be filled in by the snapshot controller with the "size_bytes" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "size_bytes" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. When restoring a volume from this snapshot, the size of the volume MUST NOT be smaller than the restoreSize if it is specified, otherwise the restoration will fail. If not specified, it indicates that the size is unknown. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + required: + - spec + type: object + served: false + storage: false + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] +{{- end }} diff --git a/helm/openebs/charts/lvm-localpv/values.yaml b/helm/openebs/charts/lvm-localpv/values.yaml new file mode 100644 index 0000000..f6c4da6 --- /dev/null +++ b/helm/openebs/charts/lvm-localpv/values.yaml @@ -0,0 +1,188 @@ +# Default values for openebs-lvmlocalpv. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. +release: + version: "1.3.0" + +imagePullSecrets: +# - name: "image-pull-secret" + +# enable storage capacity tracking feature +# Ref: https://kubernetes:io/docs/concepts/storage/storage-capacity +storageCapacity: true + +rbac: + # rbac.pspEnabled: `true` if PodSecurityPolicy resources should be created + pspEnabled: false + +# lvmNode contains the configurables for +# the lvm node daemonset +lvmNode: + componentName: openebs-lvm-node + driverRegistrar: + name: "csi-node-driver-registrar" + image: + # Make sure that registry name end with a '/'. + # For example : registry.k8s.io/ is a correct value here and quay.io is incorrect + registry: registry.k8s.io/ + repository: sig-storage/csi-node-driver-registrar + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: v2.8.0 + updateStrategy: + type: RollingUpdate + annotations: {} + podAnnotations: {} + # This can be configured to run on various different k8s distributions like + # microk8s where kubelet dir is different + kubeletDir: "/var/lib/kubelet/" + resources: {} +# limits: +# cpu: 10m +# memory: 32Mi +# requests: +# cpu: 10m +# memory: 32Mi + ## Labels to be added to openebs-lvm node pods + podLabels: + app: openebs-lvm-node + nodeSelector: {} + tolerations: [] + securityContext: {} + labels: {} + priorityClass: + create: true + name: lvm-localpv-csi-node-critical + logLevel: 5 + # Configure kubernetes client API requests rate. + kubeClientRateLimiter: + # Configure the number of queries per second. + qps: 0 + # Configure the maximum number of queries allowed after + # accounting for rolled over qps from previous seconds. + burst: 0 + + +# lvmController contains the configurables for +# the lvm controller statefulset +lvmController: + componentName: openebs-lvm-controller + replicas: 1 + serviceName: openebs-lvm + logLevel: 5 + resizer: + name: "csi-resizer" + image: + # Make sure that registry name end with a '/'. + # For example : registry.k8s.io/ is a correct value here and quay.io is incorrect + registry: registry.k8s.io/ + repository: sig-storage/csi-resizer + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: v1.8.0 + snapshotter: + name: "csi-snapshotter" + image: + # Make sure that registry name end with a '/'. + # For example : registry.k8s.io/ is a correct value here and quay.io is incorrect + registry: registry.k8s.io/ + repository: sig-storage/csi-snapshotter + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: v6.2.2 + snapshotController: + name: "snapshot-controller" + image: + # Make sure that registry name end with a '/'. + # For example : registry.k8s.io/ is a correct value here and quay.io is incorrect + registry: registry.k8s.io/ + repository: sig-storage/snapshot-controller + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: v6.2.2 + provisioner: + name: "csi-provisioner" + image: + # Make sure that registry name end with a '/'. + # For example : registry.k8s.io/ is a correct value here and quay.io is incorrect + registry: registry.k8s.io/ + repository: sig-storage/csi-provisioner + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: v3.5.0 + updateStrategy: + type: RollingUpdate + annotations: {} + podAnnotations: {} + resources: {} +# limits: +# cpu: 10m +# memory: 32Mi +# requests: +# cpu: 10m +# memory: 32Mi + ## Labels to be added to openebs-lvm controller pods + podLabels: + name: openebs-lvm-controller + nodeSelector: {} + tolerations: [] + securityContext: {} + priorityClass: + create: true + name: lvm-localpv-csi-controller-critical + # Configure kubernetes client API requests rate. + kubeClientRateLimiter: + # Configure the number of queries per second. + qps: 0 + # Configure the maximum number of queries allowed after + # accounting for rolled over qps from previous seconds. + burst: 0 + +# lvmPlugin is the common csi container used by the +# controller statefulset and node daemonset +lvmPlugin: + name: "openebs-lvm-plugin" + image: + # Make sure that registry name end with a '/'. + # For example : registry.k8s.io/ is a correct value here and quay.io is incorrect + registry: + repository: openebs/lvm-driver + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: 1.3.0 + ioLimits: + enabled: false + containerRuntime: containerd + readIopsPerGB: "" + writeIopsPerGB: "" + # The TCP port number used for exposing lvm-metrics. + # If not set, service will not be created to expose metrics endpoint + # to serviceMonitor andlisten-address flag will not be set. + metricsPort: 9500 + # Comma seperated list of k8s worker node topologies + allowedTopologies: "kubernetes.io/hostname," + +role: openebs-lvm + +crd: + enableInstall: true + # Specify installation of the kubernetes-csi volume snapshot CRDs if your Kubernetes distribution + # or another storage operator already manages them. + volumeSnapshot: true + +serviceAccount: + lvmController: + # Specifies whether a service account should be created + create: true + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: openebs-lvm-controller-sa + lvmNode: + # Specifies whether a service account should be created + create: true + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: openebs-lvm-node-sa + +analytics: + enabled: true diff --git a/helm/openebs/charts/mayastor/.helmignore b/helm/openebs/charts/mayastor/.helmignore new file mode 100644 index 0000000..7ba69a7 --- /dev/null +++ b/helm/openebs/charts/mayastor/.helmignore @@ -0,0 +1,24 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ +*.md diff --git a/helm/openebs/charts/mayastor/Chart.lock b/helm/openebs/charts/mayastor/Chart.lock new file mode 100644 index 0000000..a204cbf --- /dev/null +++ b/helm/openebs/charts/mayastor/Chart.lock @@ -0,0 +1,18 @@ +dependencies: +- name: etcd + repository: https://charts.bitnami.com/bitnami + version: 8.6.0 +- name: jaeger-operator + repository: https://jaegertracing.github.io/helm-charts + version: 2.25.0 +- name: loki-stack + repository: https://grafana.github.io/helm-charts + version: 2.6.4 +- name: nats + repository: https://nats-io.github.io/k8s/helm/charts/ + version: 0.19.14 +- name: localpv-provisioner + repository: https://openebs.github.io/dynamic-localpv-provisioner + version: 3.4.1 +digest: sha256:0a43736883b9088fad4cd9e013abc88a470fb9d0e5cba50ce63c98172522a3fc +generated: "2023-09-05T10:04:06.785720699Z" diff --git a/helm/openebs/charts/mayastor/Chart.yaml b/helm/openebs/charts/mayastor/Chart.yaml new file mode 100644 index 0000000..ac48519 --- /dev/null +++ b/helm/openebs/charts/mayastor/Chart.yaml @@ -0,0 +1,26 @@ +apiVersion: v2 +appVersion: 2.4.0 +dependencies: +- name: etcd + repository: https://charts.bitnami.com/bitnami + version: 8.6.0 +- condition: base.jaeger.enabled + name: jaeger-operator + repository: https://jaegertracing.github.io/helm-charts + version: 2.25.0 +- condition: loki-stack.enabled + name: loki-stack + repository: https://grafana.github.io/helm-charts + version: 2.6.4 +- condition: eventing.enabled + name: nats + repository: https://nats-io.github.io/k8s/helm/charts/ + version: 0.19.14 +- condition: localpv-provisioner.enabled + name: localpv-provisioner + repository: https://openebs.github.io/dynamic-localpv-provisioner + version: 3.4.1 +description: Mayastor Helm chart for Kubernetes +name: mayastor +type: application +version: 2.4.0 diff --git a/helm/openebs/charts/mayastor/README.md.tmpl b/helm/openebs/charts/mayastor/README.md.tmpl new file mode 100644 index 0000000..3092c02 --- /dev/null +++ b/helm/openebs/charts/mayastor/README.md.tmpl @@ -0,0 +1,58 @@ +{{ template "chart.header" . }} +{{ template "chart.description" . }} + +{{ template "chart.versionBadge" . }}{{ template "chart.typeBadge" . }}{{ template "chart.appVersionBadge" . }} + +## Installation Guide + +### Prerequisites + + - Make sure the [system requirement pre-requisites](https://mayastor.gitbook.io/introduction/quickstart/prerequisites) are met. + - Label the storage nodes same as the mayastor.nodeSelector in values.yaml + - Create the namespace you want the chart to be installed, or pass the `--create-namespace` flag in the `helm install` command. + ```sh + kubectl create ns + ``` + - Create secret if downloading the container images from a private repo. + ```sh + kubectl create secret docker-registry --docker-server="https://index.docker.io/v1/" --docker-username="" --docker-password="" --docker-email="" -n + ``` + +### Installing the chart via the git repo + +Clone the mayastor charts repo. +Sync the chart dependencies +```console +$ helm dependency update +``` +Install the mayastor chart using the command. +```console +$ helm install mayastor . -n +``` + +### Installing the Chart via Helm Registry + +To install the chart with the release name `my-release`: + +```console +$ helm repo add openebs https://openebs.github.io/mayastor-extensions/ +$ helm install my-release openebs/{{ template "chart.name" . }} +``` + +## Chart Dependencies + +{{ template "chart.requirementsTable" . }} + +{{ template "chart.valuesHeader" . }} + +| Key | Description | Default | +|-----|-------------|:-------:| +{{ range .Values }} +{{- if or .Description .AutoDescription -}} +{{ if eq .Type "object" -}} +| {{ .Key | replace "." ".​" }} | {{ .Description | default .AutoDescription }} |
{{ replace "}" "
}" (replace "{" "{
" (replace "," ",
" (toJson (fromJson (trimAll "`" (.Default | default .AutoDefault)))))) }}
| +{{ else -}} +| {{ .Key | replace "." ".​" }} | {{ .Description | default .AutoDescription }} | {{ .Default | default .AutoDefault }} | +{{ end -}} +{{ end }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/etcd/.helmignore b/helm/openebs/charts/mayastor/charts/etcd/.helmignore new file mode 100644 index 0000000..f0c1319 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/etcd/.helmignore @@ -0,0 +1,21 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*~ +# Various IDEs +.project +.idea/ +*.tmproj diff --git a/helm/openebs/charts/mayastor/charts/etcd/Chart.lock b/helm/openebs/charts/mayastor/charts/etcd/Chart.lock new file mode 100644 index 0000000..acaa152 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/etcd/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: common + repository: https://charts.bitnami.com/bitnami + version: 2.2.2 +digest: sha256:49ca75cf23ba5eb7df4becef52580f98c8bd8194eb80368b9d7b875f6eefa8e5 +generated: "2022-12-19T15:22:40.567625269Z" diff --git a/helm/openebs/charts/mayastor/charts/etcd/Chart.yaml b/helm/openebs/charts/mayastor/charts/etcd/Chart.yaml new file mode 100644 index 0000000..cb5c27a --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/etcd/Chart.yaml @@ -0,0 +1,29 @@ +annotations: + category: Database +apiVersion: v2 +appVersion: 3.5.6 +dependencies: +- name: common + repository: https://charts.bitnami.com/bitnami + tags: + - bitnami-common + version: 2.x.x +description: etcd is a distributed key-value store designed to securely store data + across a cluster. etcd is widely used in production on account of its reliability, + fault-tolerance and ease of use. +home: https://github.com/bitnami/charts/tree/main/bitnami/etcd +icon: https://bitnami.com/assets/stacks/etcd/img/etcd-stack-220x234.png +keywords: +- etcd +- cluster +- database +- cache +- key-value +maintainers: +- name: Bitnami + url: https://github.com/bitnami/charts +name: etcd +sources: +- https://github.com/bitnami/containers/tree/main/bitnami/etcd +- https://coreos.com/etcd/ +version: 8.6.0 diff --git a/helm/openebs/charts/mayastor/charts/etcd/README.md b/helm/openebs/charts/mayastor/charts/etcd/README.md new file mode 100644 index 0000000..59c1a2a --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/etcd/README.md @@ -0,0 +1,545 @@ + + +# Etcd packaged by Bitnami + +etcd is a distributed key-value store designed to securely store data across a cluster. etcd is widely used in production on account of its reliability, fault-tolerance and ease of use. + +[Overview of Etcd](https://etcd.io/) + +Trademarks: This software listing is packaged by Bitnami. The respective trademarks mentioned in the offering are owned by the respective companies, and use of them does not imply any affiliation or endorsement. + +## TL;DR + +```console +$ helm repo add my-repo https://charts.bitnami.com/bitnami +$ helm install my-release my-repo/etcd +``` + +## Introduction + +This chart bootstraps a [etcd](https://github.com/bitnami/containers/tree/main/bitnami/etcd) deployment on a [Kubernetes](https://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. + +Bitnami charts can be used with [Kubeapps](https://kubeapps.dev/) for deployment and management of Helm Charts in clusters. + +## Prerequisites + +- Kubernetes 1.19+ +- Helm 3.2.0+ +- PV provisioner support in the underlying infrastructure + +## Installing the Chart + +To install the chart with the release name `my-release`: + +```console +$ helm repo add my-repo https://charts.bitnami.com/bitnami +$ helm install my-release my-repo/etcd +``` + +These commands deploy etcd on the Kubernetes cluster in the default configuration. The [Parameters](#parameters) section lists the parameters that can be configured during installation. + +> **Tip**: List all releases using `helm list` + +## Uninstalling the Chart + +To uninstall/delete the `my-release` deployment: + +```console +$ helm delete my-release +``` + +The command removes all the Kubernetes components associated with the chart and deletes the release. + +## Parameters + +### Global parameters + +| Name | Description | Value | +| ------------------------- | ----------------------------------------------- | ----- | +| `global.imageRegistry` | Global Docker image registry | `""` | +| `global.imagePullSecrets` | Global Docker registry secret names as an array | `[]` | +| `global.storageClass` | Global StorageClass for Persistent Volume(s) | `""` | + + +### Common parameters + +| Name | Description | Value | +| ------------------------ | -------------------------------------------------------------------------------------------- | --------------- | +| `kubeVersion` | Force target Kubernetes version (using Helm capabilities if not set) | `""` | +| `nameOverride` | String to partially override common.names.fullname template (will maintain the release name) | `""` | +| `fullnameOverride` | String to fully override common.names.fullname template | `""` | +| `commonLabels` | Labels to add to all deployed objects | `{}` | +| `commonAnnotations` | Annotations to add to all deployed objects | `{}` | +| `clusterDomain` | Default Kubernetes cluster domain | `cluster.local` | +| `extraDeploy` | Array of extra objects to deploy with the release | `[]` | +| `diagnosticMode.enabled` | Enable diagnostic mode (all probes will be disabled and the command will be overridden) | `false` | +| `diagnosticMode.command` | Command to override all containers in the deployment | `["sleep"]` | +| `diagnosticMode.args` | Args to override all containers in the deployment | `["infinity"]` | + + +### etcd parameters + +| Name | Description | Value | +| -------------------------------------- | ----------------------------------------------------------------------------------------------------------- | --------------------- | +| `image.registry` | etcd image registry | `docker.io` | +| `image.repository` | etcd image name | `bitnami/etcd` | +| `image.tag` | etcd image tag | `3.5.6-debian-11-r10` | +| `image.digest` | etcd image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag | `""` | +| `image.pullPolicy` | etcd image pull policy | `IfNotPresent` | +| `image.pullSecrets` | etcd image pull secrets | `[]` | +| `image.debug` | Enable image debug mode | `false` | +| `auth.rbac.create` | Switch to enable RBAC authentication | `true` | +| `auth.rbac.allowNoneAuthentication` | Allow to use etcd without configuring RBAC authentication | `true` | +| `auth.rbac.rootPassword` | Root user password. The root user is always `root` | `""` | +| `auth.rbac.existingSecret` | Name of the existing secret containing credentials for the root user | `""` | +| `auth.rbac.existingSecretPasswordKey` | Name of key containing password to be retrieved from the existing secret | `""` | +| `auth.token.type` | Authentication token type. Allowed values: 'simple' or 'jwt' | `jwt` | +| `auth.token.privateKey.filename` | Name of the file containing the private key for signing the JWT token | `jwt-token.pem` | +| `auth.token.privateKey.existingSecret` | Name of the existing secret containing the private key for signing the JWT token | `""` | +| `auth.token.signMethod` | JWT token sign method | `RS256` | +| `auth.token.ttl` | JWT token TTL | `10m` | +| `auth.client.secureTransport` | Switch to encrypt client-to-server communications using TLS certificates | `false` | +| `auth.client.useAutoTLS` | Switch to automatically create the TLS certificates | `false` | +| `auth.client.existingSecret` | Name of the existing secret containing the TLS certificates for client-to-server communications | `""` | +| `auth.client.enableAuthentication` | Switch to enable host authentication using TLS certificates. Requires existing secret | `false` | +| `auth.client.certFilename` | Name of the file containing the client certificate | `cert.pem` | +| `auth.client.certKeyFilename` | Name of the file containing the client certificate private key | `key.pem` | +| `auth.client.caFilename` | Name of the file containing the client CA certificate | `""` | +| `auth.peer.secureTransport` | Switch to encrypt server-to-server communications using TLS certificates | `false` | +| `auth.peer.useAutoTLS` | Switch to automatically create the TLS certificates | `false` | +| `auth.peer.existingSecret` | Name of the existing secret containing the TLS certificates for server-to-server communications | `""` | +| `auth.peer.enableAuthentication` | Switch to enable host authentication using TLS certificates. Requires existing secret | `false` | +| `auth.peer.certFilename` | Name of the file containing the peer certificate | `cert.pem` | +| `auth.peer.certKeyFilename` | Name of the file containing the peer certificate private key | `key.pem` | +| `auth.peer.caFilename` | Name of the file containing the peer CA certificate | `""` | +| `autoCompactionMode` | Auto compaction mode, by default periodic. Valid values: "periodic", "revision". | `""` | +| `autoCompactionRetention` | Auto compaction retention for mvcc key value store in hour, by default 0, means disabled | `""` | +| `initialClusterState` | Initial cluster state. Allowed values: 'new' or 'existing' | `""` | +| `logLevel` | Sets the log level for the etcd process. Allowed values: 'debug', 'info', 'warn', 'error', 'panic', 'fatal' | `info` | +| `maxProcs` | Limits the number of operating system threads that can execute user-level | `""` | +| `removeMemberOnContainerTermination` | Use a PreStop hook to remove the etcd members from the etcd cluster on container termination | `true` | +| `configuration` | etcd configuration. Specify content for etcd.conf.yml | `""` | +| `existingConfigmap` | Existing ConfigMap with etcd configuration | `""` | +| `extraEnvVars` | Extra environment variables to be set on etcd container | `[]` | +| `extraEnvVarsCM` | Name of existing ConfigMap containing extra env vars | `""` | +| `extraEnvVarsSecret` | Name of existing Secret containing extra env vars | `""` | +| `command` | Default container command (useful when using custom images) | `[]` | +| `args` | Default container args (useful when using custom images) | `[]` | + + +### etcd statefulset parameters + +| Name | Description | Value | +| --------------------------------------------------- | ----------------------------------------------------------------------------------------- | --------------- | +| `replicaCount` | Number of etcd replicas to deploy | `1` | +| `updateStrategy.type` | Update strategy type, can be set to RollingUpdate or OnDelete. | `RollingUpdate` | +| `podManagementPolicy` | Pod management policy for the etcd statefulset | `Parallel` | +| `hostAliases` | etcd pod host aliases | `[]` | +| `lifecycleHooks` | Override default etcd container hooks | `{}` | +| `containerPorts.client` | Client port to expose at container level | `2379` | +| `containerPorts.peer` | Peer port to expose at container level | `2380` | +| `podSecurityContext.enabled` | Enabled etcd pods' Security Context | `true` | +| `podSecurityContext.fsGroup` | Set etcd pod's Security Context fsGroup | `1001` | +| `containerSecurityContext.enabled` | Enabled etcd containers' Security Context | `true` | +| `containerSecurityContext.runAsUser` | Set etcd container's Security Context runAsUser | `1001` | +| `containerSecurityContext.runAsNonRoot` | Set etcd container's Security Context runAsNonRoot | `true` | +| `containerSecurityContext.allowPrivilegeEscalation` | Force the child process to be run as nonprivilege | `false` | +| `resources.limits` | The resources limits for the etcd container | `{}` | +| `resources.requests` | The requested resources for the etcd container | `{}` | +| `livenessProbe.enabled` | Enable livenessProbe | `true` | +| `livenessProbe.initialDelaySeconds` | Initial delay seconds for livenessProbe | `60` | +| `livenessProbe.periodSeconds` | Period seconds for livenessProbe | `30` | +| `livenessProbe.timeoutSeconds` | Timeout seconds for livenessProbe | `5` | +| `livenessProbe.failureThreshold` | Failure threshold for livenessProbe | `5` | +| `livenessProbe.successThreshold` | Success threshold for livenessProbe | `1` | +| `readinessProbe.enabled` | Enable readinessProbe | `true` | +| `readinessProbe.initialDelaySeconds` | Initial delay seconds for readinessProbe | `60` | +| `readinessProbe.periodSeconds` | Period seconds for readinessProbe | `10` | +| `readinessProbe.timeoutSeconds` | Timeout seconds for readinessProbe | `5` | +| `readinessProbe.failureThreshold` | Failure threshold for readinessProbe | `5` | +| `readinessProbe.successThreshold` | Success threshold for readinessProbe | `1` | +| `startupProbe.enabled` | Enable startupProbe | `false` | +| `startupProbe.initialDelaySeconds` | Initial delay seconds for startupProbe | `0` | +| `startupProbe.periodSeconds` | Period seconds for startupProbe | `10` | +| `startupProbe.timeoutSeconds` | Timeout seconds for startupProbe | `5` | +| `startupProbe.failureThreshold` | Failure threshold for startupProbe | `60` | +| `startupProbe.successThreshold` | Success threshold for startupProbe | `1` | +| `customLivenessProbe` | Override default liveness probe | `{}` | +| `customReadinessProbe` | Override default readiness probe | `{}` | +| `customStartupProbe` | Override default startup probe | `{}` | +| `extraVolumes` | Optionally specify extra list of additional volumes for etcd pods | `[]` | +| `extraVolumeMounts` | Optionally specify extra list of additional volumeMounts for etcd container(s) | `[]` | +| `initContainers` | Add additional init containers to the etcd pods | `[]` | +| `sidecars` | Add additional sidecar containers to the etcd pods | `[]` | +| `podAnnotations` | Annotations for etcd pods | `{}` | +| `podLabels` | Extra labels for etcd pods | `{}` | +| `podAffinityPreset` | Pod affinity preset. Ignored if `affinity` is set. Allowed values: `soft` or `hard` | `""` | +| `podAntiAffinityPreset` | Pod anti-affinity preset. Ignored if `affinity` is set. Allowed values: `soft` or `hard` | `soft` | +| `nodeAffinityPreset.type` | Node affinity preset type. Ignored if `affinity` is set. Allowed values: `soft` or `hard` | `""` | +| `nodeAffinityPreset.key` | Node label key to match. Ignored if `affinity` is set. | `""` | +| `nodeAffinityPreset.values` | Node label values to match. Ignored if `affinity` is set. | `[]` | +| `affinity` | Affinity for pod assignment | `{}` | +| `nodeSelector` | Node labels for pod assignment | `{}` | +| `tolerations` | Tolerations for pod assignment | `[]` | +| `terminationGracePeriodSeconds` | Seconds the pod needs to gracefully terminate | `""` | +| `schedulerName` | Name of the k8s scheduler (other than default) | `""` | +| `priorityClassName` | Name of the priority class to be used by etcd pods | `""` | +| `runtimeClassName` | Name of the runtime class to be used by pod(s) | `""` | +| `shareProcessNamespace` | Enable shared process namespace in a pod. | `false` | +| `topologySpreadConstraints` | Topology Spread Constraints for pod assignment | `[]` | +| `persistentVolumeClaimRetentionPolicy.enabled` | Controls if and how PVCs are deleted during the lifecycle of a StatefulSet | `false` | +| `persistentVolumeClaimRetentionPolicy.whenScaled` | Volume retention behavior when the replica count of the StatefulSet is reduced | `Retain` | +| `persistentVolumeClaimRetentionPolicy.whenDeleted` | Volume retention behavior that applies when the StatefulSet is deleted | `Retain` | + + +### Traffic exposure parameters + +| Name | Description | Value | +| ---------------------------------- | ---------------------------------------------------------------------------------- | ----------- | +| `service.type` | Kubernetes Service type | `ClusterIP` | +| `service.enabled` | create second service if equal true | `true` | +| `service.clusterIP` | Kubernetes service Cluster IP | `""` | +| `service.ports.client` | etcd client port | `2379` | +| `service.ports.peer` | etcd peer port | `2380` | +| `service.nodePorts.client` | Specify the nodePort client value for the LoadBalancer and NodePort service types. | `""` | +| `service.nodePorts.peer` | Specify the nodePort peer value for the LoadBalancer and NodePort service types. | `""` | +| `service.clientPortNameOverride` | etcd client port name override | `""` | +| `service.peerPortNameOverride` | etcd peer port name override | `""` | +| `service.loadBalancerIP` | loadBalancerIP for the etcd service (optional, cloud specific) | `""` | +| `service.loadBalancerSourceRanges` | Load Balancer source ranges | `[]` | +| `service.externalIPs` | External IPs | `[]` | +| `service.externalTrafficPolicy` | %%MAIN_CONTAINER_NAME%% service external traffic policy | `Cluster` | +| `service.extraPorts` | Extra ports to expose (normally used with the `sidecar` value) | `[]` | +| `service.annotations` | Additional annotations for the etcd service | `{}` | +| `service.sessionAffinity` | Session Affinity for Kubernetes service, can be "None" or "ClientIP" | `None` | +| `service.sessionAffinityConfig` | Additional settings for the sessionAffinity | `{}` | + + +### Persistence parameters + +| Name | Description | Value | +| -------------------------- | --------------------------------------------------------------- | ------------------- | +| `persistence.enabled` | If true, use a Persistent Volume Claim. If false, use emptyDir. | `true` | +| `persistence.storageClass` | Persistent Volume Storage Class | `""` | +| `persistence.annotations` | Annotations for the PVC | `{}` | +| `persistence.accessModes` | Persistent Volume Access Modes | `["ReadWriteOnce"]` | +| `persistence.size` | PVC Storage Request for etcd data volume | `8Gi` | +| `persistence.selector` | Selector to match an existing Persistent Volume | `{}` | + + +### Volume Permissions parameters + +| Name | Description | Value | +| -------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | ----------------------- | +| `volumePermissions.enabled` | Enable init container that changes the owner and group of the persistent volume(s) mountpoint to `runAsUser:fsGroup` | `false` | +| `volumePermissions.image.registry` | Init container volume-permissions image registry | `docker.io` | +| `volumePermissions.image.repository` | Init container volume-permissions image name | `bitnami/bitnami-shell` | +| `volumePermissions.image.tag` | Init container volume-permissions image tag | `11-debian-11-r63` | +| `volumePermissions.image.digest` | Init container volume-permissions image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag | `""` | +| `volumePermissions.image.pullPolicy` | Init container volume-permissions image pull policy | `IfNotPresent` | +| `volumePermissions.image.pullSecrets` | Specify docker-registry secret names as an array | `[]` | +| `volumePermissions.resources.limits` | Init container volume-permissions resource limits | `{}` | +| `volumePermissions.resources.requests` | Init container volume-permissions resource requests | `{}` | + + +### Network Policy parameters + +| Name | Description | Value | +| --------------------------------------- | ---------------------------------------------------------- | ------- | +| `networkPolicy.enabled` | Enable creation of NetworkPolicy resources | `false` | +| `networkPolicy.allowExternal` | Don't require client label for connections | `true` | +| `networkPolicy.extraIngress` | Add extra ingress rules to the NetworkPolicy | `[]` | +| `networkPolicy.extraEgress` | Add extra ingress rules to the NetworkPolicy | `[]` | +| `networkPolicy.ingressNSMatchLabels` | Labels to match to allow traffic from other namespaces | `{}` | +| `networkPolicy.ingressNSPodMatchLabels` | Pod labels to match to allow traffic from other namespaces | `{}` | + + +### Metrics parameters + +| Name | Description | Value | +| ----------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | ------------ | +| `metrics.enabled` | Expose etcd metrics | `false` | +| `metrics.podAnnotations` | Annotations for the Prometheus metrics on etcd pods | `{}` | +| `metrics.podMonitor.enabled` | Create PodMonitor Resource for scraping metrics using PrometheusOperator | `false` | +| `metrics.podMonitor.namespace` | Namespace in which Prometheus is running | `monitoring` | +| `metrics.podMonitor.interval` | Specify the interval at which metrics should be scraped | `30s` | +| `metrics.podMonitor.scrapeTimeout` | Specify the timeout after which the scrape is ended | `30s` | +| `metrics.podMonitor.additionalLabels` | Additional labels that can be used so PodMonitors will be discovered by Prometheus | `{}` | +| `metrics.podMonitor.scheme` | Scheme to use for scraping | `http` | +| `metrics.podMonitor.tlsConfig` | TLS configuration used for scrape endpoints used by Prometheus | `{}` | +| `metrics.podMonitor.relabelings` | Prometheus relabeling rules | `[]` | +| `metrics.prometheusRule.enabled` | Create a Prometheus Operator PrometheusRule (also requires `metrics.enabled` to be `true` and `metrics.prometheusRule.rules`) | `false` | +| `metrics.prometheusRule.namespace` | Namespace for the PrometheusRule Resource (defaults to the Release Namespace) | `""` | +| `metrics.prometheusRule.additionalLabels` | Additional labels that can be used so PrometheusRule will be discovered by Prometheus | `{}` | +| `metrics.prometheusRule.rules` | Prometheus Rule definitions | `[]` | + + +### Snapshotting parameters + +| Name | Description | Value | +| ----------------------------------------------- | ----------------------------------------------------------------------- | -------------- | +| `startFromSnapshot.enabled` | Initialize new cluster recovering an existing snapshot | `false` | +| `startFromSnapshot.existingClaim` | Existing PVC containing the etcd snapshot | `""` | +| `startFromSnapshot.snapshotFilename` | Snapshot filename | `""` | +| `disasterRecovery.enabled` | Enable auto disaster recovery by periodically snapshotting the keyspace | `false` | +| `disasterRecovery.cronjob.schedule` | Schedule in Cron format to save snapshots | `*/30 * * * *` | +| `disasterRecovery.cronjob.historyLimit` | Number of successful finished jobs to retain | `1` | +| `disasterRecovery.cronjob.snapshotHistoryLimit` | Number of etcd snapshots to retain, tagged by date | `1` | +| `disasterRecovery.cronjob.podAnnotations` | Pod annotations for cronjob pods | `{}` | +| `disasterRecovery.cronjob.resources.limits` | Cronjob container resource limits | `{}` | +| `disasterRecovery.cronjob.resources.requests` | Cronjob container resource requests | `{}` | +| `disasterRecovery.cronjob.nodeSelector` | Node labels for cronjob pods assignment | `{}` | +| `disasterRecovery.cronjob.tolerations` | Tolerations for cronjob pods assignment | `[]` | +| `disasterRecovery.pvc.existingClaim` | A manually managed Persistent Volume and Claim | `""` | +| `disasterRecovery.pvc.size` | PVC Storage Request | `2Gi` | +| `disasterRecovery.pvc.storageClassName` | Storage Class for snapshots volume | `nfs` | + + +### Service account parameters + +| Name | Description | Value | +| --------------------------------------------- | ------------------------------------------------------------ | ------- | +| `serviceAccount.create` | Enable/disable service account creation | `false` | +| `serviceAccount.name` | Name of the service account to create or use | `""` | +| `serviceAccount.automountServiceAccountToken` | Enable/disable auto mounting of service account token | `true` | +| `serviceAccount.annotations` | Additional annotations to be included on the service account | `{}` | +| `serviceAccount.labels` | Additional labels to be included on the service account | `{}` | + + +### Other parameters + +| Name | Description | Value | +| -------------------- | -------------------------------------------------------------- | ------ | +| `pdb.create` | Enable/disable a Pod Disruption Budget creation | `true` | +| `pdb.minAvailable` | Minimum number/percentage of pods that should remain scheduled | `51%` | +| `pdb.maxUnavailable` | Maximum number/percentage of pods that may be made unavailable | `""` | + + +Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example, + +```console +$ helm install my-release \ + --set auth.rbac.rootPassword=secretpassword my-repo/etcd +``` + +The above command sets the etcd `root` account password to `secretpassword`. + +> NOTE: Once this chart is deployed, it is not possible to change the application's access credentials, such as usernames or passwords, using Helm. To change these application credentials after deployment, delete any persistent volumes (PVs) used by the chart and re-deploy it, or use the application's built-in administrative tools if available. + +Alternatively, a YAML file that specifies the values for the parameters can be provided while installing the chart. For example, + +```console +$ helm install my-release -f values.yaml my-repo/etcd +``` + +> **Tip**: You can use the default [values.yaml](values.yaml) + +## Configuration and installation details + +### [Rolling VS Immutable tags](https://docs.bitnami.com/containers/how-to/understand-rolling-tags-containers/) + +It is strongly recommended to use immutable tags in a production environment. This ensures your deployment does not change automatically if the same tag is updated with a different image. + +Bitnami will release a new chart updating its containers if a new version of the main container, significant changes, or critical vulnerabilities exist. + +### Cluster configuration + +The Bitnami etcd chart can be used to bootstrap an etcd cluster, easy to scale and with available features to implement disaster recovery. + +Refer to the [chart documentation](https://docs.bitnami.com/kubernetes/infrastructure/etcd/get-started/understand-default-configuration/) for more information about all these details. + +### Enable security for etcd + +The etcd chart can be configured with Role-based access control and TLS encryption to improve its security. + +[Learn more about security in the chart documentation](https://docs.bitnami.com/kubernetes/infrastructure/etcd/administration/enable-security/). + +### Persistence + +The [Bitnami etcd](https://github.com/bitnami/containers/tree/main/bitnami/etcd) image stores the etcd data at the `/bitnami/etcd` path of the container. Persistent Volume Claims are used to keep the data across statefulsets. + +The chart mounts a [Persistent Volume](https://kubernetes.io/docs/concepts/storage/persistent-volumes/) volume at this location. The volume is created using dynamic volume provisioning by default. An existing PersistentVolumeClaim can also be defined for this purpose. + +If you encounter errors when working with persistent volumes, refer to our [troubleshooting guide for persistent volumes](https://docs.bitnami.com/kubernetes/faq/troubleshooting/troubleshooting-persistence-volumes/). + +### Backup and restore the etcd keyspace + +The Bitnami etcd chart provides mechanisms to bootstrap the etcd cluster restoring an existing snapshot before initializing. + +[Learn more about backup/restore features in the chart documentation](https://docs.bitnami.com/kubernetes/infrastructure/etcd/administration/backup-restore/). + +### Exposing etcd metrics + +The metrics exposed by etcd can be exposed to be scraped by Prometheus. This can be done by adding the required annotations for Prometheus to discover the metrics endpoints or creating a PodMonitor entry if you are using the Prometheus Operator. + +[Learn more about exposing metrics in the chart documentation](https://docs.bitnami.com/kubernetes/infrastructure/etcd/administration/enable-metrics/). + +### Using custom configuration + +In order to use custom configuration parameters, two options are available: + +- Using environment variables: etcd allows setting environment variables that map to configuration settings. In order to set extra environment variables, you can use the `extraEnvVars` property. Alternatively, you can use a ConfigMap or a Secret with the environment variables using the `extraEnvVarsCM` or the `extraEnvVarsSecret` properties. + +```yaml +extraEnvVars: + - name: ETCD_AUTO_COMPACTION_RETENTION + value: "0" + - name: ETCD_HEARTBEAT_INTERVAL + value: "150" +``` + +- Using a custom `etcd.conf.yml`: The etcd chart allows mounting a custom `etcd.conf.yml` file as ConfigMap. In order to so, you can use the `configuration` property. Alternatively, you can use an existing ConfigMap using the `existingConfigmap` parameter. + +### Auto Compaction + +Since etcd keeps an exact history of its keyspace, this history should be periodically compacted to avoid performance degradation and eventual storage space exhaustion. Compacting the keyspace history drops all information about keys superseded prior to a given keyspace revision. The space used by these keys then becomes available for additional writes to the keyspace. + +`autoCompactionMode`, by default periodic. Valid values: "periodic", "revision". +- 'periodic' for duration based retention, defaulting to hours if no time unit is provided (e.g. "5m"). +- 'revision' for revision number based retention. +`autoCompactionRetention` for mvcc key value store in hour, by default 0, means disabled. + +You can enable auto compaction by using following parameters: + +```console +autoCompactionMode=periodic +autoCompactionRetention=10m +``` + +### Sidecars and Init Containers + +If you have a need for additional containers to run within the same pod as the etcd app (e.g. an additional metrics or logging exporter), you can do so via the `sidecars` config parameter. Simply define your container according to the Kubernetes container spec. + +```yaml +sidecars: + - name: your-image-name + image: your-image + imagePullPolicy: Always + ports: + - name: portname + containerPort: 1234 +``` + +Similarly, you can add extra init containers using the `initContainers` parameter. + +```yaml +initContainers: + - name: your-image-name + image: your-image + imagePullPolicy: Always + ports: + - name: portname + containerPort: 1234 +``` + +### Deploying extra resources + +There are cases where you may want to deploy extra objects, such a ConfigMap containing your app's configuration or some extra deployment with a micro service used by your app. For covering this case, the chart allows adding the full specification of other objects using the `extraDeploy` parameter. + +### Setting Pod's affinity + +This chart allows you to set your custom affinity using the `affinity` parameter. Find more information about Pod's affinity in the [kubernetes documentation](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity). + +As an alternative, you can use of the preset configurations for pod affinity, pod anti-affinity, and node affinity available at the [bitnami/common](https://github.com/bitnami/charts/tree/main/bitnami/common#affinities) chart. To do so, set the `podAffinityPreset`, `podAntiAffinityPreset`, or `nodeAffinityPreset` parameters. + +## Troubleshooting + +Find more information about how to deal with common errors related to Bitnami's Helm charts in [this troubleshooting guide](https://docs.bitnami.com/general/how-to/troubleshoot-helm-chart-issues). + +## Upgrading + +### To 8.0.0 + +This version reverts the change in the previous major bump ([7.0.0](https://github.com/bitnami/charts/tree/main/bitnami/etcd#to-700)). Now the default `etcd` branch is `3.5` again once confirmed by the [etcd developers](https://github.com/etcd-io/etcd/tree/main/CHANGELOG#production-recommendation) that this version is production-ready once solved the data corruption issue. + +### To 7.0.0 + +This version changes the default `etcd` branch to `3.4` as suggested by [etcd developers](https://github.com/etcd-io/etcd/tree/main/CHANGELOG#production-recommendation). In order to migrate the data follow the official etcd instructions. + +### To 6.0.0 + +This version introduces several features and performance improvements: + +- The statefulset can now be scaled using `kubectl scale` command. Using `helm upgrade` to recalculate available endpoints is no longer needed. +- The scripts used for bootstrapping, runtime reconfiguration, and disaster recovery have been refactored and moved to the etcd container (see [this PR](https://github.com/bitnami/bitnami-docker-etcd/pull/13)) with two purposes: removing technical debt & improving the stability. +- Several parameters were reorganized to simplify the structure and follow the same standard used on other Bitnami charts: + - `etcd.initialClusterState` is renamed to `initialClusterState`. + - `statefulset.replicaCount` is renamed to `replicaCount`. + - `statefulset.podManagementPolicy` is renamed to `podManagementPolicy`. + - `statefulset.updateStrategy` and `statefulset.rollingUpdatePartition` are merged into `updateStrategy`. + - `securityContext.*` is deprecated in favor of `podSecurityContext` and `containerSecurityContext`. + - `configFileConfigMap` is deprecated in favor of `configuration` and `existingConfigmap`. + - `envVarsConfigMap` is deprecated in favor of `extraEnvVars`, `extraEnvVarsCM` and `extraEnvVarsSecret`. + - `allowNoneAuthentication` is renamed to `auth.rbac.allowNoneAuthentication`. +- New parameters/features were added: + - `extraDeploy` to deploy any extra desired object. + - `initContainers` and `sidecars` to define custom init containers and sidecars. + - `extraVolumes` and `extraVolumeMounts` to define custom volumes and mount points. + - Probes can be now customized, and support to startup probes is added. + - LifecycleHooks can be customized using `lifecycleHooks` parameter. + - The default command/args can be customized using `command` and `args` parameters. +- Metrics integration with Prometheus Operator does no longer use a ServiceMonitor object, but a PodMonitor instead. + +Consequences: + +- Backwards compatibility is not guaranteed unless you adapt you **values.yaml** according to the changes described above. + +### To 5.2.0 + +This version introduces `bitnami/common`, a [library chart](https://helm.sh/docs/topics/library_charts/#helm) as a dependency. More documentation about this new utility could be found [here](https://github.com/bitnami/charts/tree/main/bitnami/common#bitnami-common-library-chart). Please, make sure that you have updated the chart dependencies before executing any upgrade. + +### To 5.0.0 + +[On November 13, 2020, Helm v2 support formally ended](https://github.com/helm/charts#status-of-the-project). This major version is the result of the required changes applied to the Helm Chart to be able to incorporate the different features added in Helm v3 and to be consistent with the Helm project itself regarding the Helm v2 EOL. + +[Learn more about this change and related upgrade considerations](https://docs.bitnami.com/kubernetes/infrastructure/etcd/administration/upgrade-helm3/). + +### To 4.4.14 + +In this release we addressed a vulnerability that showed the `ETCD_ROOT_PASSWORD` environment variable in the application logs. Users are advised to update immediately. More information in [this issue](https://github.com/bitnami/charts/issues/1901). + +### To 3.0.0 + +Backwards compatibility is not guaranteed. The following notables changes were included: + +- **etcdctl** uses v3 API. +- Adds support for auto disaster recovery. +- Labels are adapted to follow the Helm charts best practices. + +To upgrade from previous charts versions, create a snapshot of the keyspace and restore it in a new etcd cluster. Only v3 API data can be restored. +You can use the command below to upgrade your chart by starting a new cluster using an existing snapshot, available in an existing PVC, to initialize the members: + +```console +$ helm install new-release my-repo/etcd \ + --set statefulset.replicaCount=3 \ + --set persistence.enabled=true \ + --set persistence.size=8Gi \ + --set startFromSnapshot.enabled=true \ + --set startFromSnapshot.existingClaim=my-claim \ + --set startFromSnapshot.snapshotFilename=my-snapshot.db +``` + +### To 1.0.0 + +Backwards compatibility is not guaranteed unless you modify the labels used on the chart's deployments. +Use the workaround below to upgrade from versions previous to 1.0.0. The following example assumes that the release name is etcd: + +```console +$ kubectl delete statefulset etcd --cascade=false +``` + +## License + +Copyright © 2022 Bitnami + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/helm/openebs/charts/mayastor/charts/etcd/charts/common/.helmignore b/helm/openebs/charts/mayastor/charts/etcd/charts/common/.helmignore new file mode 100644 index 0000000..50af031 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/etcd/charts/common/.helmignore @@ -0,0 +1,22 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/helm/openebs/charts/mayastor/charts/etcd/charts/common/Chart.yaml b/helm/openebs/charts/mayastor/charts/etcd/charts/common/Chart.yaml new file mode 100644 index 0000000..f9ba944 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/etcd/charts/common/Chart.yaml @@ -0,0 +1,23 @@ +annotations: + category: Infrastructure +apiVersion: v2 +appVersion: 2.2.2 +description: A Library Helm Chart for grouping common logic between bitnami charts. + This chart is not deployable by itself. +home: https://github.com/bitnami/charts/tree/main/bitnami/common +icon: https://bitnami.com/downloads/logos/bitnami-mark.png +keywords: +- common +- helper +- template +- function +- bitnami +maintainers: +- name: Bitnami + url: https://github.com/bitnami/charts +name: common +sources: +- https://github.com/bitnami/charts +- https://www.bitnami.com/ +type: library +version: 2.2.2 diff --git a/helm/openebs/charts/mayastor/charts/etcd/charts/common/README.md b/helm/openebs/charts/mayastor/charts/etcd/charts/common/README.md new file mode 100644 index 0000000..ec43a5f --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/etcd/charts/common/README.md @@ -0,0 +1,351 @@ +# Bitnami Common Library Chart + +A [Helm Library Chart](https://helm.sh/docs/topics/library_charts/#helm) for grouping common logic between bitnami charts. + +## TL;DR + +```yaml +dependencies: + - name: common + version: 1.x.x + repository: https://charts.bitnami.com/bitnami +``` + +```bash +$ helm dependency update +``` + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "common.names.fullname" . }} +data: + myvalue: "Hello World" +``` + +## Introduction + +This chart provides a common template helpers which can be used to develop new charts using [Helm](https://helm.sh) package manager. + +Bitnami charts can be used with [Kubeapps](https://kubeapps.dev/) for deployment and management of Helm Charts in clusters. + +## Prerequisites + +- Kubernetes 1.19+ +- Helm 3.2.0+ + +## Parameters + +The following table lists the helpers available in the library which are scoped in different sections. + +### Affinities + +| Helper identifier | Description | Expected Input | +|-------------------------------|------------------------------------------------------|------------------------------------------------| +| `common.affinities.nodes.soft` | Return a soft nodeAffinity definition | `dict "key" "FOO" "values" (list "BAR" "BAZ")` | +| `common.affinities.nodes.hard` | Return a hard nodeAffinity definition | `dict "key" "FOO" "values" (list "BAR" "BAZ")` | +| `common.affinities.pods.soft` | Return a soft podAffinity/podAntiAffinity definition | `dict "component" "FOO" "context" $` | +| `common.affinities.pods.hard` | Return a hard podAffinity/podAntiAffinity definition | `dict "component" "FOO" "context" $` | +| `common.affinities.topologyKey` | Return a topologyKey definition | `dict "topologyKey" "FOO"` | + +### Capabilities + +| Helper identifier | Description | Expected Input | +|------------------------------------------------|------------------------------------------------------------------------------------------------|-------------------| +| `common.capabilities.kubeVersion` | Return the target Kubernetes version (using client default if .Values.kubeVersion is not set). | `.` Chart context | +| `common.capabilities.cronjob.apiVersion` | Return the appropriate apiVersion for cronjob. | `.` Chart context | +| `common.capabilities.deployment.apiVersion` | Return the appropriate apiVersion for deployment. | `.` Chart context | +| `common.capabilities.statefulset.apiVersion` | Return the appropriate apiVersion for statefulset. | `.` Chart context | +| `common.capabilities.ingress.apiVersion` | Return the appropriate apiVersion for ingress. | `.` Chart context | +| `common.capabilities.rbac.apiVersion` | Return the appropriate apiVersion for RBAC resources. | `.` Chart context | +| `common.capabilities.crd.apiVersion` | Return the appropriate apiVersion for CRDs. | `.` Chart context | +| `common.capabilities.policy.apiVersion` | Return the appropriate apiVersion for podsecuritypolicy. | `.` Chart context | +| `common.capabilities.networkPolicy.apiVersion` | Return the appropriate apiVersion for networkpolicy. | `.` Chart context | +| `common.capabilities.apiService.apiVersion` | Return the appropriate apiVersion for APIService. | `.` Chart context | +| `common.capabilities.hpa.apiVersion` | Return the appropriate apiVersion for Horizontal Pod Autoscaler | `.` Chart context | +| `common.capabilities.supportsHelmVersion` | Returns true if the used Helm version is 3.3+ | `.` Chart context | + +### Errors + +| Helper identifier | Description | Expected Input | +|-----------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------| +| `common.errors.upgrade.passwords.empty` | It will ensure required passwords are given when we are upgrading a chart. If `validationErrors` is not empty it will throw an error and will stop the upgrade action. | `dict "validationErrors" (list $validationError00 $validationError01) "context" $` | + +### Images + +| Helper identifier | Description | Expected Input | +|-----------------------------|------------------------------------------------------|---------------------------------------------------------------------------------------------------------| +| `common.images.image` | Return the proper and full image name | `dict "imageRoot" .Values.path.to.the.image "global" $`, see [ImageRoot](#imageroot) for the structure. | +| `common.images.pullSecrets` | Return the proper Docker Image Registry Secret Names (deprecated: use common.images.renderPullSecrets instead) | `dict "images" (list .Values.path.to.the.image1, .Values.path.to.the.image2) "global" .Values.global` | +| `common.images.renderPullSecrets` | Return the proper Docker Image Registry Secret Names (evaluates values as templates) | `dict "images" (list .Values.path.to.the.image1, .Values.path.to.the.image2) "context" $` | + +### Ingress + +| Helper identifier | Description | Expected Input | +|-------------------------------------------|-------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `common.ingress.backend` | Generate a proper Ingress backend entry depending on the API version | `dict "serviceName" "foo" "servicePort" "bar"`, see the [Ingress deprecation notice](https://kubernetes.io/blog/2019/07/18/api-deprecations-in-1-16/) for the syntax differences | +| `common.ingress.supportsPathType` | Prints "true" if the pathType field is supported | `.` Chart context | +| `common.ingress.supportsIngressClassname` | Prints "true" if the ingressClassname field is supported | `.` Chart context | +| `common.ingress.certManagerRequest` | Prints "true" if required cert-manager annotations for TLS signed certificates are set in the Ingress annotations | `dict "annotations" .Values.path.to.the.ingress.annotations` | + +### Labels + +| Helper identifier | Description | Expected Input | +|-----------------------------|-----------------------------------------------------------------------------|-------------------| +| `common.labels.standard` | Return Kubernetes standard labels | `.` Chart context | +| `common.labels.matchLabels` | Labels to use on `deploy.spec.selector.matchLabels` and `svc.spec.selector` | `.` Chart context | + +### Names + +| Helper identifier | Description | Expected Input | +|-----------------------------------|-----------------------------------------------------------------------|-------------------| +| `common.names.name` | Expand the name of the chart or use `.Values.nameOverride` | `.` Chart context | +| `common.names.fullname` | Create a default fully qualified app name. | `.` Chart context | +| `common.names.namespace` | Allow the release namespace to be overridden | `.` Chart context | +| `common.names.fullname.namespace` | Create a fully qualified app name adding the installation's namespace | `.` Chart context | +| `common.names.chart` | Chart name plus version | `.` Chart context | + +### Secrets + +| Helper identifier | Description | Expected Input | +|-----------------------------------|--------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `common.secrets.name` | Generate the name of the secret. | `dict "existingSecret" .Values.path.to.the.existingSecret "defaultNameSuffix" "mySuffix" "context" $` see [ExistingSecret](#existingsecret) for the structure. | +| `common.secrets.key` | Generate secret key. | `dict "existingSecret" .Values.path.to.the.existingSecret "key" "keyName"` see [ExistingSecret](#existingsecret) for the structure. | +| `common.secrets.passwords.manage` | Generate secret password or retrieve one if already created. | `dict "secret" "secret-name" "key" "keyName" "providedValues" (list "path.to.password1" "path.to.password2") "length" 10 "strong" false "chartName" "chartName" "context" $`, length, strong and chartNAme fields are optional. | +| `common.secrets.exists` | Returns whether a previous generated secret already exists. | `dict "secret" "secret-name" "context" $` | + +### Storage + +| Helper identifier | Description | Expected Input | +|-------------------------------|---------------------------------------|---------------------------------------------------------------------------------------------------------------------| +| `common.storage.class` | Return the proper Storage Class | `dict "persistence" .Values.path.to.the.persistence "global" $`, see [Persistence](#persistence) for the structure. | + +### TplValues + +| Helper identifier | Description | Expected Input | +|---------------------------|----------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------| +| `common.tplvalues.render` | Renders a value that contains template | `dict "value" .Values.path.to.the.Value "context" $`, value is the value should rendered as template, context frequently is the chart context `$` or `.` | + +### Utils + +| Helper identifier | Description | Expected Input | +|--------------------------------|------------------------------------------------------------------------------------------|------------------------------------------------------------------------| +| `common.utils.fieldToEnvVar` | Build environment variable name given a field. | `dict "field" "my-password"` | +| `common.utils.secret.getvalue` | Print instructions to get a secret value. | `dict "secret" "secret-name" "field" "secret-value-field" "context" $` | +| `common.utils.getValueFromKey` | Gets a value from `.Values` object given its key path | `dict "key" "path.to.key" "context" $` | +| `common.utils.getKeyFromList` | Returns first `.Values` key with a defined value or first of the list if all non-defined | `dict "keys" (list "path.to.key1" "path.to.key2") "context" $` | + +### Validations + +| Helper identifier | Description | Expected Input | +|--------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `common.validations.values.single.empty` | Validate a value must not be empty. | `dict "valueKey" "path.to.value" "secret" "secret.name" "field" "my-password" "subchart" "subchart" "context" $` secret, field and subchart are optional. In case they are given, the helper will generate a how to get instruction. See [ValidateValue](#validatevalue) | +| `common.validations.values.multiple.empty` | Validate a multiple values must not be empty. It returns a shared error for all the values. | `dict "required" (list $validateValueConf00 $validateValueConf01) "context" $`. See [ValidateValue](#validatevalue) | +| `common.validations.values.mariadb.passwords` | This helper will ensure required password for MariaDB are not empty. It returns a shared error for all the values. | `dict "secret" "mariadb-secret" "subchart" "true" "context" $` subchart field is optional and could be true or false it depends on where you will use mariadb chart and the helper. | +| `common.validations.values.mysql.passwords` | This helper will ensure required password for MySQL are not empty. It returns a shared error for all the values. | `dict "secret" "mysql-secret" "subchart" "true" "context" $` subchart field is optional and could be true or false it depends on where you will use mysql chart and the helper. | +| `common.validations.values.postgresql.passwords` | This helper will ensure required password for PostgreSQL are not empty. It returns a shared error for all the values. | `dict "secret" "postgresql-secret" "subchart" "true" "context" $` subchart field is optional and could be true or false it depends on where you will use postgresql chart and the helper. | +| `common.validations.values.redis.passwords` | This helper will ensure required password for Redis® are not empty. It returns a shared error for all the values. | `dict "secret" "redis-secret" "subchart" "true" "context" $` subchart field is optional and could be true or false it depends on where you will use redis chart and the helper. | +| `common.validations.values.cassandra.passwords` | This helper will ensure required password for Cassandra are not empty. It returns a shared error for all the values. | `dict "secret" "cassandra-secret" "subchart" "true" "context" $` subchart field is optional and could be true or false it depends on where you will use cassandra chart and the helper. | +| `common.validations.values.mongodb.passwords` | This helper will ensure required password for MongoDB® are not empty. It returns a shared error for all the values. | `dict "secret" "mongodb-secret" "subchart" "true" "context" $` subchart field is optional and could be true or false it depends on where you will use mongodb chart and the helper. | + +### Warnings + +| Helper identifier | Description | Expected Input | +|------------------------------|----------------------------------|------------------------------------------------------------| +| `common.warnings.rollingTag` | Warning about using rolling tag. | `ImageRoot` see [ImageRoot](#imageroot) for the structure. | + +## Special input schemas + +### ImageRoot + +```yaml +registry: + type: string + description: Docker registry where the image is located + example: docker.io + +repository: + type: string + description: Repository and image name + example: bitnami/nginx + +tag: + type: string + description: image tag + example: 1.16.1-debian-10-r63 + +pullPolicy: + type: string + description: Specify a imagePullPolicy. Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' + +pullSecrets: + type: array + items: + type: string + description: Optionally specify an array of imagePullSecrets (evaluated as templates). + +debug: + type: boolean + description: Set to true if you would like to see extra information on logs + example: false + +## An instance would be: +# registry: docker.io +# repository: bitnami/nginx +# tag: 1.16.1-debian-10-r63 +# pullPolicy: IfNotPresent +# debug: false +``` + +### Persistence + +```yaml +enabled: + type: boolean + description: Whether enable persistence. + example: true + +storageClass: + type: string + description: Ghost data Persistent Volume Storage Class, If set to "-", storageClassName: "" which disables dynamic provisioning. + example: "-" + +accessMode: + type: string + description: Access mode for the Persistent Volume Storage. + example: ReadWriteOnce + +size: + type: string + description: Size the Persistent Volume Storage. + example: 8Gi + +path: + type: string + description: Path to be persisted. + example: /bitnami + +## An instance would be: +# enabled: true +# storageClass: "-" +# accessMode: ReadWriteOnce +# size: 8Gi +# path: /bitnami +``` + +### ExistingSecret + +```yaml +name: + type: string + description: Name of the existing secret. + example: mySecret +keyMapping: + description: Mapping between the expected key name and the name of the key in the existing secret. + type: object + +## An instance would be: +# name: mySecret +# keyMapping: +# password: myPasswordKey +``` + +#### Example of use + +When we store sensitive data for a deployment in a secret, some times we want to give to users the possibility of using theirs existing secrets. + +```yaml +# templates/secret.yaml +--- +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "common.names.fullname" . }} + labels: + app: {{ include "common.names.fullname" . }} +type: Opaque +data: + password: {{ .Values.password | b64enc | quote }} + +# templates/dpl.yaml +--- +... + env: + - name: PASSWORD + valueFrom: + secretKeyRef: + name: {{ include "common.secrets.name" (dict "existingSecret" .Values.existingSecret "context" $) }} + key: {{ include "common.secrets.key" (dict "existingSecret" .Values.existingSecret "key" "password") }} +... + +# values.yaml +--- +name: mySecret +keyMapping: + password: myPasswordKey +``` + +### ValidateValue + +#### NOTES.txt + +```console +{{- $validateValueConf00 := (dict "valueKey" "path.to.value00" "secret" "secretName" "field" "password-00") -}} +{{- $validateValueConf01 := (dict "valueKey" "path.to.value01" "secret" "secretName" "field" "password-01") -}} + +{{ include "common.validations.values.multiple.empty" (dict "required" (list $validateValueConf00 $validateValueConf01) "context" $) }} +``` + +If we force those values to be empty we will see some alerts + +```console +$ helm install test mychart --set path.to.value00="",path.to.value01="" + 'path.to.value00' must not be empty, please add '--set path.to.value00=$PASSWORD_00' to the command. To get the current value: + + export PASSWORD_00=$(kubectl get secret --namespace default secretName -o jsonpath="{.data.password-00}" | base64 -d) + + 'path.to.value01' must not be empty, please add '--set path.to.value01=$PASSWORD_01' to the command. To get the current value: + + export PASSWORD_01=$(kubectl get secret --namespace default secretName -o jsonpath="{.data.password-01}" | base64 -d) +``` + +## Upgrading + +### To 1.0.0 + +[On November 13, 2020, Helm v2 support was formally finished](https://github.com/helm/charts#status-of-the-project), this major version is the result of the required changes applied to the Helm Chart to be able to incorporate the different features added in Helm v3 and to be consistent with the Helm project itself regarding the Helm v2 EOL. + +**What changes were introduced in this major version?** + +- Previous versions of this Helm Chart use `apiVersion: v1` (installable by both Helm 2 and 3), this Helm Chart was updated to `apiVersion: v2` (installable by Helm 3 only). [Here](https://helm.sh/docs/topics/charts/#the-apiversion-field) you can find more information about the `apiVersion` field. +- Use `type: library`. [Here](https://v3.helm.sh/docs/faq/#library-chart-support) you can find more information. +- The different fields present in the *Chart.yaml* file has been ordered alphabetically in a homogeneous way for all the Bitnami Helm Charts + +**Considerations when upgrading to this version** + +- If you want to upgrade to this version from a previous one installed with Helm v3, you shouldn't face any issues +- If you want to upgrade to this version using Helm v2, this scenario is not supported as this version doesn't support Helm v2 anymore +- If you installed the previous version with Helm v2 and wants to upgrade to this version with Helm v3, please refer to the [official Helm documentation](https://helm.sh/docs/topics/v2_v3_migration/#migration-use-cases) about migrating from Helm v2 to v3 + +**Useful links** + +- https://docs.bitnami.com/tutorials/resolve-helm2-helm3-post-migration-issues/ +- https://helm.sh/docs/topics/v2_v3_migration/ +- https://helm.sh/blog/migrate-from-helm-v2-to-helm-v3/ + +## License + +Copyright © 2022 Bitnami + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/_affinities.tpl b/helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/_affinities.tpl new file mode 100644 index 0000000..81902a6 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/_affinities.tpl @@ -0,0 +1,106 @@ +{{/* vim: set filetype=mustache: */}} + +{{/* +Return a soft nodeAffinity definition +{{ include "common.affinities.nodes.soft" (dict "key" "FOO" "values" (list "BAR" "BAZ")) -}} +*/}} +{{- define "common.affinities.nodes.soft" -}} +preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: {{ .key }} + operator: In + values: + {{- range .values }} + - {{ . | quote }} + {{- end }} + weight: 1 +{{- end -}} + +{{/* +Return a hard nodeAffinity definition +{{ include "common.affinities.nodes.hard" (dict "key" "FOO" "values" (list "BAR" "BAZ")) -}} +*/}} +{{- define "common.affinities.nodes.hard" -}} +requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: {{ .key }} + operator: In + values: + {{- range .values }} + - {{ . | quote }} + {{- end }} +{{- end -}} + +{{/* +Return a nodeAffinity definition +{{ include "common.affinities.nodes" (dict "type" "soft" "key" "FOO" "values" (list "BAR" "BAZ")) -}} +*/}} +{{- define "common.affinities.nodes" -}} + {{- if eq .type "soft" }} + {{- include "common.affinities.nodes.soft" . -}} + {{- else if eq .type "hard" }} + {{- include "common.affinities.nodes.hard" . -}} + {{- end -}} +{{- end -}} + +{{/* +Return a topologyKey definition +{{ include "common.affinities.topologyKey" (dict "topologyKey" "BAR") -}} +*/}} +{{- define "common.affinities.topologyKey" -}} +{{ .topologyKey | default "kubernetes.io/hostname" -}} +{{- end -}} + +{{/* +Return a soft podAffinity/podAntiAffinity definition +{{ include "common.affinities.pods.soft" (dict "component" "FOO" "extraMatchLabels" .Values.extraMatchLabels "topologyKey" "BAR" "context" $) -}} +*/}} +{{- define "common.affinities.pods.soft" -}} +{{- $component := default "" .component -}} +{{- $extraMatchLabels := default (dict) .extraMatchLabels -}} +preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchLabels: {{- (include "common.labels.matchLabels" .context) | nindent 10 }} + {{- if not (empty $component) }} + {{ printf "app.kubernetes.io/component: %s" $component }} + {{- end }} + {{- range $key, $value := $extraMatchLabels }} + {{ $key }}: {{ $value | quote }} + {{- end }} + topologyKey: {{ include "common.affinities.topologyKey" (dict "topologyKey" .topologyKey) }} + weight: 1 +{{- end -}} + +{{/* +Return a hard podAffinity/podAntiAffinity definition +{{ include "common.affinities.pods.hard" (dict "component" "FOO" "extraMatchLabels" .Values.extraMatchLabels "topologyKey" "BAR" "context" $) -}} +*/}} +{{- define "common.affinities.pods.hard" -}} +{{- $component := default "" .component -}} +{{- $extraMatchLabels := default (dict) .extraMatchLabels -}} +requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: {{- (include "common.labels.matchLabels" .context) | nindent 8 }} + {{- if not (empty $component) }} + {{ printf "app.kubernetes.io/component: %s" $component }} + {{- end }} + {{- range $key, $value := $extraMatchLabels }} + {{ $key }}: {{ $value | quote }} + {{- end }} + topologyKey: {{ include "common.affinities.topologyKey" (dict "topologyKey" .topologyKey) }} +{{- end -}} + +{{/* +Return a podAffinity/podAntiAffinity definition +{{ include "common.affinities.pods" (dict "type" "soft" "key" "FOO" "values" (list "BAR" "BAZ")) -}} +*/}} +{{- define "common.affinities.pods" -}} + {{- if eq .type "soft" }} + {{- include "common.affinities.pods.soft" . -}} + {{- else if eq .type "hard" }} + {{- include "common.affinities.pods.hard" . -}} + {{- end -}} +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/_capabilities.tpl b/helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/_capabilities.tpl new file mode 100644 index 0000000..9d9b760 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/_capabilities.tpl @@ -0,0 +1,154 @@ +{{/* vim: set filetype=mustache: */}} + +{{/* +Return the target Kubernetes version +*/}} +{{- define "common.capabilities.kubeVersion" -}} +{{- if .Values.global }} + {{- if .Values.global.kubeVersion }} + {{- .Values.global.kubeVersion -}} + {{- else }} + {{- default .Capabilities.KubeVersion.Version .Values.kubeVersion -}} + {{- end -}} +{{- else }} +{{- default .Capabilities.KubeVersion.Version .Values.kubeVersion -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for poddisruptionbudget. +*/}} +{{- define "common.capabilities.policy.apiVersion" -}} +{{- if semverCompare "<1.21-0" (include "common.capabilities.kubeVersion" .) -}} +{{- print "policy/v1beta1" -}} +{{- else -}} +{{- print "policy/v1" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for networkpolicy. +*/}} +{{- define "common.capabilities.networkPolicy.apiVersion" -}} +{{- if semverCompare "<1.7-0" (include "common.capabilities.kubeVersion" .) -}} +{{- print "extensions/v1beta1" -}} +{{- else -}} +{{- print "networking.k8s.io/v1" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for cronjob. +*/}} +{{- define "common.capabilities.cronjob.apiVersion" -}} +{{- if semverCompare "<1.21-0" (include "common.capabilities.kubeVersion" .) -}} +{{- print "batch/v1beta1" -}} +{{- else -}} +{{- print "batch/v1" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for deployment. +*/}} +{{- define "common.capabilities.deployment.apiVersion" -}} +{{- if semverCompare "<1.14-0" (include "common.capabilities.kubeVersion" .) -}} +{{- print "extensions/v1beta1" -}} +{{- else -}} +{{- print "apps/v1" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for statefulset. +*/}} +{{- define "common.capabilities.statefulset.apiVersion" -}} +{{- if semverCompare "<1.14-0" (include "common.capabilities.kubeVersion" .) -}} +{{- print "apps/v1beta1" -}} +{{- else -}} +{{- print "apps/v1" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for ingress. +*/}} +{{- define "common.capabilities.ingress.apiVersion" -}} +{{- if .Values.ingress -}} +{{- if .Values.ingress.apiVersion -}} +{{- .Values.ingress.apiVersion -}} +{{- else if semverCompare "<1.14-0" (include "common.capabilities.kubeVersion" .) -}} +{{- print "extensions/v1beta1" -}} +{{- else if semverCompare "<1.19-0" (include "common.capabilities.kubeVersion" .) -}} +{{- print "networking.k8s.io/v1beta1" -}} +{{- else -}} +{{- print "networking.k8s.io/v1" -}} +{{- end }} +{{- else if semverCompare "<1.14-0" (include "common.capabilities.kubeVersion" .) -}} +{{- print "extensions/v1beta1" -}} +{{- else if semverCompare "<1.19-0" (include "common.capabilities.kubeVersion" .) -}} +{{- print "networking.k8s.io/v1beta1" -}} +{{- else -}} +{{- print "networking.k8s.io/v1" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for RBAC resources. +*/}} +{{- define "common.capabilities.rbac.apiVersion" -}} +{{- if semverCompare "<1.17-0" (include "common.capabilities.kubeVersion" .) -}} +{{- print "rbac.authorization.k8s.io/v1beta1" -}} +{{- else -}} +{{- print "rbac.authorization.k8s.io/v1" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for CRDs. +*/}} +{{- define "common.capabilities.crd.apiVersion" -}} +{{- if semverCompare "<1.19-0" (include "common.capabilities.kubeVersion" .) -}} +{{- print "apiextensions.k8s.io/v1beta1" -}} +{{- else -}} +{{- print "apiextensions.k8s.io/v1" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for APIService. +*/}} +{{- define "common.capabilities.apiService.apiVersion" -}} +{{- if semverCompare "<1.10-0" (include "common.capabilities.kubeVersion" .) -}} +{{- print "apiregistration.k8s.io/v1beta1" -}} +{{- else -}} +{{- print "apiregistration.k8s.io/v1" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for Horizontal Pod Autoscaler. +*/}} +{{- define "common.capabilities.hpa.apiVersion" -}} +{{- if semverCompare "<1.23-0" (include "common.capabilities.kubeVersion" .context) -}} +{{- if .beta2 -}} +{{- print "autoscaling/v2beta2" -}} +{{- else -}} +{{- print "autoscaling/v2beta1" -}} +{{- end -}} +{{- else -}} +{{- print "autoscaling/v2" -}} +{{- end -}} +{{- end -}} + +{{/* +Returns true if the used Helm version is 3.3+. +A way to check the used Helm version was not introduced until version 3.3.0 with .Capabilities.HelmVersion, which contains an additional "{}}" structure. +This check is introduced as a regexMatch instead of {{ if .Capabilities.HelmVersion }} because checking for the key HelmVersion in <3.3 results in a "interface not found" error. +**To be removed when the catalog's minimun Helm version is 3.3** +*/}} +{{- define "common.capabilities.supportsHelmVersion" -}} +{{- if regexMatch "{(v[0-9])*[^}]*}}$" (.Capabilities | toString ) }} + {{- true -}} +{{- end -}} +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/_errors.tpl b/helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/_errors.tpl new file mode 100644 index 0000000..a79cc2e --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/_errors.tpl @@ -0,0 +1,23 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Through error when upgrading using empty passwords values that must not be empty. + +Usage: +{{- $validationError00 := include "common.validations.values.single.empty" (dict "valueKey" "path.to.password00" "secret" "secretName" "field" "password-00") -}} +{{- $validationError01 := include "common.validations.values.single.empty" (dict "valueKey" "path.to.password01" "secret" "secretName" "field" "password-01") -}} +{{ include "common.errors.upgrade.passwords.empty" (dict "validationErrors" (list $validationError00 $validationError01) "context" $) }} + +Required password params: + - validationErrors - String - Required. List of validation strings to be return, if it is empty it won't throw error. + - context - Context - Required. Parent context. +*/}} +{{- define "common.errors.upgrade.passwords.empty" -}} + {{- $validationErrors := join "" .validationErrors -}} + {{- if and $validationErrors .context.Release.IsUpgrade -}} + {{- $errorString := "\nPASSWORDS ERROR: You must provide your current passwords when upgrading the release." -}} + {{- $errorString = print $errorString "\n Note that even after reinstallation, old credentials may be needed as they may be kept in persistent volume claims." -}} + {{- $errorString = print $errorString "\n Further information can be obtained at https://docs.bitnami.com/general/how-to/troubleshoot-helm-chart-issues/#credential-errors-while-upgrading-chart-releases" -}} + {{- $errorString = print $errorString "\n%s" -}} + {{- printf $errorString $validationErrors | fail -}} + {{- end -}} +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/_images.tpl b/helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/_images.tpl new file mode 100644 index 0000000..46c659e --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/_images.tpl @@ -0,0 +1,76 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Return the proper image name +{{ include "common.images.image" ( dict "imageRoot" .Values.path.to.the.image "global" $) }} +*/}} +{{- define "common.images.image" -}} +{{- $registryName := .imageRoot.registry -}} +{{- $repositoryName := .imageRoot.repository -}} +{{- $separator := ":" -}} +{{- $termination := .imageRoot.tag | toString -}} +{{- if .global }} + {{- if .global.imageRegistry }} + {{- $registryName = .global.imageRegistry -}} + {{- end -}} +{{- end -}} +{{- if .imageRoot.digest }} + {{- $separator = "@" -}} + {{- $termination = .imageRoot.digest | toString -}} +{{- end -}} +{{- printf "%s/%s%s%s" $registryName $repositoryName $separator $termination -}} +{{- end -}} + +{{/* +Return the proper Docker Image Registry Secret Names (deprecated: use common.images.renderPullSecrets instead) +{{ include "common.images.pullSecrets" ( dict "images" (list .Values.path.to.the.image1, .Values.path.to.the.image2) "global" .Values.global) }} +*/}} +{{- define "common.images.pullSecrets" -}} + {{- $pullSecrets := list }} + + {{- if .global }} + {{- range .global.imagePullSecrets -}} + {{- $pullSecrets = append $pullSecrets . -}} + {{- end -}} + {{- end -}} + + {{- range .images -}} + {{- range .pullSecrets -}} + {{- $pullSecrets = append $pullSecrets . -}} + {{- end -}} + {{- end -}} + + {{- if (not (empty $pullSecrets)) }} +imagePullSecrets: + {{- range $pullSecrets }} + - name: {{ . }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +Return the proper Docker Image Registry Secret Names evaluating values as templates +{{ include "common.images.renderPullSecrets" ( dict "images" (list .Values.path.to.the.image1, .Values.path.to.the.image2) "context" $) }} +*/}} +{{- define "common.images.renderPullSecrets" -}} + {{- $pullSecrets := list }} + {{- $context := .context }} + + {{- if $context.Values.global }} + {{- range $context.Values.global.imagePullSecrets -}} + {{- $pullSecrets = append $pullSecrets (include "common.tplvalues.render" (dict "value" . "context" $context)) -}} + {{- end -}} + {{- end -}} + + {{- range .images -}} + {{- range .pullSecrets -}} + {{- $pullSecrets = append $pullSecrets (include "common.tplvalues.render" (dict "value" . "context" $context)) -}} + {{- end -}} + {{- end -}} + + {{- if (not (empty $pullSecrets)) }} +imagePullSecrets: + {{- range $pullSecrets }} + - name: {{ . }} + {{- end }} + {{- end }} +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/_ingress.tpl b/helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/_ingress.tpl new file mode 100644 index 0000000..831da9c --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/_ingress.tpl @@ -0,0 +1,68 @@ +{{/* vim: set filetype=mustache: */}} + +{{/* +Generate backend entry that is compatible with all Kubernetes API versions. + +Usage: +{{ include "common.ingress.backend" (dict "serviceName" "backendName" "servicePort" "backendPort" "context" $) }} + +Params: + - serviceName - String. Name of an existing service backend + - servicePort - String/Int. Port name (or number) of the service. It will be translated to different yaml depending if it is a string or an integer. + - context - Dict - Required. The context for the template evaluation. +*/}} +{{- define "common.ingress.backend" -}} +{{- $apiVersion := (include "common.capabilities.ingress.apiVersion" .context) -}} +{{- if or (eq $apiVersion "extensions/v1beta1") (eq $apiVersion "networking.k8s.io/v1beta1") -}} +serviceName: {{ .serviceName }} +servicePort: {{ .servicePort }} +{{- else -}} +service: + name: {{ .serviceName }} + port: + {{- if typeIs "string" .servicePort }} + name: {{ .servicePort }} + {{- else if or (typeIs "int" .servicePort) (typeIs "float64" .servicePort) }} + number: {{ .servicePort | int }} + {{- end }} +{{- end -}} +{{- end -}} + +{{/* +Print "true" if the API pathType field is supported +Usage: +{{ include "common.ingress.supportsPathType" . }} +*/}} +{{- define "common.ingress.supportsPathType" -}} +{{- if (semverCompare "<1.18-0" (include "common.capabilities.kubeVersion" .)) -}} +{{- print "false" -}} +{{- else -}} +{{- print "true" -}} +{{- end -}} +{{- end -}} + +{{/* +Returns true if the ingressClassname field is supported +Usage: +{{ include "common.ingress.supportsIngressClassname" . }} +*/}} +{{- define "common.ingress.supportsIngressClassname" -}} +{{- if semverCompare "<1.18-0" (include "common.capabilities.kubeVersion" .) -}} +{{- print "false" -}} +{{- else -}} +{{- print "true" -}} +{{- end -}} +{{- end -}} + +{{/* +Return true if cert-manager required annotations for TLS signed +certificates are set in the Ingress annotations +Ref: https://cert-manager.io/docs/usage/ingress/#supported-annotations +Usage: +{{ include "common.ingress.certManagerRequest" ( dict "annotations" .Values.path.to.the.ingress.annotations ) }} +*/}} +{{- define "common.ingress.certManagerRequest" -}} +{{ if or (hasKey .annotations "cert-manager.io/cluster-issuer") (hasKey .annotations "cert-manager.io/issuer") (hasKey .annotations "kubernetes.io/tls-acme") }} + {{- true -}} +{{- end -}} +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/_labels.tpl b/helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/_labels.tpl new file mode 100644 index 0000000..252066c --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/_labels.tpl @@ -0,0 +1,18 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Kubernetes standard labels +*/}} +{{- define "common.labels.standard" -}} +app.kubernetes.io/name: {{ include "common.names.name" . }} +helm.sh/chart: {{ include "common.names.chart" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end -}} + +{{/* +Labels to use on deploy.spec.selector.matchLabels and svc.spec.selector +*/}} +{{- define "common.labels.matchLabels" -}} +app.kubernetes.io/name: {{ include "common.names.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/_names.tpl b/helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/_names.tpl new file mode 100644 index 0000000..617a234 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/_names.tpl @@ -0,0 +1,66 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "common.names.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "common.names.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "common.names.fullname" -}} +{{- if .Values.fullnameOverride -}} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Create a default fully qualified dependency name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +Usage: +{{ include "common.names.dependency.fullname" (dict "chartName" "dependency-chart-name" "chartValues" .Values.dependency-chart "context" $) }} +*/}} +{{- define "common.names.dependency.fullname" -}} +{{- if .chartValues.fullnameOverride -}} +{{- .chartValues.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .chartName .chartValues.nameOverride -}} +{{- if contains $name .context.Release.Name -}} +{{- .context.Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .context.Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Allow the release namespace to be overridden for multi-namespace deployments in combined charts. +*/}} +{{- define "common.names.namespace" -}} +{{- default .Release.Namespace .Values.namespaceOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create a fully qualified app name adding the installation's namespace. +*/}} +{{- define "common.names.fullname.namespace" -}} +{{- printf "%s-%s" (include "common.names.fullname" .) (include "common.names.namespace" .) | trunc 63 | trimSuffix "-" -}} +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/_secrets.tpl b/helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/_secrets.tpl new file mode 100644 index 0000000..a1708b2 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/_secrets.tpl @@ -0,0 +1,165 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Generate secret name. + +Usage: +{{ include "common.secrets.name" (dict "existingSecret" .Values.path.to.the.existingSecret "defaultNameSuffix" "mySuffix" "context" $) }} + +Params: + - existingSecret - ExistingSecret/String - Optional. The path to the existing secrets in the values.yaml given by the user + to be used instead of the default one. Allows for it to be of type String (just the secret name) for backwards compatibility. + +info: https://github.com/bitnami/charts/tree/main/bitnami/common#existingsecret + - defaultNameSuffix - String - Optional. It is used only if we have several secrets in the same deployment. + - context - Dict - Required. The context for the template evaluation. +*/}} +{{- define "common.secrets.name" -}} +{{- $name := (include "common.names.fullname" .context) -}} + +{{- if .defaultNameSuffix -}} +{{- $name = printf "%s-%s" $name .defaultNameSuffix | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{- with .existingSecret -}} +{{- if not (typeIs "string" .) -}} +{{- with .name -}} +{{- $name = . -}} +{{- end -}} +{{- else -}} +{{- $name = . -}} +{{- end -}} +{{- end -}} + +{{- printf "%s" $name -}} +{{- end -}} + +{{/* +Generate secret key. + +Usage: +{{ include "common.secrets.key" (dict "existingSecret" .Values.path.to.the.existingSecret "key" "keyName") }} + +Params: + - existingSecret - ExistingSecret/String - Optional. The path to the existing secrets in the values.yaml given by the user + to be used instead of the default one. Allows for it to be of type String (just the secret name) for backwards compatibility. + +info: https://github.com/bitnami/charts/tree/main/bitnami/common#existingsecret + - key - String - Required. Name of the key in the secret. +*/}} +{{- define "common.secrets.key" -}} +{{- $key := .key -}} + +{{- if .existingSecret -}} + {{- if not (typeIs "string" .existingSecret) -}} + {{- if .existingSecret.keyMapping -}} + {{- $key = index .existingSecret.keyMapping $.key -}} + {{- end -}} + {{- end }} +{{- end -}} + +{{- printf "%s" $key -}} +{{- end -}} + +{{/* +Generate secret password or retrieve one if already created. + +Usage: +{{ include "common.secrets.passwords.manage" (dict "secret" "secret-name" "key" "keyName" "providedValues" (list "path.to.password1" "path.to.password2") "length" 10 "strong" false "chartName" "chartName" "context" $) }} + +Params: + - secret - String - Required - Name of the 'Secret' resource where the password is stored. + - key - String - Required - Name of the key in the secret. + - providedValues - List - Required - The path to the validating value in the values.yaml, e.g: "mysql.password". Will pick first parameter with a defined value. + - length - int - Optional - Length of the generated random password. + - strong - Boolean - Optional - Whether to add symbols to the generated random password. + - chartName - String - Optional - Name of the chart used when said chart is deployed as a subchart. + - context - Context - Required - Parent context. + +The order in which this function returns a secret password: + 1. Already existing 'Secret' resource + (If a 'Secret' resource is found under the name provided to the 'secret' parameter to this function and that 'Secret' resource contains a key with the name passed as the 'key' parameter to this function then the value of this existing secret password will be returned) + 2. Password provided via the values.yaml + (If one of the keys passed to the 'providedValues' parameter to this function is a valid path to a key in the values.yaml and has a value, the value of the first key with a value will be returned) + 3. Randomly generated secret password + (A new random secret password with the length specified in the 'length' parameter will be generated and returned) + +*/}} +{{- define "common.secrets.passwords.manage" -}} + +{{- $password := "" }} +{{- $subchart := "" }} +{{- $chartName := default "" .chartName }} +{{- $passwordLength := default 10 .length }} +{{- $providedPasswordKey := include "common.utils.getKeyFromList" (dict "keys" .providedValues "context" $.context) }} +{{- $providedPasswordValue := include "common.utils.getValueFromKey" (dict "key" $providedPasswordKey "context" $.context) }} +{{- $secretData := (lookup "v1" "Secret" (include "common.names.namespace" .context) .secret).data }} +{{- if $secretData }} + {{- if hasKey $secretData .key }} + {{- $password = index $secretData .key | quote }} + {{- else }} + {{- printf "\nPASSWORDS ERROR: The secret \"%s\" does not contain the key \"%s\"\n" .secret .key | fail -}} + {{- end -}} +{{- else if $providedPasswordValue }} + {{- $password = $providedPasswordValue | toString | b64enc | quote }} +{{- else }} + + {{- if .context.Values.enabled }} + {{- $subchart = $chartName }} + {{- end -}} + + {{- $requiredPassword := dict "valueKey" $providedPasswordKey "secret" .secret "field" .key "subchart" $subchart "context" $.context -}} + {{- $requiredPasswordError := include "common.validations.values.single.empty" $requiredPassword -}} + {{- $passwordValidationErrors := list $requiredPasswordError -}} + {{- include "common.errors.upgrade.passwords.empty" (dict "validationErrors" $passwordValidationErrors "context" $.context) -}} + + {{- if .strong }} + {{- $subStr := list (lower (randAlpha 1)) (randNumeric 1) (upper (randAlpha 1)) | join "_" }} + {{- $password = randAscii $passwordLength }} + {{- $password = regexReplaceAllLiteral "\\W" $password "@" | substr 5 $passwordLength }} + {{- $password = printf "%s%s" $subStr $password | toString | shuffle | b64enc | quote }} + {{- else }} + {{- $password = randAlphaNum $passwordLength | b64enc | quote }} + {{- end }} +{{- end -}} +{{- printf "%s" $password -}} +{{- end -}} + +{{/* +Reuses the value from an existing secret, otherwise sets its value to a default value. + +Usage: +{{ include "common.secrets.lookup" (dict "secret" "secret-name" "key" "keyName" "defaultValue" .Values.myValue "context" $) }} + +Params: + - secret - String - Required - Name of the 'Secret' resource where the password is stored. + - key - String - Required - Name of the key in the secret. + - defaultValue - String - Required - The path to the validating value in the values.yaml, e.g: "mysql.password". Will pick first parameter with a defined value. + - context - Context - Required - Parent context. + +*/}} +{{- define "common.secrets.lookup" -}} +{{- $value := "" -}} +{{- $defaultValue := required "\n'common.secrets.lookup': Argument 'defaultValue' missing or empty" .defaultValue -}} +{{- $secretData := (lookup "v1" "Secret" (include "common.names.namespace" .context) .secret).data -}} +{{- if and $secretData (hasKey $secretData .key) -}} + {{- $value = index $secretData .key -}} +{{- else -}} + {{- $value = $defaultValue | toString | b64enc -}} +{{- end -}} +{{- printf "%s" $value -}} +{{- end -}} + +{{/* +Returns whether a previous generated secret already exists + +Usage: +{{ include "common.secrets.exists" (dict "secret" "secret-name" "context" $) }} + +Params: + - secret - String - Required - Name of the 'Secret' resource where the password is stored. + - context - Context - Required - Parent context. +*/}} +{{- define "common.secrets.exists" -}} +{{- $secret := (lookup "v1" "Secret" (include "common.names.namespace" .context) .secret) }} +{{- if $secret }} + {{- true -}} +{{- end -}} +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/_storage.tpl b/helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/_storage.tpl new file mode 100644 index 0000000..60e2a84 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/_storage.tpl @@ -0,0 +1,23 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Return the proper Storage Class +{{ include "common.storage.class" ( dict "persistence" .Values.path.to.the.persistence "global" $) }} +*/}} +{{- define "common.storage.class" -}} + +{{- $storageClass := .persistence.storageClass -}} +{{- if .global -}} + {{- if .global.storageClass -}} + {{- $storageClass = .global.storageClass -}} + {{- end -}} +{{- end -}} + +{{- if $storageClass -}} + {{- if (eq "-" $storageClass) -}} + {{- printf "storageClassName: \"\"" -}} + {{- else }} + {{- printf "storageClassName: %s" $storageClass -}} + {{- end -}} +{{- end -}} + +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/_tplvalues.tpl b/helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/_tplvalues.tpl new file mode 100644 index 0000000..2db1668 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/_tplvalues.tpl @@ -0,0 +1,13 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Renders a value that contains template. +Usage: +{{ include "common.tplvalues.render" ( dict "value" .Values.path.to.the.Value "context" $) }} +*/}} +{{- define "common.tplvalues.render" -}} + {{- if typeIs "string" .value }} + {{- tpl .value .context }} + {{- else }} + {{- tpl (.value | toYaml) .context }} + {{- end }} +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/_utils.tpl b/helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/_utils.tpl new file mode 100644 index 0000000..b1ead50 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/_utils.tpl @@ -0,0 +1,62 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Print instructions to get a secret value. +Usage: +{{ include "common.utils.secret.getvalue" (dict "secret" "secret-name" "field" "secret-value-field" "context" $) }} +*/}} +{{- define "common.utils.secret.getvalue" -}} +{{- $varname := include "common.utils.fieldToEnvVar" . -}} +export {{ $varname }}=$(kubectl get secret --namespace {{ include "common.names.namespace" .context | quote }} {{ .secret }} -o jsonpath="{.data.{{ .field }}}" | base64 -d) +{{- end -}} + +{{/* +Build env var name given a field +Usage: +{{ include "common.utils.fieldToEnvVar" dict "field" "my-password" }} +*/}} +{{- define "common.utils.fieldToEnvVar" -}} + {{- $fieldNameSplit := splitList "-" .field -}} + {{- $upperCaseFieldNameSplit := list -}} + + {{- range $fieldNameSplit -}} + {{- $upperCaseFieldNameSplit = append $upperCaseFieldNameSplit ( upper . ) -}} + {{- end -}} + + {{ join "_" $upperCaseFieldNameSplit }} +{{- end -}} + +{{/* +Gets a value from .Values given +Usage: +{{ include "common.utils.getValueFromKey" (dict "key" "path.to.key" "context" $) }} +*/}} +{{- define "common.utils.getValueFromKey" -}} +{{- $splitKey := splitList "." .key -}} +{{- $value := "" -}} +{{- $latestObj := $.context.Values -}} +{{- range $splitKey -}} + {{- if not $latestObj -}} + {{- printf "please review the entire path of '%s' exists in values" $.key | fail -}} + {{- end -}} + {{- $value = ( index $latestObj . ) -}} + {{- $latestObj = $value -}} +{{- end -}} +{{- printf "%v" (default "" $value) -}} +{{- end -}} + +{{/* +Returns first .Values key with a defined value or first of the list if all non-defined +Usage: +{{ include "common.utils.getKeyFromList" (dict "keys" (list "path.to.key1" "path.to.key2") "context" $) }} +*/}} +{{- define "common.utils.getKeyFromList" -}} +{{- $key := first .keys -}} +{{- $reverseKeys := reverse .keys }} +{{- range $reverseKeys }} + {{- $value := include "common.utils.getValueFromKey" (dict "key" . "context" $.context ) }} + {{- if $value -}} + {{- $key = . }} + {{- end -}} +{{- end -}} +{{- printf "%s" $key -}} +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/_warnings.tpl b/helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/_warnings.tpl new file mode 100644 index 0000000..ae10fa4 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/_warnings.tpl @@ -0,0 +1,14 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Warning about using rolling tag. +Usage: +{{ include "common.warnings.rollingTag" .Values.path.to.the.imageRoot }} +*/}} +{{- define "common.warnings.rollingTag" -}} + +{{- if and (contains "bitnami/" .repository) (not (.tag | toString | regexFind "-r\\d+$|sha256:")) }} +WARNING: Rolling tag detected ({{ .repository }}:{{ .tag }}), please note that it is strongly recommended to avoid using rolling tags in a production environment. ++info https://docs.bitnami.com/containers/how-to/understand-rolling-tags-containers/ +{{- end }} + +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/validations/_cassandra.tpl b/helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/validations/_cassandra.tpl new file mode 100644 index 0000000..ded1ae3 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/validations/_cassandra.tpl @@ -0,0 +1,72 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Validate Cassandra required passwords are not empty. + +Usage: +{{ include "common.validations.values.cassandra.passwords" (dict "secret" "secretName" "subchart" false "context" $) }} +Params: + - secret - String - Required. Name of the secret where Cassandra values are stored, e.g: "cassandra-passwords-secret" + - subchart - Boolean - Optional. Whether Cassandra is used as subchart or not. Default: false +*/}} +{{- define "common.validations.values.cassandra.passwords" -}} + {{- $existingSecret := include "common.cassandra.values.existingSecret" . -}} + {{- $enabled := include "common.cassandra.values.enabled" . -}} + {{- $dbUserPrefix := include "common.cassandra.values.key.dbUser" . -}} + {{- $valueKeyPassword := printf "%s.password" $dbUserPrefix -}} + + {{- if and (or (not $existingSecret) (eq $existingSecret "\"\"")) (eq $enabled "true") -}} + {{- $requiredPasswords := list -}} + + {{- $requiredPassword := dict "valueKey" $valueKeyPassword "secret" .secret "field" "cassandra-password" -}} + {{- $requiredPasswords = append $requiredPasswords $requiredPassword -}} + + {{- include "common.validations.values.multiple.empty" (dict "required" $requiredPasswords "context" .context) -}} + + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for existingSecret. + +Usage: +{{ include "common.cassandra.values.existingSecret" (dict "context" $) }} +Params: + - subchart - Boolean - Optional. Whether Cassandra is used as subchart or not. Default: false +*/}} +{{- define "common.cassandra.values.existingSecret" -}} + {{- if .subchart -}} + {{- .context.Values.cassandra.dbUser.existingSecret | quote -}} + {{- else -}} + {{- .context.Values.dbUser.existingSecret | quote -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for enabled cassandra. + +Usage: +{{ include "common.cassandra.values.enabled" (dict "context" $) }} +*/}} +{{- define "common.cassandra.values.enabled" -}} + {{- if .subchart -}} + {{- printf "%v" .context.Values.cassandra.enabled -}} + {{- else -}} + {{- printf "%v" (not .context.Values.enabled) -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for the key dbUser + +Usage: +{{ include "common.cassandra.values.key.dbUser" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether Cassandra is used as subchart or not. Default: false +*/}} +{{- define "common.cassandra.values.key.dbUser" -}} + {{- if .subchart -}} + cassandra.dbUser + {{- else -}} + dbUser + {{- end -}} +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/validations/_mariadb.tpl b/helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/validations/_mariadb.tpl new file mode 100644 index 0000000..b6906ff --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/validations/_mariadb.tpl @@ -0,0 +1,103 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Validate MariaDB required passwords are not empty. + +Usage: +{{ include "common.validations.values.mariadb.passwords" (dict "secret" "secretName" "subchart" false "context" $) }} +Params: + - secret - String - Required. Name of the secret where MariaDB values are stored, e.g: "mysql-passwords-secret" + - subchart - Boolean - Optional. Whether MariaDB is used as subchart or not. Default: false +*/}} +{{- define "common.validations.values.mariadb.passwords" -}} + {{- $existingSecret := include "common.mariadb.values.auth.existingSecret" . -}} + {{- $enabled := include "common.mariadb.values.enabled" . -}} + {{- $architecture := include "common.mariadb.values.architecture" . -}} + {{- $authPrefix := include "common.mariadb.values.key.auth" . -}} + {{- $valueKeyRootPassword := printf "%s.rootPassword" $authPrefix -}} + {{- $valueKeyUsername := printf "%s.username" $authPrefix -}} + {{- $valueKeyPassword := printf "%s.password" $authPrefix -}} + {{- $valueKeyReplicationPassword := printf "%s.replicationPassword" $authPrefix -}} + + {{- if and (or (not $existingSecret) (eq $existingSecret "\"\"")) (eq $enabled "true") -}} + {{- $requiredPasswords := list -}} + + {{- $requiredRootPassword := dict "valueKey" $valueKeyRootPassword "secret" .secret "field" "mariadb-root-password" -}} + {{- $requiredPasswords = append $requiredPasswords $requiredRootPassword -}} + + {{- $valueUsername := include "common.utils.getValueFromKey" (dict "key" $valueKeyUsername "context" .context) }} + {{- if not (empty $valueUsername) -}} + {{- $requiredPassword := dict "valueKey" $valueKeyPassword "secret" .secret "field" "mariadb-password" -}} + {{- $requiredPasswords = append $requiredPasswords $requiredPassword -}} + {{- end -}} + + {{- if (eq $architecture "replication") -}} + {{- $requiredReplicationPassword := dict "valueKey" $valueKeyReplicationPassword "secret" .secret "field" "mariadb-replication-password" -}} + {{- $requiredPasswords = append $requiredPasswords $requiredReplicationPassword -}} + {{- end -}} + + {{- include "common.validations.values.multiple.empty" (dict "required" $requiredPasswords "context" .context) -}} + + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for existingSecret. + +Usage: +{{ include "common.mariadb.values.auth.existingSecret" (dict "context" $) }} +Params: + - subchart - Boolean - Optional. Whether MariaDB is used as subchart or not. Default: false +*/}} +{{- define "common.mariadb.values.auth.existingSecret" -}} + {{- if .subchart -}} + {{- .context.Values.mariadb.auth.existingSecret | quote -}} + {{- else -}} + {{- .context.Values.auth.existingSecret | quote -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for enabled mariadb. + +Usage: +{{ include "common.mariadb.values.enabled" (dict "context" $) }} +*/}} +{{- define "common.mariadb.values.enabled" -}} + {{- if .subchart -}} + {{- printf "%v" .context.Values.mariadb.enabled -}} + {{- else -}} + {{- printf "%v" (not .context.Values.enabled) -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for architecture + +Usage: +{{ include "common.mariadb.values.architecture" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether MariaDB is used as subchart or not. Default: false +*/}} +{{- define "common.mariadb.values.architecture" -}} + {{- if .subchart -}} + {{- .context.Values.mariadb.architecture -}} + {{- else -}} + {{- .context.Values.architecture -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for the key auth + +Usage: +{{ include "common.mariadb.values.key.auth" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether MariaDB is used as subchart or not. Default: false +*/}} +{{- define "common.mariadb.values.key.auth" -}} + {{- if .subchart -}} + mariadb.auth + {{- else -}} + auth + {{- end -}} +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/validations/_mongodb.tpl b/helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/validations/_mongodb.tpl new file mode 100644 index 0000000..f820ec1 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/validations/_mongodb.tpl @@ -0,0 +1,108 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Validate MongoDB® required passwords are not empty. + +Usage: +{{ include "common.validations.values.mongodb.passwords" (dict "secret" "secretName" "subchart" false "context" $) }} +Params: + - secret - String - Required. Name of the secret where MongoDB® values are stored, e.g: "mongodb-passwords-secret" + - subchart - Boolean - Optional. Whether MongoDB® is used as subchart or not. Default: false +*/}} +{{- define "common.validations.values.mongodb.passwords" -}} + {{- $existingSecret := include "common.mongodb.values.auth.existingSecret" . -}} + {{- $enabled := include "common.mongodb.values.enabled" . -}} + {{- $authPrefix := include "common.mongodb.values.key.auth" . -}} + {{- $architecture := include "common.mongodb.values.architecture" . -}} + {{- $valueKeyRootPassword := printf "%s.rootPassword" $authPrefix -}} + {{- $valueKeyUsername := printf "%s.username" $authPrefix -}} + {{- $valueKeyDatabase := printf "%s.database" $authPrefix -}} + {{- $valueKeyPassword := printf "%s.password" $authPrefix -}} + {{- $valueKeyReplicaSetKey := printf "%s.replicaSetKey" $authPrefix -}} + {{- $valueKeyAuthEnabled := printf "%s.enabled" $authPrefix -}} + + {{- $authEnabled := include "common.utils.getValueFromKey" (dict "key" $valueKeyAuthEnabled "context" .context) -}} + + {{- if and (or (not $existingSecret) (eq $existingSecret "\"\"")) (eq $enabled "true") (eq $authEnabled "true") -}} + {{- $requiredPasswords := list -}} + + {{- $requiredRootPassword := dict "valueKey" $valueKeyRootPassword "secret" .secret "field" "mongodb-root-password" -}} + {{- $requiredPasswords = append $requiredPasswords $requiredRootPassword -}} + + {{- $valueUsername := include "common.utils.getValueFromKey" (dict "key" $valueKeyUsername "context" .context) }} + {{- $valueDatabase := include "common.utils.getValueFromKey" (dict "key" $valueKeyDatabase "context" .context) }} + {{- if and $valueUsername $valueDatabase -}} + {{- $requiredPassword := dict "valueKey" $valueKeyPassword "secret" .secret "field" "mongodb-password" -}} + {{- $requiredPasswords = append $requiredPasswords $requiredPassword -}} + {{- end -}} + + {{- if (eq $architecture "replicaset") -}} + {{- $requiredReplicaSetKey := dict "valueKey" $valueKeyReplicaSetKey "secret" .secret "field" "mongodb-replica-set-key" -}} + {{- $requiredPasswords = append $requiredPasswords $requiredReplicaSetKey -}} + {{- end -}} + + {{- include "common.validations.values.multiple.empty" (dict "required" $requiredPasswords "context" .context) -}} + + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for existingSecret. + +Usage: +{{ include "common.mongodb.values.auth.existingSecret" (dict "context" $) }} +Params: + - subchart - Boolean - Optional. Whether MongoDb is used as subchart or not. Default: false +*/}} +{{- define "common.mongodb.values.auth.existingSecret" -}} + {{- if .subchart -}} + {{- .context.Values.mongodb.auth.existingSecret | quote -}} + {{- else -}} + {{- .context.Values.auth.existingSecret | quote -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for enabled mongodb. + +Usage: +{{ include "common.mongodb.values.enabled" (dict "context" $) }} +*/}} +{{- define "common.mongodb.values.enabled" -}} + {{- if .subchart -}} + {{- printf "%v" .context.Values.mongodb.enabled -}} + {{- else -}} + {{- printf "%v" (not .context.Values.enabled) -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for the key auth + +Usage: +{{ include "common.mongodb.values.key.auth" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether MongoDB® is used as subchart or not. Default: false +*/}} +{{- define "common.mongodb.values.key.auth" -}} + {{- if .subchart -}} + mongodb.auth + {{- else -}} + auth + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for architecture + +Usage: +{{ include "common.mongodb.values.architecture" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether MongoDB® is used as subchart or not. Default: false +*/}} +{{- define "common.mongodb.values.architecture" -}} + {{- if .subchart -}} + {{- .context.Values.mongodb.architecture -}} + {{- else -}} + {{- .context.Values.architecture -}} + {{- end -}} +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/validations/_mysql.tpl b/helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/validations/_mysql.tpl new file mode 100644 index 0000000..74472a0 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/validations/_mysql.tpl @@ -0,0 +1,103 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Validate MySQL required passwords are not empty. + +Usage: +{{ include "common.validations.values.mysql.passwords" (dict "secret" "secretName" "subchart" false "context" $) }} +Params: + - secret - String - Required. Name of the secret where MySQL values are stored, e.g: "mysql-passwords-secret" + - subchart - Boolean - Optional. Whether MySQL is used as subchart or not. Default: false +*/}} +{{- define "common.validations.values.mysql.passwords" -}} + {{- $existingSecret := include "common.mysql.values.auth.existingSecret" . -}} + {{- $enabled := include "common.mysql.values.enabled" . -}} + {{- $architecture := include "common.mysql.values.architecture" . -}} + {{- $authPrefix := include "common.mysql.values.key.auth" . -}} + {{- $valueKeyRootPassword := printf "%s.rootPassword" $authPrefix -}} + {{- $valueKeyUsername := printf "%s.username" $authPrefix -}} + {{- $valueKeyPassword := printf "%s.password" $authPrefix -}} + {{- $valueKeyReplicationPassword := printf "%s.replicationPassword" $authPrefix -}} + + {{- if and (or (not $existingSecret) (eq $existingSecret "\"\"")) (eq $enabled "true") -}} + {{- $requiredPasswords := list -}} + + {{- $requiredRootPassword := dict "valueKey" $valueKeyRootPassword "secret" .secret "field" "mysql-root-password" -}} + {{- $requiredPasswords = append $requiredPasswords $requiredRootPassword -}} + + {{- $valueUsername := include "common.utils.getValueFromKey" (dict "key" $valueKeyUsername "context" .context) }} + {{- if not (empty $valueUsername) -}} + {{- $requiredPassword := dict "valueKey" $valueKeyPassword "secret" .secret "field" "mysql-password" -}} + {{- $requiredPasswords = append $requiredPasswords $requiredPassword -}} + {{- end -}} + + {{- if (eq $architecture "replication") -}} + {{- $requiredReplicationPassword := dict "valueKey" $valueKeyReplicationPassword "secret" .secret "field" "mysql-replication-password" -}} + {{- $requiredPasswords = append $requiredPasswords $requiredReplicationPassword -}} + {{- end -}} + + {{- include "common.validations.values.multiple.empty" (dict "required" $requiredPasswords "context" .context) -}} + + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for existingSecret. + +Usage: +{{ include "common.mysql.values.auth.existingSecret" (dict "context" $) }} +Params: + - subchart - Boolean - Optional. Whether MySQL is used as subchart or not. Default: false +*/}} +{{- define "common.mysql.values.auth.existingSecret" -}} + {{- if .subchart -}} + {{- .context.Values.mysql.auth.existingSecret | quote -}} + {{- else -}} + {{- .context.Values.auth.existingSecret | quote -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for enabled mysql. + +Usage: +{{ include "common.mysql.values.enabled" (dict "context" $) }} +*/}} +{{- define "common.mysql.values.enabled" -}} + {{- if .subchart -}} + {{- printf "%v" .context.Values.mysql.enabled -}} + {{- else -}} + {{- printf "%v" (not .context.Values.enabled) -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for architecture + +Usage: +{{ include "common.mysql.values.architecture" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether MySQL is used as subchart or not. Default: false +*/}} +{{- define "common.mysql.values.architecture" -}} + {{- if .subchart -}} + {{- .context.Values.mysql.architecture -}} + {{- else -}} + {{- .context.Values.architecture -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for the key auth + +Usage: +{{ include "common.mysql.values.key.auth" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether MySQL is used as subchart or not. Default: false +*/}} +{{- define "common.mysql.values.key.auth" -}} + {{- if .subchart -}} + mysql.auth + {{- else -}} + auth + {{- end -}} +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/validations/_postgresql.tpl b/helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/validations/_postgresql.tpl new file mode 100644 index 0000000..164ec0d --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/validations/_postgresql.tpl @@ -0,0 +1,129 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Validate PostgreSQL required passwords are not empty. + +Usage: +{{ include "common.validations.values.postgresql.passwords" (dict "secret" "secretName" "subchart" false "context" $) }} +Params: + - secret - String - Required. Name of the secret where postgresql values are stored, e.g: "postgresql-passwords-secret" + - subchart - Boolean - Optional. Whether postgresql is used as subchart or not. Default: false +*/}} +{{- define "common.validations.values.postgresql.passwords" -}} + {{- $existingSecret := include "common.postgresql.values.existingSecret" . -}} + {{- $enabled := include "common.postgresql.values.enabled" . -}} + {{- $valueKeyPostgresqlPassword := include "common.postgresql.values.key.postgressPassword" . -}} + {{- $valueKeyPostgresqlReplicationEnabled := include "common.postgresql.values.key.replicationPassword" . -}} + {{- if and (or (not $existingSecret) (eq $existingSecret "\"\"")) (eq $enabled "true") -}} + {{- $requiredPasswords := list -}} + {{- $requiredPostgresqlPassword := dict "valueKey" $valueKeyPostgresqlPassword "secret" .secret "field" "postgresql-password" -}} + {{- $requiredPasswords = append $requiredPasswords $requiredPostgresqlPassword -}} + + {{- $enabledReplication := include "common.postgresql.values.enabled.replication" . -}} + {{- if (eq $enabledReplication "true") -}} + {{- $requiredPostgresqlReplicationPassword := dict "valueKey" $valueKeyPostgresqlReplicationEnabled "secret" .secret "field" "postgresql-replication-password" -}} + {{- $requiredPasswords = append $requiredPasswords $requiredPostgresqlReplicationPassword -}} + {{- end -}} + + {{- include "common.validations.values.multiple.empty" (dict "required" $requiredPasswords "context" .context) -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to decide whether evaluate global values. + +Usage: +{{ include "common.postgresql.values.use.global" (dict "key" "key-of-global" "context" $) }} +Params: + - key - String - Required. Field to be evaluated within global, e.g: "existingSecret" +*/}} +{{- define "common.postgresql.values.use.global" -}} + {{- if .context.Values.global -}} + {{- if .context.Values.global.postgresql -}} + {{- index .context.Values.global.postgresql .key | quote -}} + {{- end -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for existingSecret. + +Usage: +{{ include "common.postgresql.values.existingSecret" (dict "context" $) }} +*/}} +{{- define "common.postgresql.values.existingSecret" -}} + {{- $globalValue := include "common.postgresql.values.use.global" (dict "key" "existingSecret" "context" .context) -}} + + {{- if .subchart -}} + {{- default (.context.Values.postgresql.existingSecret | quote) $globalValue -}} + {{- else -}} + {{- default (.context.Values.existingSecret | quote) $globalValue -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for enabled postgresql. + +Usage: +{{ include "common.postgresql.values.enabled" (dict "context" $) }} +*/}} +{{- define "common.postgresql.values.enabled" -}} + {{- if .subchart -}} + {{- printf "%v" .context.Values.postgresql.enabled -}} + {{- else -}} + {{- printf "%v" (not .context.Values.enabled) -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for the key postgressPassword. + +Usage: +{{ include "common.postgresql.values.key.postgressPassword" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether postgresql is used as subchart or not. Default: false +*/}} +{{- define "common.postgresql.values.key.postgressPassword" -}} + {{- $globalValue := include "common.postgresql.values.use.global" (dict "key" "postgresqlUsername" "context" .context) -}} + + {{- if not $globalValue -}} + {{- if .subchart -}} + postgresql.postgresqlPassword + {{- else -}} + postgresqlPassword + {{- end -}} + {{- else -}} + global.postgresql.postgresqlPassword + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for enabled.replication. + +Usage: +{{ include "common.postgresql.values.enabled.replication" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether postgresql is used as subchart or not. Default: false +*/}} +{{- define "common.postgresql.values.enabled.replication" -}} + {{- if .subchart -}} + {{- printf "%v" .context.Values.postgresql.replication.enabled -}} + {{- else -}} + {{- printf "%v" .context.Values.replication.enabled -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for the key replication.password. + +Usage: +{{ include "common.postgresql.values.key.replicationPassword" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether postgresql is used as subchart or not. Default: false +*/}} +{{- define "common.postgresql.values.key.replicationPassword" -}} + {{- if .subchart -}} + postgresql.replication.password + {{- else -}} + replication.password + {{- end -}} +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/validations/_redis.tpl b/helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/validations/_redis.tpl new file mode 100644 index 0000000..dcccfc1 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/validations/_redis.tpl @@ -0,0 +1,76 @@ + +{{/* vim: set filetype=mustache: */}} +{{/* +Validate Redis® required passwords are not empty. + +Usage: +{{ include "common.validations.values.redis.passwords" (dict "secret" "secretName" "subchart" false "context" $) }} +Params: + - secret - String - Required. Name of the secret where redis values are stored, e.g: "redis-passwords-secret" + - subchart - Boolean - Optional. Whether redis is used as subchart or not. Default: false +*/}} +{{- define "common.validations.values.redis.passwords" -}} + {{- $enabled := include "common.redis.values.enabled" . -}} + {{- $valueKeyPrefix := include "common.redis.values.keys.prefix" . -}} + {{- $standarizedVersion := include "common.redis.values.standarized.version" . }} + + {{- $existingSecret := ternary (printf "%s%s" $valueKeyPrefix "auth.existingSecret") (printf "%s%s" $valueKeyPrefix "existingSecret") (eq $standarizedVersion "true") }} + {{- $existingSecretValue := include "common.utils.getValueFromKey" (dict "key" $existingSecret "context" .context) }} + + {{- $valueKeyRedisPassword := ternary (printf "%s%s" $valueKeyPrefix "auth.password") (printf "%s%s" $valueKeyPrefix "password") (eq $standarizedVersion "true") }} + {{- $valueKeyRedisUseAuth := ternary (printf "%s%s" $valueKeyPrefix "auth.enabled") (printf "%s%s" $valueKeyPrefix "usePassword") (eq $standarizedVersion "true") }} + + {{- if and (or (not $existingSecret) (eq $existingSecret "\"\"")) (eq $enabled "true") -}} + {{- $requiredPasswords := list -}} + + {{- $useAuth := include "common.utils.getValueFromKey" (dict "key" $valueKeyRedisUseAuth "context" .context) -}} + {{- if eq $useAuth "true" -}} + {{- $requiredRedisPassword := dict "valueKey" $valueKeyRedisPassword "secret" .secret "field" "redis-password" -}} + {{- $requiredPasswords = append $requiredPasswords $requiredRedisPassword -}} + {{- end -}} + + {{- include "common.validations.values.multiple.empty" (dict "required" $requiredPasswords "context" .context) -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for enabled redis. + +Usage: +{{ include "common.redis.values.enabled" (dict "context" $) }} +*/}} +{{- define "common.redis.values.enabled" -}} + {{- if .subchart -}} + {{- printf "%v" .context.Values.redis.enabled -}} + {{- else -}} + {{- printf "%v" (not .context.Values.enabled) -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right prefix path for the values + +Usage: +{{ include "common.redis.values.key.prefix" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether redis is used as subchart or not. Default: false +*/}} +{{- define "common.redis.values.keys.prefix" -}} + {{- if .subchart -}}redis.{{- else -}}{{- end -}} +{{- end -}} + +{{/* +Checks whether the redis chart's includes the standarizations (version >= 14) + +Usage: +{{ include "common.redis.values.standarized.version" (dict "context" $) }} +*/}} +{{- define "common.redis.values.standarized.version" -}} + + {{- $standarizedAuth := printf "%s%s" (include "common.redis.values.keys.prefix" .) "auth" -}} + {{- $standarizedAuthValues := include "common.utils.getValueFromKey" (dict "key" $standarizedAuth "context" .context) }} + + {{- if $standarizedAuthValues -}} + {{- true -}} + {{- end -}} +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/validations/_validations.tpl b/helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/validations/_validations.tpl new file mode 100644 index 0000000..9a814cf --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/etcd/charts/common/templates/validations/_validations.tpl @@ -0,0 +1,46 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Validate values must not be empty. + +Usage: +{{- $validateValueConf00 := (dict "valueKey" "path.to.value" "secret" "secretName" "field" "password-00") -}} +{{- $validateValueConf01 := (dict "valueKey" "path.to.value" "secret" "secretName" "field" "password-01") -}} +{{ include "common.validations.values.empty" (dict "required" (list $validateValueConf00 $validateValueConf01) "context" $) }} + +Validate value params: + - valueKey - String - Required. The path to the validating value in the values.yaml, e.g: "mysql.password" + - secret - String - Optional. Name of the secret where the validating value is generated/stored, e.g: "mysql-passwords-secret" + - field - String - Optional. Name of the field in the secret data, e.g: "mysql-password" +*/}} +{{- define "common.validations.values.multiple.empty" -}} + {{- range .required -}} + {{- include "common.validations.values.single.empty" (dict "valueKey" .valueKey "secret" .secret "field" .field "context" $.context) -}} + {{- end -}} +{{- end -}} + +{{/* +Validate a value must not be empty. + +Usage: +{{ include "common.validations.value.empty" (dict "valueKey" "mariadb.password" "secret" "secretName" "field" "my-password" "subchart" "subchart" "context" $) }} + +Validate value params: + - valueKey - String - Required. The path to the validating value in the values.yaml, e.g: "mysql.password" + - secret - String - Optional. Name of the secret where the validating value is generated/stored, e.g: "mysql-passwords-secret" + - field - String - Optional. Name of the field in the secret data, e.g: "mysql-password" + - subchart - String - Optional - Name of the subchart that the validated password is part of. +*/}} +{{- define "common.validations.values.single.empty" -}} + {{- $value := include "common.utils.getValueFromKey" (dict "key" .valueKey "context" .context) }} + {{- $subchart := ternary "" (printf "%s." .subchart) (empty .subchart) }} + + {{- if not $value -}} + {{- $varname := "my-value" -}} + {{- $getCurrentValue := "" -}} + {{- if and .secret .field -}} + {{- $varname = include "common.utils.fieldToEnvVar" . -}} + {{- $getCurrentValue = printf " To get the current value:\n\n %s\n" (include "common.utils.secret.getvalue" .) -}} + {{- end -}} + {{- printf "\n '%s' must not be empty, please add '--set %s%s=$%s' to the command.%s" .valueKey $subchart .valueKey $varname $getCurrentValue -}} + {{- end -}} +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/etcd/charts/common/values.yaml b/helm/openebs/charts/mayastor/charts/etcd/charts/common/values.yaml new file mode 100644 index 0000000..f2df68e --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/etcd/charts/common/values.yaml @@ -0,0 +1,5 @@ +## bitnami/common +## It is required by CI/CD tools and processes. +## @skip exampleValue +## +exampleValue: common-chart diff --git a/helm/openebs/charts/mayastor/charts/etcd/templates/NOTES.txt b/helm/openebs/charts/mayastor/charts/etcd/templates/NOTES.txt new file mode 100644 index 0000000..bfa6e16 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/etcd/templates/NOTES.txt @@ -0,0 +1,119 @@ +CHART NAME: {{ .Chart.Name }} +CHART VERSION: {{ .Chart.Version }} +APP VERSION: {{ .Chart.AppVersion }} + +{{- if and (eq .Values.service.type "LoadBalancer") .Values.auth.rbac.allowNoneAuthentication }} +------------------------------------------------------------------------------- + WARNING + + By specifying "service.type=LoadBalancer", "auth.rbac.enabled=false" and + "auth.rbac.allowNoneAuthentication=true" you have most likely exposed the etcd + service externally without any authentication mechanism. + + For security reasons, we strongly suggest that you switch to "ClusterIP" or + "NodePort". As alternative, you can also switch to "auth.rbac.enabled=true" + providing a valid password on "auth.rbac.rootPassword" parameter. + +------------------------------------------------------------------------------- +{{- end }} + +** Please be patient while the chart is being deployed ** + +{{- if .Values.diagnosticMode.enabled }} +The chart has been deployed in diagnostic mode. All probes have been disabled and the command has been overwritten with: + + command: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.command "context" $) | nindent 4 }} + args: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.args "context" $) | nindent 4 }} + +Get the list of pods by executing: + + kubectl get pods --namespace {{ .Release.Namespace }} -l app.kubernetes.io/instance={{ .Release.Name }} + +Access the pod you want to debug by executing + + kubectl exec --namespace {{ .Release.Namespace }} -ti -- bash + +In order to replicate the container startup scripts execute this command: + + /opt/bitnami/scripts/etcd/entrypoint.sh /opt/bitnami/scripts/etcd/run.sh + +{{- else }} + +etcd can be accessed via port {{ coalesce .Values.service.ports.client .Values.service.port }} on the following DNS name from within your cluster: + + {{ template "common.names.fullname" . }}.{{ .Release.Namespace }}.svc.{{ .Values.clusterDomain }} + +To create a pod that you can use as a etcd client run the following command: + + kubectl run {{ template "common.names.fullname" . }}-client --restart='Never' --image {{ template "etcd.image" . }}{{- if or .Values.auth.rbac.create .Values.auth.rbac.enabled }} --env ROOT_PASSWORD=$(kubectl get secret --namespace {{ .Release.Namespace }} {{ template "common.names.fullname" . }} -o jsonpath="{.data.etcd-root-password}" | base64 -d){{- end }} --env ETCDCTL_ENDPOINTS="{{ template "common.names.fullname" . }}.{{ .Release.Namespace }}.svc.{{ .Values.clusterDomain }}:{{ coalesce .Values.service.ports.client .Values.service.port }}" --namespace {{ .Release.Namespace }} --command -- sleep infinity + +Then, you can set/get a key using the commands below: + + kubectl exec --namespace {{ .Release.Namespace }} -it {{ template "common.names.fullname" . }}-client -- bash + {{- $etcdAuthOptions := include "etcd.authOptions" . }} + etcdctl {{ $etcdAuthOptions }} put /message Hello + etcdctl {{ $etcdAuthOptions }} get /message + +To connect to your etcd server from outside the cluster execute the following commands: + +{{- if contains "NodePort" .Values.service.type }} + + export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") + export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "common.names.fullname" . }}) + echo "etcd URL: 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. + Watch the status with: 'kubectl get svc --namespace {{ .Release.Namespace }} -w {{ template "common.names.fullname" . }}' + + export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "common.names.fullname" . }} --template "{{ "{{ range (index .status.loadBalancer.ingress 0) }}{{ . }}{{ end }}" }}") + echo "etcd URL: http://$SERVICE_IP:{{ coalesce .Values.service.ports.client .Values.service.port }}/" + +{{- else if contains "ClusterIP" .Values.service.type }} + + kubectl port-forward --namespace {{ .Release.Namespace }} svc/{{ template "common.names.fullname" . }} {{ coalesce .Values.service.ports.client .Values.service.port }}:{{ coalesce .Values.service.ports.client .Values.service.port }} & + echo "etcd URL: http://127.0.0.1:{{ coalesce .Values.service.ports.client .Values.service.port }}" + +{{- end }} +{{- if or .Values.auth.rbac.create .Values.auth.rbac.enabled }} + + * As rbac is enabled you should add the flag `--user root:$ETCD_ROOT_PASSWORD` to the etcdctl commands. Use the command below to export the password: + + export ETCD_ROOT_PASSWORD=$(kubectl get secret --namespace {{ .Release.Namespace }} {{ template "common.names.fullname" . }} -o jsonpath="{.data.etcd-root-password}" | base64 -d) + +{{- end }} +{{- if .Values.auth.client.secureTransport }} +{{- if .Values.auth.client.useAutoTLS }} + + * As TLS is enabled you should add the flag `--cert-file /bitnami/etcd/data/fixtures/client/cert.pem --key-file /bitnami/etcd/data/fixtures/client/key.pem` to the etcdctl commands. + +{{- else }} + + * As TLS is enabled you should add the flag `--cert-file /opt/bitnami/etcd/certs/client/{{ .Values.auth.client.certFilename }} --key-file /opt/bitnami/etcd/certs/client/{{ .Values.auth.client.certKeyFilename }}` to the etcdctl commands. + +{{- end }} + + * You should also export a proper etcdctl endpoint using the https schema. Eg. + + export ETCDCTL_ENDPOINTS=https://{{ template "common.names.fullname" . }}-0:{{ coalesce .Values.service.ports.client .Values.service.port }} + +{{- end }} +{{- if .Values.auth.client.enableAuthentication }} + + * As TLS host authentication is enabled you should add the flag `--ca-file /opt/bitnami/etcd/certs/client/{{ .Values.auth.client.caFilename | default "ca.crt" }}` to the etcdctl commands. + +{{- end }} +{{- end }} + +{{- include "common.warnings.rollingTag" .Values.image }} +{{- include "common.warnings.rollingTag" .Values.volumePermissions.image }} +{{- include "etcd.validateValues" . }} +{{- $requiredPassword := list -}} +{{- $secretName := include "etcd.secretName" . -}} +{{- if and (or .Values.auth.rbac.create .Values.auth.rbac.enabled) (not .Values.auth.rbac.existingSecret) -}} + {{- $requiredEtcdPassword := dict "valueKey" "auth.rbac.rootPassword" "secret" $secretName "field" "etcd-root-password" -}} + {{- $requiredPassword = append $requiredPassword $requiredEtcdPassword -}} +{{- end -}} +{{- $requiredEtcdPasswordErrors := include "common.validations.values.multiple.empty" (dict "required" $requiredPassword "context" $) -}} +{{- include "common.errors.upgrade.passwords.empty" (dict "validationErrors" (list $requiredEtcdPasswordErrors) "context" $) -}} diff --git a/helm/openebs/charts/mayastor/charts/etcd/templates/_helpers.tpl b/helm/openebs/charts/mayastor/charts/etcd/templates/_helpers.tpl new file mode 100644 index 0000000..662becc --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/etcd/templates/_helpers.tpl @@ -0,0 +1,205 @@ +{{/* vim: set filetype=mustache: */}} + +{{/* +Return the proper etcd image name +*/}} +{{- define "etcd.image" -}} +{{ include "common.images.image" (dict "imageRoot" .Values.image "global" .Values.global) }} +{{- end -}} + +{{/* +Return the proper image name (for the init container volume-permissions image) +*/}} +{{- define "etcd.volumePermissions.image" -}} +{{ include "common.images.image" (dict "imageRoot" .Values.volumePermissions.image "global" .Values.global) }} +{{- end -}} + +{{/* +Return the proper Docker Image Registry Secret Names +*/}} +{{- define "etcd.imagePullSecrets" -}} +{{ include "common.images.pullSecrets" (dict "images" (list .Values.image .Values.volumePermissions.image) "global" .Values.global) }} +{{- end -}} + +{{/* +Return the proper etcd peer protocol +*/}} +{{- define "etcd.peerProtocol" -}} +{{- if .Values.auth.peer.secureTransport -}} +{{- print "https" -}} +{{- else -}} +{{- print "http" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the proper etcd client protocol +*/}} +{{- define "etcd.clientProtocol" -}} +{{- if .Values.auth.client.secureTransport -}} +{{- print "https" -}} +{{- else -}} +{{- print "http" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the proper etcdctl authentication options +*/}} +{{- define "etcd.authOptions" -}} +{{- $rbacOption := "--user root:$ROOT_PASSWORD" -}} +{{- $certsOption := " --cert $ETCD_CERT_FILE --key $ETCD_KEY_FILE" -}} +{{- $autoCertsOption := " --cert /bitnami/etcd/data/fixtures/client/cert.pem --key /bitnami/etcd/data/fixtures/client/key.pem" -}} +{{- $caOption := " --cacert $ETCD_TRUSTED_CA_FILE" -}} +{{- if or .Values.auth.rbac.create .Values.auth.rbac.enabled -}} + {{- printf "%s" $rbacOption -}} +{{- end -}} +{{- if and .Values.auth.client.secureTransport .Values.auth.client.useAutoTLS -}} + {{- printf "%s" $autoCertsOption -}} +{{- else if and .Values.auth.client.secureTransport (not .Values.auth.client.useAutoTLS) -}} + {{- printf "%s" $certsOption -}} + {{- if .Values.auth.client.enableAuthentication -}} + {{- printf "%s" $caOption -}} + {{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Return the etcd configuration configmap +*/}} +{{- define "etcd.configmapName" -}} +{{- if .Values.existingConfigmap -}} + {{- printf "%s" (tpl .Values.existingConfigmap $) | trunc 63 | trimSuffix "-" -}} +{{- else -}} + {{- printf "%s-configuration" (include "common.names.fullname" .) | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} + +{{/* +Return true if a configmap object should be created +*/}} +{{- define "etcd.createConfigmap" -}} +{{- if and .Values.configuration (not .Values.existingConfigmap) }} + {{- true -}} +{{- end -}} +{{- end -}} + +{{/* +Return the secret with etcd credentials +*/}} +{{- define "etcd.secretName" -}} + {{- if .Values.auth.rbac.existingSecret -}} + {{- printf "%s" .Values.auth.rbac.existingSecret | trunc 63 | trimSuffix "-" -}} + {{- else -}} + {{- printf "%s" (include "common.names.fullname" .) -}} + {{- end -}} +{{- end -}} + +{{/* +Get the secret password key to be retrieved from etcd secret. +*/}} +{{- define "etcd.secretPasswordKey" -}} +{{- if and .Values.auth.rbac.existingSecret .Values.auth.rbac.existingSecretPasswordKey -}} +{{- printf "%s" .Values.auth.rbac.existingSecretPasswordKey -}} +{{- else -}} +{{- printf "etcd-root-password" -}} +{{- end -}} +{{- end -}} + +{{/* +Return true if a secret object should be created for the etcd token private key +*/}} +{{- define "etcd.token.createSecret" -}} +{{- if and (eq .Values.auth.token.type "jwt") (empty .Values.auth.token.privateKey.existingSecret) }} + {{- true -}} +{{- end -}} +{{- end -}} + +{{/* +Return the secret with etcd token private key +*/}} +{{- define "etcd.token.secretName" -}} + {{- if .Values.auth.token.privateKey.existingSecret -}} + {{- printf "%s" .Values.auth.token.privateKey.existingSecret | trunc 63 | trimSuffix "-" -}} + {{- else -}} + {{- printf "%s-jwt-token" (include "common.names.fullname" .) | trunc 63 | trimSuffix "-" -}} + {{- end -}} +{{- end -}} + +{{/* +Return the proper Disaster Recovery PVC name +*/}} +{{- define "etcd.disasterRecovery.pvc.name" -}} +{{- if .Values.disasterRecovery.pvc.existingClaim -}} + {{- printf "%s" (tpl .Values.disasterRecovery.pvc.existingClaim $) | trunc 63 | trimSuffix "-" -}} +{{- else if .Values.startFromSnapshot.existingClaim -}} + {{- printf "%s" (tpl .Values.startFromSnapshot.existingClaim $) | trunc 63 | trimSuffix "-" -}} +{{- else -}} + {{- printf "%s-snapshotter" (include "common.names.fullname" .) | trunc 63 | trimSuffix "-" }} +{{- end -}} +{{- end -}} + +{{/* + Create the name of the service account to use + */}} +{{- define "etcd.serviceAccountName" -}} +{{- if .Values.serviceAccount.create -}} +{{ default (include "common.names.fullname" .) .Values.serviceAccount.name | trunc 63 | trimSuffix "-" }} +{{- else -}} +{{ default "default" .Values.serviceAccount.name | trunc 63 | trimSuffix "-" }} +{{- end -}} +{{- end -}} + +{{/* +Compile all warnings into a single message, and call fail. +*/}} +{{- define "etcd.validateValues" -}} +{{- $messages := list -}} +{{- $messages := append $messages (include "etcd.validateValues.startFromSnapshot.existingClaim" .) -}} +{{- $messages := append $messages (include "etcd.validateValues.startFromSnapshot.snapshotFilename" .) -}} +{{- $messages := append $messages (include "etcd.validateValues.disasterRecovery" .) -}} +{{- $messages := without $messages "" -}} +{{- $message := join "\n" $messages -}} + +{{- if $message -}} +{{- printf "\nVALUES VALIDATION:\n%s" $message | fail -}} +{{- end -}} +{{- end -}} + +{{/* Validate values of etcd - an existing claim must be provided when startFromSnapshot is enabled */}} +{{- define "etcd.validateValues.startFromSnapshot.existingClaim" -}} +{{- if and .Values.startFromSnapshot.enabled (not .Values.startFromSnapshot.existingClaim) (not .Values.disasterRecovery.enabled) -}} +etcd: startFromSnapshot.existingClaim + An existing claim must be provided when startFromSnapshot is enabled and disasterRecovery is disabled!! + Please provide it (--set startFromSnapshot.existingClaim="xxxx") +{{- end -}} +{{- end -}} + +{{/* Validate values of etcd - the snapshot filename must be provided when startFromSnapshot is enabled */}} +{{- define "etcd.validateValues.startFromSnapshot.snapshotFilename" -}} +{{- if and .Values.startFromSnapshot.enabled (not .Values.startFromSnapshot.snapshotFilename) (not .Values.disasterRecovery.enabled) -}} +etcd: startFromSnapshot.snapshotFilename + The snapshot filename must be provided when startFromSnapshot is enabled and disasterRecovery is disabled!! + Please provide it (--set startFromSnapshot.snapshotFilename="xxxx") +{{- end -}} +{{- end -}} + +{{/* Validate values of etcd - persistence must be enabled when disasterRecovery is enabled */}} +{{- define "etcd.validateValues.disasterRecovery" -}} +{{- if and .Values.disasterRecovery.enabled (not .Values.persistence.enabled) -}} +etcd: disasterRecovery + Persistence must be enabled when disasterRecovery is enabled!! + Please enable persistence (--set persistence.enabled=true) +{{- end -}} +{{- end -}} + +{{- define "etcd.token.jwtToken" -}} +{{- if (include "etcd.token.createSecret" .) -}} +{{- $jwtToken := lookup "v1" "Secret" .Release.Namespace (printf "%s-jwt-token" (include "common.names.fullname" .) | trunc 63 | trimSuffix "-" ) -}} +{{- if $jwtToken -}} +{{ index $jwtToken "data" "jwt-token.pem" | b64dec }} +{{- else -}} +{{ genPrivateKey "rsa" }} +{{- end -}} +{{- end -}} +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/etcd/templates/configmap.yaml b/helm/openebs/charts/mayastor/charts/etcd/templates/configmap.yaml new file mode 100644 index 0000000..ca69d7f --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/etcd/templates/configmap.yaml @@ -0,0 +1,17 @@ +{{- if (include "etcd.createConfigmap" .) }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ printf "%s-configuration" (include "common.names.fullname" .) | trunc 63 | trimSuffix "-" }} + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +data: + etcd.conf.yml: |- + {{- include "common.tplvalues.render" ( dict "value" .Values.configuration "context" $ ) | nindent 4 }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/etcd/templates/cronjob.yaml b/helm/openebs/charts/mayastor/charts/etcd/templates/cronjob.yaml new file mode 100644 index 0000000..438cfce --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/etcd/templates/cronjob.yaml @@ -0,0 +1,132 @@ +{{- if .Values.disasterRecovery.enabled -}} +apiVersion: {{ include "common.capabilities.cronjob.apiVersion" . }} +kind: CronJob +metadata: + name: {{ printf "%s-snapshotter" (include "common.names.fullname" .) | trunc 63 | trimSuffix "-" }} + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + concurrencyPolicy: Forbid + schedule: {{ .Values.disasterRecovery.cronjob.schedule | quote }} + successfulJobsHistoryLimit: {{ .Values.disasterRecovery.cronjob.historyLimit }} + jobTemplate: + spec: + template: + metadata: + labels: {{- include "common.labels.standard" . | nindent 12 }} + app.kubernetes.io/component: snapshotter + {{- if .Values.disasterRecovery.cronjob.podAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.disasterRecovery.cronjob.podAnnotations "context" $) | nindent 12 }} + {{- end }} + spec: + {{- if .Values.disasterRecovery.cronjob.nodeSelector }} + nodeSelector: {{- toYaml .Values.disasterRecovery.cronjob.nodeSelector | nindent 12 }} + {{- end }} + {{- if .Values.disasterRecovery.cronjob.tolerations }} + tolerations: {{- toYaml .Values.disasterRecovery.cronjob.tolerations | nindent 12 }} + {{- end }} + {{- include "etcd.imagePullSecrets" . | nindent 10 }} + restartPolicy: OnFailure + {{- if .Values.podSecurityContext.enabled }} + securityContext: {{- omit .Values.podSecurityContext "enabled" | toYaml | nindent 12 }} + {{- end }} + {{- if and .Values.volumePermissions.enabled (or .Values.podSecurityContext.enabled .Values.containerSecurityContext.enabled) }} + initContainers: + - name: volume-permissions + image: {{ include "etcd.volumePermissions.image" . }} + imagePullPolicy: {{ .Values.volumePermissions.image.pullPolicy | quote }} + command: + - /bin/bash + - -ec + - | + chown -R {{ .Values.containerSecurityContext.runAsUser }}:{{ .Values.podSecurityContext.fsGroup }} /snapshots + securityContext: + runAsUser: 0 + {{- if .Values.volumePermissions.resources }} + resources: {{- include "common.tplvalues.render" (dict "value" .Values.volumePermissions.resources "context" $) | nindent 16 }} + {{- end }} + volumeMounts: + - name: snapshot-volume + mountPath: /snapshots + {{- end }} + containers: + - name: etcd-snapshotter + image: {{ include "etcd.image" . }} + imagePullPolicy: {{ .Values.image.pullPolicy | quote }} + {{- if .Values.containerSecurityContext.enabled }} + securityContext: {{- omit .Values.containerSecurityContext "enabled" | toYaml | nindent 16 }} + {{- end }} + {{- if .Values.diagnosticMode.enabled }} + command: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.command "context" $) | nindent 16 }} + args: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.args "context" $) | nindent 16 }} + {{- else }} + command: + - /opt/bitnami/scripts/etcd/snapshot.sh + {{- end }} + env: + - name: BITNAMI_DEBUG + value: {{ ternary "true" "false" (or .Values.image.debug .Values.diagnosticMode.enabled) | quote }} + - name: ETCDCTL_API + value: "3" + - name: ETCD_ON_K8S + value: "yes" + - name: MY_STS_NAME + value: {{ include "common.names.fullname" . | quote }} + {{- $releaseNamespace := .Release.Namespace }} + {{- $etcdFullname := include "common.names.fullname" . }} + {{- $etcdHeadlessServiceName := (printf "%s-%s" $etcdFullname "headless" | trunc 63 | trimSuffix "-") }} + {{- $clusterDomain := .Values.clusterDomain }} + - name: ETCD_CLUSTER_DOMAIN + value: {{ printf "%s.%s.svc.%s" $etcdHeadlessServiceName $releaseNamespace $clusterDomain | quote }} + - name: ETCD_SNAPSHOT_HISTORY_LIMIT + value: {{ .Values.disasterRecovery.cronjob.snapshotHistoryLimit | quote }} + {{- if .Values.auth.client.secureTransport }} + - name: ETCD_CERT_FILE + value: "/opt/bitnami/etcd/certs/client/{{ .Values.auth.client.certFilename }}" + - name: ETCD_KEY_FILE + value: "/opt/bitnami/etcd/certs/client/{{ .Values.auth.client.certKeyFilename }}" + {{- if .Values.auth.client.enableAuthentication }} + - name: ETCD_CLIENT_CERT_AUTH + value: "true" + - name: ETCD_TRUSTED_CA_FILE + value: "/opt/bitnami/etcd/certs/client/{{ .Values.auth.client.caFilename | default "ca.crt" }}" + {{- else if .Values.auth.client.caFilename }} + - name: ETCD_TRUSTED_CA_FILE + value: "/opt/bitnami/etcd/certs/client/{{ .Values.auth.client.caFilename | default "ca.crt" }}" + {{- end }} + {{- end }} + {{- if or .Values.auth.rbac.create .Values.auth.rbac.enabled }} + - name: ETCD_ROOT_PASSWORD + valueFrom: + secretKeyRef: + name: {{ include "etcd.secretName" . }} + key: {{ include "etcd.secretPasswordKey" . }} + {{- end }} + {{- if .Values.disasterRecovery.cronjob.resources }} + resources: {{- toYaml .Values.disasterRecovery.cronjob.resources | nindent 16 }} + {{- end }} + volumeMounts: + - name: snapshot-volume + mountPath: /snapshots + {{- if .Values.auth.client.secureTransport }} + - name: certs + mountPath: /opt/bitnami/etcd/certs/client + readOnly: true + {{- end }} + volumes: + {{- if .Values.auth.client.secureTransport }} + - name: certs + secret: + secretName: {{ required "A secret containinig the client certificates is required" (tpl .Values.auth.client.existingSecret .) }} + defaultMode: 256 + {{- end }} + - name: snapshot-volume + persistentVolumeClaim: + claimName: {{ include "etcd.disasterRecovery.pvc.name" . }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/etcd/templates/extra-list.yaml b/helm/openebs/charts/mayastor/charts/etcd/templates/extra-list.yaml new file mode 100644 index 0000000..9ac65f9 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/etcd/templates/extra-list.yaml @@ -0,0 +1,4 @@ +{{- range .Values.extraDeploy }} +--- +{{ include "common.tplvalues.render" (dict "value" . "context" $) }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/etcd/templates/networkpolicy.yaml b/helm/openebs/charts/mayastor/charts/etcd/templates/networkpolicy.yaml new file mode 100644 index 0000000..c6ce23a --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/etcd/templates/networkpolicy.yaml @@ -0,0 +1,81 @@ +{{- if .Values.networkPolicy.enabled }} +kind: NetworkPolicy +apiVersion: {{ template "common.capabilities.networkPolicy.apiVersion" . }} +metadata: + name: {{ template "common.names.fullname" . }} + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + podSelector: + matchLabels: {{- include "common.labels.standard" . | nindent 6 }} + {{- if .Values.podLabels }} + {{- include "common.tplvalues.render" (dict "value" .Values.podLabels "context" $) | nindent 6 }} + {{- end }} + policyTypes: + - Ingress + - Egress + egress: + # Allow dns resolution + - ports: + - port: 53 + protocol: UDP + - port: 53 + protocol: TCP + # Allow outbound connections to other cluster pods + - ports: + - port: {{ .Values.containerPorts.client }} + - port: {{ .Values.containerPorts.peer }} + to: + - podSelector: + matchLabels: {{- include "common.labels.standard" . | nindent 14 }} + {{- if .Values.podLabels }} + {{- include "common.tplvalues.render" (dict "value" .Values.podLabels "context" $) | nindent 14 }} + {{- end }} + {{- if .Values.networkPolicy.extraEgress }} + {{- include "common.tplvalues.render" ( dict "value" .Values.networkPolicy.extraEgress "context" $ ) | nindent 4 }} + {{- end }} + ingress: + # Allow inbound connections + - ports: + - port: {{ .Values.containerPorts.client }} + - port: {{ .Values.containerPorts.peer }} + {{- if not .Values.networkPolicy.allowExternal }} + from: + - podSelector: + matchLabels: + {{ template "common.names.fullname" . }}-client: "true" + - podSelector: + matchLabels: {{- include "common.labels.standard" . | nindent 14 }} + {{- if .Values.podLabels }} + {{- include "common.tplvalues.render" (dict "value" .Values.podLabels "context" $) | nindent 14 }} + {{- end }} + {{- if .Values.networkPolicy.ingressNSMatchLabels }} + - namespaceSelector: + matchLabels: + {{- range $key, $value := .Values.networkPolicy.ingressNSMatchLabels }} + {{ $key | quote }}: {{ $value | quote }} + {{- end }} + {{- if .Values.networkPolicy.ingressNSPodMatchLabels }} + podSelector: + matchLabels: + {{- range $key, $value := .Values.networkPolicy.ingressNSPodMatchLabels }} + {{ $key | quote }}: {{ $value | quote }} + {{- end }} + {{- end }} + {{- end }} + {{- end }} + {{- if .Values.metrics.enabled }} + # Allow prometheus scrapes for metrics + - ports: + - port: 2379 + {{- end }} + {{- if .Values.networkPolicy.extraIngress }} + {{- include "common.tplvalues.render" ( dict "value" .Values.networkPolicy.extraIngress "context" $ ) | nindent 4 }} + {{- end }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/etcd/templates/pdb.yaml b/helm/openebs/charts/mayastor/charts/etcd/templates/pdb.yaml new file mode 100644 index 0000000..f064928 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/etcd/templates/pdb.yaml @@ -0,0 +1,23 @@ +{{- if .Values.pdb.create }} +apiVersion: {{ include "common.capabilities.policy.apiVersion" . }} +kind: PodDisruptionBudget +metadata: + name: {{ include "common.names.fullname" . }} + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + {{- if .Values.pdb.minAvailable }} + minAvailable: {{ .Values.pdb.minAvailable }} + {{- end }} + {{- if .Values.pdb.maxUnavailable }} + maxUnavailable: {{ .Values.pdb.maxUnavailable }} + {{- end }} + selector: + matchLabels: {{- include "common.labels.matchLabels" . | nindent 6 }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/etcd/templates/podmonitor.yaml b/helm/openebs/charts/mayastor/charts/etcd/templates/podmonitor.yaml new file mode 100644 index 0000000..952e569 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/etcd/templates/podmonitor.yaml @@ -0,0 +1,42 @@ +{{- if and .Values.metrics.enabled .Values.metrics.podMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: PodMonitor +metadata: + name: {{ include "common.names.fullname" . }} + namespace: {{ ternary .Values.metrics.podMonitor.namespace .Release.Namespace (not (empty .Values.metrics.podMonitor.namespace)) }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.metrics.podMonitor.additionalLabels }} + {{- include "common.tplvalues.render" (dict "value" .Values.metrics.podMonitor.additionalLabels "context" $) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + podMetricsEndpoints: + - port: client + path: /metrics + {{- if .Values.metrics.podMonitor.interval }} + interval: {{ .Values.metrics.podMonitor.interval }} + {{- end }} + {{- if .Values.metrics.podMonitor.scrapeTimeout }} + scrapeTimeout: {{ .Values.metrics.podMonitor.scrapeTimeout }} + {{- end }} + {{- if .Values.metrics.podMonitor.scheme }} + scheme: {{ .Values.metrics.podMonitor.scheme }} + {{- end }} + {{- if .Values.metrics.podMonitor.tlsConfig }} + tlsConfig: {{- include "common.tplvalues.render" ( dict "value" .Values.metrics.podMonitor.tlsConfig "context" $ ) | nindent 8 }} + {{- end }} + {{- if .Values.metrics.podMonitor.relabelings }} + relabelings: + {{- include "common.tplvalues.render" (dict "value" .Values.metrics.podMonitor.relabelings "context" $) | nindent 8 }} + {{- end }} + namespaceSelector: + matchNames: + - {{ .Release.Namespace }} + selector: + matchLabels: {{- include "common.labels.matchLabels" . | nindent 6 }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/etcd/templates/prometheusrule.yaml b/helm/openebs/charts/mayastor/charts/etcd/templates/prometheusrule.yaml new file mode 100644 index 0000000..58a5594 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/etcd/templates/prometheusrule.yaml @@ -0,0 +1,26 @@ +{{- if and .Values.metrics.enabled .Values.metrics.prometheusRule.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: {{ include "common.names.fullname" . }} + {{- if .Values.metrics.prometheusRule.namespace }} + namespace: {{ .Values.metrics.prometheusRule.namespace }} + {{- else }} + namespace: {{ .Release.Namespace }} + {{- end }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + app.kubernetes.io/component: metrics + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.metrics.prometheusRule.additionalLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.metrics.prometheusRule.additionalLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + groups: + - name: {{ include "common.names.fullname" . }} + rules: {{- include "common.tplvalues.render" ( dict "value" .Values.metrics.prometheusRule.rules "context" $ ) | nindent 6 }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/etcd/templates/secrets.yaml b/helm/openebs/charts/mayastor/charts/etcd/templates/secrets.yaml new file mode 100644 index 0000000..ea46c28 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/etcd/templates/secrets.yaml @@ -0,0 +1,21 @@ +{{- if and (or .Values.auth.rbac.create .Values.auth.rbac.enabled) (not .Values.auth.rbac.existingSecret) -}} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "common.names.fullname" . }} + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +type: Opaque +data: + {{- if .Values.auth.rbac.rootPassword }} + etcd-root-password: {{ .Values.auth.rbac.rootPassword | b64enc | quote }} + {{- else }} + etcd-root-password: {{ randAlphaNum 10 | b64enc | quote }} + {{- end }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/etcd/templates/serviceaccount.yaml b/helm/openebs/charts/mayastor/charts/etcd/templates/serviceaccount.yaml new file mode 100644 index 0000000..a5721db --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/etcd/templates/serviceaccount.yaml @@ -0,0 +1,24 @@ +{{- if .Values.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }} +metadata: + name: {{ include "etcd.serviceAccountName" . }} + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.serviceAccount.labels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.serviceAccount.labels "context" $ ) | nindent 4 }} + {{- end }} + {{- if or .Values.commonAnnotations .Values.serviceAccount.annotations }} + annotations: + {{- if .Values.commonAnnotations }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.serviceAccount.annotations }} + {{- include "common.tplvalues.render" ( dict "value" .Values.serviceAccount.annotations "context" $ ) | nindent 4 }} + {{- end }} + {{- end }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/etcd/templates/snapshot-pvc.yaml b/helm/openebs/charts/mayastor/charts/etcd/templates/snapshot-pvc.yaml new file mode 100644 index 0000000..2415b89 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/etcd/templates/snapshot-pvc.yaml @@ -0,0 +1,21 @@ +{{- if and .Values.disasterRecovery.enabled (not .Values.disasterRecovery.pvc.existingClaim) -}} +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: + name: {{ printf "%s-snapshotter" (include "common.names.fullname" .) | trunc 63 | trimSuffix "-" }} + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + accessModes: + - ReadWriteMany + resources: + requests: + storage: {{ .Values.disasterRecovery.pvc.size | quote }} + storageClassName: {{ .Values.disasterRecovery.pvc.storageClassName | quote }} +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/etcd/templates/statefulset.yaml b/helm/openebs/charts/mayastor/charts/etcd/templates/statefulset.yaml new file mode 100644 index 0000000..ef02b5b --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/etcd/templates/statefulset.yaml @@ -0,0 +1,419 @@ +apiVersion: {{ include "common.capabilities.statefulset.apiVersion" . }} +kind: StatefulSet +metadata: + name: {{ include "common.names.fullname" . }} + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: {{- include "common.labels.matchLabels" . | nindent 6 }} + serviceName: {{ printf "%s-headless" (include "common.names.fullname" .) | trunc 63 | trimSuffix "-" }} + podManagementPolicy: {{ .Values.podManagementPolicy }} + updateStrategy: {{- include "common.tplvalues.render" (dict "value" .Values.updateStrategy "context" $ ) | nindent 4 }} + template: + metadata: + labels: {{- include "common.labels.standard" . | nindent 8 }} + {{- if .Values.podLabels }} + {{- include "common.tplvalues.render" (dict "value" .Values.podLabels "context" $) | nindent 8 }} + {{- end }} + annotations: + {{- if .Values.podAnnotations }} + {{- include "common.tplvalues.render" ( dict "value" .Values.podAnnotations "context" $) | nindent 8 }} + {{- end }} + {{- if and .Values.metrics.enabled .Values.metrics.podAnnotations }} + {{- include "common.tplvalues.render" ( dict "value" .Values.metrics.podAnnotations "context" $) | nindent 8 }} + {{- end }} + {{- if (include "etcd.createConfigmap" .) }} + checksum/configuration: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} + {{- end }} + {{- if (include "etcd.token.createSecret" .) }} + checksum/token-secret: {{ include (print $.Template.BasePath "/token-secrets.yaml") . | sha256sum }} + {{- end }} + spec: + {{- include "etcd.imagePullSecrets" . | nindent 6 }} + {{- if .Values.hostAliases }} + hostAliases: {{- include "common.tplvalues.render" (dict "value" .Values.hostAliases "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.affinity }} + affinity: {{- include "common.tplvalues.render" (dict "value" .Values.affinity "context" $) | nindent 8 }} + {{- else }} + affinity: + podAffinity: {{- include "common.affinities.pods" (dict "type" .Values.podAffinityPreset "context" $) | nindent 10 }} + podAntiAffinity: {{- include "common.affinities.pods" (dict "type" .Values.podAntiAffinityPreset "context" $) | nindent 10 }} + nodeAffinity: {{- include "common.affinities.nodes" (dict "type" .Values.nodeAffinityPreset.type "key" .Values.nodeAffinityPreset.key "values" .Values.nodeAffinityPreset.values) | nindent 10 }} + {{- end }} + {{- if .Values.nodeSelector }} + nodeSelector: {{- include "common.tplvalues.render" (dict "value" .Values.nodeSelector "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.tolerations }} + tolerations: {{- include "common.tplvalues.render" (dict "value" .Values.tolerations "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.terminationGracePeriodSeconds }} + terminationGracePeriodSeconds: {{ .Values.terminationGracePeriodSeconds }} + {{- end }} + {{- if .Values.schedulerName }} + schedulerName: {{ .Values.schedulerName }} + {{- end }} + {{- if .Values.topologySpreadConstraints }} + topologySpreadConstraints: {{- include "common.tplvalues.render" (dict "value" .Values.topologySpreadConstraints "context" .) | nindent 8 }} + {{- end }} + {{- if .Values.priorityClassName }} + priorityClassName: {{ .Values.priorityClassName }} + {{- end }} + {{- if .Values.runtimeClassName }} + runtimeClassName: {{ .Values.runtimeClassName }} + {{- end }} + {{- if .Values.podSecurityContext.enabled }} + securityContext: {{- omit .Values.podSecurityContext "enabled" | toYaml | nindent 8 }} + {{- end }} + {{- if .Values.shareProcessNamespace }} + shareProcessNamespace: {{ .Values.shareProcessNamespace }} + {{- end }} + serviceAccountName: {{ include "etcd.serviceAccountName" $ | quote }} + {{- if or .Values.initContainers (and .Values.volumePermissions.enabled .Values.persistence.enabled) }} + initContainers: + {{- if .Values.initContainers }} + {{- include "common.tplvalues.render" (dict "value" .Values.initContainers "context" $) | nindent 8 }} + {{- end }} + {{- if and .Values.volumePermissions.enabled .Values.persistence.enabled }} + - name: volume-permissions + image: {{ include "etcd.volumePermissions.image" . }} + imagePullPolicy: {{ .Values.volumePermissions.image.pullPolicy | quote }} + command: + - /bin/bash + - -ec + - | + chown -R {{ .Values.containerSecurityContext.runAsUser }}:{{ .Values.podSecurityContext.fsGroup }} /bitnami/etcd + securityContext: + runAsUser: 0 + {{- if .Values.volumePermissions.resources }} + resources: {{- include "common.tplvalues.render" (dict "value" .Values.volumePermissions.resources "context" $) | nindent 12 }} + {{- end }} + volumeMounts: + - name: data + mountPath: /bitnami/etcd + {{- end }} + {{- end }} + containers: + {{- $replicaCount := int .Values.replicaCount }} + {{- $peerPort := int .Values.containerPorts.peer }} + {{- $etcdFullname := include "common.names.fullname" . }} + {{- $releaseNamespace := .Release.Namespace }} + {{- $etcdHeadlessServiceName := (printf "%s-%s" $etcdFullname "headless" | trunc 63 | trimSuffix "-") }} + {{- $clusterDomain := .Values.clusterDomain }} + {{- $etcdPeerProtocol := include "etcd.peerProtocol" . }} + {{- $etcdClientProtocol := include "etcd.clientProtocol" . }} + - name: etcd + image: {{ include "etcd.image" . }} + imagePullPolicy: {{ .Values.image.pullPolicy | quote }} + {{- if .Values.containerSecurityContext.enabled }} + securityContext: {{- omit .Values.containerSecurityContext "enabled" | toYaml | nindent 12 }} + {{- end }} + {{- if .Values.diagnosticMode.enabled }} + command: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.command "context" $) | nindent 12 }} + {{- else if .Values.command }} + command: {{- include "common.tplvalues.render" (dict "value" .Values.command "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.diagnosticMode.enabled }} + args: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.args "context" $) | nindent 12 }} + {{- else if .Values.args }} + args: {{- include "common.tplvalues.render" (dict "value" .Values.args "context" $) | nindent 12 }} + {{- end }} + env: + - name: BITNAMI_DEBUG + value: {{ ternary "true" "false" (or .Values.image.debug .Values.diagnosticMode.enabled) | quote }} + - name: MY_POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: MY_POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: MY_STS_NAME + value: {{ include "common.names.fullname" . | quote }} + - name: ETCDCTL_API + value: "3" + - name: ETCD_ON_K8S + value: "yes" + - name: ETCD_START_FROM_SNAPSHOT + value: {{ ternary "yes" "no" .Values.startFromSnapshot.enabled | quote }} + - name: ETCD_DISASTER_RECOVERY + value: {{ ternary "yes" "no" .Values.disasterRecovery.enabled | quote }} + - name: ETCD_NAME + value: "$(MY_POD_NAME)" + - name: ETCD_DATA_DIR + value: "/bitnami/etcd/data" + - name: ETCD_LOG_LEVEL + value: {{ ternary "debug" .Values.logLevel .Values.image.debug | quote }} + - name: ALLOW_NONE_AUTHENTICATION + value: {{ ternary "yes" "no" (and (not (or .Values.auth.rbac.create .Values.auth.rbac.enabled)) .Values.auth.rbac.allowNoneAuthentication) | quote }} + {{- if or .Values.auth.rbac.create .Values.auth.rbac.enabled }} + - name: ETCD_ROOT_PASSWORD + valueFrom: + secretKeyRef: + name: {{ include "etcd.secretName" . }} + key: {{ include "etcd.secretPasswordKey" . }} + {{- end }} + - name: ETCD_AUTH_TOKEN + {{- if eq .Values.auth.token.type "jwt" }} + value: {{ printf "jwt,priv-key=/opt/bitnami/etcd/certs/token/%s,sign-method=%s,ttl=%s" .Values.auth.token.privateKey.filename .Values.auth.token.signMethod .Values.auth.token.ttl | quote }} + {{- else if eq .Values.auth.token.type "simple" }} + value: "simple" + {{- end }} + - name: ETCD_ADVERTISE_CLIENT_URLS + value: "{{ $etcdClientProtocol }}://$(MY_POD_NAME).{{ $etcdHeadlessServiceName }}.{{ .Release.Namespace }}.svc.{{ $clusterDomain }}:{{ .Values.containerPorts.client }},{{ $etcdClientProtocol }}://{{ $etcdFullname }}.{{ .Release.Namespace }}.svc.{{ $clusterDomain }}:{{ coalesce .Values.service.ports.client .Values.service.port }}" + - name: ETCD_LISTEN_CLIENT_URLS + value: "{{ $etcdClientProtocol }}://0.0.0.0:{{ .Values.containerPorts.client }}" + - name: ETCD_INITIAL_ADVERTISE_PEER_URLS + value: "{{ $etcdPeerProtocol }}://$(MY_POD_NAME).{{ $etcdHeadlessServiceName }}.{{ .Release.Namespace }}.svc.{{ $clusterDomain }}:{{ .Values.containerPorts.peer }}" + - name: ETCD_LISTEN_PEER_URLS + value: "{{ $etcdPeerProtocol }}://0.0.0.0:{{ .Values.containerPorts.peer }}" + {{- if .Values.autoCompactionMode }} + - name: ETCD_AUTO_COMPACTION_MODE + value: {{ .Values.autoCompactionMode | quote }} + {{- end }} + {{- if .Values.autoCompactionRetention }} + - name: ETCD_AUTO_COMPACTION_RETENTION + value: {{ .Values.autoCompactionRetention | quote }} + {{- end }} + {{- if .Values.maxProcs }} + - name: GOMAXPROCS + value: {{ .Values.maxProcs }} + {{- end }} + {{- if gt $replicaCount 1 }} + - name: ETCD_INITIAL_CLUSTER_TOKEN + value: "etcd-cluster-k8s" + - name: ETCD_INITIAL_CLUSTER_STATE + value: {{ default (ternary "new" "existing" .Release.IsInstall) .Values.initialClusterState | quote }} + {{- $initialCluster := list }} + {{- range $e, $i := until $replicaCount }} + {{- $initialCluster = append $initialCluster (printf "%s-%d=%s://%s-%d.%s.%s.svc.%s:%d" $etcdFullname $i $etcdPeerProtocol $etcdFullname $i $etcdHeadlessServiceName $releaseNamespace $clusterDomain $peerPort) }} + {{- end }} + - name: ETCD_INITIAL_CLUSTER + value: {{ join "," $initialCluster | quote }} + {{- end }} + - name: ETCD_CLUSTER_DOMAIN + value: {{ printf "%s.%s.svc.%s" $etcdHeadlessServiceName $releaseNamespace $clusterDomain | quote }} + {{- if and .Values.auth.client.secureTransport .Values.auth.client.useAutoTLS }} + - name: ETCD_AUTO_TLS + value: "true" + {{- else if .Values.auth.client.secureTransport }} + - name: ETCD_CERT_FILE + value: "/opt/bitnami/etcd/certs/client/{{ .Values.auth.client.certFilename }}" + - name: ETCD_KEY_FILE + value: "/opt/bitnami/etcd/certs/client/{{ .Values.auth.client.certKeyFilename }}" + {{- if .Values.auth.client.enableAuthentication }} + - name: ETCD_CLIENT_CERT_AUTH + value: "true" + - name: ETCD_TRUSTED_CA_FILE + value: "/opt/bitnami/etcd/certs/client/{{ .Values.auth.client.caFilename | default "ca.crt" }}" + {{- else if .Values.auth.client.caFilename }} + - name: ETCD_TRUSTED_CA_FILE + value: "/opt/bitnami/etcd/certs/client/{{ .Values.auth.client.caFilename | default "ca.crt" }}" + {{- end }} + {{- end }} + {{- if and .Values.auth.peer.secureTransport .Values.auth.peer.useAutoTLS }} + - name: ETCD_PEER_AUTO_TLS + value: "true" + {{- else if .Values.auth.peer.secureTransport }} + - name: ETCD_PEER_CERT_FILE + value: "/opt/bitnami/etcd/certs/peer/{{ .Values.auth.peer.certFilename }}" + - name: ETCD_PEER_KEY_FILE + value: "/opt/bitnami/etcd/certs/peer/{{ .Values.auth.peer.certKeyFilename }}" + {{- if .Values.auth.peer.enableAuthentication }} + - name: ETCD_PEER_CLIENT_CERT_AUTH + value: "true" + - name: ETCD_PEER_TRUSTED_CA_FILE + value: "/opt/bitnami/etcd/certs/peer/{{ .Values.auth.peer.caFilename | default "ca.crt" }}" + {{- else if .Values.auth.peer.caFilename }} + - name: ETCD_PEER_TRUSTED_CA_FILE + value: "/opt/bitnami/etcd/certs/peer/{{ .Values.auth.peer.caFilename | default "ca.crt" }}" + {{- end }} + {{- end }} + {{- if .Values.startFromSnapshot.enabled }} + - name: ETCD_INIT_SNAPSHOT_FILENAME + value: {{ .Values.startFromSnapshot.snapshotFilename | quote }} + - name: ETCD_INIT_SNAPSHOTS_DIR + value: {{ ternary "/snapshots" "/init-snapshot" (and .Values.disasterRecovery.enabled (not .Values.disasterRecovery.pvc.existingClaim)) | quote }} + {{- end }} + {{- if .Values.extraEnvVars }} + {{- include "common.tplvalues.render" (dict "value" .Values.extraEnvVars "context" $) | nindent 12 }} + {{- end }} + envFrom: + {{- if .Values.extraEnvVarsCM }} + - configMapRef: + name: {{ include "common.tplvalues.render" (dict "value" .Values.extraEnvVarsCM "context" $) }} + {{- end }} + {{- if .Values.extraEnvVarsSecret }} + - secretRef: + name: {{ include "common.tplvalues.render" (dict "value" .Values.extraEnvVarsSecret "context" $) }} + {{- end }} + ports: + - name: client + containerPort: {{ .Values.containerPorts.client }} + protocol: TCP + - name: peer + containerPort: {{ .Values.containerPorts.peer }} + protocol: TCP + {{- if not .Values.diagnosticMode.enabled }} + {{- if .Values.customLivenessProbe }} + livenessProbe: {{- include "common.tplvalues.render" (dict "value" .Values.customLivenessProbe "context" $) | nindent 12 }} + {{- else if .Values.livenessProbe.enabled }} + livenessProbe: + exec: + command: + - /opt/bitnami/scripts/etcd/healthcheck.sh + initialDelaySeconds: {{ .Values.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.livenessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.livenessProbe.timeoutSeconds }} + successThreshold: {{ .Values.livenessProbe.successThreshold }} + failureThreshold: {{ .Values.livenessProbe.failureThreshold }} + {{- end }} + {{- if .Values.customReadinessProbe }} + readinessProbe: {{- include "common.tplvalues.render" (dict "value" .Values.customReadinessProbe "context" $) | nindent 12 }} + {{- else if .Values.readinessProbe.enabled }} + readinessProbe: + exec: + command: + - /opt/bitnami/scripts/etcd/healthcheck.sh + initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.readinessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.readinessProbe.timeoutSeconds }} + successThreshold: {{ .Values.readinessProbe.successThreshold }} + failureThreshold: {{ .Values.readinessProbe.failureThreshold }} + {{- end }} + {{- if .Values.customStartupProbe }} + startupProbe: {{- include "common.tplvalues.render" (dict "value" .Values.customStartupProbe "context" $) | nindent 12 }} + {{- else if .Values.startupProbe.enabled }} + startupProbe: + exec: + command: + - /opt/bitnami/scripts/etcd/healthcheck.sh + initialDelaySeconds: {{ .Values.startupProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.startupProbe.periodSeconds }} + timeoutSeconds: {{ .Values.startupProbe.timeoutSeconds }} + successThreshold: {{ .Values.startupProbe.successThreshold }} + failureThreshold: {{ .Values.startupProbe.failureThreshold }} + {{- end }} + {{- if .Values.lifecycleHooks }} + lifecycle: {{- include "common.tplvalues.render" (dict "value" .Values.lifecycleHooks "context" $) | nindent 12 }} + {{- else if and (gt $replicaCount 1) .Values.removeMemberOnContainerTermination }} + lifecycle: + preStop: + exec: + command: + - /opt/bitnami/scripts/etcd/prestop.sh + {{- end }} + {{- end }} + {{- if .Values.resources }} + resources: {{- include "common.tplvalues.render" (dict "value" .Values.resources "context" $) | nindent 12 }} + {{- end }} + volumeMounts: + - name: data + mountPath: /bitnami/etcd + {{- if eq .Values.auth.token.type "jwt" }} + - name: etcd-jwt-token + mountPath: /opt/bitnami/etcd/certs/token/ + readOnly: true + {{- end }} + {{- if or (and .Values.startFromSnapshot.enabled (not .Values.disasterRecovery.enabled)) (and .Values.disasterRecovery.enabled .Values.startFromSnapshot.enabled .Values.disasterRecovery.pvc.existingClaim) }} + - name: init-snapshot-volume + mountPath: /init-snapshot + {{- end }} + {{- if or .Values.disasterRecovery.enabled (and .Values.disasterRecovery.enabled .Values.startFromSnapshot.enabled) }} + - name: snapshot-volume + mountPath: /snapshots + {{- end }} + {{- if or .Values.configuration .Values.existingConfigmap }} + - name: etcd-config + mountPath: /opt/bitnami/etcd/conf/ + {{- end }} + {{- if or .Values.auth.client.enableAuthentication (and .Values.auth.client.secureTransport (not .Values.auth.client.useAutoTLS )) }} + - name: etcd-client-certs + mountPath: /opt/bitnami/etcd/certs/client/ + readOnly: true + {{- end }} + {{- if or .Values.auth.peer.enableAuthentication (and .Values.auth.peer.secureTransport (not .Values.auth.peer.useAutoTLS )) }} + - name: etcd-peer-certs + mountPath: /opt/bitnami/etcd/certs/peer/ + readOnly: true + {{- end }} + {{- if .Values.extraVolumeMounts }} + {{- include "common.tplvalues.render" (dict "value" .Values.extraVolumeMounts "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.sidecars }} + {{- include "common.tplvalues.render" (dict "value" .Values.sidecars "context" $) | nindent 8 }} + {{- end }} + volumes: + {{- if eq .Values.auth.token.type "jwt" }} + - name: etcd-jwt-token + secret: + secretName: {{ include "etcd.token.secretName" . }} + defaultMode: 256 + {{- end }} + {{- if or (and .Values.startFromSnapshot.enabled (not .Values.disasterRecovery.enabled)) (and .Values.disasterRecovery.enabled .Values.startFromSnapshot.enabled .Values.disasterRecovery.pvc.existingClaim) }} + - name: init-snapshot-volume + persistentVolumeClaim: + claimName: {{ .Values.startFromSnapshot.existingClaim }} + {{- end }} + {{- if or .Values.disasterRecovery.enabled (and .Values.disasterRecovery.enabled .Values.startFromSnapshot.enabled) }} + - name: snapshot-volume + persistentVolumeClaim: + claimName: {{ include "etcd.disasterRecovery.pvc.name" . }} + {{- end }} + {{- if or .Values.configuration .Values.existingConfigmap }} + - name: etcd-config + configMap: + name: {{ include "etcd.configmapName" . }} + {{- end }} + {{- if or .Values.auth.client.enableAuthentication (and .Values.auth.client.secureTransport (not .Values.auth.client.useAutoTLS )) }} + - name: etcd-client-certs + secret: + secretName: {{ required "A secret containing the client certificates is required" (tpl .Values.auth.client.existingSecret .) }} + defaultMode: 256 + {{- end }} + {{- if or .Values.auth.peer.enableAuthentication (and .Values.auth.peer.secureTransport (not .Values.auth.peer.useAutoTLS )) }} + - name: etcd-peer-certs + secret: + secretName: {{ required "A secret containing the peer certificates is required" (tpl .Values.auth.peer.existingSecret .) }} + defaultMode: 256 + {{- end }} + {{- if .Values.extraVolumes }} + {{- include "common.tplvalues.render" (dict "value" .Values.extraVolumes "context" $) | nindent 8 }} + {{- end }} + {{- if not .Values.persistence.enabled }} + - name: data + emptyDir: {} + {{- else }} + {{- if .Values.persistentVolumeClaimRetentionPolicy.enabled }} + persistentVolumeClaimRetentionPolicy: + whenDeleted: {{ .Values.persistentVolumeClaimRetentionPolicy.whenDeleted }} + whenScaled: {{ .Values.persistentVolumeClaimRetentionPolicy.whenScaled }} + {{- end }} + volumeClaimTemplates: + - metadata: + name: data + {{- if .Values.persistence.annotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.persistence.annotations "context" $) | nindent 10 }} + {{- end }} + spec: + accessModes: + {{- range .Values.persistence.accessModes }} + - {{ . | quote }} + {{- end }} + resources: + requests: + storage: {{ .Values.persistence.size | quote }} + {{- if .Values.persistence.selector }} + selector: {{- include "common.tplvalues.render" ( dict "value" .Values.persistence.selector "context" $) | nindent 10 }} + {{- end }} + {{ include "common.storage.class" (dict "persistence" .Values.persistence "global" .Values.global) }} + {{- end }} diff --git a/helm/openebs/charts/mayastor/charts/etcd/templates/svc-headless.yaml b/helm/openebs/charts/mayastor/charts/etcd/templates/svc-headless.yaml new file mode 100644 index 0000000..d1d2556 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/etcd/templates/svc-headless.yaml @@ -0,0 +1,42 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ printf "%s-headless" (include "common.names.fullname" .) | trunc 63 | trimSuffix "-" }} + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + annotations: + service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" + {{- if .Values.commonAnnotations }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + type: ClusterIP + clusterIP: None + publishNotReadyAddresses: true + ports: + {{- if .Values.service.clientPortNameOverride }} + {{- if .Values.auth.client.secureTransport }} + - name: {{ .Values.service.clientPortNameOverride }}-ssl + {{- else }} + - name: {{ .Values.service.clientPortNameOverride }} + {{- end }} + {{- else }} + - name: client + {{- end }} + port: {{ .Values.containerPorts.client }} + targetPort: client + {{- if .Values.service.peerPortNameOverride }} + {{- if .Values.auth.peer.secureTransport }} + - name: {{ .Values.service.peerPortNameOverride }}-ssl + {{- else }} + - name: {{ .Values.service.peerPortNameOverride }} + {{- end }} + {{- else }} + - name: peer + {{- end }} + port: {{ .Values.containerPorts.peer }} + targetPort: peer + selector: {{- include "common.labels.matchLabels" . | nindent 4 }} diff --git a/helm/openebs/charts/mayastor/charts/etcd/templates/svc.yaml b/helm/openebs/charts/mayastor/charts/etcd/templates/svc.yaml new file mode 100644 index 0000000..24e9c0b --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/etcd/templates/svc.yaml @@ -0,0 +1,62 @@ +{{- if .Values.service.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "common.names.fullname" . }} + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + annotations: + {{- if .Values.service.annotations }} + {{- include "common.tplvalues.render" ( dict "value" .Values.service.annotations "context" $) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: + type: {{ .Values.service.type }} + {{- if and .Values.service.clusterIP (eq .Values.service.type "ClusterIP") }} + clusterIP: {{ .Values.service.clusterIP }} + {{- end }} + {{- if (or (eq .Values.service.type "LoadBalancer") (eq .Values.service.type "NodePort")) }} + externalTrafficPolicy: {{ .Values.service.externalTrafficPolicy | quote }} + {{- end }} + {{- if and (eq .Values.service.type "LoadBalancer") (not (empty .Values.service.loadBalancerIP)) }} + loadBalancerIP: {{ .Values.service.loadBalancerIP }} + {{- end }} + {{- if and (eq .Values.service.type "LoadBalancer") (not (empty .Values.service.loadBalancerSourceRanges)) }} + loadBalancerSourceRanges: {{- toYaml .Values.service.loadBalancerSourceRanges | nindent 4 }} + {{- end }} + {{- if .Values.service.externalIPs }} + externalIPs: {{- toYaml .Values.service.externalIPs | nindent 4 }} + {{- end }} + {{- if .Values.service.sessionAffinity }} + sessionAffinity: {{ .Values.service.sessionAffinity }} + {{- end }} + {{- if .Values.service.sessionAffinityConfig }} + sessionAffinityConfig: {{- include "common.tplvalues.render" (dict "value" .Values.service.sessionAffinityConfig "context" $) | nindent 4 }} + {{- end }} + ports: + - name: {{ default "client" .Values.service.clientPortNameOverride | quote }} + port: {{ coalesce .Values.service.ports.client .Values.service.port }} + targetPort: client + {{- if and (or (eq .Values.service.type "NodePort") (eq .Values.service.type "LoadBalancer")) (not (empty (coalesce .Values.service.nodePorts.client .Values.service.nodePorts.clientPort))) }} + nodePort: {{ coalesce .Values.service.nodePorts.client .Values.service.nodePorts.clientPort }} + {{- else if eq .Values.service.type "ClusterIP" }} + nodePort: null + {{- end }} + - name: {{ default "peer" .Values.service.peerPortNameOverride | quote }} + port: {{ coalesce .Values.service.ports.peer .Values.service.peerPort }} + targetPort: peer + {{- if and (or (eq .Values.service.type "NodePort") (eq .Values.service.type "LoadBalancer")) (not (empty (coalesce .Values.service.nodePorts.peer .Values.service.nodePorts.peerPort))) }} + nodePort: {{ coalesce .Values.service.nodePorts.peer .Values.service.nodePorts.peerPort }} + {{- else if eq .Values.service.type "ClusterIP" }} + nodePort: null + {{- end }} + {{- if .Values.service.extraPorts }} + {{- include "common.tplvalues.render" (dict "value" .Values.service.extraPorts "context" $) | nindent 4 }} + {{- end }} + selector: {{- include "common.labels.matchLabels" . | nindent 4 }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/etcd/templates/token-secrets.yaml b/helm/openebs/charts/mayastor/charts/etcd/templates/token-secrets.yaml new file mode 100644 index 0000000..c0246fb --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/etcd/templates/token-secrets.yaml @@ -0,0 +1,14 @@ +{{- if (include "etcd.token.createSecret" .) }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ printf "%s-jwt-token" (include "common.names.fullname" .) | trunc 63 | trimSuffix "-" }} + namespace: {{ .Release.Namespace | quote }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +type: Opaque +data: + jwt-token.pem: {{ include "etcd.token.jwtToken" . | b64enc | quote }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/etcd/values.yaml b/helm/openebs/charts/mayastor/charts/etcd/values.yaml new file mode 100644 index 0000000..1fd9623 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/etcd/values.yaml @@ -0,0 +1,887 @@ +## @section Global parameters +## Global Docker image parameters +## Please, note that this will override the image parameters, including dependencies, configured to use the global value +## Current available global Docker image parameters: imageRegistry, imagePullSecrets and storageClass +## + +## @param global.imageRegistry Global Docker image registry +## @param global.imagePullSecrets [array] Global Docker registry secret names as an array +## @param global.storageClass Global StorageClass for Persistent Volume(s) +## +global: + imageRegistry: "" + ## E.g. + ## imagePullSecrets: + ## - myRegistryKeySecretName + ## + imagePullSecrets: [] + storageClass: "" + +## @section Common parameters +## + +## @param kubeVersion Force target Kubernetes version (using Helm capabilities if not set) +## +kubeVersion: "" +## @param nameOverride String to partially override common.names.fullname template (will maintain the release name) +## +nameOverride: "" +## @param fullnameOverride String to fully override common.names.fullname template +## +fullnameOverride: "" +## @param commonLabels [object] Labels to add to all deployed objects +## +commonLabels: {} +## @param commonAnnotations [object] Annotations to add to all deployed objects +## +commonAnnotations: {} +## @param clusterDomain Default Kubernetes cluster domain +## +clusterDomain: cluster.local +## @param extraDeploy [array] Array of extra objects to deploy with the release +## +extraDeploy: [] + +## Enable diagnostic mode in the deployment +## +diagnosticMode: + ## @param diagnosticMode.enabled Enable diagnostic mode (all probes will be disabled and the command will be overridden) + ## + enabled: false + ## @param diagnosticMode.command Command to override all containers in the deployment + ## + command: + - sleep + ## @param diagnosticMode.args Args to override all containers in the deployment + ## + args: + - infinity + +## @section etcd parameters +## + +## Bitnami etcd image version +## ref: https://hub.docker.com/r/bitnami/etcd/tags/ +## @param image.registry etcd image registry +## @param image.repository etcd image name +## @param image.tag etcd image tag +## @param image.digest etcd image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag +## +image: + registry: docker.io + repository: bitnami/etcd + tag: 3.5.6-debian-11-r10 + digest: "" + ## @param image.pullPolicy etcd image pull policy + ## Specify a imagePullPolicy + ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' + ## ref: https://kubernetes.io/docs/user-guide/images/#pre-pulling-images + ## + pullPolicy: IfNotPresent + ## @param image.pullSecrets [array] etcd image pull secrets + ## Optionally specify an array of imagePullSecrets. + ## Secrets must be manually created in the namespace. + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ + ## e.g: + ## pullSecrets: + ## - myRegistryKeySecretName + ## + pullSecrets: [] + ## @param image.debug Enable image debug mode + ## Set to true if you would like to see extra information on logs + ## + debug: false +## Authentication parameters +## +auth: + ## Role-based access control parameters + ## ref: https://etcd.io/docs/current/op-guide/authentication/ + ## + rbac: + ## @param auth.rbac.create Switch to enable RBAC authentication + ## + create: true + ## @param auth.rbac.allowNoneAuthentication Allow to use etcd without configuring RBAC authentication + ## + allowNoneAuthentication: true + ## @param auth.rbac.rootPassword Root user password. The root user is always `root` + ## + rootPassword: "" + ## @param auth.rbac.existingSecret Name of the existing secret containing credentials for the root user + ## + existingSecret: "" + ## @param auth.rbac.existingSecretPasswordKey Name of key containing password to be retrieved from the existing secret + ## + existingSecretPasswordKey: "" + ## Authentication token + ## ref: https://etcd.io/docs/latest/learning/design-auth-v3/#two-types-of-tokens-simple-and-jwt + ## + token: + ## @param auth.token.type Authentication token type. Allowed values: 'simple' or 'jwt' + ## ref: https://etcd.io/docs/latest/op-guide/configuration/#--auth-token + ## + type: jwt + ## @param auth.token.privateKey.filename Name of the file containing the private key for signing the JWT token + ## @param auth.token.privateKey.existingSecret Name of the existing secret containing the private key for signing the JWT token + ## NOTE: Ignored if auth.token.type=simple + ## NOTE: A secret containing a private key will be auto-generated if an existing one is not provided. + ## + privateKey: + filename: jwt-token.pem + existingSecret: "" + ## @param auth.token.signMethod JWT token sign method + ## NOTE: Ignored if auth.token.type=simple + ## + signMethod: RS256 + ## @param auth.token.ttl JWT token TTL + ## NOTE: Ignored if auth.token.type=simple + ## + ttl: 10m + ## TLS authentication for client-to-server communications + ## ref: https://etcd.io/docs/current/op-guide/security/ + ## + client: + ## @param auth.client.secureTransport Switch to encrypt client-to-server communications using TLS certificates + ## + secureTransport: false + ## @param auth.client.useAutoTLS Switch to automatically create the TLS certificates + ## + useAutoTLS: false + ## @param auth.client.existingSecret Name of the existing secret containing the TLS certificates for client-to-server communications + ## + existingSecret: "" + ## @param auth.client.enableAuthentication Switch to enable host authentication using TLS certificates. Requires existing secret + ## + enableAuthentication: false + ## @param auth.client.certFilename Name of the file containing the client certificate + ## + certFilename: cert.pem + ## @param auth.client.certKeyFilename Name of the file containing the client certificate private key + ## + certKeyFilename: key.pem + ## @param auth.client.caFilename Name of the file containing the client CA certificate + ## If not specified and `auth.client.enableAuthentication=true` or `auth.rbac.enabled=true`, the default is is `ca.crt` + ## + caFilename: "" + ## TLS authentication for server-to-server communications + ## ref: https://etcd.io/docs/current/op-guide/security/ + ## + peer: + ## @param auth.peer.secureTransport Switch to encrypt server-to-server communications using TLS certificates + ## + secureTransport: false + ## @param auth.peer.useAutoTLS Switch to automatically create the TLS certificates + ## + useAutoTLS: false + ## @param auth.peer.existingSecret Name of the existing secret containing the TLS certificates for server-to-server communications + ## + existingSecret: "" + ## @param auth.peer.enableAuthentication Switch to enable host authentication using TLS certificates. Requires existing secret + ## + enableAuthentication: false + ## @param auth.peer.certFilename Name of the file containing the peer certificate + ## + certFilename: cert.pem + ## @param auth.peer.certKeyFilename Name of the file containing the peer certificate private key + ## + certKeyFilename: key.pem + ## @param auth.peer.caFilename Name of the file containing the peer CA certificate + ## If not specified and `auth.peer.enableAuthentication=true` or `rbac.enabled=true`, the default is is `ca.crt` + ## + caFilename: "" +## @param autoCompactionMode Auto compaction mode, by default periodic. Valid values: "periodic", "revision". +## - 'periodic' for duration based retention, defaulting to hours if no time unit is provided (e.g. 5m). +## - 'revision' for revision number based retention. +## +autoCompactionMode: "" +## @param autoCompactionRetention Auto compaction retention for mvcc key value store in hour, by default 0, means disabled +## +autoCompactionRetention: "" +## @param initialClusterState Initial cluster state. Allowed values: 'new' or 'existing' +## If this values is not set, the default values below are set: +## - 'new': when installing the chart ('helm install ...') +## - 'existing': when upgrading the chart ('helm upgrade ...') +## +initialClusterState: "" +## @param logLevel Sets the log level for the etcd process. Allowed values: 'debug', 'info', 'warn', 'error', 'panic', 'fatal' +## +logLevel: "info" +## @param maxProcs Limits the number of operating system threads that can execute user-level +## Go code simultaneously by setting GOMAXPROCS environment variable +## ref: https://golang.org/pkg/runtime +## +maxProcs: "" +## @param removeMemberOnContainerTermination Use a PreStop hook to remove the etcd members from the etcd cluster on container termination +## they the containers are terminated +## NOTE: Ignored if lifecycleHooks is set or replicaCount=1 +## +removeMemberOnContainerTermination: true +## @param configuration etcd configuration. Specify content for etcd.conf.yml +## e.g: +## configuration: |- +## foo: bar +## baz: +## +configuration: "" +## @param existingConfigmap Existing ConfigMap with etcd configuration +## NOTE: When it's set the configuration parameter is ignored +## +existingConfigmap: "" +## @param extraEnvVars [array] Extra environment variables to be set on etcd container +## e.g: +## extraEnvVars: +## - name: FOO +## value: "bar" +## +extraEnvVars: [] +## @param extraEnvVarsCM Name of existing ConfigMap containing extra env vars +## +extraEnvVarsCM: "" +## @param extraEnvVarsSecret Name of existing Secret containing extra env vars +## +extraEnvVarsSecret: "" +## @param command [array] Default container command (useful when using custom images) +## +command: [] +## @param args [array] Default container args (useful when using custom images) +## +args: [] + +## @section etcd statefulset parameters +## + + +## @param replicaCount Number of etcd replicas to deploy +## +replicaCount: 1 +## Update strategy +## ref: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#update-strategies +## @param updateStrategy.type Update strategy type, can be set to RollingUpdate or OnDelete. +## +updateStrategy: + type: RollingUpdate +## @param podManagementPolicy Pod management policy for the etcd statefulset +## ref: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#pod-management-policies +## +podManagementPolicy: Parallel +## @param hostAliases [array] etcd pod host aliases +## ref: https://kubernetes.io/docs/concepts/services-networking/add-entries-to-pod-etc-hosts-with-host-aliases/ +## +hostAliases: [] +## @param lifecycleHooks [object] Override default etcd container hooks +## +lifecycleHooks: {} +## etcd container ports to open +## @param containerPorts.client Client port to expose at container level +## @param containerPorts.peer Peer port to expose at container level +## +containerPorts: + client: 2379 + peer: 2380 +## etcd pods' Security Context +## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod +## @param podSecurityContext.enabled Enabled etcd pods' Security Context +## @param podSecurityContext.fsGroup Set etcd pod's Security Context fsGroup +## +podSecurityContext: + enabled: true + fsGroup: 1001 +## etcd containers' SecurityContext +## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container +## @param containerSecurityContext.enabled Enabled etcd containers' Security Context +## @param containerSecurityContext.runAsUser Set etcd container's Security Context runAsUser +## @param containerSecurityContext.runAsNonRoot Set etcd container's Security Context runAsNonRoot +## @param containerSecurityContext.allowPrivilegeEscalation Force the child process to be run as nonprivilege +## +containerSecurityContext: + enabled: true + runAsUser: 1001 + runAsNonRoot: true + allowPrivilegeEscalation: false +## etcd containers' resource requests and limits +## ref: https://kubernetes.io/docs/user-guide/compute-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:'. +## @param resources.limits [object] The resources limits for the etcd container +## @param resources.requests [object] The requested resources for the etcd container +## +resources: + ## Example: + ## limits: + ## cpu: 500m + ## memory: 1Gi + ## + limits: {} + requests: {} +## Configure extra options for liveness probe +## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#configure-probes +## @param livenessProbe.enabled Enable livenessProbe +## @param livenessProbe.initialDelaySeconds Initial delay seconds for livenessProbe +## @param livenessProbe.periodSeconds Period seconds for livenessProbe +## @param livenessProbe.timeoutSeconds Timeout seconds for livenessProbe +## @param livenessProbe.failureThreshold Failure threshold for livenessProbe +## @param livenessProbe.successThreshold Success threshold for livenessProbe +## +livenessProbe: + enabled: true + initialDelaySeconds: 60 + periodSeconds: 30 + timeoutSeconds: 5 + successThreshold: 1 + failureThreshold: 5 +## Configure extra options for readiness probe +## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#configure-probes +## @param readinessProbe.enabled Enable readinessProbe +## @param readinessProbe.initialDelaySeconds Initial delay seconds for readinessProbe +## @param readinessProbe.periodSeconds Period seconds for readinessProbe +## @param readinessProbe.timeoutSeconds Timeout seconds for readinessProbe +## @param readinessProbe.failureThreshold Failure threshold for readinessProbe +## @param readinessProbe.successThreshold Success threshold for readinessProbe +## +readinessProbe: + enabled: true + initialDelaySeconds: 60 + periodSeconds: 10 + timeoutSeconds: 5 + successThreshold: 1 + failureThreshold: 5 +## Configure extra options for liveness probe +## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#configure-probes +## @param startupProbe.enabled Enable startupProbe +## @param startupProbe.initialDelaySeconds Initial delay seconds for startupProbe +## @param startupProbe.periodSeconds Period seconds for startupProbe +## @param startupProbe.timeoutSeconds Timeout seconds for startupProbe +## @param startupProbe.failureThreshold Failure threshold for startupProbe +## @param startupProbe.successThreshold Success threshold for startupProbe +## +startupProbe: + enabled: false + initialDelaySeconds: 0 + periodSeconds: 10 + timeoutSeconds: 5 + successThreshold: 1 + failureThreshold: 60 +## @param customLivenessProbe [object] Override default liveness probe +## +customLivenessProbe: {} +## @param customReadinessProbe [object] Override default readiness probe +## +customReadinessProbe: {} +## @param customStartupProbe [object] Override default startup probe +## +customStartupProbe: {} +## @param extraVolumes [array] Optionally specify extra list of additional volumes for etcd pods +## +extraVolumes: [] +## @param extraVolumeMounts [array] Optionally specify extra list of additional volumeMounts for etcd container(s) +## +extraVolumeMounts: [] +## @param initContainers [array] Add additional init containers to the etcd pods +## e.g: +## initContainers: +## - name: your-image-name +## image: your-image +## imagePullPolicy: Always +## ports: +## - name: portname +## containerPort: 1234 +## +initContainers: [] +## @param sidecars [array] Add additional sidecar containers to the etcd pods +## e.g: +## sidecars: +## - name: your-image-name +## image: your-image +## imagePullPolicy: Always +## ports: +## - name: portname +## containerPort: 1234 +## +sidecars: [] +## @param podAnnotations [object] Annotations for etcd pods +## ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ +## +podAnnotations: {} +## @param podLabels [object] Extra labels for etcd pods +## Ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ +## +podLabels: {} +## @param podAffinityPreset Pod affinity preset. Ignored if `affinity` is set. Allowed values: `soft` or `hard` +## ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity +## +podAffinityPreset: "" +## @param podAntiAffinityPreset Pod anti-affinity preset. Ignored if `affinity` is set. Allowed values: `soft` or `hard` +## Ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity +## +podAntiAffinityPreset: soft +## Node affinity preset +## Ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#node-affinity +## @param nodeAffinityPreset.type Node affinity preset type. Ignored if `affinity` is set. Allowed values: `soft` or `hard` +## @param nodeAffinityPreset.key Node label key to match. Ignored if `affinity` is set. +## @param nodeAffinityPreset.values [array] Node label values to match. Ignored if `affinity` is set. +## +nodeAffinityPreset: + type: "" + ## e.g: + ## key: "kubernetes.io/e2e-az-name" + ## + key: "" + ## e.g: + ## values: + ## - e2e-az1 + ## - e2e-az2 + ## + values: [] +## @param affinity [object] Affinity for pod assignment +## Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity +## Note: podAffinityPreset, podAntiAffinityPreset, and nodeAffinityPreset will be ignored when it's set +## +affinity: {} +## @param nodeSelector [object] Node labels for pod assignment +## Ref: https://kubernetes.io/docs/user-guide/node-selection/ +## +nodeSelector: {} +## @param tolerations [array] Tolerations for pod assignment +## Ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ +## +tolerations: [] +## @param terminationGracePeriodSeconds Seconds the pod needs to gracefully terminate +## ref: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#hook-handler-execution +## +terminationGracePeriodSeconds: "" +## @param schedulerName Name of the k8s scheduler (other than default) +## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ +## +schedulerName: "" +## @param priorityClassName Name of the priority class to be used by etcd pods +## Priority class needs to be created beforehand +## Ref: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/ +## +priorityClassName: "" +## @param runtimeClassName Name of the runtime class to be used by pod(s) +## ref: https://kubernetes.io/docs/concepts/containers/runtime-class/ +## +runtimeClassName: "" +## @param shareProcessNamespace Enable shared process namespace in a pod. +## If set to false (default), each container will run in separate namespace, etcd will have PID=1. +## If set to true, the /pause will run as init process and will reap any zombie PIDs, +## for example, generated by a custom exec probe running longer than a probe timeoutSeconds. +## Enable this only if customLivenessProbe or customReadinessProbe is used and zombie PIDs are accumulating. +## Ref: https://kubernetes.io/docs/tasks/configure-pod-container/share-process-namespace/ +## +shareProcessNamespace: false +## @param topologySpreadConstraints Topology Spread Constraints for pod assignment +## https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ +## The value is evaluated as a template +## +topologySpreadConstraints: [] +## persistentVolumeClaimRetentionPolicy +## ref: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#persistentvolumeclaim-retention +## @param persistentVolumeClaimRetentionPolicy.enabled Controls if and how PVCs are deleted during the lifecycle of a StatefulSet +## @param persistentVolumeClaimRetentionPolicy.whenScaled Volume retention behavior when the replica count of the StatefulSet is reduced +## @param persistentVolumeClaimRetentionPolicy.whenDeleted Volume retention behavior that applies when the StatefulSet is deleted +persistentVolumeClaimRetentionPolicy: + enabled: false + whenScaled: Retain + whenDeleted: Retain +## @section Traffic exposure parameters +## + +service: + ## @param service.type Kubernetes Service type + ## + type: ClusterIP + ## @param service.enabled create second service if equal true + ## + enabled: true + ## @param service.clusterIP Kubernetes service Cluster IP + ## e.g.: + ## clusterIP: None + ## + clusterIP: "" + ## @param service.ports.client etcd client port + ## @param service.ports.peer etcd peer port + ## + ports: + client: 2379 + peer: 2380 + ## @param service.nodePorts.client Specify the nodePort client value for the LoadBalancer and NodePort service types. + ## @param service.nodePorts.peer Specify the nodePort peer value for the LoadBalancer and NodePort service types. + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + ## + nodePorts: + client: "" + peer: "" + ## @param service.clientPortNameOverride etcd client port name override + ## + clientPortNameOverride: "" + ## @param service.peerPortNameOverride etcd peer port name override + ## + peerPortNameOverride: "" + ## @param service.loadBalancerIP loadBalancerIP for the etcd service (optional, cloud specific) + ## ref: https://kubernetes.io/docs/user-guide/services/#type-loadbalancer + ## + loadBalancerIP: "" + ## @param service.loadBalancerSourceRanges [array] Load Balancer source ranges + ## ref: https://kubernetes.io/docs/tasks/access-application-cluster/configure-cloud-provider-firewall/#restrict-access-for-loadbalancer-service + ## e.g: + ## loadBalancerSourceRanges: + ## - 10.10.10.0/24 + ## + loadBalancerSourceRanges: [] + ## @param service.externalIPs [array] External IPs + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#external-ips + ## + externalIPs: [] + ## @param service.externalTrafficPolicy %%MAIN_CONTAINER_NAME%% service external traffic policy + ## ref http://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#preserving-the-client-source-ip + ## + externalTrafficPolicy: Cluster + ## @param service.extraPorts Extra ports to expose (normally used with the `sidecar` value) + ## + extraPorts: [] + ## @param service.annotations [object] Additional annotations for the etcd service + ## + annotations: {} + ## @param service.sessionAffinity Session Affinity for Kubernetes service, can be "None" or "ClientIP" + ## If "ClientIP", consecutive client requests will be directed to the same Pod + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + ## + sessionAffinity: None + ## @param service.sessionAffinityConfig Additional settings for the sessionAffinity + ## sessionAffinityConfig: + ## clientIP: + ## timeoutSeconds: 300 + ## + sessionAffinityConfig: {} + +## @section Persistence parameters +## + +## Enable persistence using Persistent Volume Claims +## ref: https://kubernetes.io/docs/user-guide/persistent-volumes/ +## +persistence: + ## @param persistence.enabled If true, use a Persistent Volume Claim. If false, use emptyDir. + ## + enabled: true + ## @param persistence.storageClass Persistent Volume Storage Class + ## If defined, storageClassName: + ## If set to "-", storageClassName: "", which disables dynamic provisioning + ## If undefined (the default) or set to null, no storageClassName spec is + ## set, choosing the default provisioner. (gp2 on AWS, standard on + ## GKE, AWS & OpenStack) + ## + storageClass: "" + ## + ## @param persistence.annotations [object] Annotations for the PVC + ## + annotations: {} + ## @param persistence.accessModes Persistent Volume Access Modes + ## + accessModes: + - ReadWriteOnce + ## @param persistence.size PVC Storage Request for etcd data volume + ## + size: 8Gi + ## @param persistence.selector [object] Selector to match an existing Persistent Volume + ## ref: https://kubernetes.io/docs/concepts/storage/persistent-volumes/#selector + ## + selector: {} + +## @section Volume Permissions parameters +## + +## Init containers parameters: +## volumePermissions: Change the owner and group of the persistent volume mountpoint to runAsUser:fsGroup values from the securityContext section. +## +volumePermissions: + ## @param volumePermissions.enabled Enable init container that changes the owner and group of the persistent volume(s) mountpoint to `runAsUser:fsGroup` + ## + enabled: false + ## @param volumePermissions.image.registry Init container volume-permissions image registry + ## @param volumePermissions.image.repository Init container volume-permissions image name + ## @param volumePermissions.image.tag Init container volume-permissions image tag + ## @param volumePermissions.image.digest Init container volume-permissions image digest in the way sha256:aa.... Please note this parameter, if set, will override the tag + ## + image: + registry: docker.io + repository: bitnami/bitnami-shell + tag: 11-debian-11-r63 + digest: "" + ## @param volumePermissions.image.pullPolicy Init container volume-permissions image pull policy + ## + pullPolicy: IfNotPresent + ## @param volumePermissions.image.pullSecrets [array] Specify docker-registry secret names as an array + ## Optionally specify an array of imagePullSecrets. + ## Secrets must be manually created in the namespace. + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ + ## e.g: + ## pullSecrets: + ## - myRegistryKeySecretName + ## + pullSecrets: [] + ## Init container' resource requests and limits + ## ref: https://kubernetes.io/docs/user-guide/compute-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:'. + ## @param volumePermissions.resources.limits [object] Init container volume-permissions resource limits + ## @param volumePermissions.resources.requests [object] Init container volume-permissions resource requests + ## + resources: + ## Example: + ## limits: + ## cpu: 500m + ## memory: 1Gi + ## + limits: {} + requests: {} + +## @section Network Policy parameters +## ref: https://kubernetes.io/docs/concepts/services-networking/network-policies/ +## +networkPolicy: + ## @param networkPolicy.enabled Enable creation of NetworkPolicy resources + ## + enabled: false + ## @param networkPolicy.allowExternal Don't require client label for connections + ## When set to false, only pods with the correct client label will have network access to the ports + ## etcd is listening on. When true, etcd will accept connections from any source + ## (with the correct destination port). + ## + allowExternal: true + ## @param networkPolicy.extraIngress [array] Add extra ingress rules to the NetworkPolicy + ## e.g: + ## extraIngress: + ## - ports: + ## - port: 1234 + ## from: + ## - podSelector: + ## - matchLabels: + ## - role: frontend + ## - podSelector: + ## - matchExpressions: + ## - key: role + ## operator: In + ## values: + ## - frontend + ## + extraIngress: [] + ## @param networkPolicy.extraEgress [array] Add extra ingress rules to the NetworkPolicy + ## e.g: + ## extraEgress: + ## - ports: + ## - port: 1234 + ## to: + ## - podSelector: + ## - matchLabels: + ## - role: frontend + ## - podSelector: + ## - matchExpressions: + ## - key: role + ## operator: In + ## values: + ## - frontend + ## + extraEgress: [] + ## @param networkPolicy.ingressNSMatchLabels [object] Labels to match to allow traffic from other namespaces + ## @param networkPolicy.ingressNSPodMatchLabels [object] Pod labels to match to allow traffic from other namespaces + ## + ingressNSMatchLabels: {} + ingressNSPodMatchLabels: {} + +## @section Metrics parameters +## + +metrics: + ## @param metrics.enabled Expose etcd metrics + ## + enabled: false + ## @param metrics.podAnnotations [object] Annotations for the Prometheus metrics on etcd pods + ## + podAnnotations: + prometheus.io/scrape: "true" + prometheus.io/port: "{{ .Values.containerPorts.client }}" + ## Prometheus Service Monitor + ## ref: https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#endpoint + ## + podMonitor: + ## @param metrics.podMonitor.enabled Create PodMonitor Resource for scraping metrics using PrometheusOperator + ## + enabled: false + ## @param metrics.podMonitor.namespace Namespace in which Prometheus is running + ## + namespace: monitoring + ## @param metrics.podMonitor.interval Specify the interval at which metrics should be scraped + ## + interval: 30s + ## @param metrics.podMonitor.scrapeTimeout Specify the timeout after which the scrape is ended + ## + scrapeTimeout: 30s + ## @param metrics.podMonitor.additionalLabels [object] Additional labels that can be used so PodMonitors will be discovered by Prometheus + ## ref: https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#prometheusspec + ## + additionalLabels: {} + ## @param metrics.podMonitor.scheme Scheme to use for scraping + ## + scheme: http + ## @param metrics.podMonitor.tlsConfig [object] TLS configuration used for scrape endpoints used by Prometheus + ## ref: https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#tlsconfig + ## e.g: + ## tlsConfig: + ## ca: + ## secret: + ## name: existingSecretName + ## + tlsConfig: {} + ## @param metrics.podMonitor.relabelings [array] Prometheus relabeling rules + ## + relabelings: [] + + ## Prometheus Operator PrometheusRule configuration + ## + prometheusRule: + ## @param metrics.prometheusRule.enabled Create a Prometheus Operator PrometheusRule (also requires `metrics.enabled` to be `true` and `metrics.prometheusRule.rules`) + ## + enabled: false + ## @param metrics.prometheusRule.namespace Namespace for the PrometheusRule Resource (defaults to the Release Namespace) + ## + namespace: "" + ## @param metrics.prometheusRule.additionalLabels Additional labels that can be used so PrometheusRule will be discovered by Prometheus + ## + additionalLabels: {} + ## @param metrics.prometheusRule.rules Prometheus Rule definitions + # - alert: ETCD has no leader + # annotations: + # summary: "ETCD has no leader" + # description: "pod {{`{{`}} $labels.pod {{`}}`}} state error, can't connect leader" + # for: 1m + # expr: etcd_server_has_leader == 0 + # labels: + # severity: critical + # group: PaaS + ## + rules: [] + + +## @section Snapshotting parameters +## + +## Start a new etcd cluster recovering the data from an existing snapshot before bootstrapping +## +startFromSnapshot: + ## @param startFromSnapshot.enabled Initialize new cluster recovering an existing snapshot + ## + enabled: false + ## @param startFromSnapshot.existingClaim Existing PVC containing the etcd snapshot + ## + existingClaim: "" + ## @param startFromSnapshot.snapshotFilename Snapshot filename + ## + snapshotFilename: "" +## Enable auto disaster recovery by periodically snapshotting the keyspace: +## - It creates a cronjob to periodically snapshotting the keyspace +## - It also creates a ReadWriteMany PVC to store the snapshots +## If the cluster permanently loses more than (N-1)/2 members, it tries to +## recover itself from the last available snapshot. +## +disasterRecovery: + ## @param disasterRecovery.enabled Enable auto disaster recovery by periodically snapshotting the keyspace + ## + enabled: false + cronjob: + ## @param disasterRecovery.cronjob.schedule Schedule in Cron format to save snapshots + ## See https://en.wikipedia.org/wiki/Cron + ## + schedule: "*/30 * * * *" + ## @param disasterRecovery.cronjob.historyLimit Number of successful finished jobs to retain + ## + historyLimit: 1 + ## @param disasterRecovery.cronjob.snapshotHistoryLimit Number of etcd snapshots to retain, tagged by date + ## + snapshotHistoryLimit: 1 + ## @param disasterRecovery.cronjob.podAnnotations [object] Pod annotations for cronjob pods + ## ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ + ## + podAnnotations: {} + ## Configure resource requests and limits for snapshotter containers + ## ref: https://kubernetes.io/docs/user-guide/compute-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:'. + ## @param disasterRecovery.cronjob.resources.limits [object] Cronjob container resource limits + ## @param disasterRecovery.cronjob.resources.requests [object] Cronjob container resource requests + ## + resources: + ## Example: + ## limits: + ## cpu: 500m + ## memory: 1Gi + ## + limits: {} + requests: {} + + ## @param disasterRecovery.cronjob.nodeSelector Node labels for cronjob pods assignment + ## Ref: https://kubernetes.io/docs/user-guide/node-selection/ + ## + nodeSelector: {} + ## @param disasterRecovery.cronjob.tolerations Tolerations for cronjob pods assignment + ## Ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ + ## + tolerations: [] + + pvc: + ## @param disasterRecovery.pvc.existingClaim A manually managed Persistent Volume and Claim + ## If defined, PVC must be created manually before volume will be bound + ## The value is evaluated as a template, so, for example, the name can depend on .Release or .Chart + ## + existingClaim: "" + ## @param disasterRecovery.pvc.size PVC Storage Request + ## + size: 2Gi + ## @param disasterRecovery.pvc.storageClassName Storage Class for snapshots volume + ## + storageClassName: nfs + +## @section Service account parameters +## + +serviceAccount: + ## @param serviceAccount.create Enable/disable service account creation + ## + create: false + ## @param serviceAccount.name Name of the service account to create or use + ## + name: "" + ## @param serviceAccount.automountServiceAccountToken Enable/disable auto mounting of service account token + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#use-the-default-service-account-to-access-the-api-server + ## + automountServiceAccountToken: true + ## @param serviceAccount.annotations [object] Additional annotations to be included on the service account + ## + annotations: {} + ## @param serviceAccount.labels [object] Additional labels to be included on the service account + ## + labels: {} + +## @section Other parameters +## + +## etcd Pod Disruption Budget configuration +## ref: https://kubernetes.io/docs/tasks/run-application/configure-pdb/ +## +pdb: + ## @param pdb.create Enable/disable a Pod Disruption Budget creation + ## + create: true + ## @param pdb.minAvailable Minimum number/percentage of pods that should remain scheduled + ## + minAvailable: 51% + ## @param pdb.maxUnavailable Maximum number/percentage of pods that may be made unavailable + ## + maxUnavailable: "" diff --git a/helm/openebs/charts/mayastor/charts/jaeger-operator/.helmignore b/helm/openebs/charts/mayastor/charts/jaeger-operator/.helmignore new file mode 100644 index 0000000..f0c1319 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/jaeger-operator/.helmignore @@ -0,0 +1,21 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*~ +# Various IDEs +.project +.idea/ +*.tmproj diff --git a/helm/openebs/charts/mayastor/charts/jaeger-operator/Chart.yaml b/helm/openebs/charts/mayastor/charts/jaeger-operator/Chart.yaml new file mode 100644 index 0000000..9a1ce85 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/jaeger-operator/Chart.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +appVersion: 1.24.0 +description: jaeger-operator Helm chart for Kubernetes +home: https://www.jaegertracing.io/ +icon: https://www.jaegertracing.io/img/jaeger-icon-reverse-color.svg +maintainers: +- email: ctadeu@gmail.com + name: cpanato +- email: batazor111@gmail.com + name: batazor +name: jaeger-operator +sources: +- https://github.com/jaegertracing/jaeger-operator +version: 2.25.0 diff --git a/helm/openebs/charts/mayastor/charts/jaeger-operator/README.md b/helm/openebs/charts/mayastor/charts/jaeger-operator/README.md new file mode 100644 index 0000000..3137e16 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/jaeger-operator/README.md @@ -0,0 +1,128 @@ +# jaeger-operator + +[jaeger-operator](https://github.com/jaegertracing/jaeger-operator) is a Kubernetes operator. + +## Install + +```console +$ helm install jaegertracing/jaeger-operator +``` + +## Introduction + +This chart bootstraps a jaeger-operator deployment on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. + +## Prerequisites + +- Kubernetes 1.19+ + +## Installing the Chart + +Add the Jaeger Tracing Helm repository: + +```console +$ helm repo add jaegertracing https://jaegertracing.github.io/helm-charts +``` + +To install the chart with the release name `my-release`: + +```console +$ helm install --name my-release jaegertracing/jaeger-operator +``` + +The command deploys jaeger-operator on the Kubernetes cluster in the default configuration. The [configuration](#configuration) section lists the parameters that can be configured during installation. + +> **Tip**: List all releases using `helm list` + +## Uninstalling the Chart + +To uninstall/delete the `my-release` deployment: + +```console +$ helm delete my-release +``` + +The command removes all the Kubernetes components associated with the chart and deletes the release. + +## Configuration + +The following table lists the configurable parameters of the jaeger-operator chart and their default values. + +| Parameter | Description | Default | +| :---------------------- | :---------------------------------------------------------------------------------------------------------- | :------------------------------ | +| `extraLabels` | Additional labels to jaeger-operator deployment | `{}` +| `image.repository` | Controller container image repository | `jaegertracing/jaeger-operator` | +| `image.tag` | Controller container image tag | `1.24.0` | +| `image.pullPolicy` | Controller container image pull policy | `IfNotPresent` | +| `jaeger.create` | Jaeger instance will be created | `false` | +| `jaeger.spec` | Jaeger instance specification | `{}` | +| `crd.install` | CustomResourceDefinition will be installed | `true` | +| `rbac.create` | All required roles and rolebindings will be created | `true` | +| `serviceAccount.create` | Service account to use | `true` | +| `rbac.pspEnabled` | Pod security policy for pod will be created and included in rbac role | `false` | +| `rbac.clusterRole` | ClusterRole will be used by operator ServiceAccount | `false` | +| `serviceAccount.name` | Service account name to use. If not set and create is true, a name is generated using the fullname template | `nil` | +| `extraEnv` | Additional environment variables passed to the operator. For example: name: LOG-LEVEL value: debug | `[]` | +| `resources` | K8s pod resources | `None` | +| `nodeSelector` | Node labels for pod assignment | `{}` | +| `tolerations` | Toleration labels for pod assignment | `[]` | +| `affinity` | Affinity settings for pod assignment | `{}` | +| `securityContext` | Security context for pod | `{}` | +| `priorityClassName` | Priority class name for the pod | `None` | + +Specify each parameter you'd like to override using a YAML file as described above in the [installation](#installing-the-chart) section. + +You can also specify any non-array parameter using the `--set key=value[,key=value]` argument to `helm install`. For example, + +```console +$ helm install jaegertracing/jaeger-operator --name my-release \ + --set rbac.create=false +``` + +## After the Helm Installation + +### Creating a new Jaeger instance + +The simplest possible way to install is by creating a YAML file like the following: + +```YAML +apiVersion: jaegertracing.io/v1 +kind: Jaeger +metadata: + name: simplest +``` + +The YAML file can then be used with `kubectl`: + +```console +$ kubectl apply -f simplest.yaml +``` + +### Creating a new Jaeger with ElasticSearch + +To do that you need to have an ElasticSearch installed in your Kubernetes cluster or install one using the [Helm Chart](https://github.com/helm/charts/tree/master/incubator/elasticsearch) available for that. + +After that just deploy the following manifest: + +```YAML +# setup an elasticsearch with `make es` +apiVersion: jaegertracing.io/v1 +kind: Jaeger +metadata: + name: simple-prod +spec: + strategy: production + storage: + type: elasticsearch + options: + es: + server-urls: http://elasticsearch:9200 + username: elastic + password: changeme +``` + +The YAML file can then be used with `kubectl`: + +```console +$ kubectl apply -f simple-prod.yaml +``` diff --git a/helm/openebs/charts/mayastor/charts/jaeger-operator/crds/crd.yaml b/helm/openebs/charts/mayastor/charts/jaeger-operator/crds/crd.yaml new file mode 100644 index 0000000..6376100 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/jaeger-operator/crds/crd.yaml @@ -0,0 +1,34 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: jaegers.jaegertracing.io + annotations: + "helm.sh/hook": crd-install + "helm.sh/hook-delete-policy": "before-hook-creation" + labels: + app: jaeger-operator +spec: + group: jaegertracing.io + names: + kind: Jaeger + listKind: JaegerList + plural: jaegers + singular: jaeger + scope: Namespaced + versions: + - name: v1 + served: true + storage: true + schema: + openAPIV3Schema: + type: object + x-kubernetes-preserve-unknown-fields: true + additionalPrinterColumns: + - jsonPath: .status.phase + description: Jaeger instance's status + name: Status + type: string + - jsonPath: .status.version + description: Jaeger Version + name: Version + type: string diff --git a/helm/openebs/charts/mayastor/charts/jaeger-operator/templates/NOTES.txt b/helm/openebs/charts/mayastor/charts/jaeger-operator/templates/NOTES.txt new file mode 100644 index 0000000..64da5f5 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/jaeger-operator/templates/NOTES.txt @@ -0,0 +1,8 @@ +jaeger-operator is installed. + + +Check the jaeger-operator logs + export POD=$(kubectl get pods -l app.kubernetes.io/instance={{ .Release.Name }} -lapp.kubernetes.io/name=jaeger-operator --namespace {{ .Release.Namespace }} --output name) + kubectl logs $POD --namespace={{ .Release.Namespace }} + + diff --git a/helm/openebs/charts/mayastor/charts/jaeger-operator/templates/_helpers.tpl b/helm/openebs/charts/mayastor/charts/jaeger-operator/templates/_helpers.tpl new file mode 100644 index 0000000..ec2de02 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/jaeger-operator/templates/_helpers.tpl @@ -0,0 +1,49 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "jaeger-operator.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "jaeger-operator.fullname" -}} +{{- if .Values.fullnameOverride -}} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Create the name of the service account to use +*/}} +{{- define "jaeger-operator.serviceAccountName" -}} +{{- if .Values.serviceAccount.create -}} + {{ default (include "jaeger-operator.fullname" .) .Values.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "jaeger-operator.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* Generate basic labels */}} +{{- define "jaeger-operator.labels" }} +app.kubernetes.io/name: {{ include "jaeger-operator.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/jaeger-operator/templates/crds.yaml b/helm/openebs/charts/mayastor/charts/jaeger-operator/templates/crds.yaml new file mode 100644 index 0000000..0ad3047 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/jaeger-operator/templates/crds.yaml @@ -0,0 +1,6 @@ +{{- if .Values.crd.install }} +{{- range $path, $bytes := .Files.Glob "crds/*.yaml" }} +{{ $.Files.Get $path }} +--- +{{- end }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/jaeger-operator/templates/deployment.yaml b/helm/openebs/charts/mayastor/charts/jaeger-operator/templates/deployment.yaml new file mode 100644 index 0000000..99df089 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/jaeger-operator/templates/deployment.yaml @@ -0,0 +1,84 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "jaeger-operator.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: +{{ include "jaeger-operator.labels" . | indent 4 }} +{{- with .Values.extraLabels }} +{{ . | toYaml | indent 4 }} +{{- end }} +spec: + replicas: 1 + selector: + matchLabels: +{{ include "jaeger-operator.labels" . | indent 6 }} + template: + metadata: + name: {{ include "jaeger-operator.fullname" . }} + labels: +{{ include "jaeger-operator.labels" . | indent 8 }} +{{- with .Values.extraLabels }} +{{ . | toYaml | indent 8 }} +{{- end }} + spec: + {{- if .Values.serviceAccount.create }} + serviceAccountName: {{ include "jaeger-operator.serviceAccountName" . }} + {{- end }} + {{- with .Values.securityContext }} + securityContext: +{{ toYaml . | indent 8 }} + {{- end }} + {{- if .Values.priorityClassName }} + priorityClassName: {{ .Values.priorityClassName | quote }} + {{- end }} + {{- if and .Values.image.imagePullSecrets (not .Values.serviceAccount.create ) }} + imagePullSecrets: + {{- range .Values.image.imagePullSecrets }} + - name: {{ . }} + {{- end }} + {{- end }} + containers: + - name: {{ include "jaeger-operator.fullname" . }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + ports: + - containerPort: 8383 + name: metrics + args: ["start"] + env: + - name: WATCH_NAMESPACE + {{- if .Values.rbac.clusterRole }} + value: "" + {{- else }} + valueFrom: + fieldRef: + fieldPath: metadata.namespace + {{- end }} + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: OPERATOR_NAME + value: {{ include "jaeger-operator.fullname" . | quote }} + {{- if .Values.extraEnv }} + {{- toYaml .Values.extraEnv | nindent 12 }} + {{- end }} + resources: +{{ toYaml .Values.resources | indent 12 }} + {{- with .Values.nodeSelector }} + nodeSelector: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: +{{ toYaml . | indent 8 }} + {{- end }} diff --git a/helm/openebs/charts/mayastor/charts/jaeger-operator/templates/jaeger.yaml b/helm/openebs/charts/mayastor/charts/jaeger-operator/templates/jaeger.yaml new file mode 100644 index 0000000..0c4f9d2 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/jaeger-operator/templates/jaeger.yaml @@ -0,0 +1,11 @@ +{{- if .Values.jaeger.create }} +apiVersion: jaegertracing.io/v1 +kind: Jaeger +metadata: + name: {{ include "jaeger-operator.fullname" . }}-jaeger + namespace: {{ default .Release.Namespace .Values.jaeger.namespace }} +{{- with .Values.jaeger.spec }} +spec: +{{ toYaml . | indent 2}} +{{- end }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/jaeger-operator/templates/psp.yaml b/helm/openebs/charts/mayastor/charts/jaeger-operator/templates/psp.yaml new file mode 100644 index 0000000..7d7cca5 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/jaeger-operator/templates/psp.yaml @@ -0,0 +1,36 @@ +{{- if and .Values.rbac.create .Values.rbac.pspEnabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ include "jaeger-operator.fullname" . }}-operator-psp + labels: +{{ include "jaeger-operator.labels" . | indent 4 }} +spec: + privileged: false + allowPrivilegeEscalation: false + volumes: + - 'configMap' + - 'emptyDir' + - 'projected' + - 'secret' + - 'downwardAPI' + - 'persistentVolumeClaim' + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + rule: 'MustRunAsNonRoot' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'MustRunAs' + ranges: + - min: 1 + max: 65535 + fsGroup: + rule: 'MustRunAs' + ranges: + - min: 1 + max: 65535 + readOnlyRootFilesystem: false +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/jaeger-operator/templates/role-binding.yaml b/helm/openebs/charts/mayastor/charts/jaeger-operator/templates/role-binding.yaml new file mode 100644 index 0000000..533f828 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/jaeger-operator/templates/role-binding.yaml @@ -0,0 +1,17 @@ +{{- if .Values.rbac.create }} +kind: {{ if .Values.rbac.clusterRole }}Cluster{{ end }}RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ include "jaeger-operator.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: +{{ include "jaeger-operator.labels" . | indent 4 }} +subjects: +- kind: ServiceAccount + namespace: {{ .Release.Namespace }} + name: {{ include "jaeger-operator.serviceAccountName" . }} +roleRef: + kind: {{ if .Values.rbac.clusterRole }}Cluster{{ end }}Role + name: {{ include "jaeger-operator.fullname" . }} + apiGroup: rbac.authorization.k8s.io +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/jaeger-operator/templates/role.yaml b/helm/openebs/charts/mayastor/charts/jaeger-operator/templates/role.yaml new file mode 100644 index 0000000..321a23c --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/jaeger-operator/templates/role.yaml @@ -0,0 +1,231 @@ +{{- if .Values.rbac.create }} +kind: {{ if .Values.rbac.clusterRole }}Cluster{{ end }}Role +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ include "jaeger-operator.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: +{{ include "jaeger-operator.labels" . | indent 4 }} +rules: +## our own custom resources +- apiGroups: + - jaegertracing.io + resources: + - '*' + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + +## for the operator's own deployment +- apiGroups: + - apps + resourceNames: + - jaeger-operator + resources: + - deployments/finalizers + verbs: + - update + +## regular things the operator manages for an instance, as the result of processing CRs +- apiGroups: + - "" + resources: + - configmaps + - persistentvolumeclaims + - pods + - secrets + - serviceaccounts + - services + - services/finalizers + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - apps + resources: + - deployments + - daemonsets + - replicasets + - statefulsets + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - extensions + resources: + - ingresses + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +# Ingress for kubernetes 1.14 or higher +- apiGroups: + - networking.k8s.io + resources: + - ingresses + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - batch + resources: + - jobs + - cronjobs + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - route.openshift.io + resources: + - routes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - console.openshift.io + resources: + - consolelinks + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - autoscaling + resources: + - horizontalpodautoscalers + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + +## needed if you want the operator to create service monitors for the Jaeger instances +- apiGroups: + - monitoring.coreos.com + resources: + - servicemonitors + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + +## for the Elasticsearch auto-provisioning +- apiGroups: + - logging.openshift.io + resources: + - elasticsearches + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + +## for the Kafka auto-provisioning +- apiGroups: + - kafka.strimzi.io + resources: + - kafkas + - kafkausers + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + +## Extra permissions +## This is an extra set of permissions that the Jaeger Operator might make use of if granted + +## needed if support for injecting sidecars based on namespace annotation is required +- apiGroups: + - "" + resources: + - namespaces + verbs: + - 'get' + - 'list' + - 'watch' + +## needed if support for injecting sidecars based on deployment annotation is required, across all namespaces +- apiGroups: + - apps + resources: + - deployments + verbs: + - get + - list + - patch + - update + - watch + +## needed only when .Spec.Ingress.Openshift.DelegateUrls is used +- apiGroups: + - rbac.authorization.k8s.io + resources: + - clusterrolebindings + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +{{- if .Values.rbac.pspEnabled }} +- apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ include "jaeger-operator.fullname" . }}-operator-psp +{{- end }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/jaeger-operator/templates/service-account.yaml b/helm/openebs/charts/mayastor/charts/jaeger-operator/templates/service-account.yaml new file mode 100644 index 0000000..dc8eea6 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/jaeger-operator/templates/service-account.yaml @@ -0,0 +1,19 @@ +{{- if .Values.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "jaeger-operator.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} + labels: +{{ include "jaeger-operator.labels" . | indent 4 }} +{{- if .Values.serviceAccount.annotations }} + annotations: +{{ toYaml .Values.serviceAccount.annotations | indent 4 }} +{{- end }} +{{- if .Values.image.imagePullSecrets }} +imagePullSecrets: +{{- range .Values.image.imagePullSecrets }} + - name: {{ . }} +{{- end }} +{{- end }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/jaeger-operator/templates/service.yaml b/helm/openebs/charts/mayastor/charts/jaeger-operator/templates/service.yaml new file mode 100644 index 0000000..d7daec2 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/jaeger-operator/templates/service.yaml @@ -0,0 +1,24 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "jaeger-operator.fullname" . }}-metrics + namespace: {{ .Release.Namespace }} + labels: +{{ include "jaeger-operator.labels" . | indent 4 }} +{{- if .Values.service.annotations }} + annotations: +{{ toYaml .Values.service.annotations | indent 4 }} +{{- end }} +spec: + ports: + - name: metrics + port: 8383 + protocol: TCP + targetPort: 8383 +{{- if and (eq .Values.service.type "NodePort") (.Values.service.nodePort) }} + nodePort: {{ .Values.service.nodePort }} +{{- end }} + selector: + app.kubernetes.io/name: {{ include "jaeger-operator.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + type: {{ .Values.service.type }} diff --git a/helm/openebs/charts/mayastor/charts/jaeger-operator/values.yaml b/helm/openebs/charts/mayastor/charts/jaeger-operator/values.yaml new file mode 100644 index 0000000..478285b --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/jaeger-operator/values.yaml @@ -0,0 +1,69 @@ +# Default values for jaeger-operator. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +image: + repository: jaegertracing/jaeger-operator + tag: 1.24.0 + pullPolicy: IfNotPresent + imagePullSecrets: [] + +crd: + install: true + +jaeger: + # Specifies whether Jaeger instance should be created + create: false + # namespace where Jaeger resource should be created default to .Release.Namespace + namespace: + spec: {} + +rbac: + # Specifies whether RBAC resources should be created + create: true + pspEnabled: false + clusterRole: false + +service: + type: ClusterIP + # Specify a specific node port when type is NodePort + # nodePort: 32500 + # Annotations for service + annotations: {} + +serviceAccount: + # Specifies whether a ServiceAccount should be created + create: true + # The name of the ServiceAccount to use. + # If not set and create is true, a name is generated using the fullname template + name: + # Annotations for serviceAccount + annotations: {} + +# Specifies extra environment variables passed to the operator: +extraEnv: [] + # Specifies log-level for the operator: + # - name: LOG-LEVEL + # value: debug + +extraLabels: {} + # Specifies extra labels for the operator deployment: + # foo: bar + +resources: {} + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + +nodeSelector: {} + +tolerations: [] + +affinity: {} + +securityContext: {} + +priorityClassName: diff --git a/helm/openebs/charts/mayastor/charts/localpv-provisioner/.helmignore b/helm/openebs/charts/mayastor/charts/localpv-provisioner/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/localpv-provisioner/.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/helm/openebs/charts/mayastor/charts/localpv-provisioner/Chart.lock b/helm/openebs/charts/mayastor/charts/localpv-provisioner/Chart.lock new file mode 100644 index 0000000..4ff3a5c --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/localpv-provisioner/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: openebs-ndm + repository: https://openebs.github.io/node-disk-manager + version: 2.1.0 +digest: sha256:47adcc8a92ea7ce83ca7f37f05f9e2f4c10154adc9551bd92e92c1ca5608f131 +generated: "2023-08-16T16:46:46.773916076Z" diff --git a/helm/openebs/charts/mayastor/charts/localpv-provisioner/Chart.yaml b/helm/openebs/charts/mayastor/charts/localpv-provisioner/Chart.yaml new file mode 100644 index 0000000..4d1e73d --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/localpv-provisioner/Chart.yaml @@ -0,0 +1,27 @@ +apiVersion: v2 +appVersion: 3.4.0 +dependencies: +- condition: openebsNDM.enabled + name: openebs-ndm + repository: https://openebs.github.io/node-disk-manager + version: 2.1.0 +description: Helm chart for OpenEBS Dynamic Local PV. For instructions to install + OpenEBS Dynamic Local PV using helm chart, refer to https://openebs.github.io/dynamic-localpv-provisioner/. +home: http://www.openebs.io/ +icon: https://raw.githubusercontent.com/cncf/artwork/master/projects/openebs/icon/color/openebs-icon-color.png +keywords: +- storage +- local +- dynamic-localpv +maintainers: +- email: akhil.mohan@mayadata.io + name: akhilerm +- email: kiran.mova@mayadata.io + name: kiranmova +- email: prateek.pandey@mayadata.io + name: prateekpandey14 +name: localpv-provisioner +sources: +- https://github.com/openebs/dynamic-localpv-provisioner +type: application +version: 3.4.1 diff --git a/helm/openebs/charts/mayastor/charts/localpv-provisioner/README.md b/helm/openebs/charts/mayastor/charts/localpv-provisioner/README.md new file mode 100644 index 0000000..fe321ca --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/localpv-provisioner/README.md @@ -0,0 +1,160 @@ +# OpenEBS LocalPV Provisioner + +[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) +![Chart Lint and Test](https://github.com/openebs/dynamic-localpv-provisioner/workflows/Chart%20Lint%20and%20Test/badge.svg) +![Release Charts](https://github.com/openebs/dynamic-localpv-provisioner/workflows/Release%20Charts/badge.svg?branch=develop) + +A Helm chart for openebs dynamic localpv provisioner. This chart bootstraps OpenEBS Dynamic LocalPV provisioner deployment on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. + + +**Homepage:** + +## Maintainers + +| Name | Email | Url | +| ---- | ------ | --- | +| akhilerm | akhil.mohan@mayadata.io | | +| kiranmova | kiran.mova@mayadata.io | | +| prateekpandey14 | prateek.pandey@mayadata.io | | + + +## Get Repo Info + +```console +helm repo add openebs-localpv https://openebs.github.io/dynamic-localpv-provisioner +helm repo update +``` + +_See [helm repo](https://helm.sh/docs/helm/helm_repo/) for command documentation._ + +## Install Chart + +Please visit the [link](https://openebs.github.io/dynamic-localpv-provisioner/) for install instructions via helm3. + +```console +# Helm +helm install [RELEASE_NAME] openebs-localpv/localpv-provisioner --namespace [NAMESPACE] --create-namespace +``` + +_See [configuration](#configuration) below._ + +_See [helm install](https://helm.sh/docs/helm/helm_install/) for command documentation._ + +## Dependencies + +By default this chart installs additional, dependent charts: + +| Repository | Name | Version | +|------------|------|---------| +| https://openebs.github.io/node-disk-manager | openebs-ndm | 2.1.0 | + +**Note:** Find detailed Node Disk Manager Helm chart configuration options [here](https://github.com/openebs/node-disk-manager/blob/master/deploy/helm/charts/README.md). + + +To disable the dependency during installation, set `openebsNDM.enabled` to `false`. + +_See [helm dependency](https://helm.sh/docs/helm/helm_dependency/) for command documentation._ + +## Uninstall Chart + +```console +# Helm +helm uninstall [RELEASE_NAME] --namespace [NAMESPACE] +``` + +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._ + +## Upgrading Chart + +```console +# Helm +helm upgrade [RELEASE_NAME] [CHART] --install --namespace [NAMESPACE] +``` + + +## Configuration + +The following table lists the configurable parameters of the OpenEBS Dynamic LocalPV Provisioner chart and their default values. + +You can modify different parameters by specifying the desired value in the `helm install` command by using the `--set` and/or the `--set-string` flag(s). You can modify the parameters of the [Node Disk Manager chart](https://openebs.github.io/node-disk-manager) by adding `openebs-ndm` before the desired parameter in the `helm install` command. + +In the following sample command we modify `deviceClass.fsType` from the localpv-provisioner chart and `ndm.nodeSelector` from the openebs-ndm chart to only schedule openebs-ndm DaemonSet pods on nodes labelled with `openebs.io/data-plane=true`. We also enable the 'Use OS-disk' feature gate using the `featureGates.UseOSDisk.enabled` parameter from the openebs-ndm chart. + + +```console +helm install openebs-localpv openebs-localpv/localpv-provisioner --namespace openebs --create-namespace \ + --set-string deviceClass.fsType="xfs" \ + --set-string openebs-ndm.ndm.nodeSelector."openebs\.io/data-plane"=true \ + --set openebs-ndm.featureGates.UseOSDisk.enabled=true +``` + +Sample command to install the provisioner with nodeAffinityLabels "openebs.io/node-affinity-key-1" and "openebs.io/node-affinity-key-2" on the hostpath StorageClass: +```console +helm install openebs-localpv openebs-localpv/localpv-provisioner --namespace openebs --create-namespace \ + --set-string hostpathClass.nodeAffinityLabels="{openebs.io/node-affinity-key-1,openebs.io/node-affinity-key-2}" +``` + +Sample command to install the provisioner with blockDeviceSelectors "openebs.io/block-device-tag=mongo" and "ndm.io/fsType=ext4": +```console +helm install openebs-localpv openebs-localpv/localpv-provisioner --namespace openebs --create-namespace \ + --set-string deviceClass.blockDeviceSelectors."openebs\.io/block-device-tag"="mongo" \ + --set-string deviceClass.blockDeviceSelectors."ndm\.io/fsType"="ext4" +``` + +| Parameter | Description | Default | +| ------------------------------------------- | --------------------------------------------- | ----------------------------------------- | +| `release.version` | LocalPV Provisioner release version | `3.4.0` | +| `analytics.enabled` | Enable sending stats to Google Analytics | `true` | +| `analytics.pingInterval` | Duration(hours) between sending ping stat | `24h` | +| `deviceClass.blockDeviceSelectors` | Label key value pairs based on which BlockDevices on the node will be selected for provisioning | `{}` | +| `deviceClass.enabled` | Enables creation of default Device StorageClass | `true` | +| `deviceClass.fsType` | Filesystem type for openebs-device StorageClass | `"ext4"` | +| `deviceClass.isDefaultClass` | Make openebs-device the default StorageClass | `"false"` | +| `deviceClass.nodeAffinityLabels` | Custom node label(or labels) key to uniquely identify nodes. `kubernetes.io/hostname` is the default label key for node selection. | `[]` | +| `deviceClass.reclaimPolicy` | ReclaimPolicy for Device PVs | `"Delete"` | +| `helperPod.image.registry` | Registry for helper image | `""` | +| `helperPod.image.repository` | Image for helper pod | `"openebs/linux-utils"` | +| `helperPod.image.pullPolicy` | Pull policy for helper pod | `"IfNotPresent"` | +| `helperPod.image.tag` | Image tag for helper image | `3.4.0` | +| `hostpathClass.basePath` | BasePath for openebs-hostpath StorageClass | `"/var/openebs/local"` | +| `hostpathClass.enabled` | Enables creation of default Hostpath StorageClass | `true` | +| `hostpathClass.isDefaultClass` | Make openebs-hostpath the default StorageClass | `"false"` | +| `hostpathClass.nodeAffinityLabels` | Custom node label(or labels) key to uniquely identify nodes. `kubernetes.io/hostname` is the default label key for node selection. | `[]` | +| `hostpathClass.xfsQuota.enabled` | Enable XFS Quota (requires XFS filesystem) | `false` | +| `hostpathClass.ext4Quota.enabled` | Enable EXT4 Quota (requires EXT4 filesystem) | `false` | +| `hostpathClass.reclaimPolicy` | ReclaimPolicy for Hostpath PVs | `"Delete"` | +| `imagePullSecrets` | Provides image pull secrect | `""` | +| `localpv.enabled` | Enable LocalPV Provisioner | `true` | +| `localpv.image.registry` | Registry for LocalPV Provisioner image | `""` | +| `localpv.image.repository` | Image repository for LocalPV Provisioner | `openebs/localpv-provisioner` | +| `localpv.image.pullPolicy` | Image pull policy for LocalPV Provisioner | `IfNotPresent` | +| `localpv.image.tag` | Image tag for LocalPV Provisioner | `3.4.0` | +| `localpv.updateStrategy.type` | Update strategy for LocalPV Provisioner | `RollingUpdate` | +| `localpv.annotations` | Annotations for LocalPV Provisioner metadata | `""` | +| `localpv.podAnnotations` | Annotations for LocalPV Provisioner pods metadata | `""` | +| `localpv.privileged` | Run LocalPV Provisioner with extra privileges | `true` | +| `localpv.resources` | Resource and request and limit for containers | `""` | +| `localpv.podLabels` | Appends labels to the pods | `""` | +| `localpv.nodeSelector` | Nodeselector for LocalPV Provisioner pods | `""` | +| `localpv.tolerations` | LocalPV Provisioner pod toleration values | `""` | +| `localpv.securityContext` | Seurity context for container | `""` | +| `localpv.healthCheck.initialDelaySeconds` | Delay before liveness probe is initiated | `30` | +| `localpv.healthCheck.periodSeconds` | How often to perform the liveness probe | `60` | +| `localpv.replicas` | No. of LocalPV Provisioner replica | `1` | +| `localpv.enableLeaderElection` | Enable leader election | `true` | +| `localpv.affinity` | LocalPV Provisioner pod affinity | `{}` | +| `localpv.waitForBDBindTimeoutRetryCount` | This sets the number of times the provisioner should try with a polling interval of 5 seconds, to get the Blockdevice Name from a BlockDeviceClaim, before the BlockDeviceClaim is deleted. | "12" | +| `openebsNDM.enabled` | Install openebs NDM dependency | `true` | +| `rbac.create` | Enable RBAC Resources | `true` | +| `rbac.pspEnabled` | Create pod security policy resources | `false` | + + +A YAML file that specifies the values for the parameters can be provided while installing the chart. For example, + +```bash +helm install -f values.yaml --namespace openebs openebs-localpv/localpv-provisioner +``` + +> **Tip**: You can use the default [values.yaml](values.yaml) diff --git a/helm/openebs/charts/mayastor/charts/localpv-provisioner/charts/openebs-ndm/Chart.yaml b/helm/openebs/charts/mayastor/charts/localpv-provisioner/charts/openebs-ndm/Chart.yaml new file mode 100644 index 0000000..53484cd --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/localpv-provisioner/charts/openebs-ndm/Chart.yaml @@ -0,0 +1,23 @@ +apiVersion: v2 +appVersion: 2.1.0 +description: Helm chart for OpenEBS Node Disk Manager - a Kubernetes native storage + device management solution. For instructions on how to install, refer to https://openebs.github.io/node-disk-manager/. +home: http://www.openebs.io/ +icon: https://raw.githubusercontent.com/cncf/artwork/master/projects/openebs/icon/color/openebs-icon-color.png +keywords: +- cloud-native-storage +- block-storage +- ndm +- disk-inventory +- storage +maintainers: +- email: akhil.mohan@mayadata.io + name: akhilerm +- email: michaelfornaro@gmail.com + name: xUnholy +- email: prateek.pandey@mayadata.io + name: prateekpandey14 +name: openebs-ndm +sources: +- https://github.com/openebs/node-disk-manager +version: 2.1.0 diff --git a/helm/openebs/charts/mayastor/charts/localpv-provisioner/charts/openebs-ndm/README.md b/helm/openebs/charts/mayastor/charts/localpv-provisioner/charts/openebs-ndm/README.md new file mode 100644 index 0000000..399a687 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/localpv-provisioner/charts/openebs-ndm/README.md @@ -0,0 +1,93 @@ +## Introduction + +This chart bootstraps OpenEBS NDM deployment on a [Kubernetes](http://kubernetes.io) cluster using the +[Helm](https://helm.sh) package manager. + +## Installation + +You can run OpenEBS NDM on any Kubernetes 1.17+ cluster in a matter of seconds. + +Please visit the [link](https://openebs.github.io/node-disk-manager/) for install instructions via helm3. + +## Configuration + +The following table lists the configurable parameters of the OpenEBS NDM chart and their default values. + +| Parameter | Description | Default | +|-------------------------------------------------------------|-------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------| +| `imagePullSecrets` | Provides image pull secrect | `""` | +| `ndm.enabled` | Enable Node Disk Manager | `true` | +| `ndm.image.registry` | Registry for Node Disk Manager image | `""` | +| `ndm.image.repository` | Image repository for Node Disk Manager | `openebs/node-disk-manager` | +| `ndm.image.pullPolicy` | Image pull policy for Node Disk Manager | `IfNotPresent` | +| `ndm.image.tag` | Image tag for Node Disk Manager | `2.1.0` | +| `ndm.sparse.path` | Directory where Sparse files are created | `/var/openebs/sparse` | +| `ndm.sparse.size` | Size of the sparse file in bytes | `10737418240` | +| `ndm.sparse.count` | Number of sparse files to be created | `0` | +| `ndm.updateStrategy.type` | Update strategy for NDM daemonset | `RollingUpdate` | +| `ndm.annotations` | Annotations for NDM daemonset metadata | `""` | +| `ndm.podAnnotations` | Annotations for NDM daemonset's pods metadata | `""` | +| `ndm.resources` | Resource and request and limit for containers | `""` | +| `ndm.podLabels` | Appends labels to the pods | `""` | +| `ndm.nodeSelector` | Nodeselector for daemonset pods | `""` | +| `ndm.tolerations` | NDM daemonset's pod toleration values | `""` | +| `ndm.securityContext` | Seurity context for container | `""` | +| `ndm.filters.enableOsDiskExcludeFilter` | Enable filters of OS disk exclude | `true` | +| `ndm.filters.osDiskExcludePaths` | Paths/Mountpoints to be excluded by OS Disk Filter | `/,/etc/hosts,/boot` | +| `ndm.filters.enableVendorFilter` | Enable filters of vendors | `true` | +| `ndm.filters.excludeVendors` | Exclude devices with specified vendor | `CLOUDBYT,OpenEBS` | +| `ndm.filters.enablePathFilter` | Enable filters of paths | `true` | +| `ndm.filters.includePaths` | Include devices with specified path patterns | `""` | +| `ndm.filters.excludePaths` | Exclude devices with specified path patterns | `loop,fd0,sr0,/dev/ram,/dev/dm-,/dev/md,/dev/rbd,/dev/zd` | +| `ndm.probes.enableSeachest` | Enable Seachest probe for NDM | `false` | +| `ndm.probes.enableUdevProbe` | Enable Udev probe for NDM | `true` | +| `ndm.probes.enableSmartProbe` | Enable Smart probe for NDM | `true` | +| `ndm.metaConfig.nodeLabelPattern` | Config for adding node labels as BD labels | `kubernetes.io*,beta.kubernetes.io*` | +| `ndm.metaConfig.deviceLabelTypes` | Config for adding device attributes as BD labels | `.spec.details.vendor,.spec.details.model,.spec.details.driveType,.spec.filesystem.fsType` | +| `ndmOperator.enabled` | Enable NDM Operator | `true` | +| `ndmOperator.replica` | Pod replica count for NDM operator | `1` | +| `ndmOperator.upgradeStrategy` | Update strategy NDM operator | `"Recreate"` | +| `ndmOperator.image.registry` | Registry for NDM operator image | `""` | +| `ndmOperator.image.repository` | Image repository for NDM operator | `openebs/node-disk-operator` | +| `ndmOperator.image.pullPolicy` | Image pull policy for NDM operator | `IfNotPresent` | +| `ndmOperator.image.tag` | Image tag for NDM operator | `2.1.0` | +| `ndmOperator.annotations` | Annotations for NDM operator metadata | `""` | +| `ndmOperator.podAnnotations` | Annotations for NDM operator's pods metadata | `""` | +| `ndmOperator.resources` | Resource and request and limit for containers | `""` | +| `ndmOperator.podLabels` | Appends labels to the pods | `""` | +| `ndmOperator.nodeSelector` | Nodeselector for operator pods | `""` | +| `ndmOperator.tolerations` | NDM operator's pod toleration values | `""` | +| `ndmOperator.securityContext` | Security context for container | `""` | +| `ndmExporter.enabled` | Enable NDM Exporters | `false` | +| `ndmExporter.image.registry` | Registry for NDM Exporters image | `""` | +| `ndmExporter.repository` | Image repository for NDM Exporters | `openebs/node-disk-exporter` | +| `ndmExporter.pullPolicy` | Image pull policy for NDM Exporters | `IfNotPresent` | +| `ndmExporter.tag` | Image tag for NDM Exporters | `2.1.0` | +| `ndmExporter.nodeExporter.metricsPort` | The TCP port number used for exposing NDM node exporter metrics | `9101` | +| `ndmExporter.nodeExporter.nodeExporter.nodeSelector` | Node selector for NDM node exporter pods | `9101` | +| `ndmExporter.nodeExporter.nodeExporter.tolerations` | NDM node exporter toleration values | `9101` | +| `ndmExporter.clusterExporter.metricsPort` | The TCP port number used for exposing NDM cluster exporter metrics | `9100` | +| `ndmExporter.clusterExporter.clusterExpoerter.nodeSelector` | Node selector for NDM cluster exporter pod | `9100` | +| `ndmExporter.clusterExporter.clusterExpoerter.tolerations` | NDM cluster exporter toleraion values | `9100` | +| `featureGates.APIService.enabled` | Enable the gRPC API service of NDM | `false` | +| `featureGates.UseOSDisk.enabled` | Enable feature-gate to use free space on OS disk | `false` | +| `featureGates.ChangeDetection.enabled` | Enable feature-gate to detect mountpoint/filesystem/size changes | `false` | +| `featureGates.PartitionTableUUID.enabled` | Enable feature-gate to use partition table UUID instead of creating partition | `true` | +| `helperPod.image.registry` | Registry for helper image | `""` | +| `helperPod.image.repository` | Image for helper pod | `openebs/linux-utils` | +| `helperPod.image.pullPolicy` | Pull policy for helper pod | `IfNotPresent` | +| `helperPod.image.tag` | Image tag for helper image | `3.4.0` | +| `varDirectoryPath.baseDir` | Directory to store debug info and so forth | `/var/openebs` | +| `serviceAccount.create` | Create a service account or not | `true` | +| `serviceAccount.name` | Name for the service account | `true` | + + +Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. + +Alternatively, a YAML file that specifies the values for the parameters can be provided while installing the chart. For example, + +```bash +helm install -f values.yaml ndm/openebs-ndm +``` + +> **Tip**: You can use the default [values.yaml](values.yaml) diff --git a/helm/openebs/charts/mayastor/charts/localpv-provisioner/charts/openebs-ndm/crds/blockdevice.yaml b/helm/openebs/charts/mayastor/charts/localpv-provisioner/charts/openebs-ndm/crds/blockdevice.yaml new file mode 100644 index 0000000..95f4070 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/localpv-provisioner/charts/openebs-ndm/crds/blockdevice.yaml @@ -0,0 +1,241 @@ + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.5.0 + creationTimestamp: null + name: blockdevices.openebs.io +spec: + group: openebs.io + names: + kind: BlockDevice + listKind: BlockDeviceList + plural: blockdevices + shortNames: + - bd + singular: blockdevice + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.nodeAttributes.nodeName + name: NodeName + type: string + - jsonPath: .spec.path + name: Path + priority: 1 + type: string + - jsonPath: .spec.filesystem.fsType + name: FSType + priority: 1 + type: string + - jsonPath: .spec.capacity.storage + name: Size + type: string + - jsonPath: .status.claimState + name: ClaimState + type: string + - jsonPath: .status.state + name: Status + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: BlockDevice is the Schema for the blockdevices 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: DeviceSpec defines the properties and runtime status of a BlockDevice + properties: + aggregateDevice: + description: AggregateDevice was intended to store the hierarchical information in cases of LVM. However this is currently not implemented and may need to be re-looked into for better design. To be deprecated + type: string + capacity: + description: Capacity + properties: + logicalSectorSize: + description: LogicalSectorSize is blockdevice logical-sector size in bytes + format: int32 + type: integer + physicalSectorSize: + description: PhysicalSectorSize is blockdevice physical-Sector size in bytes + format: int32 + type: integer + storage: + description: Storage is the blockdevice capacity in bytes + format: int64 + type: integer + required: + - storage + type: object + claimRef: + description: ClaimRef is the reference to the BDC which has claimed this BD + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: 'If referring to a piece of an object instead of an entire object, this string should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. For example, if the object reference is to a container within a pod, this would take on a value like: "spec.containers{name}" (where "name" refers to the name of the container that triggered the event) or if no container name is specified "spec.containers[2]" (container with index 2 in this pod). This syntax is chosen only to have some well-defined way of referencing a part of an object. TODO: this design is not final and this field is subject to change in the future.' + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: 'Specific resourceVersion to which this reference is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + details: + description: Details contain static attributes of BD like model,serial, and so forth + properties: + compliance: + description: Compliance is standards/specifications version implemented by device firmware such as SPC-1, SPC-2, etc + type: string + deviceType: + description: DeviceType represents the type of device like sparse, disk, partition, lvm, crypt + enum: + - disk + - partition + - sparse + - loop + - lvm + - crypt + - dm + - mpath + type: string + driveType: + description: DriveType is the type of backing drive, HDD/SSD + enum: + - HDD + - SSD + - Unknown + - "" + type: string + firmwareRevision: + description: FirmwareRevision is the disk firmware revision + type: string + hardwareSectorSize: + description: HardwareSectorSize is the hardware sector size in bytes + format: int32 + type: integer + logicalBlockSize: + description: LogicalBlockSize is the logical block size in bytes reported by /sys/class/block/sda/queue/logical_block_size + format: int32 + type: integer + model: + description: Model is model of disk + type: string + physicalBlockSize: + description: PhysicalBlockSize is the physical block size in bytes reported by /sys/class/block/sda/queue/physical_block_size + format: int32 + type: integer + serial: + description: Serial is serial number of disk + type: string + vendor: + description: Vendor is vendor of disk + type: string + type: object + devlinks: + description: DevLinks contains soft links of a block device like /dev/by-id/... /dev/by-uuid/... + items: + description: DeviceDevLink holds the mapping between type and links like by-id type or by-path type link + properties: + kind: + description: Kind is the type of link like by-id or by-path. + enum: + - by-id + - by-path + type: string + links: + description: Links are the soft links + items: + type: string + type: array + type: object + type: array + filesystem: + description: FileSystem contains mountpoint and filesystem type + properties: + fsType: + description: Type represents the FileSystem type of the block device + type: string + mountPoint: + description: MountPoint represents the mountpoint of the block device. + type: string + type: object + nodeAttributes: + description: NodeAttributes has the details of the node on which BD is attached + properties: + nodeName: + description: NodeName is the name of the Kubernetes node resource on which the device is attached + type: string + type: object + parentDevice: + description: "ParentDevice was intended to store the UUID of the parent Block Device as is the case for partitioned block devices. \n For example: /dev/sda is the parent for /dev/sda1 To be deprecated" + type: string + partitioned: + description: Partitioned represents if BlockDevice has partitions or not (Yes/No) Currently always default to No. To be deprecated + enum: + - "Yes" + - "No" + type: string + path: + description: Path contain devpath (e.g. /dev/sdb) + type: string + required: + - capacity + - devlinks + - nodeAttributes + - path + type: object + status: + description: DeviceStatus defines the observed state of BlockDevice + properties: + claimState: + description: ClaimState represents the claim state of the block device + enum: + - Claimed + - Unclaimed + - Released + type: string + state: + description: State is the current state of the blockdevice (Active/Inactive/Unknown) + enum: + - Active + - Inactive + - Unknown + type: string + required: + - claimState + - state + type: object + type: object + served: true + storage: true + subresources: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/helm/openebs/charts/mayastor/charts/localpv-provisioner/charts/openebs-ndm/crds/blockdeviceclaim.yaml b/helm/openebs/charts/mayastor/charts/localpv-provisioner/charts/openebs-ndm/crds/blockdeviceclaim.yaml new file mode 100644 index 0000000..81b9a35 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/localpv-provisioner/charts/openebs-ndm/crds/blockdeviceclaim.yaml @@ -0,0 +1,144 @@ + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.5.0 + creationTimestamp: null + name: blockdeviceclaims.openebs.io +spec: + group: openebs.io + names: + kind: BlockDeviceClaim + listKind: BlockDeviceClaimList + plural: blockdeviceclaims + shortNames: + - bdc + singular: blockdeviceclaim + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.blockDeviceName + name: BlockDeviceName + type: string + - jsonPath: .status.phase + name: Phase + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: BlockDeviceClaim is the Schema for the blockdeviceclaims 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: DeviceClaimSpec defines the request details for a BlockDevice + properties: + blockDeviceName: + description: BlockDeviceName is the reference to the block-device backing this claim + type: string + blockDeviceNodeAttributes: + description: BlockDeviceNodeAttributes is the attributes on the node from which a BD should be selected for this claim. It can include nodename, failure domain etc. + properties: + hostName: + description: HostName represents the hostname of the Kubernetes node resource where the BD should be present + type: string + nodeName: + description: NodeName represents the name of the Kubernetes node resource where the BD should be present + type: string + type: object + deviceClaimDetails: + description: Details of the device to be claimed + properties: + allowPartition: + description: AllowPartition represents whether to claim a full block device or a device that is a partition + type: boolean + blockVolumeMode: + description: 'BlockVolumeMode represents whether to claim a device in Block mode or Filesystem mode. These are use cases of BlockVolumeMode: 1) Not specified: VolumeMode check will not be effective 2) VolumeModeBlock: BD should not have any filesystem or mountpoint 3) VolumeModeFileSystem: BD should have a filesystem and mountpoint. If DeviceFormat is specified then the format should match with the FSType in BD' + type: string + formatType: + description: Format of the device required, eg:ext4, xfs + type: string + type: object + deviceType: + description: DeviceType represents the type of drive like SSD, HDD etc., + nullable: true + type: string + hostName: + description: Node name from where blockdevice has to be claimed. To be deprecated. Use NodeAttributes.HostName instead + type: string + resources: + description: Resources will help with placing claims on Capacity, IOPS + properties: + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum resources required. eg: if storage resource of 10G is requested minimum capacity of 10G should be available TODO for validating' + type: object + required: + - requests + type: object + selector: + description: Selector is used to find block devices to be considered for claiming + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + type: object + status: + description: DeviceClaimStatus defines the observed state of BlockDeviceClaim + properties: + phase: + description: Phase represents the current phase of the claim + type: string + required: + - phase + type: object + type: object + served: true + storage: true + subresources: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/helm/openebs/charts/mayastor/charts/localpv-provisioner/charts/openebs-ndm/templates/NOTES.txt b/helm/openebs/charts/mayastor/charts/localpv-provisioner/charts/openebs-ndm/templates/NOTES.txt new file mode 100644 index 0000000..3c84551 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/localpv-provisioner/charts/openebs-ndm/templates/NOTES.txt @@ -0,0 +1,8 @@ +The OpenEBS Node Disk Manager has been installed. Check its status by running: +$ kubectl get pods -n {{ .Release.Namespace }} + +Use `kubectl get bd -n {{ .Release.Namespace }} ` to see the list of +blockdevices attached to the Kubernetes cluster nodes. + +For more information, visit our Slack at https://openebs.io/community or view +the documentation online at http://docs.openebs.io/. diff --git a/helm/openebs/charts/mayastor/charts/localpv-provisioner/charts/openebs-ndm/templates/_helpers.tpl b/helm/openebs/charts/mayastor/charts/localpv-provisioner/charts/openebs-ndm/templates/_helpers.tpl new file mode 100644 index 0000000..c975510 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/localpv-provisioner/charts/openebs-ndm/templates/_helpers.tpl @@ -0,0 +1,242 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +This name is used for ndm daemonset +*/}} +{{- define "openebs-ndm.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "openebs-ndm.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified ndm daemonset 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 "openebs-ndm.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains .Release.Name $name }} +{{- $name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{- define "openebs-ndm.operator.name" -}} +{{- $ndmName := default .Chart.Name .Values.ndmOperator.nameOverride | trunc 63 | trimSuffix "-" }} +{{- $componentName := .Values.ndmOperator.name | trunc 63 | trimSuffix "-" }} +{{- printf "%s-%s" $ndmName $componentName | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified ndm operator 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 "openebs-ndm.operator.fullname" -}} +{{- if .Values.ndmOperator.fullnameOverride }} +{{- .Values.ndmOperator.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $ndmOperatorName := include "openebs-ndm.operator.name" .}} + +{{- $name := default $ndmOperatorName .Values.ndmOperator.nameOverride }} +{{- if contains .Release.Name $name }} +{{- $name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{- define "openebs-ndm.cluster-exporter.name" -}} +{{- $ndmName := default .Chart.Name .Values.ndmExporter.clusterExporter.nameOverride | trunc 63 | trimSuffix "-" }} +{{- $componentName := .Values.ndmExporter.clusterExporter.name | trunc 63 | trimSuffix "-" }} +{{- printf "%s-%s" $ndmName $componentName | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified ndm cluster exporter 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 "openebs-ndm.cluster-exporter.fullname" -}} +{{- if .Values.ndmExporter.clusterExporter.fullnameOverride }} +{{- .Values.ndmExporter.clusterExporter.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $ndmClusterExporterName := include "openebs-ndm.cluster-exporter.name" .}} + +{{- $name := default $ndmClusterExporterName .Values.ndmExporter.clusterExporter.nameOverride }} +{{- if contains .Release.Name $name }} +{{- $name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{- define "openebs-ndm.exporter.name" -}} +{{- $ndmName := .Chart.Name | trunc 63 | trimSuffix "-" }} +{{- $componentName := "exporter" | trunc 63 | trimSuffix "-" }} +{{- printf "%s-%s" $ndmName $componentName | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{- define "openebs-ndm.node-exporter.name" -}} +{{- $ndmName := default .Chart.Name .Values.ndmExporter.nodeExporter.nameOverride | trunc 63 | trimSuffix "-" }} +{{- $componentName := .Values.ndmExporter.nodeExporter.name | trunc 63 | trimSuffix "-" }} +{{- printf "%s-%s" $ndmName $componentName | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified ndm node exporter 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 "openebs-ndm.node-exporter.fullname" -}} +{{- if .Values.ndmExporter.nodeExporter.fullnameOverride }} +{{- .Values.ndmExporter.nodeExporter.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $ndmNodeExporterName := include "openebs-ndm.node-exporter.name" .}} + +{{- $name := default $ndmNodeExporterName .Values.ndmExporter.nodeExporter.nameOverride }} +{{- if contains .Release.Name $name }} +{{- $name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "openebs-ndm.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "openebs-ndm.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} + +{{/* +Define meta labels for ndm components +*/}} +{{- define "openebs-ndm.common.metaLabels" -}} +chart: {{ template "openebs-ndm.chart" . }} +heritage: {{ .Release.Service }} +openebs.io/version: {{ .Values.release.version | quote }} +{{- end -}} + + +{{/* +Create match labels for ndm daemonset component +*/}} +{{- define "openebs-ndm.matchLabels" -}} +app: {{ template "openebs-ndm.name" . }} +release: {{ .Release.Name }} +component: {{ .Values.ndm.componentName | quote }} +{{- end -}} + +{{/* +Create component labels for ndm daemonset component +*/}} +{{- define "openebs-ndm.componentLabels" -}} +openebs.io/component-name: {{ .Values.ndm.componentName | quote }} +{{- end -}} + + +{{/* +Create labels for ndm daemonset component +*/}} +{{- define "openebs-ndm.labels" -}} +{{ include "openebs-ndm.common.metaLabels" . }} +{{ include "openebs-ndm.matchLabels" . }} +{{ include "openebs-ndm.componentLabels" . }} +{{- end -}} + +{{/* +Create match labels for ndm operator deployment +*/}} +{{- define "openebs-ndm.operator.matchLabels" -}} +app: {{ template "openebs-ndm.operator.name" . }} +release: {{ .Release.Name }} +component: {{ default (include "openebs-ndm.operator.name" .) .Values.ndmOperator.componentName }} +{{- end -}} + +{{/* +Create component labels for ndm operator component +*/}} +{{- define "openebs-ndm.operator.componentLabels" -}} +openebs.io/component-name: {{ default (include "openebs-ndm.operator.name" .) .Values.ndmOperator.componentName }} +{{- end -}} + + +{{/* +Create labels for ndm operator component +*/}} +{{- define "openebs-ndm.operator.labels" -}} +{{ include "openebs-ndm.common.metaLabels" . }} +{{ include "openebs-ndm.operator.matchLabels" . }} +{{ include "openebs-ndm.operator.componentLabels" . }} +{{- end -}} + +{{/* +Create match labels for ndm cluster exporter deployment +*/}} +{{- define "openebs-ndm.cluster-exporter.matchLabels" -}} +app: {{ template "openebs-ndm.exporter.name" . }} +release: {{ .Release.Name }} +component: {{ default (include "openebs-ndm.cluster-exporter.name" .) .Values.ndmExporter.clusterExporter.componentName }} +{{- end -}} + +{{/* +Create component labels for ndm cluster exporter component +*/}} +{{- define "openebs-ndm.cluster-exporter.componentLabels" -}} +openebs.io/component-name: {{ default (include "openebs-ndm.cluster-exporter.name" .) .Values.ndmExporter.clusterExporter.componentName }} +{{- end -}} + + +{{/* +Create labels for ndm cluster exporter component +*/}} +{{- define "openebs-ndm.cluster-exporter.labels" -}} +{{ include "openebs-ndm.common.metaLabels" . }} +{{ include "openebs-ndm.cluster-exporter.matchLabels" . }} +{{ include "openebs-ndm.cluster-exporter.componentLabels" . }} +{{- end -}} + +{{/* +Create match labels for ndm node exporter deployment +*/}} +{{- define "openebs-ndm.node-exporter.matchLabels" -}} +app: {{ template "openebs-ndm.exporter.name" . }} +release: {{ .Release.Name }} +component: {{ default (include "openebs-ndm.node-exporter.name" .) .Values.ndmExporter.nodeExporter.componentName }} +{{- end -}} + +{{/* +Create component labels for ndm node exporter component +*/}} +{{- define "openebs-ndm.node-exporter.componentLabels" -}} +openebs.io/component-name: {{ default (include "openebs-ndm.node-exporter.name" .) .Values.ndmExporter.nodeExporter.componentName }} +{{- end -}} + + +{{/* +Create labels for ndm cluster node component +*/}} +{{- define "openebs-ndm.node-exporter.labels" -}} +{{ include "openebs-ndm.common.metaLabels" . }} +{{ include "openebs-ndm.node-exporter.matchLabels" . }} +{{ include "openebs-ndm.node-exporter.componentLabels" . }} +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/localpv-provisioner/charts/openebs-ndm/templates/cluster-exporter-service.yaml b/helm/openebs/charts/mayastor/charts/localpv-provisioner/charts/openebs-ndm/templates/cluster-exporter-service.yaml new file mode 100644 index 0000000..719f6b4 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/localpv-provisioner/charts/openebs-ndm/templates/cluster-exporter-service.yaml @@ -0,0 +1,18 @@ +{{- if and .Values.ndmExporter.enabled .Values.ndmExporter.clusterExporter.metricsPort }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "openebs-ndm.cluster-exporter.fullname" . }}-service + labels: + {{- include "openebs-ndm.cluster-exporter.labels" . | nindent 4 }} +spec: + clusterIP: None + ports: + - name: metrics + port: {{ .Values.ndmExporter.clusterExporter.metricsPort }} + targetPort: {{ .Values.ndmExporter.clusterExporter.metricsPort }} + selector: + {{- with .Values.ndmExporter.clusterExporter.podLabels }} + {{ toYaml . }} + {{- end }} + {{- end }} diff --git a/helm/openebs/charts/mayastor/charts/localpv-provisioner/charts/openebs-ndm/templates/cluster-exporter.yaml b/helm/openebs/charts/mayastor/charts/localpv-provisioner/charts/openebs-ndm/templates/cluster-exporter.yaml new file mode 100644 index 0000000..af8b1e6 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/localpv-provisioner/charts/openebs-ndm/templates/cluster-exporter.yaml @@ -0,0 +1,60 @@ +{{- if .Values.ndmExporter.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "openebs-ndm.cluster-exporter.fullname" . }} + labels: + {{- include "openebs-ndm.cluster-exporter.labels" . | nindent 4 }} +spec: + replicas: 1 + strategy: + type: Recreate + selector: + matchLabels: + {{- include "openebs-ndm.cluster-exporter.matchLabels" . | nindent 6 }} + template: + metadata: + labels: + {{- include "openebs-ndm.cluster-exporter.labels" . | nindent 8 }} + {{- with .Values.ndmExporter.clusterExporter.podLabels }} + {{ toYaml . }} + {{- end }} + spec: + serviceAccountName: {{ template "openebs-ndm.serviceAccountName" . }} + containers: + - name: {{ template "openebs-ndm.cluster-exporter.fullname" . }} + image: "{{ .Values.ndmExporter.image.registry }}{{ .Values.ndmExporter.image.repository }}:{{ .Values.ndmExporter.image.tag }}" + command: + - /usr/local/bin/exporter + args: + - "start" + - "--mode=cluster" + - "--port=$(METRICS_LISTEN_PORT)" + - "--metrics=/metrics" + ports: + - containerPort: {{ .Values.ndmExporter.clusterExporter.metricsPort }} + protocol: TCP + name: metrics + imagePullPolicy: {{ .Values.ndmExporter.image.pullPolicy }} + env: + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + {{- if .Values.ndmExporter.clusterExporter.metricsPort }} + - name: METRICS_LISTEN_PORT + value: :{{ .Values.ndmExporter.clusterExporter.metricsPort }} + {{- end }} +{{- if .Values.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | indent 8 }} +{{- end }} +{{- if .Values.ndmExporter.clusterExporter.nodeSelector }} + nodeSelector: +{{ toYaml .Values.ndmExporter.clusterExporter.nodeSelector | indent 8 }} +{{- end }} +{{- if .Values.ndmExporter.clusterExporter.tolerations }} + tolerations: +{{ toYaml .Values.ndmExporter.clusterExporter.tolerations | indent 8 }} +{{- end }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/localpv-provisioner/charts/openebs-ndm/templates/configmap.yaml b/helm/openebs/charts/mayastor/charts/localpv-provisioner/charts/openebs-ndm/templates/configmap.yaml new file mode 100644 index 0000000..99b814d --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/localpv-provisioner/charts/openebs-ndm/templates/configmap.yaml @@ -0,0 +1,45 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "openebs-ndm.fullname" . }}-config +data: + # node-disk-manager-config contains config of available probes and filters. + # Probes and Filters will initialize with default values if config for that + # filter or probe are not present in configmap + + # udev-probe is default or primary probe it should be enabled to run ndm + # filterconfigs contains configs of filters. To provide a group of include + # and exclude values add it as , separated string + node-disk-manager.config: | + probeconfigs: + - key: udev-probe + name: udev probe + state: {{ .Values.ndm.probes.enableUdevProbe }} + - key: seachest-probe + name: seachest probe + state: {{ .Values.ndm.probes.enableSeachest }} + - key: smart-probe + name: smart probe + state: {{ .Values.ndm.probes.enableSmartProbe }} + filterconfigs: + - key: os-disk-exclude-filter + name: os disk exclude filter + state: {{ .Values.ndm.filters.enableOsDiskExcludeFilter }} + exclude: "{{ .Values.ndm.filters.osDiskExcludePaths }}" + - key: vendor-filter + name: vendor filter + state: {{ .Values.ndm.filters.enableVendorFilter }} + include: "" + exclude: "{{ .Values.ndm.filters.excludeVendors }}" + - key: path-filter + name: path filter + state: {{ .Values.ndm.filters.enablePathFilter }} + include: "{{ .Values.ndm.filters.includePaths }}" + exclude: "{{ .Values.ndm.filters.excludePaths }}" + metaconfigs: + - key: node-labels + name: node labels + pattern: "{{ .Values.ndm.metaConfig.nodeLabelPattern }}" + - key: device-labels + name: device labels + type: "{{ .Values.ndm.metaConfig.deviceLabelTypes }}" diff --git a/helm/openebs/charts/mayastor/charts/localpv-provisioner/charts/openebs-ndm/templates/daemonset.yaml b/helm/openebs/charts/mayastor/charts/localpv-provisioner/charts/openebs-ndm/templates/daemonset.yaml new file mode 100644 index 0000000..715db87 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/localpv-provisioner/charts/openebs-ndm/templates/daemonset.yaml @@ -0,0 +1,179 @@ +{{- if .Values.ndm.enabled }} +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: {{ template "openebs-ndm.fullname" . }} + {{- with .Values.ndm.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "openebs-ndm.labels" . | nindent 4 }} +spec: + updateStrategy: +{{ toYaml .Values.ndm.updateStrategy | indent 4 }} + selector: + matchLabels: + {{- include "openebs-ndm.matchLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.ndm.podAnnotations }} + annotations: {{ toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "openebs-ndm.labels" . | nindent 8 }} + {{- with .Values.ndm.podLabels}} + {{ toYaml . }} + {{- end}} + spec: + serviceAccountName: {{ template "openebs-ndm.serviceAccountName" . }} +{{- if .Values.featureGates.enabled }} +{{- if .Values.featureGates.APIService.enabled }} + hostPID: true +{{- end}} +{{- end}} + containers: + - name: {{ template "openebs-ndm.name" . }} + image: "{{ .Values.ndm.image.registry }}{{ .Values.ndm.image.repository }}:{{ .Values.ndm.image.tag }}" + args: + - -v=4 +{{- if .Values.featureGates.enabled }} +{{- if .Values.featureGates.GPTBasedUUID.enabled }} + - --feature-gates={{ .Values.featureGates.GPTBasedUUID.featureGateFlag }} +{{- end}} +{{- if .Values.featureGates.APIService.enabled }} + - --feature-gates={{ .Values.featureGates.APIService.featureGateFlag }} + - --api-service-address={{ .Values.featureGates.APIService.address }} +{{- end}} +{{- if .Values.featureGates.UseOSDisk.enabled }} + - --feature-gates={{ .Values.featureGates.UseOSDisk.featureGateFlag }} +{{- end}} +{{- if .Values.featureGates.ChangeDetection.enabled }} + - --feature-gates={{ .Values.featureGates.ChangeDetection.featureGateFlag }} +{{- end}} +{{- if .Values.featureGates.PartitionTableUUID.enabled }} + - --feature-gates={{ .Values.featureGates.PartitionTableUUID.featureGateFlag }} +{{- end}} +{{- end}} + imagePullPolicy: {{ .Values.ndm.image.pullPolicy }} + resources: +{{ toYaml .Values.ndm.resources | indent 12 }} + securityContext: + privileged: true + env: + # namespace in which NDM is installed will be passed to NDM Daemonset + # as environment variable + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + # pass hostname as env variable using downward API to the NDM container + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName +{{- if .Values.ndm.sparse }} +{{- if .Values.ndm.sparse.path }} + # specify the directory where the sparse files need to be created. + # if not specified, then sparse files will not be created. + - name: SPARSE_FILE_DIR + value: "{{ .Values.ndm.sparse.path }}" +{{- end }} +{{- if .Values.ndm.sparse.size }} + # Size(bytes) of the sparse file to be created. + - name: SPARSE_FILE_SIZE + value: "{{ .Values.ndm.sparse.size }}" +{{- end }} +{{- if .Values.ndm.sparse.count }} + # Specify the number of sparse files to be created + - name: SPARSE_FILE_COUNT + value: "{{ .Values.ndm.sparse.count }}" +{{- end }} +{{- end }} + # Process name used for matching is limited to the 15 characters + # present in the pgrep output. + # So fullname can be used here with pgrep (cmd is < 15 chars). + livenessProbe: + exec: + command: + - pgrep + - "ndm" + initialDelaySeconds: {{ .Values.ndm.healthCheck.initialDelaySeconds }} + periodSeconds: {{ .Values.ndm.healthCheck.periodSeconds }} + volumeMounts: + - name: config + mountPath: /host/node-disk-manager.config + subPath: node-disk-manager.config + readOnly: true + - name: udev + mountPath: /run/udev + - name: procmount + mountPath: /host/proc + readOnly: true + - name: devmount + mountPath: /dev + - name: basepath + mountPath: /var/openebs/ndm +{{- if .Values.ndm.sparse }} +{{- if .Values.ndm.sparse.path }} + - name: sparsepath + mountPath: {{ .Values.ndm.sparse.path }} +{{- end }} +{{- end }} + volumes: + - name: config + configMap: + name: {{ include "openebs-ndm.fullname" . }}-config + - name: udev + hostPath: + path: /run/udev + type: Directory + # mount /proc (to access mount file of process 1 of host) inside container + # to read mount-point of disks and partitions + - name: procmount + hostPath: + path: /proc + type: Directory + - name: devmount + # the /dev directory is mounted so that we have access to the devices that + # are connected at runtime of the pod. + hostPath: + path: /dev + type: Directory + - name: basepath + hostPath: + path: "{{ .Values.varDirectoryPath.baseDir }}/ndm" + type: DirectoryOrCreate +{{- if .Values.ndm.sparse }} +{{- if .Values.ndm.sparse.path }} + - name: sparsepath + hostPath: + path: {{ .Values.ndm.sparse.path }} +{{- end }} +{{- end }} + # By default the node-disk-manager will be run on all kubernetes nodes + # If you would like to limit this to only some nodes, say the nodes + # that have storage attached, you could label those node and use + # nodeSelector. + # + # e.g. label the storage nodes with - "openebs.io/nodegroup"="storage-node" + # kubectl label node "openebs.io/nodegroup"="storage-node" + #nodeSelector: + # "openebs.io/nodegroup": "storage-node" +{{- if .Values.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | indent 8 }} +{{- end }} +{{- if .Values.ndm.nodeSelector }} + nodeSelector: +{{ toYaml .Values.ndm.nodeSelector | indent 8 }} +{{- end }} +{{- if .Values.ndm.tolerations }} + tolerations: +{{ toYaml .Values.ndm.tolerations | indent 8 }} +{{- end }} +{{- if .Values.ndm.securityContext }} + securityContext: +{{ toYaml .Values.ndm.securityContext | indent 8 }} +{{- end }} + hostNetwork: true +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/localpv-provisioner/charts/openebs-ndm/templates/deployment.yaml b/helm/openebs/charts/mayastor/charts/localpv-provisioner/charts/openebs-ndm/templates/deployment.yaml new file mode 100644 index 0000000..213a861 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/localpv-provisioner/charts/openebs-ndm/templates/deployment.yaml @@ -0,0 +1,87 @@ +{{- if .Values.ndmOperator.enabled }} +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "openebs-ndm.operator.fullname" . }} + {{- with .Values.ndmOperator.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "openebs-ndm.operator.labels" . | nindent 4 }} +spec: + replicas: {{ .Values.ndmOperator.replicas }} + strategy: + type: "Recreate" + rollingUpdate: null + selector: + matchLabels: + {{- include "openebs-ndm.operator.matchLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.ndmOperator.podAnnotations }} + annotations: {{ toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "openebs-ndm.operator.labels" . | nindent 8 }} + {{- with .Values.ndmOperator.podLabels}} + {{ toYaml . }} + {{- end}} + spec: + serviceAccountName: {{ template "openebs-ndm.serviceAccountName" . }} + containers: + - name: {{ template "openebs-ndm.operator.fullname" . }} + image: "{{ .Values.ndmOperator.image.registry }}{{ .Values.ndmOperator.image.repository }}:{{ .Values.ndmOperator.image.tag }}" + imagePullPolicy: {{ .Values.ndmOperator.image.pullPolicy }} + resources: +{{ toYaml .Values.ndmOperator.resources | indent 12 }} + livenessProbe: + httpGet: + path: /healthz + port: 8585 + initialDelaySeconds: {{ .Values.ndmOperator.healthCheck.initialDelaySeconds }} + periodSeconds: {{ .Values.ndmOperator.healthCheck.periodSeconds }} + readinessProbe: + httpGet: + path: /readyz + port: 8585 + initialDelaySeconds: {{ .Values.ndmOperator.readinessCheck.initialDelaySeconds }} + periodSeconds: {{ .Values.ndmOperator.readinessCheck.periodSeconds }} + env: + - name: WATCH_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: SERVICE_ACCOUNT + valueFrom: + fieldRef: + fieldPath: spec.serviceAccountName + - name: OPERATOR_NAME + value: "node-disk-operator" + - name: CLEANUP_JOB_IMAGE + value: "{{ .Values.helperPod.image.registry }}{{ .Values.helperPod.image.repository }}:{{ .Values.helperPod.image.tag }}" +{{- if .Values.imagePullSecrets }} + - name: OPENEBS_IO_IMAGE_PULL_SECRETS + value: "{{- range $index, $secret := .Values.imagePullSecrets}}{{if $index}},{{end}}{{ $secret.name }}{{- end}}" +{{- end }} +{{- if .Values.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | indent 8 }} +{{- end }} +{{- if .Values.ndmOperator.nodeSelector }} + nodeSelector: +{{ toYaml .Values.ndmOperator.nodeSelector | indent 8 }} +{{- end }} +{{- if .Values.ndmOperator.securityContext }} + securityContext: +{{ toYaml .Values.ndmOperator.securityContext | indent 8 }} +{{- end }} +{{- if .Values.ndmOperator.tolerations }} + tolerations: +{{ toYaml .Values.ndmOperator.tolerations | indent 8 }} +{{- end }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/localpv-provisioner/charts/openebs-ndm/templates/node-exporter-service.yaml b/helm/openebs/charts/mayastor/charts/localpv-provisioner/charts/openebs-ndm/templates/node-exporter-service.yaml new file mode 100644 index 0000000..026b77d --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/localpv-provisioner/charts/openebs-ndm/templates/node-exporter-service.yaml @@ -0,0 +1,18 @@ +{{- if and .Values.ndmExporter.enabled .Values.ndmExporter.nodeExporter.metricsPort }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "openebs-ndm.node-exporter.fullname" . }}-service + labels: + {{- include "openebs-ndm.node-exporter.labels" . | nindent 4 }} +spec: + clusterIP: None + ports: + - name: metrics + port: {{ .Values.ndmExporter.nodeExporter.metricsPort }} + targetPort: {{ .Values.ndmExporter.nodeExporter.metricsPort }} + selector: + {{- with .Values.ndmExporter.nodeExporter.podLabels }} + {{ toYaml . }} + {{- end }} + {{- end }} diff --git a/helm/openebs/charts/mayastor/charts/localpv-provisioner/charts/openebs-ndm/templates/node-exporter.yaml b/helm/openebs/charts/mayastor/charts/localpv-provisioner/charts/openebs-ndm/templates/node-exporter.yaml new file mode 100644 index 0000000..cd5f635 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/localpv-provisioner/charts/openebs-ndm/templates/node-exporter.yaml @@ -0,0 +1,62 @@ +{{- if .Values.ndmExporter.enabled }} +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: {{ template "openebs-ndm.node-exporter.fullname" . }} + labels: + {{- include "openebs-ndm.node-exporter.labels" . | nindent 4 }} +spec: + updateStrategy: + type: RollingUpdate + selector: + matchLabels: + {{- include "openebs-ndm.node-exporter.matchLabels" . | nindent 6 }} + template: + metadata: + labels: + {{- include "openebs-ndm.node-exporter.labels" . | nindent 8 }} + {{- with .Values.ndmExporter.nodeExporter.podLabels }} + {{ toYaml . }} + {{- end }} + spec: + serviceAccountName: {{ template "openebs-ndm.serviceAccountName" . }} + containers: + - name: {{ template "openebs-ndm.node-exporter.fullname" . }} + image: "{{ .Values.ndmExporter.image.registry }}{{ .Values.ndmExporter.image.repository }}:{{ .Values.ndmExporter.image.tag }}" + command: + - /usr/local/bin/exporter + args: + - "start" + - "--mode=node" + - "--port=$(METRICS_LISTEN_PORT)" + - "--metrics=/metrics" + ports: + - containerPort: {{ .Values.ndmExporter.nodeExporter.metricsPort }} + protocol: TCP + name: metrics + imagePullPolicy: {{ .Values.ndmExporter.image.pullPolicy }} + securityContext: + privileged: true + env: + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + {{- if .Values.ndmExporter.nodeExporter.metricsPort }} + - name: METRICS_LISTEN_PORT + value: :{{ .Values.ndmExporter.nodeExporter.metricsPort }} + {{- end }} +{{- if .Values.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | indent 8 }} +{{- end }} +{{- if .Values.ndmExporter.nodeExporter.nodeSelector }} + nodeSelector: +{{ toYaml .Values.ndmExporter.nodeExporter.nodeSelector | indent 8 }} +{{- end }} +{{- if .Values.ndmExporter.nodeExporter.tolerations }} + tolerations: +{{ toYaml .Values.ndmExporter.nodeExporter.tolerations | indent 8 }} +{{- end }} +{{- end }} + diff --git a/helm/openebs/charts/mayastor/charts/localpv-provisioner/charts/openebs-ndm/templates/rbac.yaml b/helm/openebs/charts/mayastor/charts/localpv-provisioner/charts/openebs-ndm/templates/rbac.yaml new file mode 100644 index 0000000..8e81c49 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/localpv-provisioner/charts/openebs-ndm/templates/rbac.yaml @@ -0,0 +1,44 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "openebs-ndm.serviceAccountName" . }} +{{- end }} +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ include "openebs-ndm.fullname" . }} +rules: + - apiGroups: ["*"] + resources: ["nodes", "pods", "events", "configmaps", "jobs"] + verbs: + - '*' + - apiGroups: ["apiextensions.k8s.io"] + resources: ["customresourcedefinitions"] + verbs: + - '*' + - apiGroups: + - openebs.io + resources: + - blockdevices + - blockdeviceclaims + verbs: + - '*' +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ include "openebs-ndm.fullname" . }} +subjects: + - kind: ServiceAccount + name: {{ include "openebs-ndm.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} + - kind: User + name: system:serviceaccount:default:default + apiGroup: rbac.authorization.k8s.io +roleRef: + kind: ClusterRole + name: {{ include "openebs-ndm.fullname" . }} + apiGroup: rbac.authorization.k8s.io +--- diff --git a/helm/openebs/charts/mayastor/charts/localpv-provisioner/charts/openebs-ndm/values.yaml b/helm/openebs/charts/mayastor/charts/localpv-provisioner/charts/openebs-ndm/values.yaml new file mode 100644 index 0000000..2548606 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/localpv-provisioner/charts/openebs-ndm/values.yaml @@ -0,0 +1,156 @@ +# Default values for ndm. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. +release: + version: "2.1.0" + +imagePullSecrets: +# - name: "image-pull-secret" + +ndm: + componentName: ndm + enabled: true + image: + # Make sure that registry name end with a '/'. + # For example : quay.io/ is a correct value here and quay.io is incorrect + registry: + repository: openebs/node-disk-manager + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: 2.1.0 + sparse: + path: "/var/openebs/sparse" + size: "10737418240" + count: "0" + updateStrategy: + type: RollingUpdate + annotations: {} + podAnnotations: {} + resources: {} + # limits: + # cpu: 10m + # memory: 32Mi + # requests: + # cpu: 10m + # memory: 32Mi + ## Labels to be added to ndm daemonset pods + podLabels: + name: openebs-ndm + nodeSelector: {} + tolerations: [] + securityContext: {} + filters: + enableOsDiskExcludeFilter: true + osDiskExcludePaths: "/,/etc/hosts,/boot" + enableVendorFilter: true + excludeVendors: "CLOUDBYT,OpenEBS" + enablePathFilter: true + includePaths: "" + excludePaths: "loop,fd0,sr0,/dev/ram,/dev/dm-,/dev/md,/dev/rbd,/dev/zd" + probes: + enableSeachest: false + enableUdevProbe: true + enableSmartProbe: true + metaConfig: + nodeLabelPattern: "" + deviceLabelTypes: "" + healthCheck: + initialDelaySeconds: 30 + periodSeconds: 60 + +ndmOperator: + name: operator + enabled: true + image: + registry: + repository: openebs/node-disk-operator + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: 2.1.0 + podLabels: + name: openebs-ndm-operator + annotations: {} + podAnnotations: {} + nodeSelector: {} + resources: {} + securityContext: {} + tolerations: [] + healthCheck: + initialDelaySeconds: 15 + periodSeconds: 20 + readinessCheck: + initialDelaySeconds: 5 + periodSeconds: 10 + replicas: 1 + upgradeStrategy: Recreate + +ndmExporter: + enabled: false + image: + registry: + repository: openebs/node-disk-exporter + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: 2.1.0 + nodeExporter: + name: node-exporter + podLabels: + name: openebs-ndm-node-exporter + # The TCP port number used for exposing ndm-node-exporter metrics. + # If not set, service will not be created to expose metrics endpoint to serviceMonitor + # and listen-port flag will not be set and container port will be empty. + metricsPort: 9101 + nodeSelector: {} + tolerations: [] + clusterExporter: + name: cluster-exporter + podLabels: + name: openebs-ndm-cluster-exporter + # The TCP port number used for exposing ndm-cluster-exporter metrics. + # If not set, service will not be created to expose metrics endpoint to serviceMonitor + # and listen-port flag will not be set and container port will be empty. + metricsPort: 9100 + nodeSelector: {} + tolerations: [] + +helperPod: + image: + registry: "" + repository: openebs/linux-utils + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: 3.4.0 + +crd: + enableInstall: false + +featureGates: + enabled: true + GPTBasedUUID: + enabled: true + featureGateFlag: "GPTBasedUUID" + APIService: + enabled: false + featureGateFlag: "APIService" + address: "0.0.0.0:9115" + UseOSDisk: + enabled: false + featureGateFlag: "UseOSDisk" + ChangeDetection: + enabled: false + featureGateFlag: "ChangeDetection" + PartitionTableUUID: + enabled: false + featureGateFlag: "PartitionTableUUID" + +# Directory used by the OpenEBS to store debug information and so forth +# that are generated in the course of running OpenEBS containers. +varDirectoryPath: + baseDir: "/var/openebs" + +serviceAccount: + # Specifies whether a service account should be created + create: true + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: openebs-ndm diff --git a/helm/openebs/charts/mayastor/charts/localpv-provisioner/templates/NOTES.txt b/helm/openebs/charts/mayastor/charts/localpv-provisioner/templates/NOTES.txt new file mode 100644 index 0000000..a82ff98 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/localpv-provisioner/templates/NOTES.txt @@ -0,0 +1,12 @@ +The OpenEBS Dynamic LocalPV Provisioner has been installed. +Check its status by running: +$ kubectl get pods -n {{ .Release.Namespace }} + +Use `kubectl get bd -n {{ .Release.Namespace }}` to list the +blockdevices attached to the Kubernetes cluster nodes. + +Get started with the Dynamic LocalPV Provisioner Quickstart guide at: +https://github.com/openebs/dynamic-localpv-provisioner/blob/develop/docs/quickstart.md + +For more information, visit our Slack at https://openebs.io/community or view +the OpenEBS documentation online at https://openebs.io/docs diff --git a/helm/openebs/charts/mayastor/charts/localpv-provisioner/templates/_helpers.tpl b/helm/openebs/charts/mayastor/charts/localpv-provisioner/templates/_helpers.tpl new file mode 100644 index 0000000..ea1ce31 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/localpv-provisioner/templates/_helpers.tpl @@ -0,0 +1,79 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "localpv.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create a default fully qualified localpv provisioner 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 "localpv.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 "localpv.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + + +{{/* +Meta labels +*/}} +{{- define "localpv.common.metaLabels" -}} +chart: {{ template "localpv.chart" . }} +heritage: {{ .Release.Service }} +openebs.io/version: {{ .Values.release.version | quote }} +{{- end -}} + +{{/* +Selector labels +*/}} +{{- define "localpv.selectorLabels" -}} +app: {{ template "localpv.name" . }} +release: {{ .Release.Name }} +component: {{ .Values.localpv.name | quote }} +{{- end -}} + +{{/* +Component labels +*/}} +{{- define "localpv.componentLabels" -}} +openebs.io/component-name: openebs-{{ .Values.localpv.name }} +{{- end -}} + +{{/* +Common labels +*/}} +{{- define "localpv.labels" -}} +{{ include "localpv.common.metaLabels" . }} +{{ include "localpv.selectorLabels" . }} +{{ include "localpv.componentLabels" . }} +{{- end -}} + + +{{/* +Create the name of the service account to use +*/}} +{{- define "localpv.serviceAccountName" -}} +{{- if .Values.serviceAccount.create -}} + {{ default (include "localpv.fullname" .) .Values.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.serviceAccount.name }} +{{- end -}} +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/localpv-provisioner/templates/deployment.yaml b/helm/openebs/charts/mayastor/charts/localpv-provisioner/templates/deployment.yaml new file mode 100644 index 0000000..63936f4 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/localpv-provisioner/templates/deployment.yaml @@ -0,0 +1,120 @@ +{{- if .Values.localpv.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "localpv.fullname" . }} + {{- with .Values.localpv.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "localpv.labels" . | nindent 4 }} +spec: + replicas: {{ .Values.localpv.replicas }} + strategy: + type: "Recreate" + rollingUpdate: null + selector: + matchLabels: + {{- include "localpv.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.localpv.podAnnotations }} + annotations: {{ toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "localpv.labels" . | nindent 8 }} + {{- with .Values.localpv.podLabels }} + {{ toYaml . | nindent 8 }} + {{- end }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ template "localpv.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: {{ template "localpv.fullname" . }} + image: "{{ .Values.localpv.image.registry }}{{ .Values.localpv.image.repository }}:{{ .Values.localpv.image.tag }}" + imagePullPolicy: {{ .Values.localpv.image.pullPolicy }} + resources: +{{ toYaml .Values.localpv.resources | indent 10 }} + args: + - "--bd-time-out=$(BDC_BD_BIND_RETRIES)" + env: + # OPENEBS_IO_K8S_MASTER enables openebs provisioner to connect to K8s + # based on this address. This is ignored if empty. + # This is supported for openebs provisioner version 0.5.2 onwards + #- name: OPENEBS_IO_K8S_MASTER + # value: "http://10.128.0.12:8080" + # OPENEBS_IO_KUBE_CONFIG enables openebs provisioner to connect to K8s + # based on this config. This is ignored if empty. + # This is supported for openebs provisioner version 0.5.2 onwards + #- name: OPENEBS_IO_KUBE_CONFIG + # value: "/home/ubuntu/.kube/config" + # This sets the number of times the provisioner should try + # with a polling interval of 5 seconds, to get the Blockdevice + # Name from a BlockDeviceClaim, before the BlockDeviceClaim + # is deleted. E.g. 12 * 5 seconds = 60 seconds timeout + - name: BDC_BD_BIND_RETRIES + value: "{{ .Values.localpv.waitForBDBindTimeoutRetryCount }}" + - name: OPENEBS_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + # OPENEBS_SERVICE_ACCOUNT provides the service account of this pod as + # environment variable + - name: OPENEBS_SERVICE_ACCOUNT + valueFrom: + fieldRef: + fieldPath: spec.serviceAccountName + # OPENEBS_IO_BASE_PATH is the environment variable that provides the + # default base path on the node where host-path PVs will be provisioned. + - name: OPENEBS_IO_ENABLE_ANALYTICS + value: "{{ .Values.analytics.enabled }}" + - name: OPENEBS_IO_BASE_PATH + value: "{{ .Values.localpv.basePath }}" + - name: OPENEBS_IO_HELPER_IMAGE + value: "{{ .Values.helperPod.image.registry }}{{ .Values.helperPod.image.repository }}:{{ .Values.helperPod.image.tag }}" + - name: OPENEBS_IO_INSTALLER_TYPE + value: "localpv-charts-helm" + # LEADER_ELECTION_ENABLED is used to enable/disable leader election. By default + # leader election is enabled. + - name: LEADER_ELECTION_ENABLED + value: "{{ .Values.localpv.enableLeaderElection }}" +{{- if .Values.imagePullSecrets }} + - name: OPENEBS_IO_IMAGE_PULL_SECRETS + value: "{{- range $index, $secret := .Values.imagePullSecrets}}{{if $index}},{{end}}{{ $secret.name }}{{- end}}" +{{- end }} + # Process name used for matching is limited to the 15 characters + # present in the pgrep output. + # So fullname can't be used here with pgrep (>15 chars).A regular expression + # that matches the entire command name has to specified. + # Anchor `^` : matches any string that starts with `provisioner-loc` + # `.*`: matches any string that has `provisioner-loc` followed by zero or more char + livenessProbe: + exec: + command: + - sh + - -c + - test `pgrep -c "^provisioner-loc.*"` = 1 + initialDelaySeconds: {{ .Values.localpv.healthCheck.initialDelaySeconds }} + periodSeconds: {{ .Values.localpv.healthCheck.periodSeconds }} +{{- if .Values.localpv.nodeSelector }} + nodeSelector: +{{ toYaml .Values.localpv.nodeSelector | indent 8 }} +{{- end }} +{{- if .Values.localpv.tolerations }} + tolerations: +{{ toYaml .Values.localpv.tolerations | indent 8 }} +{{- end }} +{{- if .Values.localpv.affinity }} + affinity: +{{ toYaml .Values.localpv.affinity | indent 8 }} +{{- end }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/localpv-provisioner/templates/device-class.yaml b/helm/openebs/charts/mayastor/charts/localpv-provisioner/templates/device-class.yaml new file mode 100644 index 0000000..35fb94b --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/localpv-provisioner/templates/device-class.yaml @@ -0,0 +1,31 @@ +{{- if .Values.deviceClass.enabled }} +apiVersion: storage.k8s.io/v1 +kind: StorageClass +metadata: + name: {{ .Values.deviceClass.name }} + annotations: + openebs.io/cas-type: local + cas.openebs.io/config: | + - name: StorageType + value: "device" +{{- if .Values.deviceClass.fsType }} + - name: FSType + value: {{ .Values.deviceClass.fsType | quote }} +{{- end }} +{{- if .Values.deviceClass.blockDeviceSelectors }} + - name: BlockDeviceSelectors + data: +{{ toYaml .Values.deviceClass.blockDeviceSelectors | indent 10 }} +{{- end }} +{{- if .Values.deviceClass.nodeAffinityLabels }} + - name: NodeAffinityLabels + list: +{{ toYaml .Values.deviceClass.nodeAffinityLabels | indent 10 }} +{{- end }} +{{- if .Values.deviceClass.isDefaultClass }} + storageclass.kubernetes.io/is-default-class: "true" +{{- end }} +provisioner: openebs.io/local +volumeBindingMode: WaitForFirstConsumer +reclaimPolicy: {{ .Values.deviceClass.reclaimPolicy }} +{{- end }} \ No newline at end of file diff --git a/helm/openebs/charts/mayastor/charts/localpv-provisioner/templates/hostpath-class.yaml b/helm/openebs/charts/mayastor/charts/localpv-provisioner/templates/hostpath-class.yaml new file mode 100644 index 0000000..6dd49d9 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/localpv-provisioner/templates/hostpath-class.yaml @@ -0,0 +1,40 @@ +{{- if .Values.hostpathClass.enabled }} +apiVersion: storage.k8s.io/v1 +kind: StorageClass +metadata: + name: {{ tpl (.Values.hostpathClass.name) .}} + annotations: + openebs.io/cas-type: local + cas.openebs.io/config: | + - name: StorageType + value: "hostpath" +{{- if or .Values.localpv.basePath .Values.hostpathClass.basePath }} + - name: BasePath + value: {{ tpl (.Values.hostpathClass.basePath | default .Values.localpv.basePath | quote) . }} +{{- end }} +{{- if .Values.hostpathClass.nodeAffinityLabels }} + - name: NodeAffinityLabels + list: +{{ toYaml .Values.hostpathClass.nodeAffinityLabels | indent 10 }} +{{- end }} +{{- if .Values.hostpathClass.xfsQuota.enabled }} + - name: XFSQuota + enabled: "{{ .Values.hostpathClass.xfsQuota.enabled }}" + data: + softLimitGrace: "{{ .Values.hostpathClass.xfsQuota.softLimitGrace }}" + hardLimitGrace: "{{ .Values.hostpathClass.xfsQuota.hardLimitGrace }}" +{{- end }} +{{- if .Values.hostpathClass.ext4Quota.enabled }} + - name: EXT4Quota + enabled: "{{ .Values.hostpathClass.ext4Quota.enabled }}" + data: + softLimitGrace: "{{ .Values.hostpathClass.ext4Quota.softLimitGrace }}" + hardLimitGrace: "{{ .Values.hostpathClass.ext4Quota.hardLimitGrace }}" +{{- end }} +{{- if .Values.hostpathClass.isDefaultClass }} + storageclass.kubernetes.io/is-default-class: "true" +{{- end }} +provisioner: openebs.io/local +volumeBindingMode: WaitForFirstConsumer +reclaimPolicy: {{ .Values.hostpathClass.reclaimPolicy }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/localpv-provisioner/templates/psp.yaml b/helm/openebs/charts/mayastor/charts/localpv-provisioner/templates/psp.yaml new file mode 100644 index 0000000..ec64aad --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/localpv-provisioner/templates/psp.yaml @@ -0,0 +1,30 @@ +{{- if .Values.rbac.pspEnabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "localpv.fullname" . }}-psp + {{- with .Values.localpv.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "localpv.labels" . | nindent 4 }} +spec: + privileged: {{ .Values.localpv.privileged }} + allowPrivilegeEscalation: true + allowedCapabilities: ['*'] + volumes: ['*'] + hostNetwork: true + hostPorts: + - min: 0 + max: 65535 + hostIPC: true + hostPID: true + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'RunAsAny' + fsGroup: + rule: 'RunAsAny' +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/localpv-provisioner/templates/rbac.yaml b/helm/openebs/charts/mayastor/charts/localpv-provisioner/templates/rbac.yaml new file mode 100644 index 0000000..04cd540 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/localpv-provisioner/templates/rbac.yaml @@ -0,0 +1,99 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "localpv.serviceAccountName" . }} + labels: + {{- include "localpv.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} +{{- if .Values.rbac.create }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "localpv.fullname" . }} + {{- with .Values.localpv.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "localpv.labels" . | nindent 4 }} +rules: +- apiGroups: ["*"] + resources: ["nodes"] + verbs: ["get", "list", "watch"] +- apiGroups: ["*"] + resources: ["namespaces", "pods", "events", "endpoints"] + verbs: ["*"] +- apiGroups: ["*"] + resources: ["resourcequotas", "limitranges"] + verbs: ["list", "watch"] +- apiGroups: ["*"] + resources: ["storageclasses", "persistentvolumeclaims", "persistentvolumes"] + verbs: ["*"] +- apiGroups: ["apiextensions.k8s.io"] + resources: ["customresourcedefinitions"] + verbs: [ "get", "list", "create", "update", "delete", "patch"] +- apiGroups: ["openebs.io"] + resources: [ "*"] + verbs: ["*" ] +- nonResourceURLs: ["/metrics"] + verbs: ["get"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "localpv.fullname" . }} + {{- with .Values.localpv.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "localpv.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "localpv.fullname" . }} +subjects: +- kind: ServiceAccount + name: {{ template "localpv.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +{{- if .Values.rbac.pspEnabled }} +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ template "localpv.fullname" . }}-psp + {{- with .Values.localpv.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "localpv.labels" . | nindent 4 }} +rules: +- apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ template "localpv.fullname" . }}-psp +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "localpv.fullname" . }}-psp + {{- with .Values.localpv.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "localpv.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "localpv.fullname" . }}-psp +subjects: + - kind: ServiceAccount + name: {{ template "localpv.serviceAccountName" . }} + namespace: {{ $.Release.Namespace }} +{{- end }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/localpv-provisioner/values.yaml b/helm/openebs/charts/mayastor/charts/localpv-provisioner/values.yaml new file mode 100644 index 0000000..d421232 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/localpv-provisioner/values.yaml @@ -0,0 +1,171 @@ +# Default values for localpv. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +release: + version: "3.4.0" + +rbac: + # rbac.create: `true` if rbac resources should be created + create: true + # rbac.pspEnabled: `true` if PodSecurityPolicy resources should be created + pspEnabled: false + +# If false, openebs NDM sub-chart will not be installed +openebsNDM: + enabled: true + +localpv: + name: localpv-provisioner + enabled: true + image: + # Make sure that registry name end with a '/'. + # For example : quay.io/ is a correct value here and quay.io is incorrect + registry: + repository: openebs/provisioner-localpv + tag: 3.4.0 + pullPolicy: IfNotPresent + updateStrategy: + type: RollingUpdate + # If set to false, containers created by the localpv provisioner will run without extra privileges. + privileged: true + annotations: {} + podAnnotations: {} + ## Labels to be added to localpv provisioner deployment pods + podLabels: + name: openebs-localpv-provisioner + healthCheck: + initialDelaySeconds: 30 + periodSeconds: 60 + replicas: 1 + enableLeaderElection: true + basePath: "/var/openebs/local" +# This sets the number of times the provisioner should try +# with a polling interval of 5 seconds, to get the Blockdevice +# Name from a BlockDeviceClaim, before the BlockDeviceClaim +# is deleted. E.g. 12 * 5 seconds = 60 seconds timeout + waitForBDBindTimeoutRetryCount: "12" + 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 + nodeSelector: {} + tolerations: [] + affinity: {} + securityContext: {} + +imagePullSecrets: + # - name: img-pull-secret + +podSecurityContext: {} + # fsGroup: 2000 + +nameOverride: "" +fullnameOverride: "" + +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: + +deviceClass: + # Name of default device StorageClass. + name: openebs-device + # If true, enables creation of the openebs-device StorageClass + enabled: true + # Available reclaim policies: Delete/Retain, defaults: Delete. + reclaimPolicy: Delete + # If true, sets the openebs-device StorageClass as the default StorageClass + isDefaultClass: false + # Custom node affinity label(s) for example "openebs.io/node-affinity-value" + # that will be used instead of hostnames + # This helps in cases where the hostname changes when the node is removed and + # added back with the disks still intact. + # Example: + # nodeAffinityLabels: + # - "openebs.io/node-affinity-key-1" + # - "openebs.io/node-affinity-key-2" + nodeAffinityLabels: [] + # Sets the filesystem to be written to the blockdevice before + # mounting (filesystem volumes) + # This is only usable if the selected BlockDevice does not already + # have a filesystem + # Valid values: "ext4", "xfs" + fsType: "ext4" + # Label block devices in the cluster that you would like the openEBS localPV + # Provisioner to pick up those specific block devices available on the node. + # Set the label key and value as shown in the example below. + # + # To read more: https://github.com/openebs/dynamic-localpv-provisioner/blob/develop/docs/tutorials/device/blockdeviceselectors.md + # + # Example: + # blockDeviceSelectors: + # ndm.io/driveType: "SSD" + # ndm.io/fsType: "none" + blockDeviceSelectors: {} + +hostpathClass: + # Name of the default hostpath StorageClass + name: openebs-hostpath + # If true, enables creation of the openebs-hostpath StorageClass + enabled: true + # Available reclaim policies: Delete/Retain, defaults: Delete. + reclaimPolicy: Delete + # If true, sets the openebs-hostpath StorageClass as the default StorageClass + isDefaultClass: false + # Path on the host where local volumes of this storage class are mounted under. + # NOTE: If not specified, this defaults to the value of localpv.basePath. + basePath: "" + # Custom node affinity label(s) for example "openebs.io/node-affinity-value" + # that will be used instead of hostnames + # This helps in cases where the hostname changes when the node is removed and + # added back with the disks still intact. + # Example: + # nodeAffinityLabels: + # - "openebs.io/node-affinity-key-1" + # - "openebs.io/node-affinity-key-2" + nodeAffinityLabels: [] + # Prerequisite: XFS Quota requires an XFS filesystem mounted with + # the 'pquota' or 'prjquota' mount option. + xfsQuota: + # If true, enables XFS project quota + enabled: false + # Detailed configuration options for XFS project quota. + # If XFS Quota is enabled with the default values, the usage limit + # is set at the storage capacity specified in the PVC. + softLimitGrace: "0%" + hardLimitGrace: "0%" + # Prerequisite: EXT4 Quota requires an EXT4 filesystem mounted with + # the 'prjquota' mount option. + ext4Quota: + # If true, enables XFS project quota + enabled: false + # Detailed configuration options for EXT4 project quota. + # If EXT4 Quota is enabled with the default values, the usage limit + # is set at the storage capacity specified in the PVC. + softLimitGrace: "0%" + hardLimitGrace: "0%" + +helperPod: + image: + registry: "" + repository: openebs/linux-utils + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: 3.4.0 + +analytics: + enabled: true + # Specify in hours the duration after which a ping event needs to be sent. + pingInterval: "24h" diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/.helmignore b/helm/openebs/charts/mayastor/charts/loki-stack/.helmignore new file mode 100644 index 0000000..50af031 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/.helmignore @@ -0,0 +1,22 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/Chart.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/Chart.yaml new file mode 100644 index 0000000..4e0553b --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/Chart.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +appVersion: v2.4.2 +description: 'Loki: like Prometheus, but for logs.' +home: https://grafana.com/loki +icon: https://raw.githubusercontent.com/grafana/loki/master/docs/sources/logo.png +kubeVersion: ^1.10.0-0 +maintainers: +- email: lokiproject@googlegroups.com + name: Loki Maintainers +name: loki-stack +sources: +- https://github.com/grafana/loki +version: 2.6.4 diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/README.md b/helm/openebs/charts/mayastor/charts/loki-stack/README.md new file mode 100644 index 0000000..ee67b03 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/README.md @@ -0,0 +1,60 @@ +# Loki-Stack Helm Chart + +## Prerequisites + +Make sure you have Helm [installed](https://helm.sh/docs/using_helm/#installing-helm) installed. + +## Get Repo Info + +```console +helm repo add grafana https://grafana.github.io/helm-charts +helm repo update +``` + +_See [helm repo](https://helm.sh/docs/helm/helm_repo/) for command documentation._ + +## Deploy Loki and Promtail to your cluster + +### Deploy with default config + +```bash +helm upgrade --install loki grafana/loki-stack +``` + +### Deploy in a custom namespace + +```bash +helm upgrade --install loki --namespace=loki-stack grafana/loki-stack +``` + +### Deploy with custom config + +```bash +helm upgrade --install loki grafana/loki-stack --set "key1=val1,key2=val2,..." +``` + +## Deploy Loki and Fluent Bit to your cluster + +```bash +helm upgrade --install loki grafana/loki-stack \ + --set fluent-bit.enabled=true,promtail.enabled=false +``` + +## Deploy Grafana to your cluster + +The chart loki-stack contains a pre-configured Grafana, simply use `--set grafana.enabled=true` + +To get the admin password for the Grafana pod, run the following command: + +```bash +kubectl get secret --namespace loki-grafana -o jsonpath="{.data.admin-password}" | base64 --decode ; echo +``` + +To access the Grafana UI, run the following command: + +```bash +kubectl port-forward --namespace service/loki-grafana 3000:80 +``` + +Navigate to and login with `admin` and the password output above. +Then follow the [instructions for adding the loki datasource](/docs/getting-started/grafana.md), using the URL `http://loki:3100/`. diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/.helmignore b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/.helmignore new file mode 100644 index 0000000..e12c0b4 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/.helmignore @@ -0,0 +1,2 @@ +tests/ +.pytest_cache/ diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/Chart.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/Chart.yaml new file mode 100644 index 0000000..f3cd8b6 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/Chart.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +appVersion: 7.17.1 +description: Official Elastic helm chart for Filebeat +home: https://github.com/elastic/helm-charts +icon: https://helm.elastic.co/icons/beats.png +maintainers: +- email: helm-charts@elastic.co + name: Elastic +name: filebeat +sources: +- https://github.com/elastic/beats +version: 7.17.1 diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/Makefile b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/Makefile new file mode 100644 index 0000000..22218a1 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/Makefile @@ -0,0 +1 @@ +include ../helpers/common.mk diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/README.md b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/README.md new file mode 100644 index 0000000..f94a900 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/README.md @@ -0,0 +1,271 @@ +# Filebeat Helm Chart + +[![Build Status](https://img.shields.io/jenkins/s/https/devops-ci.elastic.co/job/elastic+helm-charts+master.svg)](https://devops-ci.elastic.co/job/elastic+helm-charts+master/) [![Artifact HUB](https://img.shields.io/endpoint?url=https://artifacthub.io/badge/repository/elastic)](https://artifacthub.io/packages/search?repo=elastic) + +This Helm chart is a lightweight way to configure and run our official +[Filebeat Docker image][]. + + + + + + + +- [Requirements](#requirements) +- [Installing](#installing) + - [Install released version using Helm repository](#install-released-version-using-helm-repository) + - [Install development version from a branch](#install-development-version-from-a-branch) +- [Upgrading](#upgrading) +- [Usage notes](#usage-notes) +- [Configuration](#configuration) + - [Deprecated](#deprecated) +- [FAQ](#faq) + - [How to use Filebeat with Elasticsearch with security (authentication and TLS) enabled?](#how-to-use-filebeat-with-elasticsearch-with-security-authentication-and-tls-enabled) + - [How to install OSS version of Filebeat?](#how-to-install-oss-version-of-filebeat) + - [Why is Filebeat host.name field set to Kubernetes pod name?](#why-is-filebeat-hostname-field-set-to-kubernetes-pod-name) + - [How do I get multiple beats agents working with hostNetworking enabled?](#how-do-i-get-multiple-beats-agents-working-with-hostnetworking-enabled) + - [How to change readinessProbe for outputs which don't support testing](#how-to-change-readinessprobe-for-outputs-which-dont-support-testing) +- [Contributing](#contributing) + + + + + + +## Requirements + +* Kubernetes >= 1.14 +* [Helm][] >= 2.17.0 + +See [supported configurations][] for more details. + + +## Installing + +This chart is tested with the latest 7.17.1 version. + +### Install released version using Helm repository + +* Add the Elastic Helm charts repo: +`helm repo add elastic https://helm.elastic.co` + +* Install it: + - with Helm 3: `helm install filebeat --version elastic/filebeat` + - with Helm 2 (deprecated): `helm install --name filebeat --version elastic/filebeat` + +### Install development version from a branch + +* Clone the git repo: `git clone git@github.com:elastic/helm-charts.git` + +* Checkout the branch : `git checkout 7.17` +* Install it: + - with Helm 3: `helm install filebeat ./helm-charts/filebeat --set imageTag=7.17.1` + - with Helm 2 (deprecated): `helm install --name filebeat ./helm-charts/filebeat --set imageTag=7.17.1` + + +## Upgrading + +Please always check [CHANGELOG.md][] and [BREAKING_CHANGES.md][] before +upgrading to a new chart version. + + +## Usage notes + +* The default Filebeat configuration file for this chart is configured to use an +Elasticsearch endpoint. Without any additional changes, Filebeat will send +documents to the service URL that the Elasticsearch Helm chart sets up by +default. You may either set the `ELASTICSEARCH_HOSTS` environment variable in +`extraEnvs` to override this endpoint or modify the default `filebeatConfig` to +change this behavior. +* The default Filebeat configuration file is also configured to capture +container logs and enrich them with Kubernetes metadata by default. This will +capture all container logs in the cluster. +* This chart disables the [HostNetwork][] setting by default for compatibility +reasons with the majority of kubernetes providers and scenarios. Some kubernetes +providers may not allow enabling `hostNetwork` and deploying multiple Filebeat +pods on the same node isn't possible with `hostNetwork` However Filebeat does +recommend activating it. If your kubernetes provider is compatible with +`hostNetwork` and you don't need to run multiple Filebeat DaemonSets, you can +activate it by setting `hostNetworking: true` in [values.yaml][]. +* This repo includes a number of [examples][] configurations which can be used +as a reference. They are also used in the automated testing of this chart. + + +## Configuration + +| Parameter | Description | Default | +|--------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------| +| `clusterRoleRules` | Configurable [cluster role rules][] that Filebeat uses to access Kubernetes resources | see [values.yaml][] | +| `daemonset.annotations` | Configurable [annotations][] for filebeat daemonset | `{}` | +| `daemonset.labels` | Configurable [labels][] applied to all filebeat DaemonSet pods | `{}` | +| `daemonset.affinity` | Configurable [affinity][] for filebeat daemonset | `{}` | +| `daemonset.enabled` | If true, enable daemonset | `true` | +| `daemonset.envFrom` | Templatable string of `envFrom` to be passed to the [environment from variables][] which will be appended to filebeat container for DaemonSet | `[]` | +| `daemonset.extraEnvs` | Extra [environment variables][] which will be appended to filebeat container for DaemonSet | `[]` | +| `daemonset.extraVolumeMounts` | Templatable string of additional `volumeMounts` to be passed to the `tpl` function for DaemonSet | `[]` | +| `daemonset.extraVolumes` | Templatable string of additional `volumes` to be passed to the `tpl` function for DaemonSet | `[]` | +| `daemonset.hostAliases` | Configurable [hostAliases][] for filebeat DaemonSet | `[]` | +| `daemonset.hostNetworking` | Enable filebeat DaemonSet to use `hostNetwork` | `false` | +| `daemonset.filebeatConfig` | Allows you to add any config files in `/usr/share/filebeat` such as `filebeat.yml` for filebeat DaemonSet | see [values.yaml][] | +| `daemonset.maxUnavailable` | The [maxUnavailable][] value for the pod disruption budget. By default this will prevent Kubernetes from having more than 1 unhealthy pod in the node group | `1` | +| `daemonset.nodeSelector` | Configurable [nodeSelector][] for filebeat DaemonSet | `{}` | +| `daemonset.secretMounts` | Allows you easily mount a secret as a file inside the DaemonSet. Useful for mounting certificates and other secrets. See [values.yaml][] for an example | `[]` | +| `daemonset.podSecurityContext` | Configurable [podSecurityContext][] for filebeat DaemonSet pod execution environment | see [values.yaml][] | +| `daemonset.resources` | Allows you to set the [resources][] for filebeat DaemonSet | see [values.yaml][] | +| `daemonset.tolerations` | Configurable [tolerations][] for filebeat DaemonSet | `[]` | +| `deployment.annotations` | Configurable [annotations][] for filebeat Deployment | `{}` | +| `deployment.labels` | Configurable [labels][] applied to all filebeat Deployment pods | `{}` | +| `deployment.affinity` | Configurable [affinity][] for filebeat Deployment | `{}` | +| `deployment.enabled` | If true, enable deployment | `false` | +| `deployment.envFrom` | Templatable string of `envFrom` to be passed to the [environment from variables][] which will be appended to filebeat container for Deployment | `[]` | +| `deployment.extraEnvs` | Extra [environment variables][] which will be appended to filebeat container for Deployment | `[]` | +| `deployment.extraVolumeMounts` | Templatable string of additional `volumeMounts` to be passed to the `tpl` function for DaemonSet | `[]` | +| `deployment.extraVolumes` | Templatable string of additional `volumes` to be passed to the `tpl` function for Deployment | `[]` | +| `daemonset.hostAliases` | Configurable [hostAliases][] for filebeat Deployment | `[]` | +| `deployment.filebeatConfig` | Allows you to add any config files in `/usr/share/filebeat` such as `filebeat.yml` for filebeat Deployment | see [values.yaml][] | +| `deployment.nodeSelector` | Configurable [nodeSelector][] for filebeat Deployment | `{}` | +| `deployment.secretMounts` | Allows you easily mount a secret as a file inside the Deployment Useful for mounting certificates and other secrets. See [values.yaml][] for an example | `[]` | +| `deployment.resources` | Allows you to set the [resources][] for filebeat Deployment | see [values.yaml][] | +| `deployment.securityContext` | Configurable [securityContext][] for filebeat Deployment pod execution environment | see [values.yaml][] | +| `deployment.tolerations` | Configurable [tolerations][] for filebeat Deployment | `[]` | +| `replicas` | The replica count for the Filebeat deployment | `1` | +| `extraContainers` | Templatable string of additional containers to be passed to the `tpl` function | `""` | +| `extraInitContainers` | Templatable string of additional containers to be passed to the `tpl` function | `""` | +| `fullnameOverride` | Overrides the full name of the resources. If not set the name will default to " `.Release.Name` - `.Values.nameOverride or .Chart.Name` " | `""` | +| `hostPathRoot` | Fully-qualified [hostPath][] that will be used to persist filebeat registry data | `/var/lib` | +| `imagePullPolicy` | The Kubernetes [imagePullPolicy][] value | `IfNotPresent` | +| `imagePullSecrets` | Configuration for [imagePullSecrets][] so that you can use a private registry for your image | `[]` | +| `imageTag` | The filebeat Docker image tag | `7.17.1` | +| `image` | The filebeat Docker image | `docker.elastic.co/beats/filebeat` | +| `livenessProbe` | Parameters to pass to liveness [probe][] checks for values such as timeouts and thresholds | see [values.yaml][] | +| `managedServiceAccount` | Whether the `serviceAccount` should be managed by this helm chart. Set this to `false` in order to manage your own service account and related roles | `true` | +| `nameOverride` | Overrides the chart name for resources. If not set the name will default to `.Chart.Name` | `""` | +| `podAnnotations` | Configurable [annotations][] applied to all filebeat pods | `{}` | +| `priorityClassName` | The name of the [PriorityClass][]. No default is supplied as the PriorityClass must be created first | `""` | +| `readinessProbe` | Parameters to pass to readiness [probe][] checks for values such as timeouts and thresholds | see [values.yaml][] | +| `serviceAccount` | Custom [serviceAccount][] that filebeat will use during execution. By default will use the service account created by this chart | `""` | +| `serviceAccountAnnotations` | Annotations to be added to the ServiceAccount that is created by this chart. | `{}` | +| `terminationGracePeriod` | Termination period (in seconds) to wait before killing filebeat pod process on pod shutdown | `30` | +| `updateStrategy` | The [updateStrategy][] for the DaemonSet By default Kubernetes will kill and recreate pods on updates. Setting this to `OnDelete` will require that pods be deleted manually | `RollingUpdate` | + +### Deprecated + +| Parameter | Description | Default | +|----------------------|------------------------------------------------------------------------------------------------------------------------------------------------------|---------| +| `affinity` | Configurable [affinity][] for filebeat DaemonSet | `{}` | +| `envFrom` | Templatable string to be passed to the [environment from variables][] which will be appended to filebeat container for both DaemonSet and Deployment | `[]` | +| `extraEnvs` | Extra [environment variables][] which will be appended to filebeat container for both DaemonSet and Deployment | `[]` | +| `extraVolumeMounts` | Templatable string of additional `volumeMounts` to be passed to the `tpl` function for both DaemonSet and Deployment | `[]` | +| `extraVolumes` | Templatable string of additional `volumes` to be passed to the `tpl` function for both DaemonSet and Deployment | `[]` | +| `filebeatConfig` | Allows you to add any config files in `/usr/share/filebeat` such as `filebeat.yml` for both filebeat DaemonSet and Deployment | `{}` | +| `hostAliases` | Configurable [hostAliases][] | `[]` | +| `nodeSelector` | Configurable [nodeSelector][] for filebeat DaemonSet | `{}` | +| `podSecurityContext` | Configurable [securityContext][] for filebeat DaemonSet and Deployment pod execution environment | `{}` | +| `resources` | Allows you to set the [resources][] for both filebeat DaemonSet and Deployment | `{}` | +| `secretMounts` | Allows you easily mount a secret as a file inside DaemonSet and Deployment Useful for mounting certificates and other secrets | `[]` | +| `tolerations` | Configurable [tolerations][] for both filebeat DaemonSet and Deployment | `[]` | +| `labels` | Configurable [labels][] applied to all filebeat pods | `{}` | + +## FAQ + +### How to use Filebeat with Elasticsearch with security (authentication and TLS) enabled? + +This Helm chart can use existing [Kubernetes secrets][] to setup +credentials or certificates for examples. These secrets should be created +outside of this chart and accessed using [environment variables][] and volumes. + +An example can be found in [examples/security][]. + +### How to install OSS version of Filebeat? + +Deploying OSS version of Filebeat can be done by setting `image` value to +[Filebeat OSS Docker image][] + +An example of Filebeat deployment using OSS version can be found in +[examples/oss][]. + +### Why is Filebeat host.name field set to Kubernetes pod name? + +The default Filebeat configuration is using Filebeat pod name for +`agent.hostname` and `host.name` fields. The `hostname` of the Kubernetes nodes +can be find in `kubernetes.node.name` field. If you would like to have +`agent.hostname` and `host.name` fields set to the hostname of the nodes, you'll +need to set `hostNetworking` value to true. + +Note that enabling [hostNetwork][] make Filebeat pod use the host network +namespace which gives it access to the host loopback device, services listening +on localhost, could be used to snoop on network activity of other pods on the +same node. + +### How do I get multiple beats agents working with hostNetworking enabled? + +The default http port for multiple beats agents may be on the same port, for +example, Filebeats and Metricbeats both default to 5066. When `hostNetworking` +is enabled this will cause collisions when standing up the http server. The work +around for this is to set `http.port` in the config file for one of the beats agent +to use a different port. + +### How to change readinessProbe for outputs which don't support testing + +Some [Filebeat outputs][] like [Kafka output][] don't support testing using +`filebeat test output` command which is used by Filebeat chart readiness probe. + +This makes Filebeat pods crash before being ready with the following message: +`Readiness probe failed: kafka output doesn't support testing`. + +The workaround when using this kind of output is to override the readiness probe +command to check Filebeat API instead (same as existing liveness probe). + +``` +readinessProbe: + exec: + command: + - sh + - -c + - | + #!/usr/bin/env bash -e + curl --fail 127.0.0.1:5066 +``` + + +## Contributing + +Please check [CONTRIBUTING.md][] before any contribution or for any questions +about our development and testing process. + +[7.17]: https://github.com/elastic/helm-charts/releases +[BREAKING_CHANGES.md]: https://github.com/elastic/helm-charts/blob/master/BREAKING_CHANGES.md +[CHANGELOG.md]: https://github.com/elastic/helm-charts/blob/master/CHANGELOG.md +[CONTRIBUTING.md]: https://github.com/elastic/helm-charts/blob/master/CONTRIBUTING.md +[affinity]: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity +[annotations]: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ +[cluster role rules]: https://kubernetes.io/docs/reference/access-authn-authz/rbac/#role-and-clusterrole +[dnsConfig]: https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/ +[environment variables]: https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/#using-environment-variables-inside-of-your-config +[environment from variables]: https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/#configure-all-key-value-pairs-in-a-configmap-as-container-environment-variables +[examples]: https://github.com/elastic/helm-charts/tree/7.17/filebeat/examples +[examples/oss]: https://github.com/elastic/helm-charts/tree/7.17/filebeat/examples/oss +[examples/security]: https://github.com/elastic/helm-charts/tree/7.17/filebeat/examples/security +[filebeat docker image]: https://www.elastic.co/guide/en/beats/filebeat/7.17/running-on-docker.html +[filebeat oss docker image]: https://www.docker.elastic.co/r/beats/filebeat-oss +[filebeat outputs]: https://www.elastic.co/guide/en/beats/filebeat/7.17/configuring-output.html +[helm]: https://helm.sh +[hostAliases]: https://kubernetes.io/docs/concepts/services-networking/add-entries-to-pod-etc-hosts-with-host-aliases/ +[hostNetwork]: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#host-namespaces +[hostPath]: https://kubernetes.io/docs/concepts/storage/volumes/#hostpath +[imagePullPolicy]: https://kubernetes.io/docs/concepts/containers/images/#updating-images +[imagePullSecrets]: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/#create-a-pod-that-uses-your-secret +[kafka output]: https://www.elastic.co/guide/en/beats/filebeat/7.17/kafka-output.html +[kubernetes secrets]: https://kubernetes.io/docs/concepts/configuration/secret/ +[labels]: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ +[maxUnavailable]: https://kubernetes.io/docs/tasks/run-application/configure-pdb/#specifying-a-poddisruptionbudget +[nodeSelector]: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector +[podSecurityContext]: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ +[priorityClass]: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/#priorityclass +[probe]: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/ +[resources]: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/ +[supported configurations]: https://github.com/elastic/helm-charts/tree/7.17/README.md#supported-configurations +[serviceAccount]: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ +[tolerations]: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ +[updateStrategy]: https://kubernetes.io/docs/tasks/manage-daemon/update-daemon-set/#daemonset-update-strategy +[values.yaml]: https://github.com/elastic/helm-charts/tree/7.17/filebeat/values.yaml diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/default/Makefile b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/default/Makefile new file mode 100644 index 0000000..b39ece9 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/default/Makefile @@ -0,0 +1,13 @@ +default: test + +include ../../../helpers/examples.mk + +RELEASE := helm-filebeat-default + +install: + helm upgrade --wait --timeout=$(TIMEOUT) --install $(RELEASE) ../../ + +test: install goss + +purge: + helm del $(RELEASE) diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/default/README.md b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/default/README.md new file mode 100644 index 0000000..00c3ecc --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/default/README.md @@ -0,0 +1,27 @@ +# Default + +This example deploy Filebeat 7.17.1 using [default values][]. + + +## Usage + +* Deploy [Elasticsearch Helm chart][]. + +* Deploy Filebeat chart with the default values: `make install` + +* You can now setup a port forward to query Filebeat indices: + + ``` + kubectl port-forward svc/elasticsearch-master 9200 + curl localhost:9200/_cat/indices + ``` + + +## Testing + +You can also run [goss integration tests][] using `make test` + + +[elasticsearch helm chart]: https://github.com/elastic/helm-charts/tree/7.17/elasticsearch/examples/default/ +[goss integration tests]: https://github.com/elastic/helm-charts/tree/7.17/filebeat/examples/default/test/goss.yaml +[default values]: https://github.com/elastic/helm-charts/tree/7.17/filebeat/values.yaml diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/default/test/goss.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/default/test/goss.yaml new file mode 100644 index 0000000..4774c80 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/default/test/goss.yaml @@ -0,0 +1,47 @@ +port: + tcp:5066: + listening: true + ip: + - "127.0.0.1" + +mount: + /usr/share/filebeat/data: + exists: true + /run/docker.sock: + exists: true + /var/lib/docker/containers: + exists: true + opts: + - ro + /usr/share/filebeat/filebeat.yml: + exists: true + opts: + - ro + +user: + filebeat: + exists: true + uid: 1000 + gid: 1000 + +http: + http://elasticsearch-master:9200/_cat/indices: + status: 200 + timeout: 2000 + body: + - "filebeat-7.17.1" + +file: + /usr/share/filebeat/filebeat.yml: + exists: true + contains: + - "add_kubernetes_metadata" + - "output.elasticsearch" + - "elasticsearch-master:9200" + +command: + cd /usr/share/filebeat && filebeat test output: + exit-status: 0 + stdout: + - "elasticsearch: http://elasticsearch-master:9200" + - "version: 7.17.1" diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/deployment/Makefile b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/deployment/Makefile new file mode 100644 index 0000000..0bc2853 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/deployment/Makefile @@ -0,0 +1,13 @@ +default: test + +include ../../../helpers/examples.mk + +RELEASE := helm-filebeat-deployment + +install: + helm upgrade --wait --timeout=$(TIMEOUT) --install --values values.yaml $(RELEASE) ../../ + +test: install goss + +purge: + helm del $(RELEASE) diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/deployment/README.md b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/deployment/README.md new file mode 100644 index 0000000..1c0b5b6 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/deployment/README.md @@ -0,0 +1,27 @@ +# Default + +This example deploy Filebeat 7.17.1 using [default values][] as a Kubernetes Deployment. + + +## Usage + +* Deploy [Elasticsearch Helm chart][]. + +* Deploy Filebeat chart with the default values: `make install` + +* You can now setup a port forward to query Filebeat indices: + + ``` + kubectl port-forward svc/elasticsearch-master 9200 + curl localhost:9200/_cat/indices + ``` + + +## Testing + +You can also run [goss integration tests][] using `make test` + + +[elasticsearch helm chart]: https://github.com/elastic/helm-charts/tree/master/elasticsearch/examples/default/ +[goss integration tests]: https://github.com/elastic/helm-charts/tree/master/filebeat/examples/deployment/test/goss.yaml +[default values]: https://github.com/elastic/helm-charts/tree/master/filebeat/values.yaml diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/deployment/test/goss.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/deployment/test/goss.yaml new file mode 100644 index 0000000..c5e5868 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/deployment/test/goss.yaml @@ -0,0 +1,6 @@ +http: + http://elasticsearch-master:9200/_cat/indices: + status: 200 + timeout: 2000 + body: + - "filebeat-7.17.1" diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/deployment/values.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/deployment/values.yaml new file mode 100644 index 0000000..bf1cf06 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/deployment/values.yaml @@ -0,0 +1,16 @@ +deployment: + enabled: true + +daemonset: + enabled: false + +filebeatConfig: + filebeat.yml: | + filebeat.inputs: + - type: log + paths: + - /usr/share/filebeat/logs/filebeat + + output.elasticsearch: + host: '${NODE_NAME}' + hosts: '${ELASTICSEARCH_HOSTS:elasticsearch-master:9200}' \ No newline at end of file diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/oss/Makefile b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/oss/Makefile new file mode 100644 index 0000000..3caa17a --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/oss/Makefile @@ -0,0 +1,13 @@ +default: test + +include ../../../helpers/examples.mk + +RELEASE := helm-filebeat-oss + +install: + helm upgrade --wait --timeout=$(TIMEOUT) --install --values values.yaml $(RELEASE) ../../ + +test: install goss + +purge: + helm del $(RELEASE) diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/oss/README.md b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/oss/README.md new file mode 100644 index 0000000..1729b06 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/oss/README.md @@ -0,0 +1,27 @@ +# OSS + +This example deploy Filebeat 7.17.1 using [Filebeat OSS][] version. + + +## Usage + +* Deploy [Elasticsearch Helm chart][]. + +* Deploy Filebeat chart with the default values: `make install` + +* You can now setup a port forward to query Filebeat indices: + + ``` + kubectl port-forward svc/oss-master 9200 + curl localhost:9200/_cat/indices + ``` + + +## Testing + +You can also run [goss integration tests][] using `make test` + + +[filebeat oss]: https://www.elastic.co/downloads/beats/filebeat-oss +[elasticsearch helm chart]: https://github.com/elastic/helm-charts/tree/7.17/elasticsearch/examples/oss/ +[goss integration tests]: https://github.com/elastic/helm-charts/tree/7.17/filebeat/examples/oss/test/goss.yaml diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/oss/test/goss.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/oss/test/goss.yaml new file mode 100644 index 0000000..77f6b07 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/oss/test/goss.yaml @@ -0,0 +1,22 @@ +port: + tcp:5066: + listening: true + ip: + - "127.0.0.1" + +mount: + /usr/share/filebeat/data: + exists: true + +user: + filebeat: + exists: true + uid: 1000 + gid: 1000 + +http: + http://elasticsearch-master:9200/_cat/indices: + status: 200 + timeout: 2000 + body: + - "filebeat-oss-7.17.1" diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/oss/values.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/oss/values.yaml new file mode 100644 index 0000000..7f713fe --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/oss/values.yaml @@ -0,0 +1,22 @@ +image: docker.elastic.co/beats/filebeat-oss + +daemonset: + filebeatConfig: + filebeat.yml: | + filebeat.inputs: + - type: container + paths: + - /var/log/containers/*.log + processors: + - add_kubernetes_metadata: + host: ${NODE_NAME} + matchers: + - logs_path: + logs_path: "/var/log/containers/" + output.elasticsearch: + host: '${NODE_NAME}' + hosts: "elasticsearch-master:9200" + index: "filebeat-oss-%{[agent.version]}-%{+yyyy.MM.dd}" + setup.ilm.enabled: false + setup.template.name: "filebeat" + setup.template.pattern: "filebeat-oss-*" diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/security/Makefile b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/security/Makefile new file mode 100644 index 0000000..7bec9ab --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/security/Makefile @@ -0,0 +1,13 @@ +default: test + +include ../../../helpers/examples.mk + +RELEASE := helm-filebeat-security + +install: + helm upgrade --wait --timeout=$(TIMEOUT) --install --values values.yaml $(RELEASE) ../../ + +test: install goss + +purge: + helm del $(RELEASE) diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/security/README.md b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/security/README.md new file mode 100644 index 0000000..7c38422 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/security/README.md @@ -0,0 +1,28 @@ +# Security + +This example deploy Filebeat 7.17.1 using authentication and TLS to connect to +Elasticsearch (see [values][]). + + +## Usage + +* Deploy [Elasticsearch Helm chart][]. + +* Deploy Filebeat chart with security: `make install` + +* You can now setup a port forward to query Filebeat indices: + + ``` + kubectl port-forward svc/security-master 9200 + curl -u elastic:changeme https://localhost:9200/_cat/indices + ``` + + +## Testing + +You can also run [goss integration tests][] using `make test` + + +[elasticsearch helm chart]: https://github.com/elastic/helm-charts/tree/7.17/elasticsearch/examples/security/ +[goss integration tests]: https://github.com/elastic/helm-charts/tree/7.17/filebeat/examples/security/test/goss.yaml +[values]: https://github.com/elastic/helm-charts/tree/7.17/filebeat/examples/security/values.yaml diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/security/test/goss.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/security/test/goss.yaml new file mode 100644 index 0000000..c80a85e --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/security/test/goss.yaml @@ -0,0 +1,9 @@ +http: + https://security-master:9200/_cat/indices: + status: 200 + timeout: 2000 + body: + - "filebeat-7.17.1" + allow-insecure: true + username: "{{ .Env.ELASTICSEARCH_USERNAME }}" + password: "{{ .Env.ELASTICSEARCH_PASSWORD }}" diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/security/values.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/security/values.yaml new file mode 100644 index 0000000..606961f --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/security/values.yaml @@ -0,0 +1,37 @@ +filebeatConfig: + filebeat.yml: | + filebeat.inputs: + - type: container + paths: + - /var/log/containers/*.log + processors: + - add_kubernetes_metadata: + host: ${NODE_NAME} + matchers: + - logs_path: + logs_path: "/var/log/containers/" + + output.elasticsearch: + username: '${ELASTICSEARCH_USERNAME}' + password: '${ELASTICSEARCH_PASSWORD}' + protocol: https + hosts: ["security-master:9200"] + ssl.certificate_authorities: + - /usr/share/filebeat/config/certs/elastic-certificate.pem + +secretMounts: + - name: elastic-certificate-pem + secretName: elastic-certificate-pem + path: /usr/share/filebeat/config/certs + +extraEnvs: + - name: 'ELASTICSEARCH_USERNAME' + valueFrom: + secretKeyRef: + name: elastic-credentials + key: username + - name: 'ELASTICSEARCH_PASSWORD' + valueFrom: + secretKeyRef: + name: elastic-credentials + key: password diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/upgrade/Makefile b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/upgrade/Makefile new file mode 100644 index 0000000..054b53c --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/upgrade/Makefile @@ -0,0 +1,16 @@ +default: test + +include ../../../helpers/examples.mk + +CHART := filebeat +RELEASE := helm-filebeat-upgrade +FROM := 7.9.0 # registry file version 1 not supported error with previous version + +install: + ../../../helpers/upgrade.sh --chart $(CHART) --release $(RELEASE) --from $(FROM) + kubectl rollout status daemonset $(RELEASE)-filebeat + +test: install goss + +purge: + helm del $(RELEASE) diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/upgrade/README.md b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/upgrade/README.md new file mode 100644 index 0000000..fa3ee3b --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/upgrade/README.md @@ -0,0 +1,21 @@ +# Upgrade + +This example will deploy Filebeat chart using an old chart version, +then upgrade it. + + +## Usage + +* Add the Elastic Helm charts repo: `helm repo add elastic https://helm.elastic.co` + +* Deploy [Elasticsearch Helm chart][]: `helm install elasticsearch elastic/elasticsearch` + +* Deploy and upgrade Filebeat chart with the default values: `make install` + + +## Testing + +You can also run [goss integration tests][] using `make test`. + + +[goss integration tests]: https://github.com/elastic/helm-charts/tree/master/filebeat/examples/upgrade/test/goss.yaml diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/upgrade/test/goss.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/upgrade/test/goss.yaml new file mode 100644 index 0000000..0b7a0c1 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/upgrade/test/goss.yaml @@ -0,0 +1,45 @@ +port: + tcp:5066: + listening: true + ip: + - "127.0.0.1" + +mount: + /usr/share/filebeat/data: + exists: true + /run/docker.sock: + exists: true + /var/lib/docker/containers: + exists: true + opts: + - ro + /usr/share/filebeat/filebeat.yml: + exists: true + opts: + - ro + +user: + filebeat: + exists: true + uid: 1000 + gid: 1000 + +http: + http://upgrade-master:9200/_cat/indices: + status: 200 + timeout: 2000 + body: + - "filebeat-7.17.1" + +file: + /usr/share/filebeat/filebeat.yml: + exists: true + contains: + - "add_kubernetes_metadata" + - "output.elasticsearch" + +command: + cd /usr/share/filebeat && filebeat test output: + exit-status: 0 + stdout: + - "elasticsearch: http://upgrade-master:9200" diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/upgrade/values.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/upgrade/values.yaml new file mode 100644 index 0000000..8b23060 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/examples/upgrade/values.yaml @@ -0,0 +1,4 @@ +--- +extraEnvs: + - name: ELASTICSEARCH_HOSTS + value: upgrade-master:9200 diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/templates/NOTES.txt b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/templates/NOTES.txt new file mode 100644 index 0000000..d4cf00b --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/templates/NOTES.txt @@ -0,0 +1,2 @@ +1. Watch all containers come up. + $ kubectl get pods --namespace={{ .Release.Namespace }} -l app={{ template "filebeat.fullname" . }} -w diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/templates/_helpers.tpl b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/templates/_helpers.tpl new file mode 100644 index 0000000..a52a937 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/templates/_helpers.tpl @@ -0,0 +1,32 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "filebeat.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +*/}} +{{- define "filebeat.fullname" -}} +{{- if .Values.fullnameOverride -}} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} + +{{/* +Use the fullname if the serviceAccount value is not set +*/}} +{{- define "filebeat.serviceAccount" -}} +{{- if .Values.serviceAccount }} +{{- .Values.serviceAccount -}} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/templates/clusterrole.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/templates/clusterrole.yaml new file mode 100644 index 0000000..754dfd5 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/templates/clusterrole.yaml @@ -0,0 +1,12 @@ +{{- if .Values.managedServiceAccount }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "filebeat.serviceAccount" . }}-cluster-role + labels: + app: "{{ template "filebeat.fullname" . }}" + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service | quote }} + release: {{ .Release.Name | quote }} +rules: {{ toYaml .Values.clusterRoleRules | nindent 2 -}} +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/templates/clusterrolebinding.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/templates/clusterrolebinding.yaml new file mode 100644 index 0000000..887775c --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/templates/clusterrolebinding.yaml @@ -0,0 +1,19 @@ +{{- if .Values.managedServiceAccount }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "filebeat.serviceAccount" . }}-cluster-role-binding + labels: + app: "{{ template "filebeat.fullname" . }}" + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service | quote }} + release: {{ .Release.Name | quote }} +roleRef: + kind: ClusterRole + name: {{ template "filebeat.serviceAccount" . }}-cluster-role + apiGroup: rbac.authorization.k8s.io +subjects: +- kind: ServiceAccount + name: {{ template "filebeat.serviceAccount" . }} + namespace: {{ .Release.Namespace }} +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/templates/configmap.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/templates/configmap.yaml new file mode 100644 index 0000000..559abe1 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/templates/configmap.yaml @@ -0,0 +1,53 @@ +{{- if .Values.filebeatConfig }} +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "filebeat.fullname" . }}-config + labels: + app: "{{ template "filebeat.fullname" . }}" + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service | quote }} + release: {{ .Release.Name | quote }} +data: +{{- range $path, $config := .Values.filebeatConfig }} + {{ $path }}: | +{{ $config | indent 4 -}} +{{- end -}} +{{- end -}} + +{{- if and .Values.daemonset.enabled .Values.daemonset.filebeatConfig }} +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "filebeat.fullname" . }}-daemonset-config + labels: + app: "{{ template "filebeat.fullname" . }}" + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service | quote }} + release: {{ .Release.Name | quote }} +data: +{{- range $path, $config := .Values.daemonset.filebeatConfig }} + {{ $path }}: | +{{ $config | indent 4 -}} +{{- end -}} +{{- end -}} + +{{- if and .Values.deployment.enabled .Values.deployment.filebeatConfig }} +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "filebeat.fullname" . }}-deployment-config + labels: + app: "{{ template "filebeat.fullname" . }}" + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service | quote }} + release: {{ .Release.Name | quote }} +data: +{{- range $path, $config := .Values.deployment.filebeatConfig }} + {{ $path }}: | +{{ $config | indent 4 -}} +{{- end -}} +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/templates/daemonset.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/templates/daemonset.yaml new file mode 100644 index 0000000..d6cd761 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/templates/daemonset.yaml @@ -0,0 +1,201 @@ +{{- if .Values.daemonset.enabled }} +--- +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: {{ template "filebeat.fullname" . }} + labels: + app: "{{ template "filebeat.fullname" . }}" + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service | quote }} + release: {{ .Release.Name | quote }} + {{- if .Values.daemonset.labels }} + {{- range $key, $value := .Values.daemonset.labels }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- else }} + {{- range $key, $value := .Values.labels }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} + {{- if .Values.daemonset.annotations }} + annotations: + {{- range $key, $value := .Values.daemonset.annotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} +spec: + selector: + matchLabels: + app: "{{ template "filebeat.fullname" . }}" + release: {{ .Release.Name | quote }} + updateStrategy: + {{- if eq .Values.updateStrategy "RollingUpdate" }} + rollingUpdate: + maxUnavailable: {{ .Values.daemonset.maxUnavailable }} + {{- end }} + type: {{ .Values.updateStrategy }} + template: + metadata: + annotations: + {{- range $key, $value := .Values.podAnnotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{/* This forces a restart if the configmap has changed */}} + {{- if or .Values.filebeatConfig .Values.daemonset.filebeatConfig }} + configChecksum: {{ include (print .Template.BasePath "/configmap.yaml") . | sha256sum | trunc 63 }} + {{- end }} + name: "{{ template "filebeat.fullname" . }}" + labels: + app: "{{ template "filebeat.fullname" . }}" + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service | quote }} + release: {{ .Release.Name | quote }} + {{- if .Values.daemonset.labels }} + {{- range $key, $value := .Values.daemonset.labels }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- else }} + {{- range $key, $value := .Values.labels }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} + spec: + tolerations: {{ toYaml ( .Values.tolerations | default .Values.daemonset.tolerations ) | nindent 8 }} + nodeSelector: {{ toYaml ( .Values.nodeSelector | default .Values.daemonset.nodeSelector ) | nindent 8 }} + {{- if .Values.priorityClassName }} + priorityClassName: {{ .Values.priorityClassName }} + {{- end }} + affinity: {{ toYaml ( .Values.affinity | default .Values.daemonset.affinity ) | nindent 8 }} + serviceAccountName: {{ template "filebeat.serviceAccount" . }} + terminationGracePeriodSeconds: {{ .Values.terminationGracePeriod }} + {{- if .Values.daemonset.hostNetworking }} + hostNetwork: true + dnsPolicy: ClusterFirstWithHostNet + {{- end }} + {{- if .Values.dnsConfig }} + dnsConfig: {{ toYaml .Values.dnsConfig | nindent 8 }} + {{- end }} + {{- if .Values.hostAliases | default .Values.daemonset.hostAliases }} + hostAliases: {{ toYaml ( .Values.hostAliases | default .Values.daemonset.hostAliases ) | nindent 8 }} + {{- end }} + volumes: + {{- range .Values.secretMounts | default .Values.daemonset.secretMounts }} + - name: {{ .name }} + secret: + secretName: {{ .secretName }} + {{- end }} + {{- if .Values.filebeatConfig }} + - name: filebeat-config + configMap: + defaultMode: 0600 + name: {{ template "filebeat.fullname" . }}-config + {{- else if .Values.daemonset.filebeatConfig }} + - name: filebeat-config + configMap: + defaultMode: 0600 + name: {{ template "filebeat.fullname" . }}-daemonset-config + {{- end }} + - name: data + hostPath: + path: {{ .Values.hostPathRoot }}/{{ template "filebeat.fullname" . }}-{{ .Release.Namespace }}-data + type: DirectoryOrCreate + - name: varlibdockercontainers + hostPath: + path: /var/lib/docker/containers + - name: varlog + hostPath: + path: /var/log + - name: varrundockersock + hostPath: + path: /var/run/docker.sock + {{- if .Values.extraVolumes | default .Values.daemonset.extraVolumes }} +{{ toYaml ( .Values.extraVolumes | default .Values.daemonset.extraVolumes ) | indent 6 }} + {{- end }} + {{- if .Values.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | indent 8 }} + {{- end }} + {{- if .Values.extraInitContainers }} + initContainers: + # All the other beats accept a string here while + # filebeat accepts a valid yaml array. We're keeping + # this as a backwards compatible change, while adding + # also a way to pass a string as other templates to + # make these implementations consistent. + # https://github.com/elastic/helm-charts/issues/490 + {{- if eq "string" (printf "%T" .Values.extraInitContainers) }} +{{ tpl .Values.extraInitContainers . | indent 8 }} + {{- else }} +{{ toYaml .Values.extraInitContainers | indent 8 }} + {{- end }} + {{- end }} + containers: + - name: "filebeat" + image: "{{ .Values.image }}:{{ .Values.imageTag }}" + imagePullPolicy: "{{ .Values.imagePullPolicy }}" + args: + - "-e" + - "-E" + - "http.enabled=true" + livenessProbe: +{{ toYaml .Values.livenessProbe | indent 10 }} + readinessProbe: +{{ toYaml .Values.readinessProbe | indent 10 }} + resources: +{{ toYaml ( .Values.resources | default .Values.daemonset.resources ) | indent 10 }} + env: + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName +{{- if .Values.extraEnvs | default .Values.daemonset.extraEnvs }} +{{ toYaml ( .Values.extraEnvs | default .Values.daemonset.extraEnvs ) | indent 8 }} +{{- end }} + envFrom: {{ toYaml ( .Values.envFrom | default .Values.daemonset.envFrom ) | nindent 10 }} + securityContext: {{ toYaml ( .Values.podSecurityContext | default .Values.daemonset.securityContext ) | nindent 10 }} + volumeMounts: + {{- range .Values.secretMounts | default .Values.daemonset.secretMounts }} + - name: {{ .name }} + mountPath: {{ .path }} + {{- if .subPath }} + subPath: {{ .subPath }} + {{- end }} + {{- end }} + {{- range $path, $config := .Values.filebeatConfig }} + - name: filebeat-config + mountPath: /usr/share/filebeat/{{ $path }} + readOnly: true + subPath: {{ $path }} + {{ else }} + {{- range $path, $config := .Values.daemonset.filebeatConfig }} + - name: filebeat-config + mountPath: /usr/share/filebeat/{{ $path }} + readOnly: true + subPath: {{ $path }} + {{- end }} + {{- end }} + - name: data + mountPath: /usr/share/filebeat/data + - name: varlibdockercontainers + mountPath: /var/lib/docker/containers + readOnly: true + - name: varlog + mountPath: /var/log + readOnly: true + # Necessary when using autodiscovery; avoid mounting it otherwise + # See: https://www.elastic.co/guide/en/beats/filebeat/7.17/configuration-autodiscover.html + - name: varrundockersock + mountPath: /var/run/docker.sock + readOnly: true + {{- if .Values.extraVolumeMounts | default .Values.daemonset.extraVolumeMounts }} +{{ toYaml (.Values.extraVolumeMounts | default .Values.daemonset.extraVolumeMounts ) | indent 8 }} + {{- end }} + {{- if .Values.extraContainers }} +{{ tpl .Values.extraContainers . | indent 6 }} + {{- end }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/templates/deployment.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/templates/deployment.yaml new file mode 100644 index 0000000..a8fd826 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/templates/deployment.yaml @@ -0,0 +1,157 @@ +# Deploy singleton instance in the whole cluster for some unique data sources, like aws input +{{- if .Values.deployment.enabled }} +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "filebeat.fullname" . }} + labels: + app: "{{ template "filebeat.fullname" . }}" + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: '{{ .Release.Service }}' + release: {{ .Release.Name }} + {{- if .Values.deployment.labels }} + {{- range $key, $value := .Values.deployment.labels }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- else }} + {{- range $key, $value := .Values.labels }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} + {{- if .Values.deployment.annotations }} + annotations: + {{- range $key, $value := .Values.deployment.annotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} +spec: + replicas: {{ .Values.replicas }} + selector: + matchLabels: + app: "{{ template "filebeat.fullname" . }}" + release: {{ .Release.Name | quote }} + template: + metadata: + annotations: + {{- range $key, $value := .Values.podAnnotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{/* This forces a restart if the configmap has changed */}} + {{- if or .Values.filebeatConfig .Values.deployment.filebeatConfig }} + configChecksum: {{ include (print .Template.BasePath "/configmap.yaml") . | sha256sum | trunc 63 }} + {{- end }} + labels: + app: '{{ template "filebeat.fullname" . }}' + chart: '{{ .Chart.Name }}-{{ .Chart.Version }}' + release: '{{ .Release.Name }}' + {{- if .Values.deployment.labels }} + {{- range $key, $value := .Values.deployment.labels }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- else }} + {{- range $key, $value := .Values.labels }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} + spec: + affinity: {{ toYaml .Values.deployment.affinity | nindent 8 }} + nodeSelector: {{ toYaml .Values.deployment.nodeSelector | nindent 8 }} + tolerations: {{ toYaml ( .Values.tolerations | default .Values.deployment.tolerations ) | nindent 8 }} + {{- if .Values.priorityClassName }} + priorityClassName: {{ .Values.priorityClassName }} + {{- end }} + serviceAccountName: {{ template "filebeat.serviceAccount" . }} + terminationGracePeriodSeconds: {{ .Values.terminationGracePeriod }} + {{- if .Values.deployment.hostAliases }} + hostAliases: {{ toYaml .Values.deployment.hostAliases | nindent 8 }} + {{- end }} + volumes: + {{- range .Values.secretMounts | default .Values.deployment.secretMounts }} + - name: {{ .name }} + secret: + secretName: {{ .secretName }} + {{- end }} + {{- if .Values.filebeatConfig }} + - name: filebeat-config + configMap: + defaultMode: 0600 + name: {{ template "filebeat.fullname" . }}-config + {{- else if .Values.deployment.filebeatConfig }} + - name: filebeat-config + configMap: + defaultMode: 0600 + name: {{ template "filebeat.fullname" . }}-deployment-config + {{- end }} + {{- if .Values.extraVolumes | default .Values.deployment.extraVolumes }} +{{ toYaml ( .Values.extraVolumes | default .Values.deployment.extraVolumes ) | indent 6 }} + {{- end }} + {{- if .Values.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | indent 8 }} + {{- end }} + {{- if .Values.extraInitContainers }} + initContainers: + # All the other beats accept a string here while + # filebeat accepts a valid yaml array. We're keeping + # this as a backwards compatible change, while adding + # also a way to pass a string as other templates to + # make these implementations consistent. + # https://github.com/elastic/helm-charts/issues/490 + {{- if eq "string" (printf "%T" .Values.extraInitContainers) }} +{{ tpl .Values.extraInitContainers . | indent 6 }} + {{- else }} +{{ toYaml .Values.extraInitContainers | indent 6 }} + {{- end }} + {{- end }} + containers: + - name: "filebeat" + image: "{{ .Values.image }}:{{ .Values.imageTag }}" + imagePullPolicy: "{{ .Values.imagePullPolicy }}" + args: + - "-e" + - "-E" + - "http.enabled=true" + livenessProbe: +{{ toYaml .Values.livenessProbe | indent 10 }} + readinessProbe: +{{ toYaml .Values.readinessProbe | indent 10 }} + resources: {{ toYaml ( .Values.resources | default .Values.deployment.resources ) | nindent 10 }} + env: + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace +{{- if .Values.extraEnvs | default .Values.deployment.extraEnvs }} +{{ toYaml ( .Values.extraEnvs | default .Values.deployment.extraEnvs ) | indent 8 }} +{{- end }} + envFrom: {{ toYaml ( .Values.envFrom | default .Values.deployment.envFrom ) | nindent 10 }} + securityContext: {{ toYaml ( .Values.podSecurityContext | default .Values.deployment.securityContext ) | nindent 10 }} + volumeMounts: + {{- range .Values.secretMounts | default .Values.deployment.secretMounts }} + - name: {{ .name }} + mountPath: {{ .path }} + {{- if .subPath }} + subPath: {{ .subPath }} + {{- end }} + {{- end }} + {{- range $path, $config := .Values.filebeatConfig }} + - name: filebeat-config + mountPath: /usr/share/filebeat/{{ $path }} + readOnly: true + subPath: {{ $path }} + {{ else }} + {{- range $path, $config := .Values.deployment.filebeatConfig }} + - name: filebeat-config + mountPath: /usr/share/filebeat/{{ $path }} + readOnly: true + subPath: {{ $path }} + {{- end }} + {{- end }} + {{- if .Values.extraVolumeMounts | default .Values.deployment.extraVolumeMounts }} +{{ toYaml ( .Values.extraVolumeMounts | default .Values.deployment.extraVolumeMounts ) | indent 8 }} + {{- end }} + {{- if .Values.extraContainers }} +{{ tpl .Values.extraContainers . | indent 6 }} + {{- end }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/templates/role.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/templates/role.yaml new file mode 100644 index 0000000..fe3cf92 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/templates/role.yaml @@ -0,0 +1,14 @@ +{{- if .Values.managedServiceAccount }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ template "filebeat.serviceAccount" . }}-role + labels: + app: "{{ template "filebeat.fullname" . }}" +rules: + - apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: ["get", "create", "update"] +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/templates/rolebinding.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/templates/rolebinding.yaml new file mode 100644 index 0000000..ff12168 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/templates/rolebinding.yaml @@ -0,0 +1,19 @@ +{{- if .Values.managedServiceAccount }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ template "filebeat.serviceAccount" . }}-role-binding + labels: + app: "{{ template "filebeat.fullname" . }}" + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service | quote }} + release: {{ .Release.Name | quote }} +roleRef: + kind: Role + name: {{ template "filebeat.serviceAccount" . }}-role + apiGroup: rbac.authorization.k8s.io +subjects: +- kind: ServiceAccount + name: {{ template "filebeat.serviceAccount" . }} + namespace: {{ .Release.Namespace }} +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/templates/serviceaccount.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/templates/serviceaccount.yaml new file mode 100644 index 0000000..8c0fcc6 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/templates/serviceaccount.yaml @@ -0,0 +1,15 @@ +{{- if .Values.managedServiceAccount }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "filebeat.serviceAccount" . }} + annotations: + {{- with .Values.serviceAccountAnnotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + labels: + app: "{{ template "filebeat.fullname" . }}" + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + heritage: {{ .Release.Service | quote }} + release: {{ .Release.Name | quote }} +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/values.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/values.yaml new file mode 100644 index 0000000..400795b --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/filebeat/values.yaml @@ -0,0 +1,243 @@ +--- +daemonset: + # Annotations to apply to the daemonset + annotations: {} + # additionals labels + labels: {} + affinity: {} + # Include the daemonset + enabled: true + # Extra environment variables for Filebeat container. + envFrom: [] + # - configMapRef: + # name: config-secret + extraEnvs: [] + # - name: MY_ENVIRONMENT_VAR + # value: the_value_goes_here + extraVolumes: + [] + # - name: extras + # emptyDir: {} + extraVolumeMounts: + [] + # - name: extras + # mountPath: /usr/share/extras + # readOnly: true + hostNetworking: false + # Allows you to add any config files in /usr/share/filebeat + # such as filebeat.yml for daemonset + filebeatConfig: + filebeat.yml: | + filebeat.inputs: + - type: container + paths: + - /var/log/containers/*.log + processors: + - add_kubernetes_metadata: + host: ${NODE_NAME} + matchers: + - logs_path: + logs_path: "/var/log/containers/" + + output.elasticsearch: + host: '${NODE_NAME}' + hosts: '${ELASTICSEARCH_HOSTS:elasticsearch-master:9200}' + # Only used when updateStrategy is set to "RollingUpdate" + maxUnavailable: 1 + nodeSelector: {} + # A list of secrets and their paths to mount inside the pod + # This is useful for mounting certificates for security other sensitive values + secretMounts: [] + # - name: filebeat-certificates + # secretName: filebeat-certificates + # path: /usr/share/filebeat/certs + # Various pod security context settings. Bear in mind that many of these have an impact on Filebeat functioning properly. + # + # - User that the container will execute as. Typically necessary to run as root (0) in order to properly collect host container logs. + # - Whether to execute the Filebeat containers as privileged containers. Typically not necessarily unless running within environments such as OpenShift. + securityContext: + runAsUser: 0 + privileged: false + resources: + requests: + cpu: "100m" + memory: "100Mi" + limits: + cpu: "1000m" + memory: "200Mi" + tolerations: [] + +deployment: + # Annotations to apply to the deployment + annotations: {} + # additionals labels + labels: {} + affinity: {} + # Include the deployment + enabled: false + # Extra environment variables for Filebeat container. + envFrom: [] + # - configMapRef: + # name: config-secret + extraEnvs: [] + # - name: MY_ENVIRONMENT_VAR + # value: the_value_goes_here + # Allows you to add any config files in /usr/share/filebeat + extraVolumes: [] + # - name: extras + # emptyDir: {} + extraVolumeMounts: [] + # - name: extras + # mountPath: /usr/share/extras + # readOnly: true + # such as filebeat.yml for deployment + filebeatConfig: + filebeat.yml: | + filebeat.inputs: + - type: tcp + max_message_size: 10MiB + host: "localhost:9000" + + output.elasticsearch: + host: '${NODE_NAME}' + hosts: '${ELASTICSEARCH_HOSTS:elasticsearch-master:9200}' + nodeSelector: {} + # A list of secrets and their paths to mount inside the pod + # This is useful for mounting certificates for security other sensitive values + secretMounts: [] + # - name: filebeat-certificates + # secretName: filebeat-certificates + # path: /usr/share/filebeat/certs + # + # - User that the container will execute as. + # Not necessary to run as root (0) as the Filebeat Deployment use cases do not need access to Kubernetes Node internals + # - Typically not necessarily unless running within environments such as OpenShift. + securityContext: + runAsUser: 0 + privileged: false + resources: + requests: + cpu: "100m" + memory: "100Mi" + limits: + cpu: "1000m" + memory: "200Mi" + tolerations: [] + +# Replicas being used for the filebeat deployment +replicas: 1 + +extraContainers: "" +# - name: dummy-init +# image: busybox +# command: ['echo', 'hey'] + +extraInitContainers: [] +# - name: dummy-init + +# Root directory where Filebeat will write data to in order to persist registry data across pod restarts (file position and other metadata). +hostPathRoot: /var/lib + +dnsConfig: {} +# options: +# - name: ndots +# value: "2" +hostAliases: [] +#- ip: "127.0.0.1" +# hostnames: +# - "foo.local" +# - "bar.local" +image: "docker.elastic.co/beats/filebeat" +imageTag: "7.17.1" +imagePullPolicy: "IfNotPresent" +imagePullSecrets: [] + +livenessProbe: + exec: + command: + - sh + - -c + - | + #!/usr/bin/env bash -e + curl --fail 127.0.0.1:5066 + failureThreshold: 3 + initialDelaySeconds: 10 + periodSeconds: 10 + timeoutSeconds: 5 + +readinessProbe: + exec: + command: + - sh + - -c + - | + #!/usr/bin/env bash -e + filebeat test output + failureThreshold: 3 + initialDelaySeconds: 10 + periodSeconds: 10 + timeoutSeconds: 5 + +# Whether this chart should self-manage its service account, role, and associated role binding. +managedServiceAccount: true + +clusterRoleRules: + - apiGroups: + - "" + resources: + - namespaces + - nodes + - pods + verbs: + - get + - list + - watch + - apiGroups: + - "apps" + resources: + - replicasets + verbs: + - get + - list + - watch + +podAnnotations: + {} + # iam.amazonaws.com/role: es-cluster + +# Custom service account override that the pod will use +serviceAccount: "" + +# Annotations to add to the ServiceAccount that is created if the serviceAccount value isn't set. +serviceAccountAnnotations: + {} + # eks.amazonaws.com/role-arn: arn:aws:iam::111111111111:role/k8s.clustername.namespace.serviceaccount + +# How long to wait for Filebeat pods to stop gracefully +terminationGracePeriod: 30 +# This is the PriorityClass settings as defined in +# https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/#priorityclass +priorityClassName: "" + +updateStrategy: RollingUpdate + +# Override various naming aspects of this chart +# Only edit these if you know what you're doing +nameOverride: "" +fullnameOverride: "" + +# DEPRECATED +affinity: {} +envFrom: [] +extraEnvs: [] +extraVolumes: [] +extraVolumeMounts: [] +# Allows you to add any config files in /usr/share/filebeat +# such as filebeat.yml for both daemonset and deployment +filebeatConfig: {} +nodeSelector: {} +podSecurityContext: {} +resources: {} +secretMounts: [] +tolerations: [] +labels: {} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/fluent-bit/.helmignore b/helm/openebs/charts/mayastor/charts/loki-stack/charts/fluent-bit/.helmignore new file mode 100644 index 0000000..50af031 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/fluent-bit/.helmignore @@ -0,0 +1,22 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/fluent-bit/Chart.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/fluent-bit/Chart.yaml new file mode 100644 index 0000000..63a0bd2 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/fluent-bit/Chart.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +appVersion: v2.1.0 +deprecated: true +description: Uses fluent-bit Loki go plugin for gathering logs and sending them to + Loki +home: https://grafana.com/loki +icon: https://raw.githubusercontent.com/grafana/loki/master/docs/sources/logo.png +kubeVersion: ^1.10.0-0 +maintainers: +- email: lokiproject@googlegroups.com + name: Loki Maintainers +name: fluent-bit +sources: +- https://github.com/grafana/loki +version: 2.3.1 diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/fluent-bit/README.md b/helm/openebs/charts/mayastor/charts/loki-stack/charts/fluent-bit/README.md new file mode 100644 index 0000000..9a9aa7a --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/fluent-bit/README.md @@ -0,0 +1,126 @@ +# Fluent Bit Loki chart + +DEPRECATED. Please use the official Fluent-Bit chart at https://github.com/fluent/helm-charts. + +This chart install the Fluent Bit application to ship logs to Loki. It defines daemonset on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. + +## Get Repo Info + +```console +helm repo add grafana https://grafana.github.io/helm-charts +helm repo update +``` + +_See [helm repo](https://helm.sh/docs/helm/helm_repo/) for command documentation._ + +## Installing the Chart + +> If you don't have `Helm` installed locally, or `Tiller` installed in your Kubernetes cluster, read the [Using Helm](https://docs.helm.sh/using_helm/) documentation to get started. +To install the chart with the release name `my-release` using our helm repository: + +```bash +helm repo add grafana https://grafana.github.io/helm-charts +helm upgrade --install my-release grafana/fluent-bit \ + --set loki.serviceName=loki.default.svc.cluster.local +``` + +If you deploy Loki with a custom namespace or service name, you must change the value above for `loki.serviceName` to the appropriate value. + +The command deploys Fluent Bit on the Kubernetes cluster with the default configuration. The [configuration](#configuration) section lists the parameters that can be configured during installation. + +To configure the chart to send to [Grafana Cloud](https://grafana.com/products/cloud) use: + +```bash +helm upgrade --install my-release grafana/fluent-bit \ + --set loki.serviceName=logs-us-west1.grafana.net,loki.servicePort=80,loki.serviceScheme=https \ + --set loki.user=2830,loki.password=1234 +``` + +> **Tip**: List all releases using `helm list` + +To install a custom tag use the following command: + +```bash +helm upgrade --install my-release grafana/fluent-bit \ + --set image.tag= +``` + +The full list of available tags on [docker hub](https://cloud.docker.com/u/grafana/repository/docker/grafana/fluent-bit-plugin-loki). + +Alternatively you can install the full [Loki stack](../loki-stack) (Loki + Fluent Bit) using: + +```bash +helm upgrade --install my-release grafana/loki-stack \ + --set fluent-bit.enabled=true,promtail.enabled=false +``` + +This will automatically configured the `loki.serviceName` configuration field to the newly created Loki instance. + +## RBAC + +By default, `rbac.create` is set to true. This enable RBAC support in Fluent Bit and must be true if RBAC is enabled in your cluster. + +The chart will take care of creating the required service accounts and roles for Fluent Bit. + +If you have RBAC disabled, or to put it another way, ABAC enabled, you should set this value to `false`. + +## Uninstalling the Chart + +To uninstall/delete the `my-release` deployment: + +```bash +helm delete my-release +``` + +The command removes all the Kubernetes components associated with the chart and deletes the release. + +## Configuration + +The following tables lists the configurable parameters of the Fluent Bit chart and their default values. + +For more details, read the [Fluent Bit documentation](../../../cmd/fluent-bit/README.md) + +| Parameter | Description | Default | +|--------------------------|----------------------------------------------------------------------------------------------------|----------------------------------| +| `loki.serviceName` | The address of the Loki service. | `"${RELEASE}-loki"` | +| `loki.servicePort` | The port of the Loki service. | `3100` | +| `loki.serviceScheme` | The scheme of the Loki service. | `http` | +| `loki.user` | The http basic auth username to access the Loki service. | | +| `loki.password` | The http basic auth password to access the Loki service. | | +| `config.port` | the Fluent Bit port to listen. (This is mainly used to serve metrics) | `2020` | +| `config.tenantID` | The tenantID used by default to push logs to Loki | `''` | +| `config.batchWait` | Time to wait before send a log batch to Loki, full or not. (unit: secs) | `1` | +| `config.batchSize` | Log batch size to send a log batch to Loki. (unit: bytes) | `10240` (10KiB) | +| `config.loglevel` | the Fluent Bit log level (debug,info,warn,error). | `warn` | +| `config.lineFormat` | The line format to use to send a record (json/key_value) | `json` | +| `config.k8sLoggingParser`| Allow Kubernetes Pods to suggest a pre-defined Parser. See [Official Fluent Bit documentation](https://docs.fluentbit.io/manual/filter/kubernetes#kubernetes-annotations). | `Off` | +| `config.k8sLoggingExclude`| Allow Kubernetes Pods to exclude their logs from the log processor. See [Official Fluent Bit documentation](https://docs.fluentbit.io/manual/pipeline/filters/kubernetes) | `Off` +| `config.memBufLimit` | Override the default Mem_Buf_Limit [Official Fluent Bit documentation](https://docs.fluentbit.io/manual/administration/backpressure#mem_buf_limit) | `5MB` +| `config.removeKeys` | The list of key to remove from each record | `[removeKeys,stream]` | +| `config.labels` | A set of labels to send for every log | `'{job="fluent-bit"}'` | +| `config.autoKubernetesLabels` | If set to true, it will add all Kubernetes labels to Loki labels | `false` | +| `config.labelMap` | Mapping of labels from a record. See [Fluent Bit documentation](../../../cmd/fluent-bit/README.md) | | +| `config.parsers` | Definition of extras fluent bit parsers. See [Official Fluent Bit documentation](https://docs.fluentbit.io/manual/filter/parser). The format is a sequence of mappings where each key is the same as the one in the [PARSER] section of parsers.conf file | `[]` | +| `config.extraOutputs` | Definition of extras fluent bit outputs. See [Official Fluent Bit documentation](https://docs.fluentbit.io/manual/pipeline/outputs/). The format is a sequence of mappings where each key is the same as the one in the [OUTPUT] | `[]` | +| `affinity` | [affinity][affinity] settings for pod assignment | `{}` | +| `annotations` | Annotations to add to Kubernetes resources. | `{}` | +| `deploymentStrategy` | The deployment strategy to use with the daemonset | `RollingUpdate` | +| `image.repository` | The Fluent Bit docker image repository | `grafana/fluent-bit-plugin-loki` | +| `image.tag` | The Fluent Bit docker image tag | `0.1` | +| `image.pullPolicy` | The Fluent Bit docker image pull policy | `IfNotPresent` | +| `nodeSelector` | Fluent Bit [node labels][nodeSelector] for pod assignment | `{}` | +| `podLabels` | additional Fluent Bit pod labels | `{}` | +| `podAnnotations` | additional Fluent Bit pod annotations | `Prometheus discovery` | +| `rbac.create` | Activate support for RBAC | `true` | +| `resources` | Resource requests/limit | | +| `tolerations` | [Toleration][toleration] labels for pod assignment | `no schedule on master nodes` | +| `volumes` | [Volume]([volumes]) to mount | `host containers log` | +| `volumeMounts` | Volume mount mapping | | +| `serviceMonitor.enabled` | Create a [Prometheus Operator](operator) serviceMonitor resource for Fluent Bit | `false` | + + +[toleration]: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ +[nodeSelector]: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector +[affinity]: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity +[volumes]: https://kubernetes.io/docs/concepts/storage/volumes/ +[operator]: https://github.com/coreos/prometheus-operator diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/fluent-bit/templates/NOTES.txt b/helm/openebs/charts/mayastor/charts/loki-stack/charts/fluent-bit/templates/NOTES.txt new file mode 100644 index 0000000..636aa92 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/fluent-bit/templates/NOTES.txt @@ -0,0 +1,11 @@ +!WARNING! !WARNING! !WARNING! !WARNING! !WARNING! + +Please use the official fluent-bit chart + +https://github.com/fluent/helm-charts + +!WARNING! !WARNING! !WARNING! !WARNING! !WARNING! + +Verify the application is working by running these commands: + kubectl --namespace {{ .Release.Namespace }} port-forward daemonset/{{ include "fluent-bit-loki.fullname" . }} {{ .Values.config.port }} + curl http://127.0.0.1:{{ .Values.config.port }}/api/v1/metrics/prometheus diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/fluent-bit/templates/_helpers.tpl b/helm/openebs/charts/mayastor/charts/loki-stack/charts/fluent-bit/templates/_helpers.tpl new file mode 100644 index 0000000..ddbbe85 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/fluent-bit/templates/_helpers.tpl @@ -0,0 +1,66 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "fluent-bit-loki.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 "fluent-bit-loki.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 "fluent-bit-loki.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create the name of the service account +*/}} +{{- define "fluent-bit-loki.serviceAccountName" -}} +{{- if .Values.serviceAccount.create -}} + {{ default (include "fluent-bit-loki.fullname" .) .Values.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +The service name to connect to Loki. Defaults to the same logic as "loki.fullname" +*/}} +{{- define "loki.serviceName" -}} +{{- if .Values.loki.serviceName -}} +{{- .Values.loki.serviceName -}} +{{- else if .Values.loki.fullnameOverride -}} +{{- .Values.loki.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default "loki" .Values.loki.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 "helm-toolkit.utils.joinListWithComma" -}} +{{- $local := dict "first" true -}} +{{- range $k, $v := . -}}{{- if not $local.first -}},{{- end -}}{{- $v -}}{{- $_ := set $local "first" false -}}{{- end -}} +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/fluent-bit/templates/clusterrole.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/fluent-bit/templates/clusterrole.yaml new file mode 100644 index 0000000..6b1a27c --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/fluent-bit/templates/clusterrole.yaml @@ -0,0 +1,17 @@ +{{- if .Values.rbac.create }} +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + labels: + app: {{ template "fluent-bit-loki.name" . }} + chart: {{ template "fluent-bit-loki.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + name: {{ template "fluent-bit-loki.fullname" . }}-clusterrole +rules: +- apiGroups: [""] # "" indicates the core API group + resources: + - namespaces + - pods + verbs: ["get", "watch", "list"] +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/fluent-bit/templates/clusterrolebinding.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/fluent-bit/templates/clusterrolebinding.yaml new file mode 100644 index 0000000..f825c97 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/fluent-bit/templates/clusterrolebinding.yaml @@ -0,0 +1,19 @@ +{{- if .Values.rbac.create }} +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ template "fluent-bit-loki.fullname" . }}-clusterrolebinding + labels: + app: {{ template "fluent-bit-loki.name" . }} + chart: {{ template "fluent-bit-loki.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +subjects: + - kind: ServiceAccount + name: {{ template "fluent-bit-loki.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: {{ template "fluent-bit-loki.fullname" . }}-clusterrole + apiGroup: rbac.authorization.k8s.io +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/fluent-bit/templates/configmap.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/fluent-bit/templates/configmap.yaml new file mode 100644 index 0000000..e9f3745 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/fluent-bit/templates/configmap.yaml @@ -0,0 +1,75 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "fluent-bit-loki.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "fluent-bit-loki.name" . }} + chart: {{ template "fluent-bit-loki.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +data: + fluent-bit.conf: |- + [SERVICE] + HTTP_Server On + HTTP_Listen 0.0.0.0 + HTTP_PORT {{ .Values.config.port }} + Flush 1 + Daemon Off + Log_Level {{ .Values.config.loglevel }} + Parsers_File parsers.conf + [INPUT] + Name tail + Tag kube.* + Path /var/log/containers/*.log + Parser docker + DB /run/fluent-bit/flb_kube.db + Mem_Buf_Limit {{ .Values.config.memBufLimit }} + Buffer_Chunk_size {{ .Values.config.bufChunkSize }} + Buffer_Max_size {{ .Values.config.bufMaxSize }} + [FILTER] + Name kubernetes + Match kube.* + Kube_URL https://kubernetes.default.svc:443 + Merge_Log On + K8S-Logging.Exclude {{ .Values.config.k8sLoggingExclude }} + K8S-Logging.Parser {{ .Values.config.k8sLoggingParser }} + [Output] + Name grafana-loki + Match * + {{- if and .Values.loki.user .Values.loki.password }} + Url {{ .Values.loki.serviceScheme }}://{{ .Values.loki.user }}:{{ .Values.loki.password }}@{{ include "loki.serviceName" . }}:{{ .Values.loki.servicePort }}{{ .Values.loki.servicePath }} + {{- else }} + Url {{ .Values.loki.serviceScheme }}://{{ include "loki.serviceName" . }}:{{ .Values.loki.servicePort }}{{ .Values.loki.servicePath }} + {{- end }} + TenantID {{ .Values.config.tenantID }} + BatchWait {{ .Values.config.batchWait }} + BatchSize {{ int .Values.config.batchSize }} + Labels {{ .Values.config.labels }} + RemoveKeys {{ include "helm-toolkit.utils.joinListWithComma" .Values.config.removeKeys }} + AutoKubernetesLabels {{ .Values.config.autoKubernetesLabels }} + LabelMapPath /fluent-bit/etc/labelmap.json + LineFormat {{ .Values.config.lineFormat }} + LogLevel {{ .Values.config.loglevel }} + {{- range $extraOutput := .Values.config.extraOutputs }} + [OUTPUT] + {{- range $key,$value := $extraOutput }} + {{ $key }} {{ $value }} + {{- end }} + {{- end }} + parsers.conf: |- + [PARSER] + Name docker + Format json + Time_Key time + Time_Format %Y-%m-%dT%H:%M:%S.%L + {{- range $parser:= .Values.config.parsers }} + [PARSER] + {{- range $key,$value := $parser }} + {{ $key }} {{ $value }} + {{- end }} + {{- end }} + + labelmap.json: |- + {{- .Values.config.labelMap | toPrettyJson | nindent 4}} + diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/fluent-bit/templates/daemonset.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/fluent-bit/templates/daemonset.yaml new file mode 100644 index 0000000..6652c29 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/fluent-bit/templates/daemonset.yaml @@ -0,0 +1,80 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: {{ template "fluent-bit-loki.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "fluent-bit-loki.name" . }} + chart: {{ template "fluent-bit-loki.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + annotations: + {{- toYaml .Values.annotations | nindent 4 }} +spec: + selector: + matchLabels: + app: {{ template "fluent-bit-loki.name" . }} + release: {{ .Release.Name }} + updateStrategy: + type: {{ .Values.deploymentStrategy }} + {{- if ne .Values.deploymentStrategy "RollingUpdate" }} + rollingUpdate: null + {{- end }} + template: + metadata: + labels: + app: {{ template "fluent-bit-loki.name" . }} + release: {{ .Release.Name }} + {{- with .Values.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + annotations: + checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} + {{- with .Values.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + serviceAccountName: {{ template "fluent-bit-loki.serviceAccountName" . }} + {{- if .Values.priorityClassName }} + priorityClassName: {{ .Values.priorityClassName }} + {{- end }} + {{- if .Values.image.pullSecrets }} + imagePullSecrets: + {{- range .Values.image.pullSecrets }} + - name: {{ . }} + {{- end }} + {{- end }} + containers: + - name: fluent-bit-loki + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + volumeMounts: + - name: config + mountPath: /fluent-bit/etc + - name: run + mountPath: /run/fluent-bit + {{- with .Values.volumeMounts }} + {{- toYaml . | nindent 12 }} + {{- end }} + ports: + - containerPort: {{ .Values.config.port }} + name: http-metrics + resources: + {{- toYaml .Values.resources | nindent 12 }} + nodeSelector: + {{- toYaml .Values.nodeSelector | nindent 8 }} + affinity: + {{- toYaml .Values.affinity | nindent 8 }} + tolerations: + {{- toYaml .Values.tolerations | nindent 8 }} + terminationGracePeriodSeconds: 10 + volumes: + - name: config + configMap: + name: {{ template "fluent-bit-loki.fullname" . }} + - name: run + hostPath: + path: /run/fluent-bit + {{- with .Values.volumes }} + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/fluent-bit/templates/podsecuritypolicy.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/fluent-bit/templates/podsecuritypolicy.yaml new file mode 100644 index 0000000..a38514e --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/fluent-bit/templates/podsecuritypolicy.yaml @@ -0,0 +1,34 @@ +{{- if .Values.rbac.pspEnabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "fluent-bit-loki.fullname" . }} + labels: + app: {{ template "fluent-bit-loki.name" . }} + chart: {{ template "fluent-bit-loki.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +spec: + privileged: false + allowPrivilegeEscalation: false + volumes: + - 'secret' + - 'configMap' + - 'hostPath' + - 'projected' + - 'downwardAPI' + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'RunAsAny' + fsGroup: + rule: 'RunAsAny' + readOnlyRootFilesystem: true + requiredDropCapabilities: + - ALL +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/fluent-bit/templates/role.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/fluent-bit/templates/role.yaml new file mode 100644 index 0000000..036c288 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/fluent-bit/templates/role.yaml @@ -0,0 +1,19 @@ +{{- if .Values.rbac.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ template "fluent-bit-loki.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "fluent-bit-loki.name" . }} + chart: {{ template "fluent-bit-loki.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +{{- if .Values.rbac.pspEnabled }} +rules: +- apiGroups: ['extensions'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: [{{ template "fluent-bit-loki.fullname" . }}] +{{- end }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/fluent-bit/templates/rolebinding.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/fluent-bit/templates/rolebinding.yaml new file mode 100644 index 0000000..90315e8 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/fluent-bit/templates/rolebinding.yaml @@ -0,0 +1,19 @@ +{{- if .Values.rbac.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ template "fluent-bit-loki.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "fluent-bit-loki.name" . }} + chart: {{ template "fluent-bit-loki.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "fluent-bit-loki.fullname" . }} +subjects: +- kind: ServiceAccount + name: {{ template "fluent-bit-loki.serviceAccountName" . }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/fluent-bit/templates/service-headless.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/fluent-bit/templates/service-headless.yaml new file mode 100644 index 0000000..332d106 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/fluent-bit/templates/service-headless.yaml @@ -0,0 +1,22 @@ +{{- if .Values.serviceMonitor.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "fluent-bit-loki.fullname" . }}-headless + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "fluent-bit-loki.name" . }} + chart: {{ template "fluent-bit-loki.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +spec: + clusterIP: None + ports: + - port: {{ .Values.config.port }} + protocol: TCP + name: http-metrics + targetPort: http-metrics + selector: + app: {{ template "fluent-bit-loki.name" . }} + release: {{ .Release.Name }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/fluent-bit/templates/serviceaccount.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/fluent-bit/templates/serviceaccount.yaml new file mode 100644 index 0000000..7933b61 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/fluent-bit/templates/serviceaccount.yaml @@ -0,0 +1,12 @@ +{{- if .Values.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app: {{ template "fluent-bit-loki.name" . }} + chart: {{ template "fluent-bit-loki.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + name: {{ template "fluent-bit-loki.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/fluent-bit/templates/servicemonitor.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/fluent-bit/templates/servicemonitor.yaml new file mode 100644 index 0000000..162f960 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/fluent-bit/templates/servicemonitor.yaml @@ -0,0 +1,35 @@ +{{- if .Values.serviceMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "fluent-bit-loki.fullname" . }} + labels: + app: {{ template "fluent-bit-loki.name" . }} + chart: {{ template "fluent-bit-loki.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + {{- if .Values.serviceMonitor.additionalLabels }} +{{ toYaml .Values.serviceMonitor.additionalLabels | indent 4 }} + {{- end }} + {{- if .Values.serviceMonitor.annotations }} + annotations: +{{ toYaml .Values.serviceMonitor.annotations | indent 4 }} + {{- end }} +spec: + selector: + matchLabels: + app: {{ template "fluent-bit-loki.name" . }} + release: {{ .Release.Name | quote }} + namespaceSelector: + matchNames: + - {{ .Release.Namespace | quote }} + endpoints: + - port: http-metrics + path: /api/v1/metrics/prometheus + {{- if .Values.serviceMonitor.interval }} + interval: {{ .Values.serviceMonitor.interval }} + {{- end }} + {{- if .Values.serviceMonitor.scrapeTimeout }} + scrapeTimeout: {{ .Values.serviceMonitor.scrapeTimeout }} + {{- end }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/fluent-bit/values.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/fluent-bit/values.yaml new file mode 100644 index 0000000..6cacf72 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/fluent-bit/values.yaml @@ -0,0 +1,122 @@ +--- +loki: + serviceName: "" # Defaults to "${RELEASE}-loki" if not set + servicePort: 3100 + serviceScheme: http + servicePath: /api/prom/push + # user: user + # password: pass +config: + port: 2020 + tenantID: '""' + batchWait: 1 + batchSize: 1048576 + loglevel: warn + lineFormat: json + k8sLoggingExclude: "Off" + k8sLoggingParser: "Off" + memBufLimit: "5MB" + bufChunkSize: "32k" + bufMaxSize: "32k" + removeKeys: + - kubernetes + - stream + autoKubernetesLabels: false + labels: '{job="fluent-bit"}' + labelMap: + kubernetes: + namespace_name: namespace + labels: + app: app + release: release + host: node + container_name: container + pod_name: instance + stream: stream + # parsers: # Allow to define custom parsers. The key here is the same as the one in the [PARSER] section of parsers.conf file. + # - Name: json + # Format: json + # Time_Key: time + # Time_Format: "%d/%b/%Y:%H:%M:%S %z" + + # extraOutputs: # Allow to define extra outputs in addition to the one automatically created + # - Name: stdout + # Format: json + # json_date_format: time + +affinity: {} + +annotations: {} + +deploymentStrategy: RollingUpdate + +image: + repository: grafana/fluent-bit-plugin-loki + tag: 2.1.0-amd64 + pullPolicy: IfNotPresent + ## Optionally specify an array of imagePullSecrets. + ## Secrets must be present in the namespace. + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ + # pullSecrets: + # - myRegistrKeySecretName + +nameOverride: fluent-bit-loki + +## Node labels for pod assignment +## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ +nodeSelector: {} + +## Pod Labels +podLabels: {} + +podAnnotations: + prometheus.io/scrape: "true" + prometheus.io/port: "2020" + prometheus.io/path: /api/v1/metrics/prometheus + +## Assign a PriorityClassName to pods if set +# priorityClassName: + +rbac: + create: true + pspEnabled: true + +resources: + limits: + memory: 100Mi + requests: + cpu: 100m + memory: 100Mi + +serviceAccount: + create: true + name: + +## Tolerations for pod assignment +## ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ +tolerations: +- key: node-role.kubernetes.io/master + effect: NoSchedule + +# Extra volumes to scrape logs from +volumes: +- name: varlog + hostPath: + path: /var/log +- name: varlibdockercontainers + hostPath: + path: /var/lib/docker/containers + +volumeMounts: +- name: varlog + mountPath: /var/log +- name: varlibdockercontainers + mountPath: /var/lib/docker/containers + readOnly: true + +serviceMonitor: + enabled: false + interval: "" + additionalLabels: {} + annotations: {} + # scrapeTimeout: 10s diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/.helmignore b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/.helmignore new file mode 100644 index 0000000..8cade13 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/.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 +*~ +# Various IDEs +.vscode +.project +.idea/ +*.tmproj +OWNERS diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/Chart.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/Chart.yaml new file mode 100644 index 0000000..9e570a4 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/Chart.yaml @@ -0,0 +1,22 @@ +apiVersion: v2 +appVersion: 8.4.2 +description: The leading tool for querying and visualizing time series and metrics. +home: https://grafana.net +icon: https://raw.githubusercontent.com/grafana/grafana/master/public/img/logo_transparent_400x.png +kubeVersion: ^1.8.0-0 +maintainers: +- email: zanhsieh@gmail.com + name: zanhsieh +- email: rluckie@cisco.com + name: rtluckie +- email: maor.friedman@redhat.com + name: maorfr +- email: miroslav.hadzhiev@gmail.com + name: Xtigyro +- email: mail@torstenwalter.de + name: torstenwalter +name: grafana +sources: +- https://github.com/grafana/grafana +type: application +version: 6.24.1 diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/README.md b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/README.md new file mode 100644 index 0000000..3d426b3 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/README.md @@ -0,0 +1,561 @@ +# Grafana Helm Chart + +* Installs the web dashboarding system [Grafana](http://grafana.org/) + +## Get Repo Info + +```console +helm repo add grafana https://grafana.github.io/helm-charts +helm repo update +``` + +_See [helm repo](https://helm.sh/docs/helm/helm_repo/) for command documentation._ + +## Installing the Chart + +To install the chart with the release name `my-release`: + +```console +helm install my-release grafana/grafana +``` + +## Uninstalling the Chart + +To uninstall/delete the my-release deployment: + +```console +helm delete my-release +``` + +The command removes all the Kubernetes components associated with the chart and deletes the release. + +## Upgrading an existing Release to a new major version + +A major chart version change (like v1.2.3 -> v2.0.0) indicates that there is an +incompatible breaking change needing manual actions. + +### To 4.0.0 (And 3.12.1) + +This version requires Helm >= 2.12.0. + +### To 5.0.0 + +You have to add --force to your helm upgrade command as the labels of the chart have changed. + +### To 6.0.0 + +This version requires Helm >= 3.1.0. + +## Configuration + +| Parameter | Description | Default | +|-------------------------------------------|-----------------------------------------------|---------------------------------------------------------| +| `replicas` | Number of nodes | `1` | +| `podDisruptionBudget.minAvailable` | Pod disruption minimum available | `nil` | +| `podDisruptionBudget.maxUnavailable` | Pod disruption maximum unavailable | `nil` | +| `deploymentStrategy` | Deployment strategy | `{ "type": "RollingUpdate" }` | +| `livenessProbe` | Liveness Probe settings | `{ "httpGet": { "path": "/api/health", "port": 3000 } "initialDelaySeconds": 60, "timeoutSeconds": 30, "failureThreshold": 10 }` | +| `readinessProbe` | Readiness Probe settings | `{ "httpGet": { "path": "/api/health", "port": 3000 } }`| +| `securityContext` | Deployment securityContext | `{"runAsUser": 472, "runAsGroup": 472, "fsGroup": 472}` | +| `priorityClassName` | Name of Priority Class to assign pods | `nil` | +| `image.repository` | Image repository | `grafana/grafana` | +| `image.tag` | Image tag (`Must be >= 5.0.0`) | `8.2.5` | +| `image.sha` | Image sha (optional) | `2acf04c016c77ca2e89af3536367ce847ee326effb933121881c7c89781051d3` | +| `image.pullPolicy` | Image pull policy | `IfNotPresent` | +| `image.pullSecrets` | Image pull secrets | `{}` | +| `service.enabled` | Enable grafana service | `true` | +| `service.type` | Kubernetes service type | `ClusterIP` | +| `service.port` | Kubernetes port where service is exposed | `80` | +| `service.portName` | Name of the port on the service | `service` | +| `service.targetPort` | Internal service is port | `3000` | +| `service.nodePort` | Kubernetes service nodePort | `nil` | +| `service.annotations` | Service annotations | `{}` | +| `service.labels` | Custom labels | `{}` | +| `service.clusterIP` | internal cluster service IP | `nil` | +| `service.loadBalancerIP` | IP address to assign to load balancer (if supported) | `nil` | +| `service.loadBalancerSourceRanges` | list of IP CIDRs allowed access to lb (if supported) | `[]` | +| `service.externalIPs` | service external IP addresses | `[]` | +| `headlessService` | Create a headless service | `false` | +| `extraExposePorts` | Additional service ports for sidecar containers| `[]` | +| `hostAliases` | adds rules to the pod's /etc/hosts | `[]` | +| `ingress.enabled` | Enables Ingress | `false` | +| `ingress.annotations` | Ingress annotations (values are templated) | `{}` | +| `ingress.labels` | Custom labels | `{}` | +| `ingress.path` | Ingress accepted path | `/` | +| `ingress.pathType` | Ingress type of path | `Prefix` | +| `ingress.hosts` | Ingress accepted hostnames | `["chart-example.local"]` | +| `ingress.extraPaths` | Ingress extra paths to prepend to every host configuration. Useful when configuring [custom actions with AWS ALB Ingress Controller](https://kubernetes-sigs.github.io/aws-alb-ingress-controller/guide/ingress/annotation/#actions). Requires `ingress.hosts` to have one or more host entries. | `[]` | +| `ingress.tls` | Ingress TLS configuration | `[]` | +| `resources` | CPU/Memory resource requests/limits | `{}` | +| `nodeSelector` | Node labels for pod assignment | `{}` | +| `tolerations` | Toleration labels for pod assignment | `[]` | +| `affinity` | Affinity settings for pod assignment | `{}` | +| `extraInitContainers` | Init containers to add to the grafana pod | `{}` | +| `extraContainers` | Sidecar containers to add to the grafana pod | `""` | +| `extraContainerVolumes` | Volumes that can be mounted in sidecar containers | `[]` | +| `extraLabels` | Custom labels for all manifests | `{}` | +| `schedulerName` | Name of the k8s scheduler (other than default) | `nil` | +| `persistence.enabled` | Use persistent volume to store data | `false` | +| `persistence.type` | Type of persistence (`pvc` or `statefulset`) | `pvc` | +| `persistence.size` | Size of persistent volume claim | `10Gi` | +| `persistence.existingClaim` | Use an existing PVC to persist data | `nil` | +| `persistence.storageClassName` | Type of persistent volume claim | `nil` | +| `persistence.accessModes` | Persistence access modes | `[ReadWriteOnce]` | +| `persistence.annotations` | PersistentVolumeClaim annotations | `{}` | +| `persistence.finalizers` | PersistentVolumeClaim finalizers | `[ "kubernetes.io/pvc-protection" ]` | +| `persistence.subPath` | Mount a sub dir of the persistent volume | `nil` | +| `persistence.inMemory.enabled` | If persistence is not enabled, whether to mount the local storage in-memory to improve performance | `false` | +| `persistence.inMemory.sizeLimit` | SizeLimit for the in-memory local storage | `nil` | +| `initChownData.enabled` | If false, don't reset data ownership at startup | true | +| `initChownData.image.repository` | init-chown-data container image repository | `busybox` | +| `initChownData.image.tag` | init-chown-data container image tag | `1.31.1` | +| `initChownData.image.sha` | init-chown-data container image sha (optional)| `""` | +| `initChownData.image.pullPolicy` | init-chown-data container image pull policy | `IfNotPresent` | +| `initChownData.resources` | init-chown-data pod resource requests & limits | `{}` | +| `schedulerName` | Alternate scheduler name | `nil` | +| `env` | Extra environment variables passed to pods | `{}` | +| `envValueFrom` | Environment variables from alternate sources. See the API docs on [EnvVarSource](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#envvarsource-v1-core) for format details. | `{}` | +| `envFromSecret` | Name of a Kubernetes secret (must be manually created in the same namespace) containing values to be added to the environment. Can be templated | `""` | +| `envRenderSecret` | Sensible environment variables passed to pods and stored as secret | `{}` | +| `enableServiceLinks` | Inject Kubernetes services as environment variables. | `true` | +| `extraSecretMounts` | Additional grafana server secret mounts | `[]` | +| `extraVolumeMounts` | Additional grafana server volume mounts | `[]` | +| `extraConfigmapMounts` | Additional grafana server configMap volume mounts | `[]` | +| `extraEmptyDirMounts` | Additional grafana server emptyDir volume mounts | `[]` | +| `plugins` | Plugins to be loaded along with Grafana | `[]` | +| `datasources` | Configure grafana datasources (passed through tpl) | `{}` | +| `notifiers` | Configure grafana notifiers | `{}` | +| `dashboardProviders` | Configure grafana dashboard providers | `{}` | +| `dashboards` | Dashboards to import | `{}` | +| `dashboardsConfigMaps` | ConfigMaps reference that contains dashboards | `{}` | +| `grafana.ini` | Grafana's primary configuration | `{}` | +| `ldap.enabled` | Enable LDAP authentication | `false` | +| `ldap.existingSecret` | The name of an existing secret containing the `ldap.toml` file, this must have the key `ldap-toml`. | `""` | +| `ldap.config` | Grafana's LDAP configuration | `""` | +| `annotations` | Deployment annotations | `{}` | +| `labels` | Deployment labels | `{}` | +| `podAnnotations` | Pod annotations | `{}` | +| `podLabels` | Pod labels | `{}` | +| `podPortName` | Name of the grafana port on the pod | `grafana` | +| `sidecar.image.repository` | Sidecar image repository | `quay.io/kiwigrid/k8s-sidecar` | +| `sidecar.image.tag` | Sidecar image tag | `1.15.6` | +| `sidecar.image.sha` | Sidecar image sha (optional) | `""` | +| `sidecar.imagePullPolicy` | Sidecar image pull policy | `IfNotPresent` | +| `sidecar.resources` | Sidecar resources | `{}` | +| `sidecar.securityContext` | Sidecar securityContext | `{}` | +| `sidecar.enableUniqueFilenames` | Sets the kiwigrid/k8s-sidecar UNIQUE_FILENAMES environment variable. If set to `true` the sidecar will create unique filenames where duplicate data keys exist between ConfigMaps and/or Secrets within the same or multiple Namespaces. | `false` | +| `sidecar.dashboards.enabled` | Enables the cluster wide search for dashboards and adds/updates/deletes them in grafana | `false` | +| `sidecar.dashboards.SCProvider` | Enables creation of sidecar provider | `true` | +| `sidecar.dashboards.provider.name` | Unique name of the grafana provider | `sidecarProvider` | +| `sidecar.dashboards.provider.orgid` | Id of the organisation, to which the dashboards should be added | `1` | +| `sidecar.dashboards.provider.folder` | Logical folder in which grafana groups dashboards | `""` | +| `sidecar.dashboards.provider.disableDelete` | Activate to avoid the deletion of imported dashboards | `false` | +| `sidecar.dashboards.provider.allowUiUpdates` | Allow updating provisioned dashboards from the UI | `false` | +| `sidecar.dashboards.provider.type` | Provider type | `file` | +| `sidecar.dashboards.provider.foldersFromFilesStructure` | Allow Grafana to replicate dashboard structure from filesystem. | `false` | +| `sidecar.dashboards.watchMethod` | Method to use to detect ConfigMap changes. With WATCH the sidecar will do a WATCH requests, with SLEEP it will list all ConfigMaps, then sleep for 60 seconds. | `WATCH` | +| `sidecar.skipTlsVerify` | Set to true to skip tls verification for kube api calls | `nil` | +| `sidecar.dashboards.label` | Label that config maps with dashboards should have to be added | `grafana_dashboard` | +| `sidecar.dashboards.labelValue` | Label value that config maps with dashboards should have to be added | `nil` | +| `sidecar.dashboards.folder` | Folder in the pod that should hold the collected dashboards (unless `sidecar.dashboards.defaultFolderName` is set). This path will be mounted. | `/tmp/dashboards` | +| `sidecar.dashboards.folderAnnotation` | The annotation the sidecar will look for in configmaps to override the destination folder for files | `nil` | +| `sidecar.dashboards.defaultFolderName` | The default folder name, it will create a subfolder under the `sidecar.dashboards.folder` and put dashboards in there instead | `nil` | +| `sidecar.dashboards.searchNamespace` | Namespaces list. If specified, the sidecar will search for dashboards config-maps inside these namespaces.Otherwise the namespace in which the sidecar is running will be used.It's also possible to specify ALL to search in all namespaces. | `nil` | +| `sidecar.dashboards.script` | Absolute path to shell script to execute after a configmap got reloaded. | `nil` | +| `sidecar.dashboards.resource` | Should the sidecar looks into secrets, configmaps or both. | `both` | +| `sidecar.dashboards.extraMounts` | Additional dashboard sidecar volume mounts. | `[]` | +| `sidecar.datasources.enabled` | Enables the cluster wide search for datasources and adds/updates/deletes them in grafana |`false` | +| `sidecar.datasources.label` | Label that config maps with datasources should have to be added | `grafana_datasource` | +| `sidecar.datasources.labelValue` | Label value that config maps with datasources should have to be added | `nil` | +| `sidecar.datasources.searchNamespace` | Namespaces list. If specified, the sidecar will search for datasources config-maps inside these namespaces.Otherwise the namespace in which the sidecar is running will be used.It's also possible to specify ALL to search in all namespaces. | `nil` | +| `sidecar.datasources.resource` | Should the sidecar looks into secrets, configmaps or both. | `both` | +| `sidecar.datasources.reloadURL` | Full url of datasource configuration reload API endpoint, to invoke after a config-map change | `"http://localhost:3000/api/admin/provisioning/datasources/reload"` | +| `sidecar.datasources.skipReload` | Enabling this omits defining the REQ_URL and REQ_METHOD environment variables | `false` | +| `sidecar.notifiers.enabled` | Enables the cluster wide search for notifiers and adds/updates/deletes them in grafana | `false` | +| `sidecar.notifiers.label` | Label that config maps with notifiers should have to be added | `grafana_notifier` | +| `sidecar.notifiers.searchNamespace` | Namespaces list. If specified, the sidecar will search for notifiers config-maps (or secrets) inside these namespaces.Otherwise the namespace in which the sidecar is running will be used.It's also possible to specify ALL to search in all namespaces. | `nil` | +| `sidecar.notifiers.resource` | Should the sidecar looks into secrets, configmaps or both. | `both` | +| `smtp.existingSecret` | The name of an existing secret containing the SMTP credentials. | `""` | +| `smtp.userKey` | The key in the existing SMTP secret containing the username. | `"user"` | +| `smtp.passwordKey` | The key in the existing SMTP secret containing the password. | `"password"` | +| `admin.existingSecret` | The name of an existing secret containing the admin credentials. | `""` | +| `admin.userKey` | The key in the existing admin secret containing the username. | `"admin-user"` | +| `admin.passwordKey` | The key in the existing admin secret containing the password. | `"admin-password"` | +| `serviceAccount.autoMount` | Automount the service account token in the pod| `true` | +| `serviceAccount.annotations` | ServiceAccount annotations | | +| `serviceAccount.create` | Create service account | `true` | +| `serviceAccount.name` | Service account name to use, when empty will be set to created account if `serviceAccount.create` is set else to `default` | `` | +| `serviceAccount.nameTest` | Service account name to use for test, when empty will be set to created account if `serviceAccount.create` is set else to `default` | `nil` | +| `rbac.create` | Create and use RBAC resources | `true` | +| `rbac.namespaced` | Creates Role and Rolebinding instead of the default ClusterRole and ClusteRoleBindings for the grafana instance | `false` | +| `rbac.useExistingRole` | Set to a rolename to use existing role - skipping role creating - but still doing serviceaccount and rolebinding to the rolename set here. | `nil` | +| `rbac.pspEnabled` | Create PodSecurityPolicy (with `rbac.create`, grant roles permissions as well) | `true` | +| `rbac.pspUseAppArmor` | Enforce AppArmor in created PodSecurityPolicy (requires `rbac.pspEnabled`) | `true` | +| `rbac.extraRoleRules` | Additional rules to add to the Role | [] | +| `rbac.extraClusterRoleRules` | Additional rules to add to the ClusterRole | [] | +| `command` | Define command to be executed by grafana container at startup | `nil` | +| `testFramework.enabled` | Whether to create test-related resources | `true` | +| `testFramework.image` | `test-framework` image repository. | `bats/bats` | +| `testFramework.tag` | `test-framework` image tag. | `v1.4.1` | +| `testFramework.imagePullPolicy` | `test-framework` image pull policy. | `IfNotPresent` | +| `testFramework.securityContext` | `test-framework` securityContext | `{}` | +| `downloadDashboards.env` | Environment variables to be passed to the `download-dashboards` container | `{}` | +| `downloadDashboards.envFromSecret` | Name of a Kubernetes secret (must be manually created in the same namespace) containing values to be added to the environment. Can be templated | `""` | +| `downloadDashboards.resources` | Resources of `download-dashboards` container | `{}` | +| `downloadDashboardsImage.repository` | Curl docker image repo | `curlimages/curl` | +| `downloadDashboardsImage.tag` | Curl docker image tag | `7.73.0` | +| `downloadDashboardsImage.sha` | Curl docker image sha (optional) | `""` | +| `downloadDashboardsImage.pullPolicy` | Curl docker image pull policy | `IfNotPresent` | +| `namespaceOverride` | Override the deployment namespace | `""` (`Release.Namespace`) | +| `serviceMonitor.enabled` | Use servicemonitor from prometheus operator | `false` | +| `serviceMonitor.namespace` | Namespace this servicemonitor is installed in | | +| `serviceMonitor.interval` | How frequently Prometheus should scrape | `1m` | +| `serviceMonitor.path` | Path to scrape | `/metrics` | +| `serviceMonitor.scheme` | Scheme to use for metrics scraping | `http` | +| `serviceMonitor.tlsConfig` | TLS configuration block for the endpoint | `{}` | +| `serviceMonitor.labels` | Labels for the servicemonitor passed to Prometheus Operator | `{}` | +| `serviceMonitor.scrapeTimeout` | Timeout after which the scrape is ended | `30s` | +| `serviceMonitor.relabelings` | MetricRelabelConfigs to apply to samples before ingestion. | `[]` | +| `revisionHistoryLimit` | Number of old ReplicaSets to retain | `10` | +| `imageRenderer.enabled` | Enable the image-renderer deployment & service | `false` | +| `imageRenderer.image.repository` | image-renderer Image repository | `grafana/grafana-image-renderer` | +| `imageRenderer.image.tag` | image-renderer Image tag | `latest` | +| `imageRenderer.image.sha` | image-renderer Image sha (optional) | `""` | +| `imageRenderer.image.pullPolicy` | image-renderer ImagePullPolicy | `Always` | +| `imageRenderer.env` | extra env-vars for image-renderer | `{}` | +| `imageRenderer.serviceAccountName` | image-renderer deployment serviceAccountName | `""` | +| `imageRenderer.securityContext` | image-renderer deployment securityContext | `{}` | +| `imageRenderer.hostAliases` | image-renderer deployment Host Aliases | `[]` | +| `imageRenderer.priorityClassName` | image-renderer deployment priority class | `''` | +| `imageRenderer.service.enabled` | Enable the image-renderer service | `true` | +| `imageRenderer.service.portName` | image-renderer service port name | `http` | +| `imageRenderer.service.port` | image-renderer service port used by both service and deployment | `8081` | +| `imageRenderer.grafanaProtocol` | Protocol to use for image renderer callback url | `http` | +| `imageRenderer.grafanaSubPath` | Grafana sub path to use for image renderer callback url | `''` | +| `imageRenderer.podPortName` | name of the image-renderer port on the pod | `http` | +| `imageRenderer.revisionHistoryLimit` | number of image-renderer replica sets to keep | `10` | +| `imageRenderer.networkPolicy.limitIngress` | Enable a NetworkPolicy to limit inbound traffic from only the created grafana pods | `true` | +| `imageRenderer.networkPolicy.limitEgress` | Enable a NetworkPolicy to limit outbound traffic to only the created grafana pods | `false` | +| `imageRenderer.resources` | Set resource limits for image-renderer pdos | `{}` | +| `networkPolicy.enabled` | Enable creation of NetworkPolicy resources. | `false` | +| `networkPolicy.allowExternal` | Don't require client label for connections | `true` | +| `networkPolicy.explicitNamespacesSelector` | A Kubernetes LabelSelector to explicitly select namespaces from which traffic could be allowed | `{}` | +| `enableKubeBackwardCompatibility` | Enable backward compatibility of kubernetes where pod's defintion version below 1.13 doesn't have the enableServiceLinks option | `false` | + + + +### Example ingress with path + +With grafana 6.3 and above +```yaml +grafana.ini: + server: + domain: monitoring.example.com + root_url: "%(protocol)s://%(domain)s/grafana" + serve_from_sub_path: true +ingress: + enabled: true + hosts: + - "monitoring.example.com" + path: "/grafana" +``` + +### Example of extraVolumeMounts + +Volume can be type persistentVolumeClaim or hostPath but not both at same time. +If none existingClaim or hostPath argument is givent then type is emptyDir. + +```yaml +- extraVolumeMounts: + - name: plugins + mountPath: /var/lib/grafana/plugins + subPath: configs/grafana/plugins + existingClaim: existing-grafana-claim + readOnly: false + - name: dashboards + mountPath: /var/lib/grafana/dashboards + hostPath: /usr/shared/grafana/dashboards + readOnly: false +``` + +## Import dashboards + +There are a few methods to import dashboards to Grafana. Below are some examples and explanations as to how to use each method: + +```yaml +dashboards: + default: + some-dashboard: + json: | + { + "annotations": + + ... + # Complete json file here + ... + + "title": "Some Dashboard", + "uid": "abcd1234", + "version": 1 + } + custom-dashboard: + # This is a path to a file inside the dashboards directory inside the chart directory + file: dashboards/custom-dashboard.json + prometheus-stats: + # Ref: https://grafana.com/dashboards/2 + gnetId: 2 + revision: 2 + datasource: Prometheus + local-dashboard: + url: https://raw.githubusercontent.com/user/repository/master/dashboards/dashboard.json +``` + +## BASE64 dashboards + +Dashboards could be stored on a server that does not return JSON directly and instead of it returns a Base64 encoded file (e.g. Gerrit) +A new parameter has been added to the url use case so if you specify a b64content value equals to true after the url entry a Base64 decoding is applied before save the file to disk. +If this entry is not set or is equals to false not decoding is applied to the file before saving it to disk. + +### Gerrit use case + +Gerrit API for download files has the following schema: where {project-name} and +{file-id} usually has '/' in their values and so they MUST be replaced by %2F so if project-name is user/repo, branch-id is master and file-id is equals to dir1/dir2/dashboard +the url value is + +## Sidecar for dashboards + +If the parameter `sidecar.dashboards.enabled` is set, a sidecar container is deployed in the grafana +pod. This container watches all configmaps (or secrets) in the cluster and filters out the ones with +a label as defined in `sidecar.dashboards.label`. The files defined in those configmaps are written +to a folder and accessed by grafana. Changes to the configmaps are monitored and the imported +dashboards are deleted/updated. + +A recommendation is to use one configmap per dashboard, as a reduction of multiple dashboards inside +one configmap is currently not properly mirrored in grafana. + +Example dashboard config: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: sample-grafana-dashboard + labels: + grafana_dashboard: "1" +data: + k8s-dashboard.json: |- + [...] +``` + +## Sidecar for datasources + +If the parameter `sidecar.datasources.enabled` is set, an init container is deployed in the grafana +pod. This container lists all secrets (or configmaps, though not recommended) in the cluster and +filters out the ones with a label as defined in `sidecar.datasources.label`. The files defined in +those secrets are written to a folder and accessed by grafana on startup. Using these yaml files, +the data sources in grafana can be imported. + +Secrets are recommended over configmaps for this usecase because datasources usually contain private +data like usernames and passwords. Secrets are the more appropriate cluster resource to manage those. + +Example values to add a datasource adapted from [Grafana](http://docs.grafana.org/administration/provisioning/#example-datasource-config-file): + +```yaml +datasources: + datasources.yaml: + apiVersion: 1 + datasources: + # name of the datasource. Required + - name: Graphite + # datasource type. Required + type: graphite + # access mode. proxy or direct (Server or Browser in the UI). Required + access: proxy + # org id. will default to orgId 1 if not specified + orgId: 1 + # url + url: http://localhost:8080 + # database password, if used + password: + # database user, if used + user: + # database name, if used + database: + # enable/disable basic auth + basicAuth: + # basic auth username + basicAuthUser: + # basic auth password + basicAuthPassword: + # enable/disable with credentials headers + withCredentials: + # mark as default datasource. Max one per org + isDefault: + # fields that will be converted to json and stored in json_data + jsonData: + graphiteVersion: "1.1" + tlsAuth: true + tlsAuthWithCACert: true + # json object of data that will be encrypted. + secureJsonData: + tlsCACert: "..." + tlsClientCert: "..." + tlsClientKey: "..." + version: 1 + # allow users to edit datasources from the UI. + editable: false +``` + +## Sidecar for notifiers + +If the parameter `sidecar.notifiers.enabled` is set, an init container is deployed in the grafana +pod. This container lists all secrets (or configmaps, though not recommended) in the cluster and +filters out the ones with a label as defined in `sidecar.notifiers.label`. The files defined in +those secrets are written to a folder and accessed by grafana on startup. Using these yaml files, +the notification channels in grafana can be imported. The secrets must be created before +`helm install` so that the notifiers init container can list the secrets. + +Secrets are recommended over configmaps for this usecase because alert notification channels usually contain +private data like SMTP usernames and passwords. Secrets are the more appropriate cluster resource to manage those. + +Example datasource config adapted from [Grafana](https://grafana.com/docs/grafana/latest/administration/provisioning/#alert-notification-channels): + +```yaml +notifiers: + - name: notification-channel-1 + type: slack + uid: notifier1 + # either + org_id: 2 + # or + org_name: Main Org. + is_default: true + send_reminder: true + frequency: 1h + disable_resolve_message: false + # See `Supported Settings` section for settings supporter for each + # alert notification type. + settings: + recipient: 'XXX' + token: 'xoxb' + uploadImage: true + url: https://slack.com + +delete_notifiers: + - name: notification-channel-1 + uid: notifier1 + org_id: 2 + - name: notification-channel-2 + # default org_id: 1 +``` + +## How to serve Grafana with a path prefix (/grafana) + +In order to serve Grafana with a prefix (e.g., ), add the following to your values.yaml. + +```yaml +ingress: + enabled: true + annotations: + kubernetes.io/ingress.class: "nginx" + nginx.ingress.kubernetes.io/rewrite-target: /$1 + nginx.ingress.kubernetes.io/use-regex: "true" + + path: /grafana/?(.*) + hosts: + - k8s.example.dev + +grafana.ini: + server: + root_url: http://localhost:3000/grafana # this host can be localhost +``` + +## How to securely reference secrets in grafana.ini + +This example uses Grafana uses [file providers](https://grafana.com/docs/grafana/latest/administration/configuration/#file-provider) for secret values and the `extraSecretMounts` configuration flag (Additional grafana server secret mounts) to mount the secrets. + +In grafana.ini: + +```yaml +grafana.ini: + [auth.generic_oauth] + enabled = true + client_id = $__file{/etc/secrets/auth_generic_oauth/client_id} + client_secret = $__file{/etc/secrets/auth_generic_oauth/client_secret} +``` + +Existing secret, or created along with helm: + +```yaml +--- +apiVersion: v1 +kind: Secret +metadata: + name: auth-generic-oauth-secret +type: Opaque +stringData: + client_id: + client_secret: +``` + +Include in the `extraSecretMounts` configuration flag: + +```yaml +- extraSecretMounts: + - name: auth-generic-oauth-secret-mount + secretName: auth-generic-oauth-secret + defaultMode: 0440 + mountPath: /etc/secrets/auth_generic_oauth + readOnly: true +``` + +### extraSecretMounts using a Container Storage Interface (CSI) provider + +This example uses a CSI driver e.g. retrieving secrets using [Azure Key Vault Provider](https://github.com/Azure/secrets-store-csi-driver-provider-azure) + +```yaml +- extraSecretMounts: + - name: secrets-store-inline + mountPath: /run/secrets + readOnly: true + csi: + driver: secrets-store.csi.k8s.io + readOnly: true + volumeAttributes: + secretProviderClass: "my-provider" + nodePublishSecretRef: + name: akv-creds +``` + +## Image Renderer Plug-In + +This chart supports enabling [remote image rendering](https://github.com/grafana/grafana-image-renderer/blob/master/README.md#run-in-docker) + +```yaml +imageRenderer: + enabled: true +``` + +### Image Renderer NetworkPolicy + +By default the image-renderer pods will have a network policy which only allows ingress traffic from the created grafana instance + +### High Availability for unified alerting + +If you want to run Grafana in a high availability cluster you need to enable +the headless service by setting `headlessService: true` in your `values.yaml` +file. + +As next step you have to setup the `grafana.ini` in your `values.yaml` in a way +that it will make use of the headless service to obtain all the IPs of the +cluster. You should replace ``{{ Name }}`` with the name of your helm deployment. + +```yaml +grafana.ini: + ... + unified_alerting: + enabled: true + ha_peers: {{ Name }}-headless:9094 + alerting: + enabled: false +``` diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/ci/default-values.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/ci/default-values.yaml new file mode 100644 index 0000000..fc2ba60 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/ci/default-values.yaml @@ -0,0 +1 @@ +# Leave this file empty to ensure that CI runs builds against the default configuration in values.yaml. diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/ci/with-dashboard-json-values.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/ci/with-dashboard-json-values.yaml new file mode 100644 index 0000000..e0c4e41 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/ci/with-dashboard-json-values.yaml @@ -0,0 +1,53 @@ +dashboards: + my-provider: + my-awesome-dashboard: + # An empty but valid dashboard + json: | + { + "__inputs": [], + "__requires": [ + { + "type": "grafana", + "id": "grafana", + "name": "Grafana", + "version": "6.3.5" + } + ], + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": "-- Grafana --", + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "name": "Annotations & Alerts", + "type": "dashboard" + } + ] + }, + "editable": true, + "gnetId": null, + "graphTooltip": 0, + "id": null, + "links": [], + "panels": [], + "schemaVersion": 19, + "style": "dark", + "tags": [], + "templating": { + "list": [] + }, + "time": { + "from": "now-6h", + "to": "now" + }, + "timepicker": { + "refresh_intervals": ["5s"] + }, + "timezone": "", + "title": "Dummy Dashboard", + "uid": "IdcYQooWk", + "version": 1 + } + datasource: Prometheus diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/ci/with-dashboard-values.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/ci/with-dashboard-values.yaml new file mode 100644 index 0000000..7b662c5 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/ci/with-dashboard-values.yaml @@ -0,0 +1,19 @@ +dashboards: + my-provider: + my-awesome-dashboard: + gnetId: 10000 + revision: 1 + datasource: Prometheus +dashboardProviders: + dashboardproviders.yaml: + apiVersion: 1 + providers: + - name: 'my-provider' + orgId: 1 + folder: '' + type: file + updateIntervalSeconds: 10 + disableDeletion: true + editable: true + options: + path: /var/lib/grafana/dashboards/my-provider diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/ci/with-image-renderer-values.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/ci/with-image-renderer-values.yaml new file mode 100644 index 0000000..32f3074 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/ci/with-image-renderer-values.yaml @@ -0,0 +1,19 @@ +podLabels: + customLableA: Aaaaa +imageRenderer: + enabled: true + env: + RENDERING_ARGS: --disable-gpu,--window-size=1280x758 + RENDERING_MODE: clustered + podLabels: + customLableB: Bbbbb + networkPolicy: + limitIngress: true + limitEgress: true + resources: + limits: + cpu: 1000m + memory: 1000Mi + requests: + cpu: 500m + memory: 50Mi diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/dashboards/custom-dashboard.json b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/dashboards/custom-dashboard.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/dashboards/custom-dashboard.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/NOTES.txt b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/NOTES.txt new file mode 100644 index 0000000..1fc8436 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/NOTES.txt @@ -0,0 +1,54 @@ +1. Get your '{{ .Values.adminUser }}' user password by running: + + kubectl get secret --namespace {{ template "grafana.namespace" . }} {{ template "grafana.fullname" . }} -o jsonpath="{.data.admin-password}" | base64 --decode ; echo + +2. The Grafana server can be accessed via port {{ .Values.service.port }} on the following DNS name from within your cluster: + + {{ template "grafana.fullname" . }}.{{ template "grafana.namespace" . }}.svc.cluster.local +{{ if .Values.ingress.enabled }} + If you bind grafana to 80, please update values in values.yaml and reinstall: + ``` + securityContext: + runAsUser: 0 + runAsGroup: 0 + fsGroup: 0 + + command: + - "setcap" + - "'cap_net_bind_service=+ep'" + - "/usr/sbin/grafana-server &&" + - "sh" + - "/run.sh" + ``` + Details refer to https://grafana.com/docs/installation/configuration/#http-port. + Or grafana would always crash. + + From outside the cluster, the server URL(s) are: +{{- range .Values.ingress.hosts }} + http://{{ . }} +{{- end }} +{{ else }} + Get the Grafana URL to visit by running these commands in the same shell: +{{ if contains "NodePort" .Values.service.type -}} + export NODE_PORT=$(kubectl get --namespace {{ template "grafana.namespace" . }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "grafana.fullname" . }}) + export NODE_IP=$(kubectl get nodes --namespace {{ template "grafana.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 svc --namespace {{ template "grafana.namespace" . }} -w {{ template "grafana.fullname" . }}' + export SERVICE_IP=$(kubectl get svc --namespace {{ template "grafana.namespace" . }} {{ template "grafana.fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}') + http://$SERVICE_IP:{{ .Values.service.port -}} +{{ else if contains "ClusterIP" .Values.service.type }} + export POD_NAME=$(kubectl get pods --namespace {{ template "grafana.namespace" . }} -l "app.kubernetes.io/name={{ template "grafana.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") + kubectl --namespace {{ template "grafana.namespace" . }} port-forward $POD_NAME 3000 +{{- end }} +{{- end }} + +3. Login with the password from step 1 and the username: {{ .Values.adminUser }} + +{{- if not .Values.persistence.enabled }} +################################################################################# +###### WARNING: Persistence is disabled!!! You will lose your data when ##### +###### the Grafana pod is terminated. ##### +################################################################################# +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/_helpers.tpl b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/_helpers.tpl new file mode 100644 index 0000000..f0c06aa --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/_helpers.tpl @@ -0,0 +1,163 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "grafana.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 "grafana.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 "grafana.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create the name of the service account +*/}} +{{- define "grafana.serviceAccountName" -}} +{{- if .Values.serviceAccount.create -}} + {{ default (include "grafana.fullname" .) .Values.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{- define "grafana.serviceAccountNameTest" -}} +{{- if .Values.serviceAccount.create -}} + {{ default (print (include "grafana.fullname" .) "-test") .Values.serviceAccount.nameTest }} +{{- else -}} + {{ default "default" .Values.serviceAccount.nameTest }} +{{- end -}} +{{- end -}} + +{{/* +Allow the release namespace to be overridden for multi-namespace deployments in combined charts +*/}} +{{- define "grafana.namespace" -}} + {{- if .Values.namespaceOverride -}} + {{- .Values.namespaceOverride -}} + {{- else -}} + {{- .Release.Namespace -}} + {{- end -}} +{{- end -}} + +{{/* +Common labels +*/}} +{{- define "grafana.labels" -}} +helm.sh/chart: {{ include "grafana.chart" . }} +{{ include "grafana.selectorLabels" . }} +{{- if or .Chart.AppVersion .Values.image.tag }} +app.kubernetes.io/version: {{ .Values.image.tag | default .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- if .Values.extraLabels }} +{{ toYaml .Values.extraLabels }} +{{- end }} +{{- end -}} + +{{/* +Selector labels +*/}} +{{- define "grafana.selectorLabels" -}} +app.kubernetes.io/name: {{ include "grafana.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end -}} + +{{/* +Common labels +*/}} +{{- define "grafana.imageRenderer.labels" -}} +helm.sh/chart: {{ include "grafana.chart" . }} +{{ include "grafana.imageRenderer.selectorLabels" . }} +{{- if or .Chart.AppVersion .Values.image.tag }} +app.kubernetes.io/version: {{ .Values.image.tag | default .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end -}} + +{{/* +Selector labels ImageRenderer +*/}} +{{- define "grafana.imageRenderer.selectorLabels" -}} +app.kubernetes.io/name: {{ include "grafana.name" . }}-image-renderer +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end -}} + +{{/* +Looks if there's an existing secret and reuse its password. If not it generates +new password and use it. +*/}} +{{- define "grafana.password" -}} +{{- $secret := (lookup "v1" "Secret" (include "grafana.namespace" .) (include "grafana.fullname" .) ) -}} + {{- if $secret -}} + {{- index $secret "data" "admin-password" -}} + {{- else -}} + {{- (randAlphaNum 40) | b64enc | quote -}} + {{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for rbac. +*/}} +{{- define "grafana.rbac.apiVersion" -}} + {{- if .Capabilities.APIVersions.Has "rbac.authorization.k8s.io/v1" }} + {{- print "rbac.authorization.k8s.io/v1" -}} + {{- else -}} + {{- print "rbac.authorization.k8s.io/v1beta1" -}} + {{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for ingress. +*/}} +{{- define "grafana.ingress.apiVersion" -}} + {{- if and (.Capabilities.APIVersions.Has "networking.k8s.io/v1") (semverCompare ">= 1.19-0" .Capabilities.KubeVersion.Version) -}} + {{- print "networking.k8s.io/v1" -}} + {{- else if .Capabilities.APIVersions.Has "networking.k8s.io/v1beta1" -}} + {{- print "networking.k8s.io/v1beta1" -}} + {{- else -}} + {{- print "extensions/v1beta1" -}} + {{- end -}} +{{- end -}} + +{{/* +Return if ingress is stable. +*/}} +{{- define "grafana.ingress.isStable" -}} + {{- eq (include "grafana.ingress.apiVersion" .) "networking.k8s.io/v1" -}} +{{- end -}} + +{{/* +Return if ingress supports ingressClassName. +*/}} +{{- define "grafana.ingress.supportsIngressClassName" -}} + {{- or (eq (include "grafana.ingress.isStable" .) "true") (and (eq (include "grafana.ingress.apiVersion" .) "networking.k8s.io/v1beta1") (semverCompare ">= 1.18-0" .Capabilities.KubeVersion.Version)) -}} +{{- end -}} + +{{/* +Return if ingress supports pathType. +*/}} +{{- define "grafana.ingress.supportsPathType" -}} + {{- or (eq (include "grafana.ingress.isStable" .) "true") (and (eq (include "grafana.ingress.apiVersion" .) "networking.k8s.io/v1beta1") (semverCompare ">= 1.18-0" .Capabilities.KubeVersion.Version)) -}} +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/_pod.tpl b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/_pod.tpl new file mode 100644 index 0000000..855c010 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/_pod.tpl @@ -0,0 +1,684 @@ + +{{- define "grafana.pod" -}} +{{- if .Values.schedulerName }} +schedulerName: "{{ .Values.schedulerName }}" +{{- end }} +serviceAccountName: {{ template "grafana.serviceAccountName" . }} +automountServiceAccountToken: {{ .Values.serviceAccount.autoMount }} +{{- if .Values.securityContext }} +securityContext: +{{ toYaml .Values.securityContext | indent 2 }} +{{- end }} +{{- if .Values.hostAliases }} +hostAliases: +{{ toYaml .Values.hostAliases | indent 2 }} +{{- end }} +{{- if .Values.priorityClassName }} +priorityClassName: {{ .Values.priorityClassName }} +{{- end }} +{{- if ( or .Values.persistence.enabled .Values.dashboards .Values.sidecar.notifiers.enabled .Values.extraInitContainers) }} +initContainers: +{{- end }} +{{- if ( and .Values.persistence.enabled .Values.initChownData.enabled ) }} + - name: init-chown-data + {{- if .Values.initChownData.image.sha }} + image: "{{ .Values.initChownData.image.repository }}:{{ .Values.initChownData.image.tag }}@sha256:{{ .Values.initChownData.image.sha }}" + {{- else }} + image: "{{ .Values.initChownData.image.repository }}:{{ .Values.initChownData.image.tag }}" + {{- end }} + imagePullPolicy: {{ .Values.initChownData.image.pullPolicy }} + securityContext: + runAsNonRoot: false + runAsUser: 0 + command: ["chown", "-R", "{{ .Values.securityContext.runAsUser }}:{{ .Values.securityContext.runAsGroup }}", "/var/lib/grafana"] + resources: +{{ toYaml .Values.initChownData.resources | indent 6 }} + volumeMounts: + - name: storage + mountPath: "/var/lib/grafana" +{{- if .Values.persistence.subPath }} + subPath: {{ .Values.persistence.subPath }} +{{- end }} +{{- end }} +{{- if .Values.dashboards }} + - name: download-dashboards + {{- if .Values.downloadDashboardsImage.sha }} + image: "{{ .Values.downloadDashboardsImage.repository }}:{{ .Values.downloadDashboardsImage.tag }}@sha256:{{ .Values.downloadDashboardsImage.sha }}" + {{- else }} + image: "{{ .Values.downloadDashboardsImage.repository }}:{{ .Values.downloadDashboardsImage.tag }}" + {{- end }} + imagePullPolicy: {{ .Values.downloadDashboardsImage.pullPolicy }} + command: ["/bin/sh"] + args: [ "-c", "mkdir -p /var/lib/grafana/dashboards/default && /bin/sh -x /etc/grafana/download_dashboards.sh" ] + resources: +{{ toYaml .Values.downloadDashboards.resources | indent 6 }} + env: +{{- range $key, $value := .Values.downloadDashboards.env }} + - name: "{{ $key }}" + value: "{{ $value }}" +{{- end }} +{{- if .Values.downloadDashboards.envFromSecret }} + envFrom: + - secretRef: + name: {{ tpl .Values.downloadDashboards.envFromSecret . }} +{{- end }} + volumeMounts: + - name: config + mountPath: "/etc/grafana/download_dashboards.sh" + subPath: download_dashboards.sh + - name: storage + mountPath: "/var/lib/grafana" +{{- if .Values.persistence.subPath }} + subPath: {{ .Values.persistence.subPath }} +{{- end }} + {{- range .Values.extraSecretMounts }} + - name: {{ .name }} + mountPath: {{ .mountPath }} + readOnly: {{ .readOnly }} + {{- end }} +{{- end }} +{{- if and .Values.sidecar.datasources.enabled .Values.sidecar.datasources.initDatasources }} + - name: {{ template "grafana.name" . }}-init-sc-datasources + {{- if .Values.sidecar.image.sha }} + image: "{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}@sha256:{{ .Values.sidecar.image.sha }}" + {{- else }} + image: "{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}" + {{- end }} + imagePullPolicy: {{ .Values.sidecar.imagePullPolicy }} + env: + - name: METHOD + value: "LIST" + - name: LABEL + value: "{{ .Values.sidecar.datasources.label }}" + {{- if .Values.sidecar.datasources.labelValue }} + - name: LABEL_VALUE + value: {{ quote .Values.sidecar.datasources.labelValue }} + {{- end }} + - name: FOLDER + value: "/etc/grafana/provisioning/datasources" + - name: RESOURCE + value: {{ quote .Values.sidecar.datasources.resource }} + {{- if .Values.sidecar.enableUniqueFilenames }} + - name: UNIQUE_FILENAMES + value: "{{ .Values.sidecar.enableUniqueFilenames }}" + {{- end }} + {{- if .Values.sidecar.datasources.searchNamespace }} + - name: NAMESPACE + value: "{{ .Values.sidecar.datasources.searchNamespace | join "," }}" + {{- end }} + {{- if .Values.sidecar.skipTlsVerify }} + - name: SKIP_TLS_VERIFY + value: "{{ .Values.sidecar.skipTlsVerify }}" + {{- end }} + resources: +{{ toYaml .Values.sidecar.resources | indent 6 }} +{{- if .Values.sidecar.securityContext }} + securityContext: +{{- toYaml .Values.sidecar.securityContext | nindent 6 }} +{{- end }} + volumeMounts: + - name: sc-datasources-volume + mountPath: "/etc/grafana/provisioning/datasources" +{{- end }} +{{- if .Values.sidecar.notifiers.enabled }} + - name: {{ template "grafana.name" . }}-sc-notifiers + {{- if .Values.sidecar.image.sha }} + image: "{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}@sha256:{{ .Values.sidecar.image.sha }}" + {{- else }} + image: "{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}" + {{- end }} + imagePullPolicy: {{ .Values.sidecar.imagePullPolicy }} + env: + - name: METHOD + value: LIST + - name: LABEL + value: "{{ .Values.sidecar.notifiers.label }}" + - name: FOLDER + value: "/etc/grafana/provisioning/notifiers" + - name: RESOURCE + value: {{ quote .Values.sidecar.notifiers.resource }} + {{- if .Values.sidecar.enableUniqueFilenames }} + - name: UNIQUE_FILENAMES + value: "{{ .Values.sidecar.enableUniqueFilenames }}" + {{- end }} + {{- if .Values.sidecar.notifiers.searchNamespace }} + - name: NAMESPACE + value: "{{ .Values.sidecar.notifiers.searchNamespace | join "," }}" + {{- end }} + {{- if .Values.sidecar.skipTlsVerify }} + - name: SKIP_TLS_VERIFY + value: "{{ .Values.sidecar.skipTlsVerify }}" + {{- end }} + resources: +{{ toYaml .Values.sidecar.resources | indent 6 }} +{{- if .Values.sidecar.securityContext }} + securityContext: +{{- toYaml .Values.sidecar.securityContext | nindent 6 }} +{{- end }} + volumeMounts: + - name: sc-notifiers-volume + mountPath: "/etc/grafana/provisioning/notifiers" +{{- end}} +{{- if .Values.extraInitContainers }} +{{ toYaml .Values.extraInitContainers | indent 2 }} +{{- end }} +{{- if .Values.image.pullSecrets }} +imagePullSecrets: +{{- range .Values.image.pullSecrets }} + - name: {{ . }} +{{- end}} +{{- end }} +{{- if not .Values.enableKubeBackwardCompatibility }} +enableServiceLinks: {{ .Values.enableServiceLinks }} +{{- end }} +containers: +{{- if .Values.sidecar.dashboards.enabled }} + - name: {{ template "grafana.name" . }}-sc-dashboard + {{- if .Values.sidecar.image.sha }} + image: "{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}@sha256:{{ .Values.sidecar.image.sha }}" + {{- else }} + image: "{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}" + {{- end }} + imagePullPolicy: {{ .Values.sidecar.imagePullPolicy }} + env: + - name: METHOD + value: {{ .Values.sidecar.dashboards.watchMethod }} + - name: LABEL + value: "{{ .Values.sidecar.dashboards.label }}" + {{- if .Values.sidecar.dashboards.labelValue }} + - name: LABEL_VALUE + value: {{ quote .Values.sidecar.dashboards.labelValue }} + {{- end }} + - name: FOLDER + value: "{{ .Values.sidecar.dashboards.folder }}{{- with .Values.sidecar.dashboards.defaultFolderName }}/{{ . }}{{- end }}" + - name: RESOURCE + value: {{ quote .Values.sidecar.dashboards.resource }} + {{- if .Values.sidecar.enableUniqueFilenames }} + - name: UNIQUE_FILENAMES + value: "{{ .Values.sidecar.enableUniqueFilenames }}" + {{- end }} + {{- if .Values.sidecar.dashboards.searchNamespace }} + - name: NAMESPACE + value: "{{ .Values.sidecar.dashboards.searchNamespace | join "," }}" + {{- end }} + {{- if .Values.sidecar.skipTlsVerify }} + - name: SKIP_TLS_VERIFY + value: "{{ .Values.sidecar.skipTlsVerify }}" + {{- end }} + {{- if .Values.sidecar.dashboards.folderAnnotation }} + - name: FOLDER_ANNOTATION + value: "{{ .Values.sidecar.dashboards.folderAnnotation }}" + {{- end }} + {{- if .Values.sidecar.dashboards.script }} + - name: SCRIPT + value: "{{ .Values.sidecar.dashboards.script }}" + {{- end }} + {{- if .Values.sidecar.dashboards.watchServerTimeout }} + - name: WATCH_SERVER_TIMEOUT + value: "{{ .Values.sidecar.dashboards.watchServerTimeout }}" + {{- end }} + {{- if .Values.sidecar.dashboards.watchClientTimeout }} + - name: WATCH_CLIENT_TIMEOUT + value: "{{ .Values.sidecar.dashboards.watchClientTimeout }}" + {{- end }} + resources: +{{ toYaml .Values.sidecar.resources | indent 6 }} +{{- if .Values.sidecar.securityContext }} + securityContext: +{{- toYaml .Values.sidecar.securityContext | nindent 6 }} +{{- end }} + volumeMounts: + - name: sc-dashboard-volume + mountPath: {{ .Values.sidecar.dashboards.folder | quote }} + {{- if .Values.sidecar.dashboards.extraMounts }} + {{- toYaml .Values.sidecar.dashboards.extraMounts | trim | nindent 6}} + {{- end }} +{{- end}} +{{- if .Values.sidecar.datasources.enabled }} + - name: {{ template "grafana.name" . }}-sc-datasources + {{- if .Values.sidecar.image.sha }} + image: "{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}@sha256:{{ .Values.sidecar.image.sha }}" + {{- else }} + image: "{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}" + {{- end }} + imagePullPolicy: {{ .Values.sidecar.imagePullPolicy }} + env: + - name: METHOD + value: {{ .Values.sidecar.datasources.watchMethod }} + - name: LABEL + value: "{{ .Values.sidecar.datasources.label }}" + {{- if .Values.sidecar.datasources.labelValue }} + - name: LABEL_VALUE + value: {{ quote .Values.sidecar.datasources.labelValue }} + {{- end }} + - name: FOLDER + value: "/etc/grafana/provisioning/datasources" + - name: RESOURCE + value: {{ quote .Values.sidecar.datasources.resource }} + {{- if .Values.sidecar.enableUniqueFilenames }} + - name: UNIQUE_FILENAMES + value: "{{ .Values.sidecar.enableUniqueFilenames }}" + {{- end }} + {{- if .Values.sidecar.datasources.searchNamespace }} + - name: NAMESPACE + value: "{{ .Values.sidecar.datasources.searchNamespace | join "," }}" + {{- end }} + {{- if .Values.sidecar.skipTlsVerify }} + - name: SKIP_TLS_VERIFY + value: "{{ .Values.sidecar.skipTlsVerify }}" + {{- end }} + {{- if and (not .Values.env.GF_SECURITY_ADMIN_USER) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) }} + - name: REQ_USERNAME + valueFrom: + secretKeyRef: + name: {{ .Values.admin.existingSecret | default (include "grafana.fullname" .) }} + key: {{ .Values.admin.userKey | default "admin-user" }} + {{- end }} + {{- if and (not .Values.env.GF_SECURITY_ADMIN_PASSWORD) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD__FILE) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) }} + - name: REQ_PASSWORD + valueFrom: + secretKeyRef: + name: {{ .Values.admin.existingSecret | default (include "grafana.fullname" .) }} + key: {{ .Values.admin.passwordKey | default "admin-password" }} + {{- end }} + {{- if not .Values.sidecar.datasources.skipReload }} + - name: REQ_URL + value: {{ .Values.sidecar.datasources.reloadURL }} + - name: REQ_METHOD + value: POST + {{- end }} + resources: +{{ toYaml .Values.sidecar.resources | indent 6 }} +{{- if .Values.sidecar.securityContext }} + securityContext: +{{- toYaml .Values.sidecar.securityContext | nindent 6 }} +{{- end }} + volumeMounts: + - name: sc-datasources-volume + mountPath: "/etc/grafana/provisioning/datasources" +{{- end}} +{{- if .Values.sidecar.plugins.enabled }} + - name: {{ template "grafana.name" . }}-sc-plugins + {{- if .Values.sidecar.image.sha }} + image: "{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}@sha256:{{ .Values.sidecar.image.sha }}" + {{- else }} + image: "{{ .Values.sidecar.image.repository }}:{{ .Values.sidecar.image.tag }}" + {{- end }} + imagePullPolicy: {{ .Values.sidecar.imagePullPolicy }} + env: + - name: METHOD + value: {{ .Values.sidecar.plugins.watchMethod }} + - name: LABEL + value: "{{ .Values.sidecar.plugins.label }}" + {{- if .Values.sidecar.plugins.labelValue }} + - name: LABEL_VALUE + value: {{ quote .Values.sidecar.plugins.labelValue }} + {{- end }} + - name: FOLDER + value: "/etc/grafana/provisioning/plugins" + - name: RESOURCE + value: {{ quote .Values.sidecar.plugins.resource }} + {{- if .Values.sidecar.enableUniqueFilenames }} + - name: UNIQUE_FILENAMES + value: "{{ .Values.sidecar.enableUniqueFilenames }}" + {{- end }} + {{- if .Values.sidecar.plugins.searchNamespace }} + - name: NAMESPACE + value: "{{ .Values.sidecar.plugins.searchNamespace | join "," }}" + {{- end }} + {{- if .Values.sidecar.skipTlsVerify }} + - name: SKIP_TLS_VERIFY + value: "{{ .Values.sidecar.skipTlsVerify }}" + {{- end }} + {{- if and (not .Values.env.GF_SECURITY_ADMIN_USER) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) }} + - name: REQ_USERNAME + valueFrom: + secretKeyRef: + name: {{ .Values.admin.existingSecret | default (include "grafana.fullname" .) }} + key: {{ .Values.admin.userKey | default "admin-user" }} + {{- end }} + {{- if and (not .Values.env.GF_SECURITY_ADMIN_PASSWORD) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD__FILE) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) }} + - name: REQ_PASSWORD + valueFrom: + secretKeyRef: + name: {{ .Values.admin.existingSecret | default (include "grafana.fullname" .) }} + key: {{ .Values.admin.passwordKey | default "admin-password" }} + {{- end }} + {{- if not .Values.sidecar.plugins.skipReload }} + - name: REQ_URL + value: {{ .Values.sidecar.plugins.reloadURL }} + - name: REQ_METHOD + value: POST + {{- end }} + resources: +{{ toYaml .Values.sidecar.resources | indent 6 }} +{{- if .Values.sidecar.securityContext }} + securityContext: +{{- toYaml .Values.sidecar.securityContext | nindent 6 }} +{{- end }} + volumeMounts: + - name: sc-plugins-volume + mountPath: "/etc/grafana/provisioning/plugins" +{{- end}} + - name: {{ .Chart.Name }} + {{- if .Values.image.sha }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}@sha256:{{ .Values.image.sha }}" + {{- else }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + {{- end }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + {{- if .Values.command }} + command: + {{- range .Values.command }} + - {{ . }} + {{- end }} + {{- end}} +{{- if .Values.containerSecurityContext }} + securityContext: +{{- toYaml .Values.containerSecurityContext | nindent 6 }} +{{- end }} + volumeMounts: + - name: config + mountPath: "/etc/grafana/grafana.ini" + subPath: grafana.ini + {{- if .Values.ldap.enabled }} + - name: ldap + mountPath: "/etc/grafana/ldap.toml" + subPath: ldap.toml + {{- end }} + {{- range .Values.extraConfigmapMounts }} + - name: {{ .name }} + mountPath: {{ .mountPath }} + subPath: {{ .subPath | default "" }} + readOnly: {{ .readOnly }} + {{- end }} + - name: storage + mountPath: "/var/lib/grafana" +{{- if .Values.persistence.subPath }} + subPath: {{ .Values.persistence.subPath }} +{{- end }} +{{- if .Values.dashboards }} +{{- range $provider, $dashboards := .Values.dashboards }} +{{- range $key, $value := $dashboards }} +{{- if (or (hasKey $value "json") (hasKey $value "file")) }} + - name: dashboards-{{ $provider }} + mountPath: "/var/lib/grafana/dashboards/{{ $provider }}/{{ $key }}.json" + subPath: "{{ $key }}.json" +{{- end }} +{{- end }} +{{- end }} +{{- end -}} +{{- if .Values.dashboardsConfigMaps }} +{{- range (keys .Values.dashboardsConfigMaps | sortAlpha) }} + - name: dashboards-{{ . }} + mountPath: "/var/lib/grafana/dashboards/{{ . }}" +{{- end }} +{{- end }} +{{- if .Values.datasources }} +{{- range (keys .Values.datasources | sortAlpha) }} + - name: config + mountPath: "/etc/grafana/provisioning/datasources/{{ . }}" + subPath: {{ . | quote }} +{{- end }} +{{- end }} +{{- if .Values.notifiers }} +{{- range (keys .Values.notifiers | sortAlpha) }} + - name: config + mountPath: "/etc/grafana/provisioning/notifiers/{{ . }}" + subPath: {{ . | quote }} +{{- end }} +{{- end }} +{{- if .Values.dashboardProviders }} +{{- range (keys .Values.dashboardProviders | sortAlpha) }} + - name: config + mountPath: "/etc/grafana/provisioning/dashboards/{{ . }}" + subPath: {{ . | quote }} +{{- end }} +{{- end }} +{{- if .Values.sidecar.dashboards.enabled }} + - name: sc-dashboard-volume + mountPath: {{ .Values.sidecar.dashboards.folder | quote }} +{{ if .Values.sidecar.dashboards.SCProvider }} + - name: sc-dashboard-provider + mountPath: "/etc/grafana/provisioning/dashboards/sc-dashboardproviders.yaml" + subPath: provider.yaml +{{- end}} +{{- end}} +{{- if .Values.sidecar.datasources.enabled }} + - name: sc-datasources-volume + mountPath: "/etc/grafana/provisioning/datasources" +{{- end}} +{{- if .Values.sidecar.plugins.enabled }} + - name: sc-plugins-volume + mountPath: "/etc/grafana/provisioning/plugins" +{{- end}} +{{- if .Values.sidecar.notifiers.enabled }} + - name: sc-notifiers-volume + mountPath: "/etc/grafana/provisioning/notifiers" +{{- end}} + {{- range .Values.extraSecretMounts }} + - name: {{ .name }} + mountPath: {{ .mountPath }} + readOnly: {{ .readOnly }} + subPath: {{ .subPath | default "" }} + {{- end }} + {{- range .Values.extraVolumeMounts }} + - name: {{ .name }} + mountPath: {{ .mountPath }} + subPath: {{ .subPath | default "" }} + readOnly: {{ .readOnly }} + {{- end }} + {{- range .Values.extraEmptyDirMounts }} + - name: {{ .name }} + mountPath: {{ .mountPath }} + {{- end }} + ports: + - name: {{ .Values.service.portName }} + containerPort: {{ .Values.service.port }} + protocol: TCP + - name: {{ .Values.podPortName }} + containerPort: 3000 + protocol: TCP + env: + {{- if and (not .Values.env.GF_SECURITY_ADMIN_USER) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) }} + - name: GF_SECURITY_ADMIN_USER + valueFrom: + secretKeyRef: + name: {{ .Values.admin.existingSecret | default (include "grafana.fullname" .) }} + key: {{ .Values.admin.userKey | default "admin-user" }} + {{- end }} + {{- if and (not .Values.env.GF_SECURITY_ADMIN_PASSWORD) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD__FILE) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) }} + - name: GF_SECURITY_ADMIN_PASSWORD + valueFrom: + secretKeyRef: + name: {{ .Values.admin.existingSecret | default (include "grafana.fullname" .) }} + key: {{ .Values.admin.passwordKey | default "admin-password" }} + {{- end }} + {{- if .Values.plugins }} + - name: GF_INSTALL_PLUGINS + valueFrom: + configMapKeyRef: + name: {{ template "grafana.fullname" . }} + key: plugins + {{- end }} + {{- if .Values.smtp.existingSecret }} + - name: GF_SMTP_USER + valueFrom: + secretKeyRef: + name: {{ .Values.smtp.existingSecret }} + key: {{ .Values.smtp.userKey | default "user" }} + - name: GF_SMTP_PASSWORD + valueFrom: + secretKeyRef: + name: {{ .Values.smtp.existingSecret }} + key: {{ .Values.smtp.passwordKey | default "password" }} + {{- end }} + {{- if .Values.imageRenderer.enabled }} + - name: GF_RENDERING_SERVER_URL + value: http://{{ template "grafana.fullname" . }}-image-renderer.{{ template "grafana.namespace" . }}:{{ .Values.imageRenderer.service.port }}/render + - name: GF_RENDERING_CALLBACK_URL + value: {{ .Values.imageRenderer.grafanaProtocol }}://{{ template "grafana.fullname" . }}.{{ template "grafana.namespace" . }}:{{ .Values.service.port }}/{{ .Values.imageRenderer.grafanaSubPath }} + {{- end }} + - name: GF_PATHS_DATA + value: {{ (get .Values "grafana.ini").paths.data }} + - name: GF_PATHS_LOGS + value: {{ (get .Values "grafana.ini").paths.logs }} + - name: GF_PATHS_PLUGINS + value: {{ (get .Values "grafana.ini").paths.plugins }} + - name: GF_PATHS_PROVISIONING + value: {{ (get .Values "grafana.ini").paths.provisioning }} + {{- range $key, $value := .Values.envValueFrom }} + - name: {{ $key | quote }} + valueFrom: +{{ toYaml $value | indent 10 }} + {{- end }} +{{- range $key, $value := .Values.env }} + - name: "{{ tpl $key $ }}" + value: "{{ tpl (print $value) $ }}" +{{- end }} + {{- if or .Values.envFromSecret (or .Values.envRenderSecret .Values.envFromSecrets) }} + envFrom: + {{- if .Values.envFromSecret }} + - secretRef: + name: {{ tpl .Values.envFromSecret . }} + {{- end }} + {{- if .Values.envRenderSecret }} + - secretRef: + name: {{ template "grafana.fullname" . }}-env + {{- end }} + {{- range .Values.envFromSecrets }} + - secretRef: + name: {{ .name }} + optional: {{ .optional | default false }} + {{- end }} + {{- end }} + livenessProbe: +{{ toYaml .Values.livenessProbe | indent 6 }} + readinessProbe: +{{ toYaml .Values.readinessProbe | indent 6 }} + resources: +{{ toYaml .Values.resources | indent 6 }} +{{- with .Values.extraContainers }} +{{ tpl . $ | indent 2 }} +{{- end }} +{{- with .Values.nodeSelector }} +nodeSelector: +{{ toYaml . | indent 2 }} +{{- end }} +{{- with .Values.affinity }} +affinity: +{{ toYaml . | indent 2 }} +{{- end }} +{{- with .Values.tolerations }} +tolerations: +{{ toYaml . | indent 2 }} +{{- end }} +volumes: + - name: config + configMap: + name: {{ template "grafana.fullname" . }} +{{- range .Values.extraConfigmapMounts }} + - name: {{ .name }} + configMap: + name: {{ .configMap }} +{{- end }} + {{- if .Values.dashboards }} + {{- range (keys .Values.dashboards | sortAlpha) }} + - name: dashboards-{{ . }} + configMap: + name: {{ template "grafana.fullname" $ }}-dashboards-{{ . }} + {{- end }} + {{- end }} + {{- if .Values.dashboardsConfigMaps }} + {{ $root := . }} + {{- range $provider, $name := .Values.dashboardsConfigMaps }} + - name: dashboards-{{ $provider }} + configMap: + name: {{ tpl $name $root }} + {{- end }} + {{- end }} + {{- if .Values.ldap.enabled }} + - name: ldap + secret: + {{- if .Values.ldap.existingSecret }} + secretName: {{ .Values.ldap.existingSecret }} + {{- else }} + secretName: {{ template "grafana.fullname" . }} + {{- end }} + items: + - key: ldap-toml + path: ldap.toml + {{- end }} +{{- if and .Values.persistence.enabled (eq .Values.persistence.type "pvc") }} + - name: storage + persistentVolumeClaim: + claimName: {{ .Values.persistence.existingClaim | default (include "grafana.fullname" .) }} +{{- else if and .Values.persistence.enabled (eq .Values.persistence.type "statefulset") }} +# nothing +{{- else }} + - name: storage +{{- if .Values.persistence.inMemory.enabled }} + emptyDir: + medium: Memory +{{- if .Values.persistence.inMemory.sizeLimit }} + sizeLimit: {{ .Values.persistence.inMemory.sizeLimit }} +{{- end -}} +{{- else }} + emptyDir: {} +{{- end -}} +{{- end -}} +{{- if .Values.sidecar.dashboards.enabled }} + - name: sc-dashboard-volume + emptyDir: {} +{{- if .Values.sidecar.dashboards.SCProvider }} + - name: sc-dashboard-provider + configMap: + name: {{ template "grafana.fullname" . }}-config-dashboards +{{- end }} +{{- end }} +{{- if .Values.sidecar.datasources.enabled }} + - name: sc-datasources-volume + emptyDir: {} +{{- end -}} +{{- if .Values.sidecar.plugins.enabled }} + - name: sc-plugins-volume + emptyDir: {} +{{- end -}} +{{- if .Values.sidecar.notifiers.enabled }} + - name: sc-notifiers-volume + emptyDir: {} +{{- end -}} +{{- range .Values.extraSecretMounts }} +{{- if .secretName }} + - name: {{ .name }} + secret: + secretName: {{ .secretName }} + defaultMode: {{ .defaultMode }} +{{- else if .projected }} + - name: {{ .name }} + projected: {{- toYaml .projected | nindent 6 }} +{{- else if .csi }} + - name: {{ .name }} + csi: {{- toYaml .csi | nindent 6 }} +{{- end }} +{{- end }} +{{- range .Values.extraVolumeMounts }} + - name: {{ .name }} + {{- if .existingClaim }} + persistentVolumeClaim: + claimName: {{ .existingClaim }} + {{- else if .hostPath }} + hostPath: + path: {{ .hostPath }} + {{- else }} + emptyDir: {} + {{- end }} +{{- end }} +{{- range .Values.extraEmptyDirMounts }} + - name: {{ .name }} + emptyDir: {} +{{- end -}} +{{- if .Values.extraContainerVolumes }} +{{ toYaml .Values.extraContainerVolumes | indent 2 }} +{{- end }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/clusterrole.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/clusterrole.yaml new file mode 100644 index 0000000..f09e065 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/clusterrole.yaml @@ -0,0 +1,25 @@ +{{- if and .Values.rbac.create (not .Values.rbac.namespaced) (not .Values.rbac.useExistingRole) }} +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + labels: + {{- include "grafana.labels" . | nindent 4 }} +{{- with .Values.annotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} + name: {{ template "grafana.fullname" . }}-clusterrole +{{- if or .Values.sidecar.dashboards.enabled (or .Values.sidecar.datasources.enabled .Values.rbac.extraClusterRoleRules) }} +rules: +{{- if or .Values.sidecar.dashboards.enabled .Values.sidecar.datasources.enabled }} +- apiGroups: [""] # "" indicates the core API group + resources: ["configmaps", "secrets"] + verbs: ["get", "watch", "list"] +{{- end}} +{{- with .Values.rbac.extraClusterRoleRules }} +{{ toYaml . | indent 0 }} +{{- end}} +{{- else }} +rules: [] +{{- end}} +{{- end}} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/clusterrolebinding.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/clusterrolebinding.yaml new file mode 100644 index 0000000..4accbfa --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/clusterrolebinding.yaml @@ -0,0 +1,24 @@ +{{- if and .Values.rbac.create (not .Values.rbac.namespaced) }} +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ template "grafana.fullname" . }}-clusterrolebinding + labels: + {{- include "grafana.labels" . | nindent 4 }} +{{- with .Values.annotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} +subjects: + - kind: ServiceAccount + name: {{ template "grafana.serviceAccountName" . }} + namespace: {{ template "grafana.namespace" . }} +roleRef: + kind: ClusterRole +{{- if (not .Values.rbac.useExistingRole) }} + name: {{ template "grafana.fullname" . }}-clusterrole +{{- else }} + name: {{ .Values.rbac.useExistingRole }} +{{- end }} + apiGroup: rbac.authorization.k8s.io +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/configmap-dashboard-provider.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/configmap-dashboard-provider.yaml new file mode 100644 index 0000000..65d7385 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/configmap-dashboard-provider.yaml @@ -0,0 +1,29 @@ +{{- if .Values.sidecar.dashboards.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + labels: + {{- include "grafana.labels" . | nindent 4 }} +{{- with .Values.annotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} + name: {{ template "grafana.fullname" . }}-config-dashboards + namespace: {{ template "grafana.namespace" . }} +data: + provider.yaml: |- + apiVersion: 1 + providers: + - name: '{{ .Values.sidecar.dashboards.provider.name }}' + orgId: {{ .Values.sidecar.dashboards.provider.orgid }} + {{- if not .Values.sidecar.dashboards.provider.foldersFromFilesStructure }} + folder: '{{ .Values.sidecar.dashboards.provider.folder }}' + {{- end}} + type: {{ .Values.sidecar.dashboards.provider.type }} + disableDeletion: {{ .Values.sidecar.dashboards.provider.disableDelete }} + allowUiUpdates: {{ .Values.sidecar.dashboards.provider.allowUiUpdates }} + updateIntervalSeconds: {{ .Values.sidecar.dashboards.provider.updateIntervalSeconds | default 30 }} + options: + foldersFromFilesStructure: {{ .Values.sidecar.dashboards.provider.foldersFromFilesStructure }} + path: {{ .Values.sidecar.dashboards.folder }}{{- with .Values.sidecar.dashboards.defaultFolderName }}/{{ . }}{{- end }} +{{- end}} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/configmap.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/configmap.yaml new file mode 100644 index 0000000..c72219f --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/configmap.yaml @@ -0,0 +1,82 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "grafana.fullname" . }} + namespace: {{ template "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} +{{- with .Values.annotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} +data: +{{- if .Values.plugins }} + plugins: {{ join "," .Values.plugins }} +{{- end }} + grafana.ini: | +{{- range $key, $value := index .Values "grafana.ini" }} + [{{ $key }}] + {{- range $elem, $elemVal := $value }} + {{- if kindIs "invalid" $elemVal }} + {{ $elem }} = + {{- else if kindIs "string" $elemVal }} + {{ $elem }} = {{ tpl $elemVal $ }} + {{- else }} + {{ $elem }} = {{ $elemVal }} + {{- end }} + {{- end }} +{{- end }} + +{{- if .Values.datasources }} +{{ $root := . }} + {{- range $key, $value := .Values.datasources }} + {{ $key }}: | +{{ tpl (toYaml $value | indent 4) $root }} + {{- end -}} +{{- end -}} + +{{- if .Values.notifiers }} + {{- range $key, $value := .Values.notifiers }} + {{ $key }}: | +{{ toYaml $value | indent 4 }} + {{- end -}} +{{- end -}} + +{{- if .Values.dashboardProviders }} + {{- range $key, $value := .Values.dashboardProviders }} + {{ $key }}: | +{{ toYaml $value | indent 4 }} + {{- end -}} +{{- end -}} + +{{- if .Values.dashboards }} + download_dashboards.sh: | + #!/usr/bin/env sh + set -euf + {{- if .Values.dashboardProviders }} + {{- range $key, $value := .Values.dashboardProviders }} + {{- range $value.providers }} + mkdir -p {{ .options.path }} + {{- end }} + {{- end }} + {{- end }} + + {{- range $provider, $dashboards := .Values.dashboards }} + {{- range $key, $value := $dashboards }} + {{- if (or (hasKey $value "gnetId") (hasKey $value "url")) }} + curl -skf \ + --connect-timeout 60 \ + --max-time 60 \ + {{- if not $value.b64content }} + -H "Accept: application/json" \ + {{- if $value.token }} + -H "Authorization: token {{ $value.token }}" \ + {{- end }} + -H "Content-Type: application/json;charset=UTF-8" \ + {{ end }} + {{- if $value.url -}}"{{ $value.url }}"{{- else -}}"https://grafana.com/api/dashboards/{{ $value.gnetId }}/revisions/{{- if $value.revision -}}{{ $value.revision }}{{- else -}}1{{- end -}}/download"{{- end -}}{{ if $value.datasource }} | sed '/-- .* --/! s/"datasource":.*,/"datasource": "{{ $value.datasource }}",/g'{{ end }}{{- if $value.b64content -}} | base64 -d {{- end -}} \ + > "/var/lib/grafana/dashboards/{{ $provider }}/{{ $key }}.json" + {{- end -}} + {{- end }} + {{- end }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/dashboards-json-configmap.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/dashboards-json-configmap.yaml new file mode 100644 index 0000000..59e0be6 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/dashboards-json-configmap.yaml @@ -0,0 +1,35 @@ +{{- if .Values.dashboards }} +{{ $files := .Files }} +{{- range $provider, $dashboards := .Values.dashboards }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "grafana.fullname" $ }}-dashboards-{{ $provider }} + namespace: {{ template "grafana.namespace" $ }} + labels: + {{- include "grafana.labels" $ | nindent 4 }} + dashboard-provider: {{ $provider }} +{{- if $dashboards }} +data: +{{- $dashboardFound := false }} +{{- range $key, $value := $dashboards }} +{{- if (or (hasKey $value "json") (hasKey $value "file")) }} +{{- $dashboardFound = true }} +{{ print $key | indent 2 }}.json: +{{- if hasKey $value "json" }} + |- +{{ $value.json | indent 6 }} +{{- end }} +{{- if hasKey $value "file" }} +{{ toYaml ( $files.Get $value.file ) | indent 4}} +{{- end }} +{{- end }} +{{- end }} +{{- if not $dashboardFound }} + {} +{{- end }} +{{- end }} +--- +{{- end }} + +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/deployment.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/deployment.yaml new file mode 100644 index 0000000..8dbe5e1 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/deployment.yaml @@ -0,0 +1,50 @@ +{{ if (or (not .Values.persistence.enabled) (eq .Values.persistence.type "pvc")) }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "grafana.fullname" . }} + namespace: {{ template "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} +{{- if .Values.labels }} +{{ toYaml .Values.labels | indent 4 }} +{{- end }} +{{- with .Values.annotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} +spec: + {{- if and (not .Values.autoscaling.enabled) (.Values.replicas) }} + replicas: {{ .Values.replicas }} + {{- end }} + revisionHistoryLimit: {{ .Values.revisionHistoryLimit }} + selector: + matchLabels: + {{- include "grafana.selectorLabels" . | nindent 6 }} +{{- with .Values.deploymentStrategy }} + strategy: +{{ toYaml . | trim | indent 4 }} +{{- end }} + template: + metadata: + labels: + {{- include "grafana.selectorLabels" . | nindent 8 }} +{{- with .Values.podLabels }} +{{ toYaml . | indent 8 }} +{{- end }} + annotations: + checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} + checksum/dashboards-json-config: {{ include (print $.Template.BasePath "/dashboards-json-configmap.yaml") . | sha256sum }} + checksum/sc-dashboard-provider-config: {{ include (print $.Template.BasePath "/configmap-dashboard-provider.yaml") . | sha256sum }} +{{- if and (or (and (not .Values.admin.existingSecret) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD__FILE) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD)) (and .Values.ldap.enabled (not .Values.ldap.existingSecret))) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) }} + checksum/secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }} +{{- end }} +{{- if .Values.envRenderSecret }} + checksum/secret-env: {{ include (print $.Template.BasePath "/secret-env.yaml") . | sha256sum }} +{{- end }} +{{- with .Values.podAnnotations }} +{{ toYaml . | indent 8 }} +{{- end }} + spec: + {{- include "grafana.pod" . | nindent 6 }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/extra-manifests.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/extra-manifests.yaml new file mode 100644 index 0000000..a9bb3b6 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/extra-manifests.yaml @@ -0,0 +1,4 @@ +{{ range .Values.extraObjects }} +--- +{{ tpl (toYaml .) $ }} +{{ end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/headless-service.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/headless-service.yaml new file mode 100644 index 0000000..1df42e9 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/headless-service.yaml @@ -0,0 +1,22 @@ +{{- if or .Values.headlessService (and .Values.persistence.enabled (not .Values.persistence.existingClaim) (eq .Values.persistence.type "statefulset"))}} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "grafana.fullname" . }}-headless + namespace: {{ template "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} +{{- with .Values.annotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} +spec: + clusterIP: None + selector: + {{- include "grafana.selectorLabels" . | nindent 4 }} + type: ClusterIP + ports: + - protocol: TCP + port: 3000 + targetPort: 3000 +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/hpa.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/hpa.yaml new file mode 100644 index 0000000..9c186d7 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/hpa.yaml @@ -0,0 +1,20 @@ +{{- if .Values.autoscaling.enabled }} +apiVersion: autoscaling/v2beta1 +kind: HorizontalPodAutoscaler +metadata: + name: {{ template "grafana.fullname" . }} + labels: + app.kubernetes.io/name: {{ template "grafana.name" . }} + helm.sh/chart: {{ template "grafana.chart" . }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ template "grafana.fullname" . }} + minReplicas: {{ .Values.autoscaling.minReplicas }} + maxReplicas: {{ .Values.autoscaling.maxReplicas }} + metrics: +{{ toYaml .Values.autoscaling.metrics | indent 4 }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/image-renderer-deployment.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/image-renderer-deployment.yaml new file mode 100644 index 0000000..3976995 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/image-renderer-deployment.yaml @@ -0,0 +1,119 @@ +{{ if .Values.imageRenderer.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "grafana.fullname" . }}-image-renderer + namespace: {{ template "grafana.namespace" . }} + labels: + {{- include "grafana.imageRenderer.labels" . | nindent 4 }} +{{- if .Values.imageRenderer.labels }} +{{ toYaml .Values.imageRenderer.labels | indent 4 }} +{{- end }} +{{- with .Values.imageRenderer.annotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} +spec: + replicas: {{ .Values.imageRenderer.replicas }} + revisionHistoryLimit: {{ .Values.imageRenderer.revisionHistoryLimit }} + selector: + matchLabels: + {{- include "grafana.imageRenderer.selectorLabels" . | nindent 6 }} +{{- with .Values.imageRenderer.deploymentStrategy }} + strategy: +{{ toYaml . | trim | indent 4 }} +{{- end }} + template: + metadata: + labels: + {{- include "grafana.imageRenderer.selectorLabels" . | nindent 8 }} +{{- with .Values.imageRenderer.podLabels }} +{{ toYaml . | indent 8 }} +{{- end }} + annotations: + checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} +{{- with .Values.imageRenderer.podAnnotations }} +{{ toYaml . | indent 8 }} +{{- end }} + spec: + + {{- if .Values.imageRenderer.schedulerName }} + schedulerName: "{{ .Values.imageRenderer.schedulerName }}" + {{- end }} + {{- if .Values.imageRenderer.serviceAccountName }} + serviceAccountName: "{{ .Values.imageRenderer.serviceAccountName }}" + {{- end }} + {{- if .Values.imageRenderer.securityContext }} + securityContext: + {{- toYaml .Values.imageRenderer.securityContext | nindent 8 }} + {{- end }} + {{- if .Values.imageRenderer.hostAliases }} + hostAliases: + {{- toYaml .Values.imageRenderer.hostAliases | nindent 8 }} + {{- end }} + {{- if .Values.imageRenderer.priorityClassName }} + priorityClassName: {{ .Values.imageRenderer.priorityClassName }} + {{- end }} + {{- if .Values.imageRenderer.image.pullSecrets }} + imagePullSecrets: + {{- range .Values.imageRenderer.image.pullSecrets }} + - name: {{ . }} + {{- end}} + {{- end }} + containers: + - name: {{ .Chart.Name }}-image-renderer + {{- if .Values.imageRenderer.image.sha }} + image: "{{ .Values.imageRenderer.image.repository }}:{{ .Values.imageRenderer.image.tag }}@sha256:{{ .Values.imageRenderer.image.sha }}" + {{- else }} + image: "{{ .Values.imageRenderer.image.repository }}:{{ .Values.imageRenderer.image.tag }}" + {{- end }} + imagePullPolicy: {{ .Values.imageRenderer.image.pullPolicy }} + {{- if .Values.imageRenderer.command }} + command: + {{- range .Values.imageRenderer.command }} + - {{ . }} + {{- end }} + {{- end}} + ports: + - name: {{ .Values.imageRenderer.service.portName }} + containerPort: {{ .Values.imageRenderer.service.port }} + protocol: TCP + livenessProbe: + httpGet: + path: / + port: {{ .Values.imageRenderer.service.portName }} + env: + - name: HTTP_PORT + value: {{ .Values.imageRenderer.service.port | quote }} + {{- range $key, $value := .Values.imageRenderer.env }} + - name: {{ $key | quote }} + value: {{ $value | quote }} + {{- end }} + securityContext: + capabilities: + drop: ['all'] + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + volumeMounts: + - mountPath: /tmp + name: image-renderer-tmpfs + {{- with .Values.imageRenderer.resources }} + resources: +{{ toYaml . | indent 12 }} + {{- end }} + {{- with .Values.imageRenderer.nodeSelector }} + nodeSelector: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.imageRenderer.affinity }} + affinity: +{{ toYaml . | indent 8 }} + {{- end }} + {{- with .Values.imageRenderer.tolerations }} + tolerations: +{{ toYaml . | indent 8 }} + {{- end }} + volumes: + - name: image-renderer-tmpfs + emptyDir: {} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/image-renderer-network-policy.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/image-renderer-network-policy.yaml new file mode 100644 index 0000000..f8ca73a --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/image-renderer-network-policy.yaml @@ -0,0 +1,76 @@ +{{- if and (.Values.imageRenderer.enabled) (.Values.imageRenderer.networkPolicy.limitIngress) }} +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ template "grafana.fullname" . }}-image-renderer-ingress + namespace: {{ template "grafana.namespace" . }} + annotations: + comment: Limit image-renderer ingress traffic from grafana +spec: + podSelector: + matchLabels: + {{- include "grafana.imageRenderer.selectorLabels" . | nindent 6 }} + {{- if .Values.imageRenderer.podLabels }} + {{ toYaml .Values.imageRenderer.podLabels | nindent 6 }} + {{- end }} + + policyTypes: + - Ingress + ingress: + - ports: + - port: {{ .Values.imageRenderer.service.port }} + protocol: TCP + from: + - namespaceSelector: + matchLabels: + name: {{ template "grafana.namespace" . }} + podSelector: + matchLabels: + {{- include "grafana.selectorLabels" . | nindent 14 }} + {{- if .Values.podLabels }} + {{ toYaml .Values.podLabels | nindent 14 }} + {{- end }} +{{ end }} + +{{- if and (.Values.imageRenderer.enabled) (.Values.imageRenderer.networkPolicy.limitEgress) }} +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ template "grafana.fullname" . }}-image-renderer-egress + namespace: {{ template "grafana.namespace" . }} + annotations: + comment: Limit image-renderer egress traffic to grafana +spec: + podSelector: + matchLabels: + {{- include "grafana.imageRenderer.selectorLabels" . | nindent 6 }} + {{- if .Values.imageRenderer.podLabels }} + {{ toYaml .Values.imageRenderer.podLabels | nindent 6 }} + {{- end }} + + policyTypes: + - Egress + egress: + # allow dns resolution + - ports: + - port: 53 + protocol: UDP + - port: 53 + protocol: TCP + # talk only to grafana + - ports: + - port: {{ .Values.service.port }} + protocol: TCP + to: + - namespaceSelector: + matchLabels: + name: {{ template "grafana.namespace" . }} + podSelector: + matchLabels: + {{- include "grafana.selectorLabels" . | nindent 14 }} + {{- if .Values.podLabels }} + {{ toYaml .Values.podLabels | nindent 14 }} + {{- end }} +{{ end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/image-renderer-service.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/image-renderer-service.yaml new file mode 100644 index 0000000..f29586c --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/image-renderer-service.yaml @@ -0,0 +1,30 @@ +{{ if .Values.imageRenderer.enabled }} +{{ if .Values.imageRenderer.service.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "grafana.fullname" . }}-image-renderer + namespace: {{ template "grafana.namespace" . }} + labels: + {{- include "grafana.imageRenderer.labels" . | nindent 4 }} +{{- if .Values.imageRenderer.service.labels }} +{{ toYaml .Values.imageRenderer.service.labels | indent 4 }} +{{- end }} +{{- with .Values.imageRenderer.service.annotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} +spec: + type: ClusterIP + {{- if .Values.imageRenderer.service.clusterIP }} + clusterIP: {{ .Values.imageRenderer.service.clusterIP }} + {{end}} + ports: + - name: {{ .Values.imageRenderer.service.portName }} + port: {{ .Values.imageRenderer.service.port }} + protocol: TCP + targetPort: {{ .Values.imageRenderer.service.targetPort }} + selector: + {{- include "grafana.imageRenderer.selectorLabels" . | nindent 4 }} +{{ end }} +{{ end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/ingress.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/ingress.yaml new file mode 100644 index 0000000..7699cec --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/ingress.yaml @@ -0,0 +1,78 @@ +{{- if .Values.ingress.enabled -}} +{{- $ingressApiIsStable := eq (include "grafana.ingress.isStable" .) "true" -}} +{{- $ingressSupportsIngressClassName := eq (include "grafana.ingress.supportsIngressClassName" .) "true" -}} +{{- $ingressSupportsPathType := eq (include "grafana.ingress.supportsPathType" .) "true" -}} +{{- $fullName := include "grafana.fullname" . -}} +{{- $servicePort := .Values.service.port -}} +{{- $ingressPath := .Values.ingress.path -}} +{{- $ingressPathType := .Values.ingress.pathType -}} +{{- $extraPaths := .Values.ingress.extraPaths -}} +apiVersion: {{ include "grafana.ingress.apiVersion" . }} +kind: Ingress +metadata: + name: {{ $fullName }} + namespace: {{ template "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} +{{- if .Values.ingress.labels }} +{{ toYaml .Values.ingress.labels | indent 4 }} +{{- end }} + {{- if .Values.ingress.annotations }} + annotations: + {{- range $key, $value := .Values.ingress.annotations }} + {{ $key }}: {{ tpl $value $ | quote }} + {{- end }} + {{- end }} +spec: + {{- if and $ingressSupportsIngressClassName .Values.ingress.ingressClassName }} + ingressClassName: {{ .Values.ingress.ingressClassName }} + {{- end -}} +{{- if .Values.ingress.tls }} + tls: +{{ tpl (toYaml .Values.ingress.tls) $ | indent 4 }} +{{- end }} + rules: + {{- if .Values.ingress.hosts }} + {{- range .Values.ingress.hosts }} + - host: {{ tpl . $}} + http: + paths: +{{- if $extraPaths }} +{{ toYaml $extraPaths | indent 10 }} +{{- end }} + - path: {{ $ingressPath }} + {{- if $ingressSupportsPathType }} + pathType: {{ $ingressPathType }} + {{- end }} + backend: + {{- if $ingressApiIsStable }} + service: + name: {{ $fullName }} + port: + number: {{ $servicePort }} + {{- else }} + serviceName: {{ $fullName }} + servicePort: {{ $servicePort }} + {{- end }} + {{- end }} + {{- else }} + - http: + paths: + - backend: + {{- if $ingressApiIsStable }} + service: + name: {{ $fullName }} + port: + number: {{ $servicePort }} + {{- else }} + serviceName: {{ $fullName }} + servicePort: {{ $servicePort }} + {{- end }} + {{- if $ingressPath }} + path: {{ $ingressPath }} + {{- end }} + {{- if $ingressSupportsPathType }} + pathType: {{ $ingressPathType }} + {{- end }} + {{- end -}} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/networkpolicy.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/networkpolicy.yaml new file mode 100644 index 0000000..fc24382 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/networkpolicy.yaml @@ -0,0 +1,37 @@ +{{- if .Values.networkPolicy.enabled }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ template "grafana.fullname" . }} + namespace: {{ template "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} +{{- if .Values.labels }} +{{ toYaml .Values.labels | indent 4 }} +{{- end }} +{{- with .Values.annotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} +spec: + podSelector: + matchLabels: + {{- include "grafana.selectorLabels" . | nindent 6 }} + ingress: + - ports: + - port: {{ .Values.service.targetPort }} + {{- if not .Values.networkPolicy.allowExternal }} + from: + - podSelector: + matchLabels: + {{ template "grafana.fullname" . }}-client: "true" + {{- if .Values.networkPolicy.explicitNamespacesSelector }} + namespaceSelector: + {{ toYaml .Values.networkPolicy.explicitNamespacesSelector | indent 12 }} + {{- end }} + - podSelector: + matchLabels: + {{- include "grafana.labels" . | nindent 14 }} + role: read + {{- end }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/poddisruptionbudget.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/poddisruptionbudget.yaml new file mode 100644 index 0000000..61813a4 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/poddisruptionbudget.yaml @@ -0,0 +1,22 @@ +{{- if .Values.podDisruptionBudget }} +apiVersion: policy/v1beta1 +kind: PodDisruptionBudget +metadata: + name: {{ template "grafana.fullname" . }} + namespace: {{ template "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} +{{- if .Values.labels }} +{{ toYaml .Values.labels | indent 4 }} +{{- end }} +spec: +{{- if .Values.podDisruptionBudget.minAvailable }} + minAvailable: {{ .Values.podDisruptionBudget.minAvailable }} +{{- end }} +{{- if .Values.podDisruptionBudget.maxUnavailable }} + maxUnavailable: {{ .Values.podDisruptionBudget.maxUnavailable }} +{{- end }} + selector: + matchLabels: + {{- include "grafana.selectorLabels" . | nindent 6 }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/podsecuritypolicy.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/podsecuritypolicy.yaml new file mode 100644 index 0000000..7de6c02 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/podsecuritypolicy.yaml @@ -0,0 +1,49 @@ +{{- if .Values.rbac.pspEnabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "grafana.fullname" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} + annotations: + seccomp.security.alpha.kubernetes.io/allowedProfileNames: 'docker/default,runtime/default' + seccomp.security.alpha.kubernetes.io/defaultProfileName: 'docker/default' + {{- if .Values.rbac.pspUseAppArmor }} + apparmor.security.beta.kubernetes.io/allowedProfileNames: 'runtime/default' + apparmor.security.beta.kubernetes.io/defaultProfileName: 'runtime/default' + {{- end }} +spec: + privileged: false + allowPrivilegeEscalation: false + requiredDropCapabilities: + # Default set from Docker, with DAC_OVERRIDE and CHOWN + - ALL + volumes: + - 'configMap' + - 'emptyDir' + - 'projected' + - 'csi' + - 'secret' + - 'downwardAPI' + - 'persistentVolumeClaim' + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'MustRunAs' + ranges: + # Forbid adding the root group. + - min: 1 + max: 65535 + fsGroup: + rule: 'MustRunAs' + ranges: + # Forbid adding the root group. + - min: 1 + max: 65535 + readOnlyRootFilesystem: false +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/pvc.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/pvc.yaml new file mode 100644 index 0000000..8d93f5c --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/pvc.yaml @@ -0,0 +1,33 @@ +{{- if and .Values.persistence.enabled (not .Values.persistence.existingClaim) (eq .Values.persistence.type "pvc")}} +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ template "grafana.fullname" . }} + namespace: {{ template "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} + {{- with .Values.persistence.annotations }} + annotations: +{{ toYaml . | indent 4 }} + {{- end }} + {{- with .Values.persistence.finalizers }} + finalizers: +{{ toYaml . | indent 4 }} + {{- end }} +spec: + accessModes: + {{- range .Values.persistence.accessModes }} + - {{ . | quote }} + {{- end }} + resources: + requests: + storage: {{ .Values.persistence.size | quote }} + {{- if .Values.persistence.storageClassName }} + storageClassName: {{ .Values.persistence.storageClassName }} + {{- end -}} + {{- with .Values.persistence.selectorLabels }} + selector: + matchLabels: +{{ toYaml . | indent 6 }} + {{- end }} +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/role.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/role.yaml new file mode 100644 index 0000000..6a1890f --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/role.yaml @@ -0,0 +1,32 @@ +{{- if and .Values.rbac.create (not .Values.rbac.useExistingRole) -}} +apiVersion: {{ template "grafana.rbac.apiVersion" . }} +kind: Role +metadata: + name: {{ template "grafana.fullname" . }} + namespace: {{ template "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} +{{- with .Values.annotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} +{{- if or .Values.rbac.pspEnabled (and .Values.rbac.namespaced (or .Values.sidecar.dashboards.enabled (or .Values.sidecar.datasources.enabled .Values.rbac.extraRoleRules))) }} +rules: +{{- if .Values.rbac.pspEnabled }} +- apiGroups: ['extensions'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: [{{ template "grafana.fullname" . }}] +{{- end }} +{{- if and .Values.rbac.namespaced (or .Values.sidecar.dashboards.enabled .Values.sidecar.datasources.enabled) }} +- apiGroups: [""] # "" indicates the core API group + resources: ["configmaps", "secrets"] + verbs: ["get", "watch", "list"] +{{- end }} +{{- with .Values.rbac.extraRoleRules }} +{{ toYaml . | indent 0 }} +{{- end}} +{{- else }} +rules: [] +{{- end }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/rolebinding.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/rolebinding.yaml new file mode 100644 index 0000000..e010725 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/rolebinding.yaml @@ -0,0 +1,25 @@ +{{- if .Values.rbac.create -}} +apiVersion: {{ template "grafana.rbac.apiVersion" . }} +kind: RoleBinding +metadata: + name: {{ template "grafana.fullname" . }} + namespace: {{ template "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} +{{- with .Values.annotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role +{{- if (not .Values.rbac.useExistingRole) }} + name: {{ template "grafana.fullname" . }} +{{- else }} + name: {{ .Values.rbac.useExistingRole }} +{{- end }} +subjects: +- kind: ServiceAccount + name: {{ template "grafana.serviceAccountName" . }} + namespace: {{ template "grafana.namespace" . }} +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/secret-env.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/secret-env.yaml new file mode 100644 index 0000000..5c09313 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/secret-env.yaml @@ -0,0 +1,14 @@ +{{- if .Values.envRenderSecret }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "grafana.fullname" . }}-env + namespace: {{ template "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} +type: Opaque +data: +{{- range $key, $val := .Values.envRenderSecret }} + {{ $key }}: {{ $val | b64enc | quote }} +{{- end -}} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/secret.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/secret.yaml new file mode 100644 index 0000000..c8aa750 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/secret.yaml @@ -0,0 +1,26 @@ +{{- if or (and (not .Values.admin.existingSecret) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD__FILE) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION)) (and .Values.ldap.enabled (not .Values.ldap.existingSecret)) }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "grafana.fullname" . }} + namespace: {{ template "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} +{{- with .Values.annotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} +type: Opaque +data: + {{- if and (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) (not .Values.admin.existingSecret) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD__FILE) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD) }} + admin-user: {{ .Values.adminUser | b64enc | quote }} + {{- if .Values.adminPassword }} + admin-password: {{ .Values.adminPassword | b64enc | quote }} + {{- else }} + admin-password: {{ template "grafana.password" . }} + {{- end }} + {{- end }} + {{- if not .Values.ldap.existingSecret }} + ldap-toml: {{ tpl .Values.ldap.config $ | b64enc | quote }} + {{- end }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/service.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/service.yaml new file mode 100644 index 0000000..ba84ef9 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/service.yaml @@ -0,0 +1,51 @@ +{{ if .Values.service.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "grafana.fullname" . }} + namespace: {{ template "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} +{{- if .Values.service.labels }} +{{ toYaml .Values.service.labels | indent 4 }} +{{- end }} +{{- with .Values.service.annotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} +spec: +{{- if (or (eq .Values.service.type "ClusterIP") (empty .Values.service.type)) }} + type: ClusterIP + {{- if .Values.service.clusterIP }} + clusterIP: {{ .Values.service.clusterIP }} + {{end}} +{{- else if eq .Values.service.type "LoadBalancer" }} + type: {{ .Values.service.type }} + {{- if .Values.service.loadBalancerIP }} + loadBalancerIP: {{ .Values.service.loadBalancerIP }} + {{- end }} + {{- if .Values.service.loadBalancerSourceRanges }} + loadBalancerSourceRanges: +{{ toYaml .Values.service.loadBalancerSourceRanges | indent 4 }} + {{- end -}} +{{- else }} + type: {{ .Values.service.type }} +{{- end }} +{{- if .Values.service.externalIPs }} + externalIPs: +{{ toYaml .Values.service.externalIPs | indent 4 }} +{{- end }} + ports: + - name: {{ .Values.service.portName }} + port: {{ .Values.service.port }} + protocol: TCP + targetPort: {{ .Values.service.targetPort }} +{{ if (and (eq .Values.service.type "NodePort") (not (empty .Values.service.nodePort))) }} + nodePort: {{.Values.service.nodePort}} +{{ end }} + {{- if .Values.extraExposePorts }} + {{- tpl (toYaml .Values.extraExposePorts) . | indent 4 }} + {{- end }} + selector: + {{- include "grafana.selectorLabels" . | nindent 4 }} +{{ end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/serviceaccount.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/serviceaccount.yaml new file mode 100644 index 0000000..7576eee --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/serviceaccount.yaml @@ -0,0 +1,13 @@ +{{- if .Values.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + {{- include "grafana.labels" . | nindent 4 }} +{{- with .Values.serviceAccount.annotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} + name: {{ template "grafana.serviceAccountName" . }} + namespace: {{ template "grafana.namespace" . }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/servicemonitor.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/servicemonitor.yaml new file mode 100644 index 0000000..4b6437e --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/servicemonitor.yaml @@ -0,0 +1,42 @@ +{{- if .Values.serviceMonitor.enabled }} +--- +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "grafana.fullname" . }} + {{- if .Values.serviceMonitor.namespace }} + namespace: {{ .Values.serviceMonitor.namespace }} + {{- end }} + labels: + {{- include "grafana.labels" . | nindent 4 }} + {{- if .Values.serviceMonitor.labels }} + {{- toYaml .Values.serviceMonitor.labels | nindent 4 }} + {{- end }} +spec: + endpoints: + - port: {{ .Values.service.portName }} + {{- with .Values.serviceMonitor.interval }} + interval: {{ . }} + {{- end }} + {{- with .Values.serviceMonitor.scrapeTimeout }} + scrapeTimeout: {{ . }} + {{- end }} + honorLabels: true + path: {{ .Values.serviceMonitor.path }} + scheme: {{ .Values.serviceMonitor.scheme }} + {{- if .Values.serviceMonitor.tlsConfig }} + tlsConfig: + {{- toYaml .Values.serviceMonitor.tlsConfig | nindent 6 }} + {{- end }} + {{- if .Values.serviceMonitor.relabelings }} + relabelings: + {{- toYaml .Values.serviceMonitor.relabelings | nindent 4 }} + {{- end }} + jobLabel: "{{ .Release.Name }}" + selector: + matchLabels: + {{- include "grafana.selectorLabels" . | nindent 8 }} + namespaceSelector: + matchNames: + - {{ .Release.Namespace }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/statefulset.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/statefulset.yaml new file mode 100644 index 0000000..ad3dd06 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/statefulset.yaml @@ -0,0 +1,52 @@ +{{- if and .Values.persistence.enabled (not .Values.persistence.existingClaim) (eq .Values.persistence.type "statefulset")}} +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ template "grafana.fullname" . }} + namespace: {{ template "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} +{{- with .Values.annotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} +spec: + replicas: {{ .Values.replicas }} + selector: + matchLabels: + {{- include "grafana.selectorLabels" . | nindent 6 }} + serviceName: {{ template "grafana.fullname" . }}-headless + template: + metadata: + labels: + {{- include "grafana.selectorLabels" . | nindent 8 }} +{{- with .Values.podLabels }} +{{ toYaml . | indent 8 }} +{{- end }} + annotations: + checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} + checksum/dashboards-json-config: {{ include (print $.Template.BasePath "/dashboards-json-configmap.yaml") . | sha256sum }} + checksum/sc-dashboard-provider-config: {{ include (print $.Template.BasePath "/configmap-dashboard-provider.yaml") . | sha256sum }} + {{- if and (or (and (not .Values.admin.existingSecret) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD__FILE) (not .Values.env.GF_SECURITY_ADMIN_PASSWORD)) (and .Values.ldap.enabled (not .Values.ldap.existingSecret))) (not .Values.env.GF_SECURITY_DISABLE_INITIAL_ADMIN_CREATION) }} + checksum/secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }} +{{- end }} +{{- with .Values.podAnnotations }} +{{ toYaml . | indent 8 }} +{{- end }} + spec: + {{- include "grafana.pod" . | nindent 6 }} + volumeClaimTemplates: + - metadata: + name: storage + spec: + accessModes: {{ .Values.persistence.accessModes }} + storageClassName: {{ .Values.persistence.storageClassName }} + resources: + requests: + storage: {{ .Values.persistence.size }} + {{- with .Values.persistence.selectorLabels }} + selector: + matchLabels: +{{ toYaml . | indent 10 }} + {{- end }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/tests/test-configmap.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/tests/test-configmap.yaml new file mode 100644 index 0000000..ff53aaf --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/tests/test-configmap.yaml @@ -0,0 +1,17 @@ +{{- if .Values.testFramework.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "grafana.fullname" . }}-test + namespace: {{ template "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} +data: + run.sh: |- + @test "Test Health" { + url="http://{{ template "grafana.fullname" . }}/api/health" + + code=$(wget --server-response --spider --timeout 10 --tries 1 ${url} 2>&1 | awk '/^ HTTP/{print $2}') + [ "$code" == "200" ] + } +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/tests/test-podsecuritypolicy.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/tests/test-podsecuritypolicy.yaml new file mode 100644 index 0000000..58b4649 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/tests/test-podsecuritypolicy.yaml @@ -0,0 +1,29 @@ +{{- if and .Values.testFramework.enabled .Values.rbac.pspEnabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "grafana.fullname" . }}-test + labels: + {{- include "grafana.labels" . | nindent 4 }} +spec: + allowPrivilegeEscalation: true + privileged: false + hostNetwork: false + hostIPC: false + hostPID: false + fsGroup: + rule: RunAsAny + seLinux: + rule: RunAsAny + supplementalGroups: + rule: RunAsAny + runAsUser: + rule: RunAsAny + volumes: + - configMap + - downwardAPI + - emptyDir + - projected + - csi + - secret +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/tests/test-role.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/tests/test-role.yaml new file mode 100644 index 0000000..6b10677 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/tests/test-role.yaml @@ -0,0 +1,14 @@ +{{- if and .Values.testFramework.enabled .Values.rbac.pspEnabled -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ template "grafana.fullname" . }}-test + namespace: {{ template "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} +rules: +- apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: [{{ template "grafana.fullname" . }}-test] +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/tests/test-rolebinding.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/tests/test-rolebinding.yaml new file mode 100644 index 0000000..58fa5e7 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/tests/test-rolebinding.yaml @@ -0,0 +1,17 @@ +{{- if and .Values.testFramework.enabled .Values.rbac.pspEnabled -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ template "grafana.fullname" . }}-test + namespace: {{ template "grafana.namespace" . }} + labels: + {{- include "grafana.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "grafana.fullname" . }}-test +subjects: +- kind: ServiceAccount + name: {{ template "grafana.serviceAccountNameTest" . }} + namespace: {{ template "grafana.namespace" . }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/tests/test-serviceaccount.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/tests/test-serviceaccount.yaml new file mode 100644 index 0000000..5c33507 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/tests/test-serviceaccount.yaml @@ -0,0 +1,9 @@ +{{- if and .Values.testFramework.enabled .Values.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + {{- include "grafana.labels" . | nindent 4 }} + name: {{ template "grafana.serviceAccountNameTest" . }} + namespace: {{ template "grafana.namespace" . }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/tests/test.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/tests/test.yaml new file mode 100644 index 0000000..cdc86e5 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/templates/tests/test.yaml @@ -0,0 +1,48 @@ +{{- if .Values.testFramework.enabled }} +apiVersion: v1 +kind: Pod +metadata: + name: {{ template "grafana.fullname" . }}-test + labels: + {{- include "grafana.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test-success + namespace: {{ template "grafana.namespace" . }} +spec: + serviceAccountName: {{ template "grafana.serviceAccountNameTest" . }} + {{- if .Values.testFramework.securityContext }} + securityContext: {{ toYaml .Values.testFramework.securityContext | nindent 4 }} + {{- end }} + {{- if .Values.image.pullSecrets }} + imagePullSecrets: + {{- range .Values.image.pullSecrets }} + - name: {{ . }} + {{- end}} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: +{{ toYaml . | indent 4 }} + {{- end }} + {{- with .Values.affinity }} + affinity: +{{ toYaml . | indent 4 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: +{{ toYaml . | indent 4 }} + {{- end }} + containers: + - name: {{ .Release.Name }}-test + image: "{{ .Values.testFramework.image}}:{{ .Values.testFramework.tag }}" + imagePullPolicy: "{{ .Values.testFramework.imagePullPolicy}}" + command: ["/opt/bats/bin/bats", "-t", "/tests/run.sh"] + volumeMounts: + - mountPath: /tests + name: tests + readOnly: true + volumes: + - name: tests + configMap: + name: {{ template "grafana.fullname" . }}-test + restartPolicy: Never +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/values.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/values.yaml new file mode 100644 index 0000000..8c3cd1c --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/grafana/values.yaml @@ -0,0 +1,846 @@ +rbac: + create: true + ## Use an existing ClusterRole/Role (depending on rbac.namespaced false/true) + # useExistingRole: name-of-some-(cluster)role + pspEnabled: true + pspUseAppArmor: true + namespaced: false + extraRoleRules: [] + # - apiGroups: [] + # resources: [] + # verbs: [] + extraClusterRoleRules: [] + # - apiGroups: [] + # resources: [] + # verbs: [] +serviceAccount: + create: true + name: + nameTest: +# annotations: +# eks.amazonaws.com/role-arn: arn:aws:iam::123456789000:role/iam-role-name-here + autoMount: true + +replicas: 1 + +## Create a headless service for the deployment +headlessService: false + +## Create HorizontalPodAutoscaler object for deployment type +# +autoscaling: + enabled: false +# minReplicas: 1 +# maxReplicas: 10 +# metrics: +# - type: Resource +# resource: +# name: cpu +# targetAverageUtilization: 60 +# - type: Resource +# resource: +# name: memory +# targetAverageUtilization: 60 + +## See `kubectl explain poddisruptionbudget.spec` for more +## ref: https://kubernetes.io/docs/tasks/run-application/configure-pdb/ +podDisruptionBudget: {} +# minAvailable: 1 +# maxUnavailable: 1 + +## See `kubectl explain deployment.spec.strategy` for more +## ref: https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#strategy +deploymentStrategy: + type: RollingUpdate + +readinessProbe: + httpGet: + path: /api/health + port: 3000 + +livenessProbe: + httpGet: + path: /api/health + port: 3000 + initialDelaySeconds: 60 + timeoutSeconds: 30 + failureThreshold: 10 + +## Use an alternate scheduler, e.g. "stork". +## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ +## +# schedulerName: "default-scheduler" + +image: + repository: grafana/grafana + tag: 8.4.2 + sha: "" + pullPolicy: IfNotPresent + + ## Optionally specify an array of imagePullSecrets. + ## Secrets must be manually created in the namespace. + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ + ## + # pullSecrets: + # - myRegistrKeySecretName + +testFramework: + enabled: true + image: "bats/bats" + tag: "v1.4.1" + imagePullPolicy: IfNotPresent + securityContext: {} + +securityContext: + runAsUser: 472 + runAsGroup: 472 + fsGroup: 472 + +containerSecurityContext: + {} + +extraConfigmapMounts: [] + # - name: certs-configmap + # mountPath: /etc/grafana/ssl/ + # subPath: certificates.crt # (optional) + # configMap: certs-configmap + # readOnly: true + + +extraEmptyDirMounts: [] + # - name: provisioning-notifiers + # mountPath: /etc/grafana/provisioning/notifiers + + +# Apply extra labels to common labels. +extraLabels: {} + +## Assign a PriorityClassName to pods if set +# priorityClassName: + +downloadDashboardsImage: + repository: curlimages/curl + tag: 7.73.0 + sha: "" + pullPolicy: IfNotPresent + +downloadDashboards: + env: {} + envFromSecret: "" + resources: {} + +## Pod Annotations +# podAnnotations: {} + +## Pod Labels +# podLabels: {} + +podPortName: grafana + +## Deployment annotations +# annotations: {} + +## Expose the grafana service to be accessed from outside the cluster (LoadBalancer service). +## or access it from within the cluster (ClusterIP service). Set the service type and the port to serve it. +## ref: http://kubernetes.io/docs/user-guide/services/ +## +service: + enabled: true + type: ClusterIP + port: 80 + targetPort: 3000 + # targetPort: 4181 To be used with a proxy extraContainer + annotations: {} + labels: {} + portName: service + +serviceMonitor: + ## If true, a ServiceMonitor CRD is created for a prometheus operator + ## https://github.com/coreos/prometheus-operator + ## + enabled: false + path: /metrics + # namespace: monitoring (defaults to use the namespace this chart is deployed to) + labels: {} + interval: 1m + scheme: http + tlsConfig: {} + scrapeTimeout: 30s + relabelings: [] + +extraExposePorts: [] + # - name: keycloak + # port: 8080 + # targetPort: 8080 + # type: ClusterIP + +# overrides pod.spec.hostAliases in the grafana deployment's pods +hostAliases: [] + # - ip: "1.2.3.4" + # hostnames: + # - "my.host.com" + +ingress: + enabled: false + # For Kubernetes >= 1.18 you should specify the ingress-controller via the field ingressClassName + # See https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/#specifying-the-class-of-an-ingress + # ingressClassName: nginx + # Values can be templated + annotations: {} + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: "true" + labels: {} + path: / + + # pathType is only for k8s >= 1.1= + pathType: Prefix + + hosts: + - chart-example.local + ## Extra paths to prepend to every host configuration. This is useful when working with annotation based services. + extraPaths: [] + # - path: /* + # backend: + # serviceName: ssl-redirect + # servicePort: use-annotation + ## Or for k8s > 1.19 + # - path: /* + # pathType: Prefix + # backend: + # service: + # name: ssl-redirect + # port: + # name: use-annotation + + + tls: [] + # - secretName: chart-example-tls + # hosts: + # - chart-example.local + +resources: {} +# limits: +# cpu: 100m +# memory: 128Mi +# requests: +# cpu: 100m +# memory: 128Mi + +## Node labels for pod assignment +## ref: https://kubernetes.io/docs/user-guide/node-selection/ +# +nodeSelector: {} + +## Tolerations for pod assignment +## ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ +## +tolerations: [] + +## Affinity for pod assignment +## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity +## +affinity: {} + +extraInitContainers: [] + +## Enable an Specify container in extraContainers. This is meant to allow adding an authentication proxy to a grafana pod +extraContainers: "" +# extraContainers: | +# - name: proxy +# image: quay.io/gambol99/keycloak-proxy:latest +# args: +# - -provider=github +# - -client-id= +# - -client-secret= +# - -github-org= +# - -email-domain=* +# - -cookie-secret= +# - -http-address=http://0.0.0.0:4181 +# - -upstream-url=http://127.0.0.1:3000 +# ports: +# - name: proxy-web +# containerPort: 4181 + +## Volumes that can be used in init containers that will not be mounted to deployment pods +extraContainerVolumes: [] +# - name: volume-from-secret +# secret: +# secretName: secret-to-mount +# - name: empty-dir-volume +# emptyDir: {} + +## Enable persistence using Persistent Volume Claims +## ref: http://kubernetes.io/docs/user-guide/persistent-volumes/ +## +persistence: + type: pvc + enabled: false + # storageClassName: default + accessModes: + - ReadWriteOnce + size: 10Gi + # annotations: {} + finalizers: + - kubernetes.io/pvc-protection + # selectorLabels: {} + # subPath: "" + # existingClaim: + + ## If persistence is not enabled, this allows to mount the + ## local storage in-memory to improve performance + ## + inMemory: + enabled: false + ## The maximum usage on memory medium EmptyDir would be + ## the minimum value between the SizeLimit specified + ## here and the sum of memory limits of all containers in a pod + ## + # sizeLimit: 300Mi + +initChownData: + ## If false, data ownership will not be reset at startup + ## This allows the prometheus-server to be run with an arbitrary user + ## + enabled: true + + ## initChownData container image + ## + image: + repository: busybox + tag: "1.31.1" + sha: "" + pullPolicy: IfNotPresent + + ## initChownData resource requests and limits + ## Ref: http://kubernetes.io/docs/user-guide/compute-resources/ + ## + resources: {} + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + + +# Administrator credentials when not using an existing secret (see below) +adminUser: admin +# adminPassword: strongpassword + +# Use an existing secret for the admin user. +admin: + existingSecret: "" + userKey: admin-user + passwordKey: admin-password + +## Define command to be executed at startup by grafana container +## Needed if using `vault-env` to manage secrets (ref: https://banzaicloud.com/blog/inject-secrets-into-pods-vault/) +## Default is "run.sh" as defined in grafana's Dockerfile +# command: +# - "sh" +# - "/run.sh" + +## Use an alternate scheduler, e.g. "stork". +## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ +## +# schedulerName: + +## Extra environment variables that will be pass onto deployment pods +## +## to provide grafana with access to CloudWatch on AWS EKS: +## 1. create an iam role of type "Web identity" with provider oidc.eks.* (note the provider for later) +## 2. edit the "Trust relationships" of the role, add a line inside the StringEquals clause using the +## same oidc eks provider as noted before (same as the existing line) +## also, replace NAMESPACE and prometheus-operator-grafana with the service account namespace and name +## +## "oidc.eks.us-east-1.amazonaws.com/id/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:sub": "system:serviceaccount:NAMESPACE:prometheus-operator-grafana", +## +## 3. attach a policy to the role, you can use a built in policy called CloudWatchReadOnlyAccess +## 4. use the following env: (replace 123456789000 and iam-role-name-here with your aws account number and role name) +## +## env: +## AWS_ROLE_ARN: arn:aws:iam::123456789000:role/iam-role-name-here +## AWS_WEB_IDENTITY_TOKEN_FILE: /var/run/secrets/eks.amazonaws.com/serviceaccount/token +## AWS_REGION: us-east-1 +## +## 5. uncomment the EKS section in extraSecretMounts: below +## 6. uncomment the annotation section in the serviceAccount: above +## make sure to replace arn:aws:iam::123456789000:role/iam-role-name-here with your role arn + +env: {} + +## "valueFrom" environment variable references that will be added to deployment pods +## ref: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#envvarsource-v1-core +## Renders in container spec as: +## env: +## ... +## - name: +## valueFrom: +## +envValueFrom: {} + # ENV_NAME: + # configMapKeyRef: + # name: configmap-name + # key: value_key + +## The name of a secret in the same kubernetes namespace which contain values to be added to the environment +## This can be useful for auth tokens, etc. Value is templated. +envFromSecret: "" + +## Sensible environment variables that will be rendered as new secret object +## This can be useful for auth tokens, etc +envRenderSecret: {} + +## The names of secrets in the same kubernetes namespace which contain values to be added to the environment +## Each entry should contain a name key, and can optionally specify whether the secret must be defined with an optional key. +envFromSecrets: [] +## - name: secret-name +## optional: true + +# Inject Kubernetes services as environment variables. +# See https://kubernetes.io/docs/concepts/services-networking/connect-applications-service/#environment-variables +enableServiceLinks: true + +## Additional grafana server secret mounts +# Defines additional mounts with secrets. Secrets must be manually created in the namespace. +extraSecretMounts: [] + # - name: secret-files + # mountPath: /etc/secrets + # secretName: grafana-secret-files + # readOnly: true + # subPath: "" + # + # for AWS EKS (cloudwatch) use the following (see also instruction in env: above) + # - name: aws-iam-token + # mountPath: /var/run/secrets/eks.amazonaws.com/serviceaccount + # readOnly: true + # projected: + # defaultMode: 420 + # sources: + # - serviceAccountToken: + # audience: sts.amazonaws.com + # expirationSeconds: 86400 + # path: token + # + # for CSI e.g. Azure Key Vault use the following + # - name: secrets-store-inline + # mountPath: /run/secrets + # readOnly: true + # csi: + # driver: secrets-store.csi.k8s.io + # readOnly: true + # volumeAttributes: + # secretProviderClass: "akv-grafana-spc" + # nodePublishSecretRef: # Only required when using service principal mode + # name: grafana-akv-creds # Only required when using service principal mode + +## Additional grafana server volume mounts +# Defines additional volume mounts. +extraVolumeMounts: [] + # - name: extra-volume-0 + # mountPath: /mnt/volume0 + # readOnly: true + # existingClaim: volume-claim + # - name: extra-volume-1 + # mountPath: /mnt/volume1 + # readOnly: true + # hostPath: /usr/shared/ + +## Pass the plugins you want installed as a list. +## +plugins: [] + # - digrich-bubblechart-panel + # - grafana-clock-panel + +## Configure grafana datasources +## ref: http://docs.grafana.org/administration/provisioning/#datasources +## +datasources: {} +# datasources.yaml: +# apiVersion: 1 +# datasources: +# - name: Prometheus +# type: prometheus +# url: http://prometheus-prometheus-server +# access: proxy +# isDefault: true +# - name: CloudWatch +# type: cloudwatch +# access: proxy +# uid: cloudwatch +# editable: false +# jsonData: +# authType: default +# defaultRegion: us-east-1 + +## Configure notifiers +## ref: http://docs.grafana.org/administration/provisioning/#alert-notification-channels +## +notifiers: {} +# notifiers.yaml: +# notifiers: +# - name: email-notifier +# type: email +# uid: email1 +# # either: +# org_id: 1 +# # or +# org_name: Main Org. +# is_default: true +# settings: +# addresses: an_email_address@example.com +# delete_notifiers: + +## Configure grafana dashboard providers +## ref: http://docs.grafana.org/administration/provisioning/#dashboards +## +## `path` must be /var/lib/grafana/dashboards/ +## +dashboardProviders: {} +# dashboardproviders.yaml: +# apiVersion: 1 +# providers: +# - name: 'default' +# orgId: 1 +# folder: '' +# type: file +# disableDeletion: false +# editable: true +# options: +# path: /var/lib/grafana/dashboards/default + +## Configure grafana dashboard to import +## NOTE: To use dashboards you must also enable/configure dashboardProviders +## ref: https://grafana.com/dashboards +## +## dashboards per provider, use provider name as key. +## +dashboards: {} + # default: + # some-dashboard: + # json: | + # $RAW_JSON + # custom-dashboard: + # file: dashboards/custom-dashboard.json + # prometheus-stats: + # gnetId: 2 + # revision: 2 + # datasource: Prometheus + # local-dashboard: + # url: https://example.com/repository/test.json + # token: '' + # local-dashboard-base64: + # url: https://example.com/repository/test-b64.json + # token: '' + # b64content: true + +## Reference to external ConfigMap per provider. Use provider name as key and ConfigMap name as value. +## A provider dashboards must be defined either by external ConfigMaps or in values.yaml, not in both. +## ConfigMap data example: +## +## data: +## example-dashboard.json: | +## RAW_JSON +## +dashboardsConfigMaps: {} +# default: "" + +## Grafana's primary configuration +## NOTE: values in map will be converted to ini format +## ref: http://docs.grafana.org/installation/configuration/ +## +grafana.ini: + paths: + data: /var/lib/grafana/ + logs: /var/log/grafana + plugins: /var/lib/grafana/plugins + provisioning: /etc/grafana/provisioning + analytics: + check_for_updates: true + log: + mode: console + grafana_net: + url: https://grafana.net +## grafana Authentication can be enabled with the following values on grafana.ini + # server: + # The full public facing url you use in browser, used for redirects and emails + # root_url: + # https://grafana.com/docs/grafana/latest/auth/github/#enable-github-in-grafana + # auth.github: + # enabled: false + # allow_sign_up: false + # scopes: user:email,read:org + # auth_url: https://github.com/login/oauth/authorize + # token_url: https://github.com/login/oauth/access_token + # api_url: https://api.github.com/user + # team_ids: + # allowed_organizations: + # client_id: + # client_secret: +## LDAP Authentication can be enabled with the following values on grafana.ini +## NOTE: Grafana will fail to start if the value for ldap.toml is invalid + # auth.ldap: + # enabled: true + # allow_sign_up: true + # config_file: /etc/grafana/ldap.toml + +## Grafana's LDAP configuration +## Templated by the template in _helpers.tpl +## NOTE: To enable the grafana.ini must be configured with auth.ldap.enabled +## ref: http://docs.grafana.org/installation/configuration/#auth-ldap +## ref: http://docs.grafana.org/installation/ldap/#configuration +ldap: + enabled: false + # `existingSecret` is a reference to an existing secret containing the ldap configuration + # for Grafana in a key `ldap-toml`. + existingSecret: "" + # `config` is the content of `ldap.toml` that will be stored in the created secret + config: "" + # config: |- + # verbose_logging = true + + # [[servers]] + # host = "my-ldap-server" + # port = 636 + # use_ssl = true + # start_tls = false + # ssl_skip_verify = false + # bind_dn = "uid=%s,ou=users,dc=myorg,dc=com" + +## Grafana's SMTP configuration +## NOTE: To enable, grafana.ini must be configured with smtp.enabled +## ref: http://docs.grafana.org/installation/configuration/#smtp +smtp: + # `existingSecret` is a reference to an existing secret containing the smtp configuration + # for Grafana. + existingSecret: "" + userKey: "user" + passwordKey: "password" + +## Sidecars that collect the configmaps with specified label and stores the included files them into the respective folders +## Requires at least Grafana 5 to work and can't be used together with parameters dashboardProviders, datasources and dashboards +sidecar: + image: + repository: quay.io/kiwigrid/k8s-sidecar + tag: 1.15.6 + sha: "" + imagePullPolicy: IfNotPresent + resources: {} +# limits: +# cpu: 100m +# memory: 100Mi +# requests: +# cpu: 50m +# memory: 50Mi + securityContext: {} + # skipTlsVerify Set to true to skip tls verification for kube api calls + # skipTlsVerify: true + enableUniqueFilenames: false + dashboards: + enabled: false + SCProvider: true + # label that the configmaps with dashboards are marked with + label: grafana_dashboard + # value of label that the configmaps with dashboards are set to + labelValue: null + # folder in the pod that should hold the collected dashboards (unless `defaultFolderName` is set) + folder: /tmp/dashboards + # The default folder name, it will create a subfolder under the `folder` and put dashboards in there instead + defaultFolderName: null + # Namespaces list. If specified, the sidecar will search for config-maps/secrets inside these namespaces. + # Otherwise the namespace in which the sidecar is running will be used. + # It's also possible to specify ALL to search in all namespaces. + searchNamespace: null + # Method to use to detect ConfigMap changes. With WATCH the sidecar will do a WATCH requests, with SLEEP it will list all ConfigMaps, then sleep for 60 seconds. + watchMethod: WATCH + # search in configmap, secret or both + resource: both + # If specified, the sidecar will look for annotation with this name to create folder and put graph here. + # You can use this parameter together with `provider.foldersFromFilesStructure`to annotate configmaps and create folder structure. + folderAnnotation: null + # Absolute path to shell script to execute after a configmap got reloaded + script: null + # watchServerTimeout: request to the server, asking it to cleanly close the connection after that. + # defaults to 60sec; much higher values like 3600 seconds (1h) are feasible for non-Azure K8S + # watchServerTimeout: 3600 + # + # watchClientTimeout: is a client-side timeout, configuring your local socket. + # If you have a network outage dropping all packets with no RST/FIN, + # this is how long your client waits before realizing & dropping the connection. + # defaults to 66sec (sic!) + # watchClientTimeout: 60 + # + # provider configuration that lets grafana manage the dashboards + provider: + # name of the provider, should be unique + name: sidecarProvider + # orgid as configured in grafana + orgid: 1 + # folder in which the dashboards should be imported in grafana + folder: '' + # type of the provider + type: file + # disableDelete to activate a import-only behaviour + disableDelete: false + # allow updating provisioned dashboards from the UI + allowUiUpdates: false + # allow Grafana to replicate dashboard structure from filesystem + foldersFromFilesStructure: false + # Additional dashboard sidecar volume mounts + extraMounts: [] + datasources: + enabled: false + # label that the configmaps with datasources are marked with + label: grafana_datasource + # value of label that the configmaps with datasources are set to + labelValue: null + # If specified, the sidecar will search for datasource config-maps inside this namespace. + # Otherwise the namespace in which the sidecar is running will be used. + # It's also possible to specify ALL to search in all namespaces + searchNamespace: null + # Method to use to detect ConfigMap changes. With WATCH the sidecar will do a WATCH requests, with SLEEP it will list all ConfigMaps, then sleep for 60 seconds. + watchMethod: WATCH + # search in configmap, secret or both + resource: both + # Endpoint to send request to reload datasources + reloadURL: "http://localhost:3000/api/admin/provisioning/datasources/reload" + skipReload: false + # Deploy the datasource sidecar as an initContainer in addition to a container. + # This is needed if skipReload is true, to load any datasources defined at startup time. + initDatasources: false + plugins: + enabled: false + # label that the configmaps with plugins are marked with + label: grafana_plugin + # value of label that the configmaps with plugins are set to + labelValue: null + # If specified, the sidecar will search for plugin config-maps inside this namespace. + # Otherwise the namespace in which the sidecar is running will be used. + # It's also possible to specify ALL to search in all namespaces + searchNamespace: null + # Method to use to detect ConfigMap changes. With WATCH the sidecar will do a WATCH requests, with SLEEP it will list all ConfigMaps, then sleep for 60 seconds. + watchMethod: WATCH + # search in configmap, secret or both + resource: both + # Endpoint to send request to reload plugins + reloadURL: "http://localhost:3000/api/admin/provisioning/plugins/reload" + skipReload: false + # Deploy the datasource sidecar as an initContainer in addition to a container. + # This is needed if skipReload is true, to load any plugins defined at startup time. + initPlugins: false + notifiers: + enabled: false + # label that the configmaps with notifiers are marked with + label: grafana_notifier + # If specified, the sidecar will search for notifier config-maps inside this namespace. + # Otherwise the namespace in which the sidecar is running will be used. + # It's also possible to specify ALL to search in all namespaces + searchNamespace: null + # search in configmap, secret or both + resource: both + +## Override the deployment namespace +## +namespaceOverride: "" + +## Number of old ReplicaSets to retain +## +revisionHistoryLimit: 10 + +## Add a seperate remote image renderer deployment/service +imageRenderer: + # Enable the image-renderer deployment & service + enabled: false + replicas: 1 + image: + # image-renderer Image repository + repository: grafana/grafana-image-renderer + # image-renderer Image tag + tag: latest + # image-renderer Image sha (optional) + sha: "" + # image-renderer ImagePullPolicy + pullPolicy: Always + # extra environment variables + env: + HTTP_HOST: "0.0.0.0" + # RENDERING_ARGS: --no-sandbox,--disable-gpu,--window-size=1280x758 + # RENDERING_MODE: clustered + # IGNORE_HTTPS_ERRORS: true + # image-renderer deployment serviceAccount + serviceAccountName: "" + # image-renderer deployment securityContext + securityContext: {} + # image-renderer deployment Host Aliases + hostAliases: [] + # image-renderer deployment priority class + priorityClassName: '' + service: + # Enable the image-renderer service + enabled: true + # image-renderer service port name + portName: 'http' + # image-renderer service port used by both service and deployment + port: 8081 + targetPort: 8081 + # If https is enabled in Grafana, this needs to be set as 'https' to correctly configure the callback used in Grafana + grafanaProtocol: http + # In case a sub_path is used this needs to be added to the image renderer callback + grafanaSubPath: "" + # name of the image-renderer port on the pod + podPortName: http + # number of image-renderer replica sets to keep + revisionHistoryLimit: 10 + networkPolicy: + # Enable a NetworkPolicy to limit inbound traffic to only the created grafana pods + limitIngress: true + # Enable a NetworkPolicy to limit outbound traffic to only the created grafana pods + limitEgress: false + resources: {} +# limits: +# cpu: 100m +# memory: 100Mi +# requests: +# cpu: 50m +# memory: 50Mi + +networkPolicy: + ## @param networkPolicy.enabled Enable creation of NetworkPolicy resources. Only Ingress traffic is filtered for now. + ## + enabled: false + ## @param networkPolicy.allowExternal Don't require client label for connections + ## The Policy model to apply. When set to false, only pods with the correct + ## client label will have network access to grafana port defined. + ## When true, grafana will accept connections from any source + ## (with the correct destination port). + ## + allowExternal: true + ## @param networkPolicy.explicitNamespacesSelector A Kubernetes LabelSelector to explicitly select namespaces from which traffic could be allowed + ## If explicitNamespacesSelector is missing or set to {}, only client Pods that are in the networkPolicy's namespace + ## and that match other criteria, the ones that have the good label, can reach the grafana. + ## But sometimes, we want the grafana to be accessible to clients from other namespaces, in this case, we can use this + ## LabelSelector to select these namespaces, note that the networkPolicy's namespace should also be explicitly added. + ## + ## Example: + ## explicitNamespacesSelector: + ## matchLabels: + ## role: frontend + ## matchExpressions: + ## - {key: role, operator: In, values: [frontend]} + ## + explicitNamespacesSelector: {} + +# Enable backward compatibility of kubernetes where version below 1.13 doesn't have the enableServiceLinks option +enableKubeBackwardCompatibility: false + +# Create a dynamic manifests via values: +extraObjects: [] + # - apiVersion: "kubernetes-client.io/v1" + # kind: ExternalSecret + # metadata: + # name: grafana-secrets + # spec: + # backendType: gcpSecretsManager + # data: + # - key: grafana-admin-password + # name: adminPassword diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/.helmignore b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/.helmignore new file mode 100644 index 0000000..e12c0b4 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/.helmignore @@ -0,0 +1,2 @@ +tests/ +.pytest_cache/ diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/Chart.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/Chart.yaml new file mode 100644 index 0000000..6c09b44 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/Chart.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +appVersion: 7.17.1 +description: Official Elastic helm chart for Logstash +home: https://github.com/elastic/helm-charts +icon: https://helm.elastic.co/icons/logstash.png +maintainers: +- email: helm-charts@elastic.co + name: Elastic +name: logstash +sources: +- https://github.com/elastic/logstash +version: 7.17.1 diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/Makefile b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/Makefile new file mode 100644 index 0000000..22218a1 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/Makefile @@ -0,0 +1 @@ +include ../helpers/common.mk diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/README.md b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/README.md new file mode 100644 index 0000000..682925d --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/README.md @@ -0,0 +1,237 @@ +# Logstash Helm Chart + +[![Build Status](https://img.shields.io/jenkins/s/https/devops-ci.elastic.co/job/elastic+helm-charts+master.svg)](https://devops-ci.elastic.co/job/elastic+helm-charts+master/) [![Artifact HUB](https://img.shields.io/endpoint?url=https://artifacthub.io/badge/repository/elastic)](https://artifacthub.io/packages/search?repo=elastic) + +This Helm chart is a lightweight way to configure and run our official +[Logstash Docker image][]. + +**Warning**: This functionality is in beta and is subject to change. +The design and code is less mature than official GA features and is being +provided as-is with no warranties. Alpha features are not subject to the support +SLA of official GA features (see [supported configurations][] for more details). + + + + + + + +- [Requirements](#requirements) +- [Installing](#installing) + - [Install released version using Helm repository](#install-released-version-using-helm-repository) + - [Install development version from a branch](#install-development-version-from-a-branch) +- [Upgrading](#upgrading) +- [Usage notes](#usage-notes) +- [Configuration](#configuration) +- [FAQ](#faq) + - [How to install OSS version of Logstash?](#how-to-install-oss-version-of-logstash) + - [How to install plugins?](#how-to-install-plugins) +- [Contributing](#contributing) + + + + + + +## Requirements + +* Kubernetes >= 1.14 +* [Helm][] >= 2.17.0 + +See [supported configurations][] for more details. + + +## Installing + +This chart is tested with the latest 7.17.1 version. + +### Install released version using Helm repository + +* Add the Elastic Helm charts repo: +`helm repo add elastic https://helm.elastic.co` + +* Install it: + - with Helm 3: `helm install logstash --version elastic/logstash` + - with Helm 2 (deprecated): `helm install --name logstash --version elastic/logstash` + +### Install development version from a branch + +* Clone the git repo: `git clone git@github.com:elastic/helm-charts.git` + +* Checkout the branch : `git checkout 7.17` + +* Install it: + - with Helm 3: `helm install logstash ./helm-charts/logstash --set imageTag=7.17.1` + - with Helm 2 (deprecated): `helm install --name logstash ./helm-charts/logstash --set imageTag=7.17.1` + + +## Upgrading + +Please always check [CHANGELOG.md][] and [BREAKING_CHANGES.md][] before +upgrading to a new chart version. + + +## Usage notes + +* This repo includes a number of [examples][] configurations which can be used +as a reference. They are also used in the automated testing of this chart +* Automated testing of this chart is currently only run against GKE (Google +Kubernetes Engine). +* The chart deploys a StatefulSet and by default will do an automated rolling +update of your cluster. It does this by waiting for the cluster health to become +green after each instance is updated. If you prefer to update manually you can +set `OnDelete` [updateStrategy][]. +* It is important to verify that the JVM heap size in `logstashJavaOpts` and to +set the CPU/Memory `resources` to something suitable for your cluster. +* We have designed this chart to be very un-opinionated about how to configure +Logstash. It exposes ways to set environment variables and mount secrets inside +of the container. Doing this makes it much easier for this chart to support +multiple versions with minimal changes. +* `logstash.yml` configuration files can be set either by a ConfigMap using +`logstashConfig` in `values.yml` or by environment variables using `extraEnvs` +in `values.yml` , however Logstash Docker image can't mix both methods as +defining settings with environment variables causes `logstash.yml` to be +modified in place while using ConfigMap bind-mount the same file (more details +in this [note][]). +* When overriding `logstash.yml`, `http.host: 0.0.0.0` should always be included +to make default probes work. If restricting HTTP API to 127.0.0.1 is required by +using `http.host: 127.0.0.1`, default probes should be disabled or overridden +(see [values.yaml][] for the good syntax). +* An ingress is provided that can be used to expose the HTTP port. This can be +useful for the [http input plugin][], for instance. + + +## Configuration + +| Parameter | Description | Default | +|---------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------| +| `antiAffinityTopologyKey` | The [anti-affinity][] topology key]. By default this will prevent multiple Logstash nodes from running on the same Kubernetes node | `kubernetes.io/hostname` | +| `antiAffinity` | Setting this to hard enforces the [anti-affinity][] rules. If it is set to soft it will be done "best effort". Other values will be ignored | `hard` | +| `envFrom` | Templatable string to be passed to the [environment from variables][] which will be appended to the `envFrom:` definition for the container | `[]` | +| `extraContainers` | Templatable string of additional containers to be passed to the `tpl` function | `[]` | +| `extraEnvs` | Extra [environment variables][] which will be appended to the `env:` definition for the container | `[]` | +| `extraInitContainers` | Templatable string of additional `initContainers` to be passed to the `tpl` function | `[]` | +| `extraPorts` | An array of extra ports to open on the pod | `[]` | +| `extraVolumeMounts` | Templatable string of additional `volumeMounts` to be passed to the `tpl` function | `[]` | +| `extraVolumes` | Templatable string of additional `volumes` to be passed to the `tpl` function | `[]` | +| `fullnameOverride` | Overrides the full name of the resources. If not set the name will default to " `.Release.Name` - `.Values.nameOverride or .Chart.Name` " | `""` | +| `hostAliases` | Configurable [hostAliases][] | `[]` | +| `httpPort` | The http port that Kubernetes will use for the healthchecks and the service | `9600` | +| `imagePullPolicy` | The Kubernetes [imagePullPolicy][] value | `IfNotPresent` | +| `imagePullSecrets` | Configuration for [imagePullSecrets][] so that you can use a private registry for your image | `[]` | +| `imageTag` | The Logstash Docker image tag | `7.17.1` | +| `image` | The Logstash Docker image | `docker.elastic.co/logstash/logstash` | +| `labels` | Configurable [labels][] applied to all Logstash pods | `{}` | +| `ingress` | Configurable [ingress][] for external access to Logstash HTTP port. | see [values.yaml][] | +| `lifecycle` | Allows you to add lifecycle configuration. See [values.yaml][] for an example of the formatting | `{}` | +| `livenessProbe` | Configuration fields for the liveness [probe][] | see [values.yaml][] | +| `logstashConfig` | Allows you to add any config files in `/usr/share/logstash/config/` such as `logstash.yml` and `log4j2.properties` See [values.yaml][] for an example of the formatting | `{}` | +| `logstashJavaOpts` | Java options for Logstash. This is where you should configure the JVM heap size | `-Xmx1g -Xms1g` | +| `logstashPipeline` | Allows you to add any pipeline files in `/usr/share/logstash/pipeline/` | `{}` | +| `logstashPatternDir` | Allows you to define a custom directory to store pattern files | `/usr/share/logstash/patterns/` | +| `logstashPattern` | Allows you to add any pattern files in `logstashPatternDir` | `{}` | +| `maxUnavailable` | The [maxUnavailable][] value for the pod disruption budget. By default this will prevent Kubernetes from having more than 1 unhealthy pod in the node group | `1` | +| `nameOverride` | Overrides the chart name for resources. If not set the name will default to `.Chart.Name` | `""` | +| `nodeAffinity` | Value for the [node affinity settings][] | `{}` | +| `podAffinity` | Value for the [pod affinity settings][] | `{}` | +| `nodeSelector` | Configurable [nodeSelector][] so that you can target specific nodes for your Logstash cluster | `{}` | +| `persistence` | Enables a persistent volume for Logstash data | see [values.yaml][] | +| `podAnnotations` | Configurable [annotations][] applied to all Logstash pods | `{}` | +| `podManagementPolicy` | By default Kubernetes [deploys StatefulSets serially][]. This deploys them in parallel so that they can discover each other | `Parallel` | +| `podSecurityContext` | Allows you to set the [securityContext][] for the pod | see [values.yaml][] | +| `podSecurityPolicy` | Configuration for create a pod security policy with minimal permissions to run this Helm chart with `create: true` Also can be used to reference an external pod security policy with `name: "externalPodSecurityPolicy"` | see [values.yaml][] | +| `priorityClassName` | The name of the [PriorityClass][]. No default is supplied as the PriorityClass must be created first | `""` | +| `rbac` | Configuration for creating a role, role binding and service account as part of this Helm chart with `create: true` Also can be used to reference an external service account with `serviceAccountName: "externalServiceAccountName"` | see [values.yaml][] | +| `readinessProbe` | Configuration fields for the readiness [probe][] | see [values.yaml][] | +| `replicas` | Kubernetes replica count for the StatefulSet (i.e. how many pods) | `1` | +| `resources` | Allows you to set the [resources][] for the StatefulSet | see [values.yaml][] | +| `schedulerName` | Name of the [alternate scheduler][] | `""` | +| `secrets` | Allows you easily create a secret from as variables or file. For add secrets from file, add suffix `.filepath` to the key of secret key. The value will be encoded to base64. Useful for store certificates and other secrets. | See [values.yaml][] | +| `secretMounts` | Allows you easily mount a secret as a file inside the StatefulSet. Useful for mounting certificates and other secrets. See [values.yaml][] for an example | `[]` | +| `securityContext` | Allows you to set the [securityContext][] for the container | see [values.yaml][] | +| `service` | Configurable [service][] to expose the Logstash service. | see [values.yaml][] | +| `terminationGracePeriod` | The [terminationGracePeriod][] in seconds used when trying to stop the pod | `120` | +| `tolerations` | Configurable [tolerations][] | `[]` | +| `updateStrategy` | The [updateStrategy][] for the StatefulSet. By default Kubernetes will wait for the cluster to be green after upgrading each pod. Setting this to `OnDelete` will allow you to manually delete each pod during upgrades | `RollingUpdate` | +| `volumeClaimTemplate` | Configuration for the [volumeClaimTemplate for StatefulSets][]. You will want to adjust the storage (default `30Gi` ) and the `storageClassName` if you are using a different storage class | see [values.yaml][] | + + +## FAQ + +### How to install OSS version of Logstash? + +Deploying OSS version of Logstash can be done by setting `image` value to +[Logstash OSS Docker image][] + +An example of Logstash deployment using OSS version can be found in +[examples/oss][]. + +### How to install plugins? + +The recommended way to install plugins into our Docker images is to create a +[custom Docker image][]. + +The Dockerfile would look something like: + +``` +ARG logstash_version +FROM docker.elastic.co/logstash/logstash:${logstash_version} +RUN bin/logstash-plugin install logstash-output-kafka +``` + +And then updating the `image` in values to point to your custom image. + +There are a couple reasons we recommend this: + +1. Tying the availability of Logstash to the download service to install plugins +is not a great idea or something that we recommend. Especially in Kubernetes +where it is normal and expected for a container to be moved to another host at +random times. +2. Mutating the state of a running Docker image (by installing plugins) goes +against best practices of containers and immutable infrastructure. + + +## Contributing + +Please check [CONTRIBUTING.md][] before any contribution or for any questions +about our development and testing process. + +[7.17]: https://github.com/elastic/helm-charts/releases +[BREAKING_CHANGES.md]: https://github.com/elastic/helm-charts/blob/master/BREAKING_CHANGES.md +[CHANGELOG.md]: https://github.com/elastic/helm-charts/blob/master/CHANGELOG.md +[CONTRIBUTING.md]: https://github.com/elastic/helm-charts/blob/master/CONTRIBUTING.md +[alternate scheduler]: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/#specify-schedulers-for-pods +[annotations]: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ +[anti-affinity]: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity +[deploys statefulsets serially]: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#pod-management-policies +[custom docker image]: https://www.elastic.co/guide/en/logstash/7.17/docker-config.html#_custom_images +[environment variables]: https://kubernetes.io/docs/tasks/inject-data-application/define-environment-variable-container/#using-environment-variables-inside-of-your-config +[environment from variables]: https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/#configure-all-key-value-pairs-in-a-configmap-as-container-environment-variables +[examples]: https://github.com/elastic/helm-charts/tree/7.17/logstash/examples +[examples/oss]: https://github.com/elastic/helm-charts/tree/7.17/logstash/examples/oss +[helm]: https://helm.sh +[hostAliases]: https://kubernetes.io/docs/concepts/services-networking/add-entries-to-pod-etc-hosts-with-host-aliases/ +[http input plugin]: https://www.elastic.co/guide/en/logstash/current/plugins-inputs-http.html +[imagePullPolicy]: https://kubernetes.io/docs/concepts/containers/images/#updating-images +[imagePullSecrets]: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/#create-a-pod-that-uses-your-secret +[ingress]: https://kubernetes.io/docs/concepts/services-networking/ingress/ +[kubernetes secrets]: https://kubernetes.io/docs/concepts/configuration/secret/ +[labels]: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ +[logstash docker image]: https://www.elastic.co/guide/en/logstash/7.17/docker.html +[logstash oss docker image]: https://www.docker.elastic.co/r/logstash/logstash-oss +[maxUnavailable]: https://kubernetes.io/docs/tasks/run-application/configure-pdb/#specifying-a-poddisruptionbudget +[node affinity settings]: https://kubernetes.io/docs/tasks/configure-pod-container/assign-pods-nodes-using-node-affinity/ +[pod affinity settings]: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity +[nodeSelector]: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector +[note]: https://www.elastic.co/guide/en/logstash/7.17/docker-config.html#docker-env-config +[priorityClass]: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/#priorityclass +[probe]: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/ +[resources]: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/ +[updateStrategy]: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/ +[securityContext]: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod +[service]: https://kubernetes.io/docs/concepts/services-networking/service/ +[supported configurations]: https://github.com/elastic/helm-charts/tree/7.17/README.md#supported-configurations +[terminationGracePeriod]: https://kubernetes.io/docs/concepts/workloads/pods/pod/#termination-of-pods +[tolerations]: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ +[values.yaml]: https://github.com/elastic/helm-charts/tree/7.17/logstash/values.yaml +[volumeClaimTemplate for statefulsets]: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#stable-storage diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/default/Makefile b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/default/Makefile new file mode 100644 index 0000000..03d77f8 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/default/Makefile @@ -0,0 +1,14 @@ +default: test + +include ../../../helpers/examples.mk + +RELEASE := helm-logstash-default +TIMEOUT := 1200s + +install: + helm upgrade --wait --timeout=$(TIMEOUT) --install $(RELEASE) ../../ + +test: install goss + +purge: + helm del $(RELEASE) diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/default/README.md b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/default/README.md new file mode 100644 index 0000000..7183d78 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/default/README.md @@ -0,0 +1,17 @@ +# Default + +This example deploy Logstash 7.17.1 using [default values][]. + + +## Usage + +* Deploy Logstash chart with the default values: `make install` + + +## Testing + +You can also run [goss integration tests][] using `make test` + + +[goss integration tests]: https://github.com/elastic/helm-charts/tree/7.17/logstash/examples/default/test/goss.yaml +[default values]: https://github.com/elastic/helm-charts/tree/7.17/logstash/values.yaml diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/default/test/goss.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/default/test/goss.yaml new file mode 100644 index 0000000..c0ca0d6 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/default/test/goss.yaml @@ -0,0 +1,41 @@ +user: + logstash: + exists: true + uid: 1000 + gid: 1000 + +http: + http://localhost:9600?pretty: + status: 200 + timeout: 2000 + body: + - '"version" : "7.17.1"' + - '"http_address" : "0.0.0.0:9600"' + - '"status" : "green"' + - '"workers" : 1' + - '"batch_size" : 125' + - '"batch_delay" : 50' + +file: + /usr/share/logstash/config/logstash.yml: + exists: true + mode: "0644" + owner: logstash + group: root + filetype: file + contains: + - 'http.host: "0.0.0.0"' + - 'xpack.monitoring.elasticsearch.hosts: [ "http://elasticsearch:9200" ]' + /usr/share/logstash/pipeline/logstash.conf: + exists: true + mode: "0644" + owner: logstash + group: root + filetype: file + contains: + - "input {" + - "beats {" + - "port => 5044" + - "output {" + - "stdout {" + - "codec => rubydebug" diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/elasticsearch/Makefile b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/elasticsearch/Makefile new file mode 100644 index 0000000..6b914df --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/elasticsearch/Makefile @@ -0,0 +1,15 @@ +default: test + +include ../../../helpers/examples.mk + +RELEASE := helm-logstash-elasticsearch +TIMEOUT := 1200s + +install: + helm upgrade --wait --timeout=$(TIMEOUT) --install --values values.yaml $(RELEASE) ../../ + +test: install goss + +purge: + helm del $(RELEASE) + kubectl delete $$(kubectl get pvc -l release=$(RELEASE) -o name) diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/elasticsearch/README.md b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/elasticsearch/README.md new file mode 100644 index 0000000..64174ba --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/elasticsearch/README.md @@ -0,0 +1,28 @@ +# Elasticsearch + +This example deploy Logstash 7.17.1 which connects to Elasticsearch (see +[values][]). + + +## Usage + +* Deploy [Elasticsearch Helm chart][]. + +* Deploy Logstash chart: `make install` + +* You can now setup a port forward to query Logstash indices: + + ``` + kubectl port-forward svc/elasticsearch-master 9200 + curl localhost:9200/_cat/indices + ``` + + +## Testing + +You can also run [goss integration tests][] using `make test` + + +[elasticsearch helm chart]: https://github.com/elastic/helm-charts/tree/7.17/elasticsearch/examples/default/ +[goss integration tests]: https://github.com/elastic/helm-charts/tree/7.17/logstash/examples/elasticsearch/test/goss.yaml +[values]: https://github.com/elastic/helm-charts/tree/7.17/logstash/examples/elasticsearch/values.yaml diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/elasticsearch/test/goss.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/elasticsearch/test/goss.yaml new file mode 100644 index 0000000..4ffe5b3 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/elasticsearch/test/goss.yaml @@ -0,0 +1,54 @@ +mount: + /usr/share/logstash/data: + exists: true + /usr/share/logstash/config/logstash.yml: + exists: true + opts: + - ro + /usr/share/logstash/pipeline/uptime.conf: + exists: true + opts: + - ro + +user: + logstash: + exists: true + uid: 1000 + gid: 1000 + +http: + http://localhost:9600?pretty: + status: 200 + timeout: 2000 + body: + - '"version" : "7.17.1"' + - '"http_address" : "0.0.0.0:9600"' + - '"status" : "green"' + - '"workers" : 1' + - '"batch_size" : 125' + - '"batch_delay" : 50' + http://elasticsearch-master:9200/_cat/indices: + status: 200 + timeout: 2000 + body: + - "logstash" + +file: + /usr/share/logstash/config/logstash.yml: + exists: true + mode: "0644" + owner: root + group: logstash + filetype: file + contains: + - "http.host: 0.0.0.0" + - "xpack.monitoring.enabled: false" + /usr/share/logstash/pipeline/uptime.conf: + exists: true + mode: "0644" + owner: root + group: logstash + filetype: file + contains: + - 'input { exec { command => "uptime" interval => 30 } }' + - 'output { elasticsearch { hosts => ["http://elasticsearch-master:9200"] index => "logstash" } }' diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/elasticsearch/values.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/elasticsearch/values.yaml new file mode 100644 index 0000000..c51d1a4 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/elasticsearch/values.yaml @@ -0,0 +1,12 @@ +persistence: + enabled: true + +logstashConfig: + logstash.yml: | + http.host: 0.0.0.0 + xpack.monitoring.enabled: false + +logstashPipeline: + uptime.conf: | + input { exec { command => "uptime" interval => 30 } } + output { elasticsearch { hosts => ["http://elasticsearch-master:9200"] index => "logstash" } } diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/oss/Makefile b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/oss/Makefile new file mode 100644 index 0000000..8f96d82 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/oss/Makefile @@ -0,0 +1,14 @@ +default: test + +include ../../../helpers/examples.mk + +RELEASE := helm-logstash-oss +TIMEOUT := 1200s + +install: + helm upgrade --wait --timeout=$(TIMEOUT) --install --values values.yaml $(RELEASE) ../../ + +test: install goss + +purge: + helm del $(RELEASE) diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/oss/README.md b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/oss/README.md new file mode 100644 index 0000000..4a1e64c --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/oss/README.md @@ -0,0 +1,17 @@ +# OSS + +This example deploy Logstash 7.17.1 using [Logstash OSS][] version. + + +## Usage + +* Deploy Logstash chart with the default values: `make install` + + +## Testing + +You can also run [goss integration tests][] using `make test` + + +[logstash oss]: https://www.elastic.co/downloads/logstash-oss +[goss integration tests]: https://github.com/elastic/helm-charts/tree/7.17/logstash/examples/oss/test/goss.yaml diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/oss/test/goss.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/oss/test/goss.yaml new file mode 100644 index 0000000..a426001 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/oss/test/goss.yaml @@ -0,0 +1,40 @@ +user: + logstash: + exists: true + uid: 1000 + gid: 1000 + +http: + http://localhost:9600?pretty: + status: 200 + timeout: 2000 + body: + - '"version" : "7.17.1"' + - '"http_address" : "0.0.0.0:9600"' + - '"status" : "green"' + - '"workers" : 1' + - '"batch_size" : 125' + - '"batch_delay" : 50' + +file: + /usr/share/logstash/config/logstash.yml: + exists: true + mode: "0644" + owner: logstash + group: root + filetype: file + contains: + - 'http.host: "0.0.0.0"' + /usr/share/logstash/pipeline/logstash.conf: + exists: true + mode: "0644" + owner: logstash + group: root + filetype: file + contains: + - "input {" + - "beats {" + - "port => 5044" + - "output {" + - "stdout {" + - "codec => rubydebug" diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/oss/values.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/oss/values.yaml new file mode 100644 index 0000000..5a2616c --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/oss/values.yaml @@ -0,0 +1,2 @@ +--- +image: "docker.elastic.co/logstash/logstash-oss" diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/security/Makefile b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/security/Makefile new file mode 100644 index 0000000..d5bfcb2 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/security/Makefile @@ -0,0 +1,15 @@ +default: test + +include ../../../helpers/examples.mk + +RELEASE := helm-logstash-security +TIMEOUT := 1200s + +install: + helm upgrade --wait --timeout=$(TIMEOUT) --install --values values.yaml $(RELEASE) ../../ + +test: install goss + +purge: + helm del $(RELEASE) + kubectl delete $$(kubectl get pvc -l release=$(RELEASE) -o name) diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/security/README.md b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/security/README.md new file mode 100644 index 0000000..0f9af83 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/security/README.md @@ -0,0 +1,28 @@ +# Security + +This example deploy Logstash 7.7.1 which connects to Elasticsearch using TLS +(see [values][]). + + +## Usage + +* Deploy [Elasticsearch Helm chart with security][]. + +* Deploy Logstash chart: `make install` + +* You can now setup a port forward to query Logstash indices: + + ``` + kubectl port-forward svc/elasticsearch-master 9200 + curl localhost:9200/_cat/indices + ``` + + +## Testing + +You can also run [goss integration tests][] using `make test` + + +[elasticsearch helm chart with security]: https://github.com/elastic/helm-charts/tree/master/elasticsearch/examples/security/ +[goss integration tests]: https://github.com/elastic/helm-charts/tree/master/logstash/examples/security/test/goss.yaml +[values]: https://github.com/elastic/helm-charts/tree/master/logstash/examples/security/values.yaml diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/security/test/goss.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/security/test/goss.yaml new file mode 100644 index 0000000..d095a2a --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/security/test/goss.yaml @@ -0,0 +1,62 @@ +mount: + /usr/share/logstash/data: + exists: true + /usr/share/logstash/config/logstash.yml: + exists: true + opts: + - ro + /usr/share/logstash/pipeline/uptime.conf: + exists: true + opts: + - ro + +user: + logstash: + exists: true + uid: 1000 + gid: 1000 + +http: + http://localhost:9600?pretty: + status: 200 + timeout: 2000 + body: + - '"version" : "7.17.1"' + - '"http_address" : "0.0.0.0:9600"' + - '"status" : "green"' + - '"workers" : 1' + - '"batch_size" : 125' + - '"batch_delay" : 50' + https://security-master:9200/_cat/indices: + status: 200 + timeout: 2000 + body: + - "logstash" + allow-insecure: true + username: "{{ .Env.ELASTICSEARCH_USERNAME }}" + password: "{{ .Env.ELASTICSEARCH_PASSWORD }}" + +file: + /usr/share/logstash/config/logstash.yml: + exists: true + mode: "0644" + owner: root + group: logstash + filetype: file + contains: + - "http.host: 0.0.0.0" + - "xpack.monitoring.enabled: true" + - 'xpack.monitoring.elasticsearch.hosts: ["https://security-master:9200"]' + - "xpack.monitoring.elasticsearch.ssl.certificate_authority: /usr/share/logstash/config/certs/elastic-certificate.crt" + /usr/share/logstash/pipeline/uptime.conf: + exists: true + mode: "0644" + owner: root + group: logstash + filetype: file + contains: + - 'input { exec { command => "uptime" interval => 30 } }' + - "output { elasticsearch {" + - 'hosts => ["https://security-master:9200"]' + - 'cacert => "/usr/share/logstash/config/certs/elastic-certificate.crt"' + - 'index => "logstash"' diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/security/values.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/security/values.yaml new file mode 100644 index 0000000..1457d78 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/security/values.yaml @@ -0,0 +1,40 @@ +persistence: + enabled: true + +logstashConfig: + logstash.yml: | + http.host: 0.0.0.0 + xpack.monitoring.enabled: true + xpack.monitoring.elasticsearch.username: '${ELASTICSEARCH_USERNAME}' + xpack.monitoring.elasticsearch.password: '${ELASTICSEARCH_PASSWORD}' + xpack.monitoring.elasticsearch.hosts: ["https://security-master:9200"] + xpack.monitoring.elasticsearch.ssl.certificate_authority: /usr/share/logstash/config/certs/elastic-certificate.crt + +logstashPipeline: + uptime.conf: | + input { exec { command => "uptime" interval => 30 } } + output { elasticsearch { + hosts => ["https://security-master:9200"] + cacert => "/usr/share/logstash/config/certs/elastic-certificate.crt" + user => '${ELASTICSEARCH_USERNAME}' + password => '${ELASTICSEARCH_PASSWORD}' + index => "logstash" + } + } + +secretMounts: + - name: elastic-certificate-crt + secretName: elastic-certificate-crt + path: /usr/share/logstash/config/certs + +extraEnvs: + - name: 'ELASTICSEARCH_USERNAME' + valueFrom: + secretKeyRef: + name: elastic-credentials + key: username + - name: 'ELASTICSEARCH_PASSWORD' + valueFrom: + secretKeyRef: + name: elastic-credentials + key: password diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/upgrade/Makefile b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/upgrade/Makefile new file mode 100644 index 0000000..e5ee636 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/upgrade/Makefile @@ -0,0 +1,16 @@ +default: test + +include ../../../helpers/examples.mk + +CHART := logstash +RELEASE := helm-logstash-upgrade +FROM := 7.9.0 # upgrade from version < 7.9.0 is failing due to headless service breaking change + +install: + ../../../helpers/upgrade.sh --chart $(CHART) --release $(RELEASE) --from $(FROM) + kubectl rollout status statefulset $(RELEASE)-logstash + +test: install goss + +purge: + helm del $(RELEASE) diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/upgrade/README.md b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/upgrade/README.md new file mode 100644 index 0000000..c8986a0 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/upgrade/README.md @@ -0,0 +1,19 @@ +# Upgrade + +This example will deploy Logstash chart using an old chart version, +then upgrade it. + + +## Usage + +* Add the Elastic Helm charts repo: `helm repo add elastic https://helm.elastic.co` + +* Deploy and upgrade Logstash chart with the default values: `make install` + + +## Testing + +You can also run [goss integration tests][] using `make test`. + + +[goss integration tests]: https://github.com/elastic/helm-charts/tree/master/logstash/examples/upgrade/test/goss.yaml diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/upgrade/test/goss.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/upgrade/test/goss.yaml new file mode 100644 index 0000000..c0ca0d6 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/upgrade/test/goss.yaml @@ -0,0 +1,41 @@ +user: + logstash: + exists: true + uid: 1000 + gid: 1000 + +http: + http://localhost:9600?pretty: + status: 200 + timeout: 2000 + body: + - '"version" : "7.17.1"' + - '"http_address" : "0.0.0.0:9600"' + - '"status" : "green"' + - '"workers" : 1' + - '"batch_size" : 125' + - '"batch_delay" : 50' + +file: + /usr/share/logstash/config/logstash.yml: + exists: true + mode: "0644" + owner: logstash + group: root + filetype: file + contains: + - 'http.host: "0.0.0.0"' + - 'xpack.monitoring.elasticsearch.hosts: [ "http://elasticsearch:9200" ]' + /usr/share/logstash/pipeline/logstash.conf: + exists: true + mode: "0644" + owner: logstash + group: root + filetype: file + contains: + - "input {" + - "beats {" + - "port => 5044" + - "output {" + - "stdout {" + - "codec => rubydebug" diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/upgrade/values.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/upgrade/values.yaml new file mode 100644 index 0000000..ed97d53 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/examples/upgrade/values.yaml @@ -0,0 +1 @@ +--- diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/templates/NOTES.txt b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/templates/NOTES.txt new file mode 100644 index 0000000..215c0e9 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/templates/NOTES.txt @@ -0,0 +1,2 @@ +1. Watch all cluster members come up. + $ kubectl get pods --namespace={{ .Release.Namespace }} -l app={{ template "logstash.fullname" . }} -w diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/templates/_helpers.tpl b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/templates/_helpers.tpl new file mode 100644 index 0000000..f015b26 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/templates/_helpers.tpl @@ -0,0 +1,27 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "logstash.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +*/}} +{{- define "logstash.fullname" -}} +{{- if .Values.fullnameOverride -}} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} + +{{/* +Use the fullname if the serviceAccount value is not set +*/}} +{{- define "logstash.serviceAccount" -}} +{{- .Values.rbac.serviceAccountName | default (include "logstash.fullname" .) -}} +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/templates/configmap-config.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/templates/configmap-config.yaml new file mode 100644 index 0000000..6380384 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/templates/configmap-config.yaml @@ -0,0 +1,17 @@ +{{- if .Values.logstashConfig }} +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "logstash.fullname" . }}-config + labels: + app: "{{ template "logstash.fullname" . }}" + chart: "{{ .Chart.Name }}" + heritage: {{ .Release.Service | quote }} + release: {{ .Release.Name | quote }} +data: +{{- range $path, $config := .Values.logstashConfig }} + {{ $path }}: | +{{ tpl $config $ | indent 4 -}} +{{- end -}} +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/templates/configmap-pattern.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/templates/configmap-pattern.yaml new file mode 100644 index 0000000..0eb5859 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/templates/configmap-pattern.yaml @@ -0,0 +1,17 @@ +{{- if .Values.logstashPattern }} +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "logstash.fullname" . }}-pattern + labels: + app: "{{ template "logstash.fullname" . }}" + chart: "{{ .Chart.Name }}" + heritage: {{ .Release.Service | quote }} + release: {{ .Release.Name | quote }} +data: +{{- range $path, $config := .Values.logstashPattern }} + {{ $path }}: | +{{ tpl $config $ | indent 4 -}} +{{- end -}} +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/templates/configmap-pipeline.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/templates/configmap-pipeline.yaml new file mode 100644 index 0000000..2a92bd4 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/templates/configmap-pipeline.yaml @@ -0,0 +1,17 @@ +{{- if .Values.logstashPipeline }} +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "logstash.fullname" . }}-pipeline + labels: + app: "{{ template "logstash.fullname" . }}" + chart: "{{ .Chart.Name }}" + heritage: {{ .Release.Service | quote }} + release: {{ .Release.Name | quote }} +data: +{{- range $path, $config := .Values.logstashPipeline }} + {{ $path }}: | +{{ tpl $config $ | indent 4 -}} +{{- end -}} +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/templates/ingress.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/templates/ingress.yaml new file mode 100644 index 0000000..cf23fb3 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/templates/ingress.yaml @@ -0,0 +1,68 @@ +{{- if .Values.ingress.enabled -}} +{{- $fullName := include "logstash.fullname" . -}} +{{- $httpPort := .Values.httpPort -}} +{{- $ingressPath := .Values.ingress.path -}} +{{- $pathtype := .Values.ingress.pathtype -}} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ $fullName }} + labels: + app: {{ $fullName | quote}} + chart: "{{ .Chart.Name }}" + heritage: {{ .Release.Service | quote }} + release: {{ .Release.Name | quote }} +{{- with .Values.ingress.annotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} +spec: + {{- if .Values.ingress.className }} + ingressClassName: {{ .Values.ingress.className | quote }} + {{- end }} +{{- if .Values.ingress.tls }} + tls: + {{- if .ingressPath }} + {{- range .Values.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ . }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} + {{- else }} +{{ toYaml .Values.ingress.tls | indent 4 }} + {{- end }} +{{- end}} + rules: + {{- range .Values.ingress.hosts }} + {{- /* + TODO: deprecate $ingressPath for Logstash 8.0.0 + */}} + {{- if $ingressPath }} + - host: {{ . }} + http: + paths: + - path: {{ $ingressPath }} + pathType: {{ $pathtype }} + backend: + service: + name: {{ $fullName }} + port: + number: {{ $httpPort }} + {{- else }} + - host: {{ .host }} + http: + paths: + {{- range .paths }} + - path: {{ .path }} + pathType: {{ $pathtype }} + backend: + service: + name: {{ $fullName }} + port: + number: {{ .servicePort | default $httpPort }} + {{- end }} + {{- end }} + {{- end }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/templates/poddisruptionbudget.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/templates/poddisruptionbudget.yaml new file mode 100644 index 0000000..a089823 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/templates/poddisruptionbudget.yaml @@ -0,0 +1,20 @@ +{{- if .Values.maxUnavailable }} +{{- if .Capabilities.APIVersions.Has "policy/v1" -}} +apiVersion: policy/v1 +{{- else}} +apiVersion: policy/v1beta1 +{{- end }} +kind: PodDisruptionBudget +metadata: + name: "{{ template "logstash.fullname" . }}-pdb" + labels: + app: "{{ template "logstash.fullname" . }}" + chart: "{{ .Chart.Name }}" + heritage: {{ .Release.Service | quote }} + release: {{ .Release.Name | quote }} +spec: + maxUnavailable: {{ .Values.maxUnavailable }} + selector: + matchLabels: + app: "{{ template "logstash.fullname" . }}" +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/templates/podsecuritypolicy.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/templates/podsecuritypolicy.yaml new file mode 100644 index 0000000..c6f9dbf --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/templates/podsecuritypolicy.yaml @@ -0,0 +1,18 @@ +{{- if .Values.podSecurityPolicy.create -}} +{{- $fullName := include "logstash.fullname" . -}} +{{- if .Capabilities.APIVersions.Has "policy/v1" -}} +apiVersion: policy/v1 +{{- else}} +apiVersion: policy/v1beta1 +{{- end }} +kind: PodSecurityPolicy +metadata: + name: {{ default $fullName .Values.podSecurityPolicy.name | quote }} + labels: + app: "{{ template "logstash.fullname" . }}" + chart: "{{ .Chart.Name }}" + heritage: {{ .Release.Service | quote }} + release: {{ .Release.Name | quote }} +spec: +{{ toYaml .Values.podSecurityPolicy.spec | indent 2 }} +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/templates/role.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/templates/role.yaml new file mode 100644 index 0000000..489311b --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/templates/role.yaml @@ -0,0 +1,25 @@ +{{- if .Values.rbac.create -}} +{{- $fullName := include "logstash.fullname" . -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ $fullName | quote }} + labels: + app: "{{ template "logstash.fullname" . }}" + chart: "{{ .Chart.Name }}" + heritage: {{ .Release.Service | quote }} + release: {{ .Release.Name | quote }} +rules: + - apiGroups: + - extensions + resources: + - podsecuritypolicies + resourceNames: + {{- if eq .Values.podSecurityPolicy.name "" }} + - {{ $fullName | quote }} + {{- else }} + - {{ .Values.podSecurityPolicy.name | quote }} + {{- end }} + verbs: + - use +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/templates/rolebinding.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/templates/rolebinding.yaml new file mode 100644 index 0000000..c822428 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/templates/rolebinding.yaml @@ -0,0 +1,20 @@ +{{- if .Values.rbac.create -}} +{{- $fullName := include "logstash.fullname" . -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ $fullName | quote }} + labels: + app: "{{ template "logstash.fullname" . }}" + chart: "{{ .Chart.Name }}" + heritage: {{ .Release.Service | quote }} + release: {{ .Release.Name | quote }} +subjects: + - kind: ServiceAccount + name: "{{ template "logstash.serviceAccount" . }}" + namespace: {{ .Release.Namespace | quote }} +roleRef: + kind: Role + name: {{ $fullName | quote }} + apiGroup: rbac.authorization.k8s.io +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/templates/secret.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/templates/secret.yaml new file mode 100644 index 0000000..0abf786 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/templates/secret.yaml @@ -0,0 +1,27 @@ +{{- if .Values.secrets }} +{{- $fullName := include "logstash.fullname" . -}} +{{- range .Values.secrets }} +--- +apiVersion: v1 +kind: Secret +metadata: + name: {{ printf "%s-%s" $fullName .name | quote }} + labels: + app: {{ $fullName | quote }} + chart: {{ $.Chart.Name | quote }} + heritage: {{ $.Release.Service | quote }} + release: {{ $.Release.Name | quote }} + {{- range $key, $value := $.Values.labels }} + {{ $key }}: {{ $value | quote }} + {{- end }} +data: +{{- range $key, $val := .value }} + {{- if hasSuffix "filepath" $key }} + {{ $key | replace ".filepath" "" }}: {{ $.Files.Get $val | b64enc | quote }} + {{ else }} + {{ $key }}: {{ $val | b64enc | quote }} + {{- end }} +{{- end }} +type: Opaque +{{- end }} +{{- end }} \ No newline at end of file diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/templates/service-headless.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/templates/service-headless.yaml new file mode 100644 index 0000000..47148df --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/templates/service-headless.yaml @@ -0,0 +1,20 @@ +--- +kind: Service +apiVersion: v1 +metadata: + name: "{{ template "logstash.fullname" . }}-headless" + labels: + app: "{{ template "logstash.fullname" . }}" + chart: "{{ .Chart.Name }}" + heritage: {{ .Release.Service | quote }} + release: {{ .Release.Name | quote }} +{{- if .Values.labels }} +{{ toYaml .Values.labels | indent 4 }} +{{- end }} +spec: + clusterIP: None + selector: + app: "{{ template "logstash.fullname" . }}" + ports: + - name: http + port: {{ .Values.httpPort }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/templates/service.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/templates/service.yaml new file mode 100644 index 0000000..7b91617 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/templates/service.yaml @@ -0,0 +1,32 @@ +{{- if .Values.service }} +--- +kind: Service +apiVersion: v1 +metadata: + name: "{{ template "logstash.fullname" . }}" + labels: + app: "{{ template "logstash.fullname" . }}" + chart: "{{ .Chart.Name }}" + heritage: {{ .Release.Service | quote }} + release: {{ .Release.Name | quote }} + annotations: +{{ toYaml .Values.service.annotations | indent 4 }} +spec: + type: {{ .Values.service.type }} +{{- if .Values.service.loadBalancerIP }} + loadBalancerIP: {{ .Values.service.loadBalancerIP }} +{{- end }} +{{- with .Values.service.loadBalancerSourceRanges }} + loadBalancerSourceRanges: +{{ toYaml . | indent 4 }} +{{- end }} +{{- if .Values.service.externalTrafficPolicy }} + externalTrafficPolicy: {{ .Values.service.externalTrafficPolicy }} +{{- end }} + selector: + app: "{{ template "logstash.fullname" . }}" + chart: "{{ .Chart.Name }}" + release: {{ .Release.Name | quote }} + ports: +{{ toYaml .Values.service.ports | indent 4 }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/templates/serviceaccount.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/templates/serviceaccount.yaml new file mode 100644 index 0000000..98a6f92 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/templates/serviceaccount.yaml @@ -0,0 +1,22 @@ +{{- if .Values.rbac.create -}} +{{- $fullName := include "logstash.fullname" . -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: "{{ template "logstash.serviceAccount" . }}" + annotations: + {{- with .Values.rbac.serviceAccountAnnotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + labels: + app: "{{ template "logstash.fullname" . }}" + chart: "{{ .Chart.Name }}" + heritage: {{ .Release.Service | quote }} + release: {{ .Release.Name | quote }} + {{- if .Values.rbac.annotations }} + annotations: + {{- range $key, $value := .Values.rbac.annotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/templates/statefulset.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/templates/statefulset.yaml new file mode 100644 index 0000000..239fac3 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/templates/statefulset.yaml @@ -0,0 +1,237 @@ +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ template "logstash.fullname" . }} + labels: + app: "{{ template "logstash.fullname" . }}" + chart: "{{ .Chart.Name }}" + heritage: {{ .Release.Service | quote }} + release: {{ .Release.Name | quote }} + {{- range $key, $value := .Values.labels }} + {{ $key }}: {{ $value | quote }} + {{- end }} +spec: + serviceName: {{ template "logstash.fullname" . }}-headless + selector: + matchLabels: + app: "{{ template "logstash.fullname" . }}" + release: {{ .Release.Name | quote }} + replicas: {{ .Values.replicas }} + podManagementPolicy: {{ .Values.podManagementPolicy }} + updateStrategy: + type: {{ .Values.updateStrategy }} + {{- if .Values.persistence.enabled }} + volumeClaimTemplates: + - metadata: + name: {{ template "logstash.fullname" . }} + {{- with .Values.persistence.annotations }} + annotations: +{{ toYaml . | indent 8 }} + {{- end }} + spec: +{{ toYaml .Values.volumeClaimTemplate | indent 6 }} + {{- end }} + template: + metadata: + name: "{{ template "logstash.fullname" . }}" + labels: + app: "{{ template "logstash.fullname" . }}" + chart: "{{ .Chart.Name }}" + heritage: {{ .Release.Service | quote }} + release: {{ .Release.Name | quote }} + {{- range $key, $value := .Values.labels }} + {{ $key }}: {{ $value | quote }} + {{- end }} + annotations: + {{- range $key, $value := .Values.podAnnotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- /* This forces a restart if the configmap has changed */}} + {{- if .Values.logstashConfig }} + configchecksum: {{ include (print .Template.BasePath "/configmap-config.yaml") . | sha256sum | trunc 63 }} + {{- end }} + {{- /* This forces a restart if the configmap has changed */}} + {{- if .Values.logstashPipeline }} + pipelinechecksum: {{ include (print .Template.BasePath "/configmap-pipeline.yaml") . | sha256sum | trunc 63 }} + {{- end }} + {{- if .Values.logstashPattern }} + patternchecksum: {{ include (print .Template.BasePath "/configmap-pattern.yaml") . | sha256sum | trunc 63 }} + {{- end }} + {{- if .Values.secrets }} + secretschecksum: {{ include (print .Template.BasePath "/secret.yaml") . | sha256sum | trunc 63 }} + {{- end }} + spec: + {{- if .Values.schedulerName }} + schedulerName: "{{ .Values.schedulerName }}" + {{- end }} + securityContext: +{{ toYaml .Values.podSecurityContext | indent 8 }} + {{- if or .Values.rbac.create .Values.rbac.serviceAccountName }} + serviceAccountName: "{{ template "logstash.serviceAccount" . }}" + {{- end }} + {{- with .Values.tolerations }} + tolerations: +{{ toYaml . | indent 6 }} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: +{{ toYaml . | indent 8 }} + {{- end }} + {{- if or (eq .Values.antiAffinity "hard") (eq .Values.antiAffinity "soft") .Values.nodeAffinity .Values.podAffinity }} + {{- if .Values.priorityClassName }} + priorityClassName: {{ .Values.priorityClassName }} + {{- end }} + affinity: + {{- end }} + {{- if eq .Values.antiAffinity "hard" }} + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: app + operator: In + values: + - "{{ template "logstash.fullname" .}}" + topologyKey: {{ .Values.antiAffinityTopologyKey }} + {{- else if eq .Values.antiAffinity "soft" }} + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 1 + podAffinityTerm: + topologyKey: {{ .Values.antiAffinityTopologyKey }} + labelSelector: + matchExpressions: + - key: app + operator: In + values: + - "{{ template "logstash.fullname" . }}" + {{- end }} + {{- with .Values.nodeAffinity }} + nodeAffinity: +{{ toYaml . | indent 10 }} + {{- end }} + {{- with .Values.podAffinity }} + podAffinity: +{{ toYaml . | indent 10 }} + {{- end }} + terminationGracePeriodSeconds: {{ .Values.terminationGracePeriod }} + volumes: + {{- range .Values.secretMounts }} + - name: {{ .name }} + secret: + secretName: {{ .secretName }} + {{- end }} + {{- if .Values.logstashConfig }} + - name: logstashconfig + configMap: + name: {{ template "logstash.fullname" . }}-config + {{- end }} + {{- if .Values.logstashPipeline }} + - name: logstashpipeline + configMap: + name: {{ template "logstash.fullname" . }}-pipeline + {{- end }} + {{- if .Values.logstashPattern }} + - name: logstashpattern + configMap: + name: {{ template "logstash.fullname" . }}-pattern + {{- end }} + {{- if .Values.extraVolumes }} + {{- if eq "string" (printf "%T" .Values.extraVolumes) }} +{{ tpl .Values.extraVolumes . | indent 8 }} + {{- else }} +{{ toYaml .Values.extraVolumes | indent 8 }} + {{- end }} + {{- end }} + {{- if .Values.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | indent 8 }} + {{- end}} + {{- if .Values.hostAliases }} + hostAliases: {{ toYaml .Values.hostAliases | nindent 6 }} + {{- end }} + {{- if .Values.extraInitContainers }} + initContainers: + {{- if eq "string" (printf "%T" .Values.extraInitContainers) }} +{{ tpl .Values.extraInitContainers . | indent 6 }} + {{- else }} +{{ toYaml .Values.extraInitContainers | indent 6 }} + {{- end }} + {{- end }} + containers: + - name: "{{ template "logstash.name" . }}" + securityContext: +{{ toYaml .Values.securityContext | indent 10 }} + image: "{{ .Values.image }}:{{ .Values.imageTag }}" + imagePullPolicy: "{{ .Values.imagePullPolicy }}" + livenessProbe: +{{ toYaml .Values.livenessProbe | indent 10 }} + readinessProbe: +{{ toYaml .Values.readinessProbe | indent 10 }} + ports: + - name: http + containerPort: {{ .Values.httpPort }} + {{- if .Values.extraPorts }} + {{- toYaml .Values.extraPorts | nindent 8 }} + {{- end }} + resources: +{{ toYaml .Values.resources | indent 10 }} + env: + - name: LS_JAVA_OPTS + value: "{{ .Values.logstashJavaOpts }}" +{{- if .Values.extraEnvs }} +{{ toYaml .Values.extraEnvs | indent 10 }} +{{- end }} +{{- if .Values.envFrom }} + envFrom: +{{ toYaml .Values.envFrom | indent 10 }} +{{- end }} + volumeMounts: + {{- if .Values.persistence.enabled }} + - name: "{{ template "logstash.fullname" . }}" + mountPath: /usr/share/logstash/data + {{- end }} + {{- range .Values.secretMounts }} + - name: {{ .name }} + mountPath: {{ .path }} + {{- if .subPath }} + subPath: {{ .subPath }} + {{- end }} + {{- end }} + {{- range $path, $config := .Values.logstashConfig }} + - name: logstashconfig + mountPath: /usr/share/logstash/config/{{ $path }} + subPath: {{ $path }} + {{- end -}} + {{- range $path, $config := .Values.logstashPipeline }} + - name: logstashpipeline + mountPath: /usr/share/logstash/pipeline/{{ $path }} + subPath: {{ $path }} + {{- end -}} + {{- if .Values.logstashPattern }} + {{- $logstashPatternDir := .Values.logstashPatternDir -}} + {{- range $path, $config := .Values.logstashPattern }} + - name: logstashpattern + mountPath: {{ $logstashPatternDir }}{{ $path }} + subPath: {{ $path }} + {{- end -}} + {{- end -}} + {{- if .Values.extraVolumeMounts }} + {{- if eq "string" (printf "%T" .Values.extraVolumeMounts) }} +{{ tpl .Values.extraVolumeMounts . | indent 10 }} + {{- else }} +{{ toYaml .Values.extraVolumeMounts | indent 10 }} + {{- end }} + {{- end }} +{{- if .Values.lifecycle }} + lifecycle: +{{ toYaml .Values.lifecycle | indent 10 }} +{{- end }} + {{- if .Values.extraContainers }} + {{- if eq "string" (printf "%T" .Values.extraContainers) }} +{{ tpl .Values.extraContainers . | indent 6 }} + {{- else }} +{{ toYaml .Values.extraContainers | indent 6 }} + {{- end }} + {{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/values.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/values.yaml new file mode 100644 index 0000000..0940377 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/logstash/values.yaml @@ -0,0 +1,295 @@ +--- +replicas: 1 + +# Allows you to add any config files in /usr/share/logstash/config/ +# such as logstash.yml and log4j2.properties +# +# Note that when overriding logstash.yml, `http.host: 0.0.0.0` should always be included +# to make default probes work. +logstashConfig: {} +# logstash.yml: | +# key: +# nestedkey: value +# log4j2.properties: | +# key = value + +# Allows you to add any pipeline files in /usr/share/logstash/pipeline/ +### ***warn*** there is a hardcoded logstash.conf in the image, override it first +logstashPipeline: {} +# logstash.conf: | +# input { +# exec { +# command => "uptime" +# interval => 30 +# } +# } +# output { stdout { } } + +# Allows you to add any pattern files in your custom pattern dir +logstashPatternDir: "/usr/share/logstash/patterns/" +logstashPattern: {} +# pattern.conf: | +# DPKG_VERSION [-+~<>\.0-9a-zA-Z]+ + +# Extra environment variables to append to this nodeGroup +# This will be appended to the current 'env:' key. You can use any of the kubernetes env +# syntax here +extraEnvs: [] +# - name: MY_ENVIRONMENT_VAR +# value: the_value_goes_here + +# Allows you to load environment variables from kubernetes secret or config map +envFrom: [] +# - secretRef: +# name: env-secret +# - configMapRef: +# name: config-map + +# Add sensitive data to k8s secrets +secrets: [] +# - name: "env" +# value: +# ELASTICSEARCH_PASSWORD: "LS1CRUdJTiBgUFJJVkFURSB" +# api_key: ui2CsdUadTiBasRJRkl9tvNnw +# - name: "tls" +# value: +# ca.crt: | +# LS0tLS1CRUdJT0K +# LS0tLS1CRUdJT0K +# LS0tLS1CRUdJT0K +# LS0tLS1CRUdJT0K +# cert.crt: "LS0tLS1CRUdJTiBlRJRklDQVRFLS0tLS0K" +# cert.key.filepath: "secrets.crt" # The path to file should be relative to the `values.yaml` file. + +# A list of secrets and their paths to mount inside the pod +secretMounts: [] + +hostAliases: [] +#- ip: "127.0.0.1" +# hostnames: +# - "foo.local" +# - "bar.local" + +image: "docker.elastic.co/logstash/logstash" +imageTag: "7.17.1" +imagePullPolicy: "IfNotPresent" +imagePullSecrets: [] + +podAnnotations: {} + +# additionals labels +labels: {} + +logstashJavaOpts: "-Xmx1g -Xms1g" + +resources: + requests: + cpu: "100m" + memory: "1536Mi" + limits: + cpu: "1000m" + memory: "1536Mi" + +volumeClaimTemplate: + accessModes: ["ReadWriteOnce"] + resources: + requests: + storage: 1Gi + +rbac: + create: false + serviceAccountAnnotations: {} + serviceAccountName: "" + annotations: + {} + #annotation1: "value1" + #annotation2: "value2" + #annotation3: "value3" + +podSecurityPolicy: + create: false + name: "" + spec: + privileged: false + fsGroup: + rule: RunAsAny + runAsUser: + rule: RunAsAny + seLinux: + rule: RunAsAny + supplementalGroups: + rule: RunAsAny + volumes: + - secret + - configMap + - persistentVolumeClaim + +persistence: + enabled: false + annotations: {} + +extraVolumes: + [] + # - name: extras + # emptyDir: {} + +extraVolumeMounts: + [] + # - name: extras + # mountPath: /usr/share/extras + # readOnly: true + +extraContainers: + [] + # - name: do-something + # image: busybox + # command: ['do', 'something'] + +extraInitContainers: + [] + # - name: do-something + # image: busybox + # command: ['do', 'something'] + +# This is the PriorityClass settings as defined in +# https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/#priorityclass +priorityClassName: "" + +# By default this will make sure two pods don't end up on the same node +# Changing this to a region would allow you to spread pods across regions +antiAffinityTopologyKey: "kubernetes.io/hostname" + +# Hard means that by default pods will only be scheduled if there are enough nodes for them +# and that they will never end up on the same node. Setting this to soft will do this "best effort" +antiAffinity: "hard" + +# This is the node affinity settings as defined in +# https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#node-affinity +nodeAffinity: {} + +# This is inter-pod affinity settings as defined in +# https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity +podAffinity: {} + +# The default is to deploy all pods serially. By setting this to parallel all pods are started at +# the same time when bootstrapping the cluster +podManagementPolicy: "Parallel" + +httpPort: 9600 + +# Custom ports to add to logstash +extraPorts: + [] + # - name: beats + # containerPort: 5001 + +updateStrategy: RollingUpdate + +# This is the max unavailable setting for the pod disruption budget +# The default value of 1 will make sure that kubernetes won't allow more than 1 +# of your pods to be unavailable during maintenance +maxUnavailable: 1 + +podSecurityContext: + fsGroup: 1000 + runAsUser: 1000 + +securityContext: + capabilities: + drop: + - ALL + # readOnlyRootFilesystem: true + runAsNonRoot: true + runAsUser: 1000 + +# How long to wait for logstash to stop gracefully +terminationGracePeriod: 120 + +# Probes +# Default probes are using `httpGet` which requires that `http.host: 0.0.0.0` is part of +# `logstash.yml`. If needed probes can be disabled or overridden using the following syntaxes: +# +# disable livenessProbe +# livenessProbe: null +# +# replace httpGet default readinessProbe by some exec probe +# readinessProbe: +# httpGet: null +# exec: +# command: +# - curl +# - localhost:9600 + +livenessProbe: + httpGet: + path: / + port: http + initialDelaySeconds: 300 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 3 + successThreshold: 1 + +readinessProbe: + httpGet: + path: / + port: http + initialDelaySeconds: 60 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 3 + successThreshold: 3 + +## Use an alternate scheduler. +## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ +## +schedulerName: "" + +nodeSelector: {} +tolerations: [] + +nameOverride: "" +fullnameOverride: "" + +lifecycle: + {} + # preStop: + # exec: + # command: ["/bin/sh", "-c", "echo Hello from the postStart handler > /usr/share/message"] + # postStart: + # exec: + # command: ["/bin/sh", "-c", "echo Hello from the postStart handler > /usr/share/message"] + +service: + {} + # annotations: {} + # type: ClusterIP + # loadBalancerIP: "" + # ports: + # - name: beats + # port: 5044 + # protocol: TCP + # targetPort: 5044 + # - name: http + # port: 8080 + # protocol: TCP + # targetPort: 8080 + +ingress: + enabled: false + annotations: + {} + # kubernetes.io/tls-acme: "true" + className: "nginx" + pathtype: ImplementationSpecific + hosts: + - host: logstash-example.local + paths: + - path: /beats + servicePort: 5044 + - path: /http + servicePort: 8080 + tls: [] + # - secretName: logstash-example-tls + # hosts: + # - logstash-example.local diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/.helmignore b/helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/.helmignore new file mode 100644 index 0000000..50af031 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/.helmignore @@ -0,0 +1,22 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/Chart.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/Chart.yaml new file mode 100644 index 0000000..1837dd2 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/Chart.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +appVersion: v2.5.0 +description: 'Loki: like Prometheus, but for logs.' +home: https://grafana.com/loki +icon: https://raw.githubusercontent.com/grafana/loki/master/docs/sources/logo.png +kubeVersion: ^1.10.0-0 +maintainers: +- email: lokiproject@googlegroups.com + name: Loki Maintainers +name: loki +sources: +- https://github.com/grafana/loki +version: 2.11.0 diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/README.md b/helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/README.md new file mode 100644 index 0000000..fa63386 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/README.md @@ -0,0 +1,82 @@ +# Loki Helm Chart + +## Prerequisites + +Make sure you have Helm [installed](https://helm.sh/docs/using_helm/#installing-helm). + +## Get Repo Info + +```console +helm repo add grafana https://grafana.github.io/helm-charts +helm repo update +``` + +_See [helm repo](https://helm.sh/docs/helm/helm_repo/) for command documentation._ + + +## Deploy Loki only + +```bash +helm upgrade --install loki grafana/loki +``` + +## Run Loki behind https ingress + +If Loki and Promtail are deployed on different clusters you can add an Ingress in front of Loki. +By adding a certificate you create an https endpoint. For extra security enable basic authentication on the Ingress. + +In Promtail set the following values to communicate with https and basic auth + +```yaml +loki: + serviceScheme: https + user: user + password: pass +``` + +Sample helm template for ingress: + +```yaml +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: loki + annotations: + kubernetes.io/ingress.class: {{ .Values.ingress.class }} + ingress.kubernetes.io/auth-type: basic + ingress.kubernetes.io/auth-secret: {{ .Values.ingress.basic.secret }} +spec: + rules: + - host: {{ .Values.ingress.host }} + http: + paths: + - backend: + service: + name: loki + port: + number: 3100 + path: / + pathType: Prefix + tls: + - hosts: + - {{ .Values.ingress.host }} + secretName: {{ .Values.ingress.cert }} +``` + +## Use Loki Alerting + +You can add your own alerting rules with `alerting_groups` in `values.yaml`. This will create a ConfigMap with your rules and additional volumes and mounts for Loki. + +This does **not** enable the Loki `ruler` component which does the evaluation of your rules. The `values.yaml` file does contain a simple example. For more details take a look at the official [alerting docs](https://grafana.com/docs/loki/latest/rules/). + +## Enable retention policy (log deletion) + +Set Helm value `config.compactor.retention_enabled` to enable retention using the default policy, which deletes logs after 31 days. + +```yaml +config: + compactor: + retention_enabled: true +``` + +See [the documentation](https://grafana.com/docs/loki/latest/operations/storage/retention/) for additional options. diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/templates/NOTES.txt b/helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/templates/NOTES.txt new file mode 100644 index 0000000..abe023a --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/templates/NOTES.txt @@ -0,0 +1,3 @@ +Verify the application is working by running these commands: + kubectl --namespace {{ .Release.Namespace }} port-forward service/{{ include "loki.fullname" . }} {{ .Values.service.port }} + curl http://127.0.0.1:{{ .Values.service.port }}/api/prom/label diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/templates/_helpers.tpl b/helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/templates/_helpers.tpl new file mode 100644 index 0000000..d873a0f --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/templates/_helpers.tpl @@ -0,0 +1,75 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "loki.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 "loki.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 "loki.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create the name of the service account +*/}} +{{- define "loki.serviceAccountName" -}} +{{- if .Values.serviceAccount.create -}} + {{ default (include "loki.fullname" .) .Values.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +Create the app name of loki clients. Defaults to the same logic as "loki.fullname", and default client expects "promtail". +*/}} +{{- define "client.name" -}} +{{- if .Values.client.name -}} +{{- .Values.client.name -}} +{{- else if .Values.client.fullnameOverride -}} +{{- .Values.client.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default "promtail" .Values.client.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Generate a right Ingress apiVersion +*/}} +{{- define "ingress.apiVersion" -}} +{{- if semverCompare ">=1.20-0" .Capabilities.KubeVersion.GitVersion -}} +networking.k8s.io/v1 +{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} +networking.k8s.io/v1beta1 +{{- else -}} +extensions/v1 +{{- end }} +{{- end -}} + diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/templates/configmap-alert.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/templates/configmap-alert.yaml new file mode 100644 index 0000000..07fab47 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/templates/configmap-alert.yaml @@ -0,0 +1,17 @@ +{{- if or (.Values.useExistingAlertingGroup.enabled) (gt (len .Values.alerting_groups) 0) }} +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "loki.fullname" . }}-alerting-rules + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "loki.name" . }} + chart: {{ template "loki.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +data: + {{ template "loki.fullname" . }}-alerting-rules.yaml: |- + groups: + {{- toYaml .Values.alerting_groups | nindent 6 }} +{{- end }} \ No newline at end of file diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/templates/ingress.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/templates/ingress.yaml new file mode 100644 index 0000000..2a0314e --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/templates/ingress.yaml @@ -0,0 +1,55 @@ +{{- if .Values.ingress.enabled -}} +{{- $fullName := include "loki.fullname" . -}} +{{- $svcPort := .Values.service.port -}} +{{- $apiVersion := include "ingress.apiVersion" . -}} +apiVersion: {{ $apiVersion }} +kind: Ingress +metadata: + name: {{ $fullName }} + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "loki.name" . }} + chart: {{ template "loki.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + {{- with .Values.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: +{{- if .Values.ingress.ingressClassName }} + ingressClassName: {{ .Values.ingress.ingressClassName }} +{{- end }} +{{- if .Values.ingress.tls }} + tls: + {{- range .Values.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ . | quote }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} +{{- end }} + rules: + {{- range .Values.ingress.hosts }} + - host: {{ .host | quote }} + http: + paths: + {{- range .paths }} + - path: {{ . }} + {{- if eq $apiVersion "networking.k8s.io/v1" }} + pathType: Prefix + {{- end }} + backend: + {{- if eq $apiVersion "networking.k8s.io/v1" }} + service: + name: {{ $fullName }} + port: + number: {{ $svcPort }} + {{- else }} + serviceName: {{ $fullName }} + servicePort: {{ $svcPort }} + {{- end }} + {{- end }} + {{- end }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/templates/networkpolicy.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/templates/networkpolicy.yaml new file mode 100644 index 0000000..5d73832 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/templates/networkpolicy.yaml @@ -0,0 +1,26 @@ +{{- if .Values.networkPolicy.enabled }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ template "loki.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "loki.name" . }} + chart: {{ template "loki.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +spec: + podSelector: + matchLabels: + name: {{ template "loki.fullname" . }} + app: {{ template "loki.name" . }} + release: {{ .Release.Name }} + ingress: + - from: + - podSelector: + matchLabels: + app: {{ template "client.name" . }} + release: {{ .Release.Name }} + - ports: + - port: {{ .Values.service.port }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/templates/pdb.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/templates/pdb.yaml new file mode 100644 index 0000000..c64ad50 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/templates/pdb.yaml @@ -0,0 +1,17 @@ +{{- if .Values.podDisruptionBudget -}} +apiVersion: policy/v1beta1 +kind: PodDisruptionBudget +metadata: + name: {{ template "loki.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "loki.name" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + chart: {{ template "loki.chart" . }} +spec: + selector: + matchLabels: + app: {{ template "loki.name" . }} +{{ toYaml .Values.podDisruptionBudget | indent 2 }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/templates/podsecuritypolicy.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/templates/podsecuritypolicy.yaml new file mode 100644 index 0000000..ce1c1c1 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/templates/podsecuritypolicy.yaml @@ -0,0 +1,41 @@ +{{- if .Values.rbac.pspEnabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "loki.fullname" . }} + labels: + app: {{ template "loki.name" . }} + chart: {{ template "loki.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +spec: + privileged: false + allowPrivilegeEscalation: false + volumes: + - 'configMap' + - 'emptyDir' + - 'persistentVolumeClaim' + - 'secret' + - 'projected' + - 'downwardAPI' + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + rule: 'MustRunAsNonRoot' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'MustRunAs' + ranges: + - min: 1 + max: 65535 + fsGroup: + rule: 'MustRunAs' + ranges: + - min: 1 + max: 65535 + readOnlyRootFilesystem: true + requiredDropCapabilities: + - ALL +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/templates/prometheusrule.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/templates/prometheusrule.yaml new file mode 100644 index 0000000..effe6f1 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/templates/prometheusrule.yaml @@ -0,0 +1,23 @@ +{{- if and .Values.serviceMonitor.enabled .Values.serviceMonitor.prometheusRule.enabled -}} +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: {{ template "loki.fullname" . }} +{{- if .Values.serviceMonitor.prometheusRule.namespace }} + namespace: {{ .Values.serviceMonitor.prometheusRule.namespace | quote }} +{{- end }} + labels: + app: {{ template "loki.name" . }} + chart: {{ template "loki.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + {{- if .Values.serviceMonitor.prometheusRule.additionalLabels }} + {{- toYaml .Values.serviceMonitor.prometheusRule.additionalLabels | nindent 4 }} + {{- end }} +spec: +{{- if .Values.serviceMonitor.prometheusRule.rules }} + groups: + - name: {{ template "loki.fullname" . }} + rules: {{- toYaml .Values.serviceMonitor.prometheusRule.rules | nindent 4 }} +{{- end }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/templates/role.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/templates/role.yaml new file mode 100644 index 0000000..b7bfb29 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/templates/role.yaml @@ -0,0 +1,20 @@ +{{- if .Values.rbac.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ template "loki.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "loki.name" . }} + chart: {{ template "loki.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +{{- if .Values.rbac.pspEnabled }} +rules: +- apiGroups: ['extensions'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: [{{ template "loki.fullname" . }}] +{{- end }} +{{- end }} + diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/templates/rolebinding.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/templates/rolebinding.yaml new file mode 100644 index 0000000..41fc503 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/templates/rolebinding.yaml @@ -0,0 +1,20 @@ +{{- if .Values.rbac.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ template "loki.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "loki.name" . }} + chart: {{ template "loki.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "loki.fullname" . }} +subjects: +- kind: ServiceAccount + name: {{ template "loki.serviceAccountName" . }} +{{- end }} + diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/templates/secret.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/templates/secret.yaml new file mode 100644 index 0000000..1f6db2d --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/templates/secret.yaml @@ -0,0 +1,14 @@ +{{- if not .Values.config.existingSecret -}} +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "loki.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "loki.name" . }} + chart: {{ template "loki.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +data: + loki.yaml: {{ tpl (toYaml .Values.config) . | b64enc}} +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/templates/service-headless.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/templates/service-headless.yaml new file mode 100644 index 0000000..1efdde6 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/templates/service-headless.yaml @@ -0,0 +1,24 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ template "loki.fullname" . }}-headless + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "loki.name" . }} + chart: {{ template "loki.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + variant: headless +spec: + clusterIP: None + ports: + - port: {{ .Values.service.port }} + protocol: TCP + name: http-metrics + targetPort: {{ .Values.service.targetPort }} +{{- if .Values.extraPorts }} +{{ toYaml .Values.extraPorts | indent 4}} +{{- end }} + selector: + app: {{ template "loki.name" . }} + release: {{ .Release.Name }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/templates/service.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/templates/service.yaml new file mode 100644 index 0000000..d6ee92d --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/templates/service.yaml @@ -0,0 +1,43 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ template "loki.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "loki.name" . }} + chart: {{ template "loki.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + {{- with .Values.service.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + annotations: + {{- toYaml .Values.service.annotations | nindent 4 }} +spec: + type: {{ .Values.service.type }} +{{- if (and (eq .Values.service.type "ClusterIP") (not (empty .Values.service.clusterIP))) }} + clusterIP: {{ .Values.service.clusterIP }} +{{- end }} +{{- if (and (eq .Values.service.type "LoadBalancer") (not (empty .Values.service.loadBalancerIP))) }} + loadBalancerIP: {{ .Values.service.loadBalancerIP }} +{{- end }} +{{- if .Values.service.loadBalancerSourceRanges }} + loadBalancerSourceRanges: + {{- range $cidr := .Values.service.loadBalancerSourceRanges }} + - {{ $cidr }} + {{- end }} +{{- end }} + ports: + - port: {{ .Values.service.port }} + protocol: TCP + name: http-metrics + targetPort: {{ .Values.service.targetPort }} +{{- if (and (eq .Values.service.type "NodePort") (not (empty .Values.service.nodePort))) }} + nodePort: {{ .Values.service.nodePort }} +{{- end }} +{{- if .Values.extraPorts }} +{{ toYaml .Values.extraPorts | indent 4}} +{{- end }} + selector: + app: {{ template "loki.name" . }} + release: {{ .Release.Name }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/templates/serviceaccount.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/templates/serviceaccount.yaml new file mode 100644 index 0000000..510972c --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/templates/serviceaccount.yaml @@ -0,0 +1,16 @@ +{{- if .Values.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app: {{ template "loki.name" . }} + chart: {{ template "loki.chart" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + annotations: + {{- toYaml .Values.serviceAccount.annotations | nindent 4 }} + name: {{ template "loki.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }} +{{- end }} + diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/templates/servicemonitor.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/templates/servicemonitor.yaml new file mode 100644 index 0000000..0a48672 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/templates/servicemonitor.yaml @@ -0,0 +1,38 @@ +{{- if .Values.serviceMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "loki.fullname" . }} + labels: + app: {{ template "loki.name" . }} + chart: {{ template "loki.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + {{- if .Values.serviceMonitor.additionalLabels }} +{{ toYaml .Values.serviceMonitor.additionalLabels | indent 4 }} + {{- end }} + {{- if .Values.serviceMonitor.annotations }} + annotations: +{{ toYaml .Values.serviceMonitor.annotations | indent 4 }} + {{- end }} +spec: + selector: + matchLabels: + app: {{ template "loki.name" . }} + release: {{ .Release.Name | quote }} + variant: headless + namespaceSelector: + matchNames: + - {{ .Release.Namespace | quote }} + endpoints: + - port: http-metrics + {{- if .Values.serviceMonitor.interval }} + interval: {{ .Values.serviceMonitor.interval }} + {{- end }} + {{- if .Values.serviceMonitor.scrapeTimeout }} + scrapeTimeout: {{ .Values.serviceMonitor.scrapeTimeout }} + {{- end }} + {{- if .Values.serviceMonitor.path }} + path: {{ .Values.serviceMonitor.path }} + {{- end }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/templates/statefulset.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/templates/statefulset.yaml new file mode 100644 index 0000000..8942f51 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/templates/statefulset.yaml @@ -0,0 +1,154 @@ +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ template "loki.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "loki.name" . }} + chart: {{ template "loki.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + annotations: + {{- toYaml .Values.annotations | nindent 4 }} +spec: + podManagementPolicy: {{ .Values.podManagementPolicy }} + replicas: {{ .Values.replicas }} + selector: + matchLabels: + app: {{ template "loki.name" . }} + release: {{ .Release.Name }} + serviceName: {{ template "loki.fullname" . }}-headless + updateStrategy: + {{- toYaml .Values.updateStrategy | nindent 4 }} + template: + metadata: + labels: + app: {{ template "loki.name" . }} + name: {{ template "loki.fullname" . }} + release: {{ .Release.Name }} + {{- with .Values.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + annotations: + {{- if not .Values.config.existingSecret }} + checksum/config: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }} + {{- end }} + {{- with .Values.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + serviceAccountName: {{ template "loki.serviceAccountName" . }} + {{- if .Values.priorityClassName }} + priorityClassName: {{ .Values.priorityClassName }} + {{- end }} + securityContext: + {{- toYaml .Values.securityContext | nindent 8 }} + initContainers: + {{- toYaml .Values.initContainers | nindent 8 }} + {{- if .Values.image.pullSecrets }} + imagePullSecrets: + {{- range .Values.image.pullSecrets }} + - name: {{ . }} + {{- end}} + {{- end }} + containers: + - name: {{ .Chart.Name }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + args: + - "-config.file=/etc/loki/loki.yaml" + {{- range $key, $value := .Values.extraArgs }} + - "-{{ $key }}={{ $value }}" + {{- end }} + volumeMounts: + - name: tmp + mountPath: /tmp + {{- if .Values.extraVolumeMounts }} + {{ toYaml .Values.extraVolumeMounts | nindent 12}} + {{- end }} + - name: config + mountPath: /etc/loki + - name: storage + mountPath: "/data" + subPath: {{ .Values.persistence.subPath }} + {{- if or (.Values.useExistingAlertingGroup.enabled) (gt (len .Values.alerting_groups) 0) }} + - name: rules + mountPath: /rules/fake + {{- end }} + ports: + - name: http-metrics + containerPort: {{ .Values.config.server.http_listen_port }} + protocol: TCP + livenessProbe: + {{- toYaml .Values.livenessProbe | nindent 12 }} + readinessProbe: + {{- toYaml .Values.readinessProbe | nindent 12 }} + resources: + {{- toYaml .Values.resources | nindent 12 }} + securityContext: + readOnlyRootFilesystem: true + env: + {{- if .Values.env }} + {{- toYaml .Values.env | nindent 12 }} + {{- end }} + {{- if .Values.tracing.jaegerAgentHost }} + - name: JAEGER_AGENT_HOST + value: "{{ .Values.tracing.jaegerAgentHost }}" + {{- end }} +{{- if .Values.extraContainers }} +{{ toYaml .Values.extraContainers | indent 8}} +{{- end }} + nodeSelector: + {{- toYaml .Values.nodeSelector | nindent 8 }} + affinity: + {{- toYaml .Values.affinity | nindent 8 }} + tolerations: + {{- toYaml .Values.tolerations | nindent 8 }} + terminationGracePeriodSeconds: {{ .Values.terminationGracePeriodSeconds }} + volumes: + - name: tmp + emptyDir: {} + {{- if or (.Values.useExistingAlertingGroup.enabled) (gt (len .Values.alerting_groups) 0) }} + - name: rules + configMap: + {{- if .Values.useExistingAlertingGroup.enabled }} + name: {{ .Values.useExistingAlertingGroup.configmapName }} + {{- else }} + name: {{ template "loki.fullname" . }}-alerting-rules + {{- end }} + {{- end }} + - name: config + secret: + {{- if .Values.config.existingSecret }} + secretName: {{ .Values.config.existingSecret }} + {{- else }} + secretName: {{ template "loki.fullname" . }} + {{- end }} +{{- if .Values.extraVolumes }} +{{ toYaml .Values.extraVolumes | indent 8}} +{{- end }} + {{- if not .Values.persistence.enabled }} + - name: storage + emptyDir: {} + {{- else if .Values.persistence.existingClaim }} + - name: storage + persistentVolumeClaim: + claimName: {{ .Values.persistence.existingClaim }} + {{- else }} + volumeClaimTemplates: + - metadata: + name: storage + annotations: + {{- toYaml .Values.persistence.annotations | nindent 8 }} + spec: + accessModes: + {{- toYaml .Values.persistence.accessModes | nindent 8 }} + resources: + requests: + storage: {{ .Values.persistence.size | quote }} + storageClassName: {{ .Values.persistence.storageClassName }} + {{- if .Values.persistence.selector }} + selector: + {{- toYaml .Values.persistence.selector | nindent 8 }} + {{- end }} + {{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/values.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/values.yaml new file mode 100644 index 0000000..99b8302 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/loki/values.yaml @@ -0,0 +1,324 @@ +image: + repository: grafana/loki + tag: 2.5.0 + pullPolicy: IfNotPresent + + ## Optionally specify an array of imagePullSecrets. + ## Secrets must be manually created in the namespace. + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ + ## + # pullSecrets: + # - myRegistryKeySecretName + +ingress: + enabled: false + # For Kubernetes >= 1.18 you should specify the ingress-controller via the field ingressClassName + # See https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/#specifying-the-class-of-an-ingress + # ingressClassName: nginx + annotations: {} + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: "true" + hosts: + - host: chart-example.local + paths: [] + tls: [] + # - secretName: chart-example-tls + # hosts: + # - chart-example.local + +## Affinity for pod assignment +## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity +affinity: {} +# podAntiAffinity: +# requiredDuringSchedulingIgnoredDuringExecution: +# - labelSelector: +# matchExpressions: +# - key: app +# operator: In +# values: +# - loki +# topologyKey: "kubernetes.io/hostname" + +## StatefulSet annotations +annotations: {} + +# enable tracing for debug, need install jaeger and specify right jaeger_agent_host +tracing: + jaegerAgentHost: + +config: + # existingSecret: + auth_enabled: false + ingester: + chunk_idle_period: 3m + chunk_block_size: 262144 + chunk_retain_period: 1m + max_transfer_retries: 0 + wal: + dir: /data/loki/wal + lifecycler: + ring: + kvstore: + store: inmemory + replication_factor: 1 + + ## Different ring configs can be used. E.g. Consul + # ring: + # store: consul + # replication_factor: 1 + # consul: + # host: "consul:8500" + # prefix: "" + # http_client_timeout: "20s" + # consistent_reads: true + limits_config: + enforce_metric_name: false + reject_old_samples: true + reject_old_samples_max_age: 168h + schema_config: + configs: + - from: 2020-10-24 + store: boltdb-shipper + object_store: filesystem + schema: v11 + index: + prefix: index_ + period: 24h + server: + http_listen_port: 3100 + storage_config: + boltdb_shipper: + active_index_directory: /data/loki/boltdb-shipper-active + cache_location: /data/loki/boltdb-shipper-cache + cache_ttl: 24h # Can be increased for faster performance over longer query periods, uses more disk space + shared_store: filesystem + filesystem: + directory: /data/loki/chunks + chunk_store_config: + max_look_back_period: 0s + table_manager: + retention_deletes_enabled: false + retention_period: 0s + compactor: + working_directory: /data/loki/boltdb-shipper-compactor + shared_store: filesystem +# Needed for Alerting: https://grafana.com/docs/loki/latest/rules/ +# This is just a simple example, for more details: https://grafana.com/docs/loki/latest/configuration/#ruler_config +# ruler: +# storage: +# type: local +# local: +# directory: /rules +# rule_path: /tmp/scratch +# alertmanager_url: http://alertmanager.svc.namespace:9093 +# ring: +# kvstore: +# store: inmemory +# enable_api: true + +## Additional Loki container arguments, e.g. log level (debug, info, warn, error) +extraArgs: {} + # log.level: debug + +livenessProbe: + httpGet: + path: /ready + port: http-metrics + initialDelaySeconds: 45 + +## ref: https://kubernetes.io/docs/concepts/services-networking/network-policies/ +networkPolicy: + enabled: false + +## The app name of loki clients +client: {} + # name: + +## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ +nodeSelector: {} + +## ref: https://kubernetes.io/docs/concepts/storage/persistent-volumes/ +## If you set enabled as "True", you need : +## - create a pv which above 10Gi and has same namespace with loki +## - keep storageClassName same with below setting +persistence: + enabled: false + accessModes: + - ReadWriteOnce + size: 10Gi + annotations: {} + # selector: + # matchLabels: + # app.kubernetes.io/name: loki + # subPath: "" + # existingClaim: + +## Pod Labels +podLabels: {} + +## Pod Annotations +podAnnotations: + prometheus.io/scrape: "true" + prometheus.io/port: "http-metrics" + +podManagementPolicy: OrderedReady + +## Assign a PriorityClassName to pods if set +# priorityClassName: + +rbac: + create: true + pspEnabled: true + +readinessProbe: + httpGet: + path: /ready + port: http-metrics + initialDelaySeconds: 45 + +replicas: 1 + +resources: {} +# limits: +# cpu: 200m +# memory: 256Mi +# requests: +# cpu: 100m +# memory: 128Mi + +securityContext: + fsGroup: 10001 + runAsGroup: 10001 + runAsNonRoot: true + runAsUser: 10001 + +service: + type: ClusterIP + nodePort: + port: 3100 + annotations: {} + labels: {} + targetPort: http-metrics + +serviceAccount: + create: true + name: + annotations: {} + automountServiceAccountToken: true + +terminationGracePeriodSeconds: 4800 + +## Tolerations for pod assignment +## ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ +tolerations: [] + +# The values to set in the PodDisruptionBudget spec +# If not set then a PodDisruptionBudget will not be created +podDisruptionBudget: {} +# minAvailable: 1 +# maxUnavailable: 1 + +updateStrategy: + type: RollingUpdate + +serviceMonitor: + enabled: false + interval: "" + additionalLabels: {} + annotations: {} + # scrapeTimeout: 10s + # path: /metrics + prometheusRule: + enabled: false + additionalLabels: {} + # namespace: + rules: [] + # Some examples from https://awesome-prometheus-alerts.grep.to/rules.html#loki + # - alert: LokiProcessTooManyRestarts + # expr: changes(process_start_time_seconds{job=~"loki"}[15m]) > 2 + # for: 0m + # labels: + # severity: warning + # annotations: + # summary: Loki process too many restarts (instance {{ $labels.instance }}) + # description: "A loki process had too many restarts (target {{ $labels.instance }})\n VALUE = {{ $value }}\n LABELS = {{ $labels }}" + # - alert: LokiRequestErrors + # expr: 100 * sum(rate(loki_request_duration_seconds_count{status_code=~"5.."}[1m])) by (namespace, job, route) / sum(rate(loki_request_duration_seconds_count[1m])) by (namespace, job, route) > 10 + # for: 15m + # labels: + # severity: critical + # annotations: + # summary: Loki request errors (instance {{ $labels.instance }}) + # description: "The {{ $labels.job }} and {{ $labels.route }} are experiencing errors\n VALUE = {{ $value }}\n LABELS = {{ $labels }}" + # - alert: LokiRequestPanic + # expr: sum(increase(loki_panic_total[10m])) by (namespace, job) > 0 + # for: 5m + # labels: + # severity: critical + # annotations: + # summary: Loki request panic (instance {{ $labels.instance }}) + # description: "The {{ $labels.job }} is experiencing {{ printf \"%.2f\" $value }}% increase of panics\n VALUE = {{ $value }}\n LABELS = {{ $labels }}" + # - alert: LokiRequestLatency + # expr: (histogram_quantile(0.99, sum(rate(loki_request_duration_seconds_bucket{route!~"(?i).*tail.*"}[5m])) by (le))) > 1 + # for: 5m + # labels: + # severity: critical + # annotations: + # summary: Loki request latency (instance {{ $labels.instance }}) + # description: "The {{ $labels.job }} {{ $labels.route }} is experiencing {{ printf \"%.2f\" $value }}s 99th percentile latency\n VALUE = {{ $value }}\n LABELS = {{ $labels }}" + + +initContainers: [] +## Init containers to be added to the loki pod. +# - name: my-init-container +# image: busybox:latest +# command: ['sh', '-c', 'echo hello'] + +extraContainers: [] +## Additional containers to be added to the loki pod. +# - name: reverse-proxy +# image: angelbarrera92/basic-auth-reverse-proxy:dev +# args: +# - "serve" +# - "--upstream=http://localhost:3100" +# - "--auth-config=/etc/reverse-proxy-conf/authn.yaml" +# ports: +# - name: http +# containerPort: 11811 +# protocol: TCP +# volumeMounts: +# - name: reverse-proxy-auth-config +# mountPath: /etc/reverse-proxy-conf + + +extraVolumes: [] +## Additional volumes to the loki pod. +# - name: reverse-proxy-auth-config +# secret: +# secretName: reverse-proxy-auth-config + +## Extra volume mounts that will be added to the loki container +extraVolumeMounts: [] + +extraPorts: [] +## Additional ports to the loki services. Useful to expose extra container ports. +# - port: 11811 +# protocol: TCP +# name: http +# targetPort: http + +# Extra env variables to pass to the loki container +env: [] + +# Specify Loki Alerting rules based on this documentation: https://grafana.com/docs/loki/latest/rules/ +# When specified, you also need to add a ruler config section above. An example is shown in the alerting docs. +alerting_groups: [] +# - name: example +# rules: +# - alert: HighThroughputLogStreams +# expr: sum by(container) (rate({job=~"loki-dev/.*"}[1m])) > 1000 +# for: 2m + +useExistingAlertingGroup: + enabled: false + configmapName: "" diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/.helmignore b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/.helmignore new file mode 100644 index 0000000..825c007 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/.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 +*~ +# Various IDEs +.project +.idea/ +*.tmproj + +OWNERS diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/Chart.lock b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/Chart.lock new file mode 100644 index 0000000..20259ef --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: kube-state-metrics + repository: https://prometheus-community.github.io/helm-charts + version: 4.4.3 +digest: sha256:12753c953cca46b23980c65586d19c2016b959712a08e476660417f299810e3d +generated: "2022-03-23T22:52:43.250972737Z" diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/Chart.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/Chart.yaml new file mode 100644 index 0000000..26ef7d1 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/Chart.yaml @@ -0,0 +1,30 @@ +apiVersion: v2 +appVersion: 2.34.0 +dependencies: +- condition: kubeStateMetrics.enabled + name: kube-state-metrics + repository: https://prometheus-community.github.io/helm-charts + version: 4.4.* +description: Prometheus is a monitoring system and time series database. +home: https://prometheus.io/ +icon: https://raw.githubusercontent.com/prometheus/prometheus.github.io/master/assets/prometheus_logo-cb55bb5c346.png +maintainers: +- email: gianrubio@gmail.com + name: gianrubio +- email: zanhsieh@gmail.com + name: zanhsieh +- email: miroslav.hadzhiev@gmail.com + name: Xtigyro +- email: monotek23@gmail.com + name: monotek +- email: naseem@transit.app + name: naseemkullah +name: prometheus +sources: +- https://github.com/prometheus/alertmanager +- https://github.com/prometheus/prometheus +- https://github.com/prometheus/pushgateway +- https://github.com/prometheus/node_exporter +- https://github.com/kubernetes/kube-state-metrics +type: application +version: 15.5.4 diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/README.md b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/README.md new file mode 100644 index 0000000..d8a1e9a --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/README.md @@ -0,0 +1,226 @@ +# Prometheus + +[Prometheus](https://prometheus.io/), a [Cloud Native Computing Foundation](https://cncf.io/) project, is a systems and service monitoring system. It collects metrics from configured targets at given intervals, evaluates rule expressions, displays the results, and can trigger alerts if some condition is observed to be true. + +This chart bootstraps a [Prometheus](https://prometheus.io/) deployment on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. + +## Prerequisites + +- Kubernetes 1.16+ +- Helm 3+ + +## Get Repo Info + +```console +helm repo add prometheus-community https://prometheus-community.github.io/helm-charts +helm repo update +``` + +_See [helm repo](https://helm.sh/docs/helm/helm_repo/) for command documentation._ + +## Install Chart + +```console +helm install [RELEASE_NAME] prometheus-community/prometheus +``` + +_See [configuration](#configuration) below._ + +_See [helm install](https://helm.sh/docs/helm/helm_install/) for command documentation._ + +## Dependencies + +By default this chart installs additional, dependent charts: + +- [kube-state-metrics](https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-state-metrics) + +To disable the dependency during installation, set `kubeStateMetrics.enabled` to `false`. + +_See [helm dependency](https://helm.sh/docs/helm/helm_dependency/) for command documentation._ + +## Uninstall Chart + +```console +helm uninstall [RELEASE_NAME] +``` + +This removes all the Kubernetes components associated with the chart and deletes the release. + +_See [helm uninstall](https://helm.sh/docs/helm/helm_uninstall/) for command documentation._ + +## Upgrading Chart + +```console +helm upgrade [RELEASE_NAME] [CHART] --install +``` + +_See [helm upgrade](https://helm.sh/docs/helm/helm_upgrade/) for command documentation._ + +### To 15.0 + +Version 15.0.0 changes the relabeling config, aligning it with the [Prometheus community conventions](https://github.com/prometheus/prometheus/pull/9832). If you've made manual changes to the relabeling config, you have to adapt your changes. + +Before you update please execute the following command, to be able to update kube-state-metrics: + +```bash +kubectl delete deployments.apps -l app.kubernetes.io/instance=prometheus,app.kubernetes.io/name=kube-state-metrics --cascade=orphan +``` + +### To 9.0 + +Version 9.0 adds a new option to enable or disable the Prometheus Server. This supports the use case of running a Prometheus server in one k8s cluster and scraping exporters in another cluster while using the same chart for each deployment. To install the server `server.enabled` must be set to `true`. + +### To 5.0 + +As of version 5.0, this chart uses Prometheus 2.x. This version of prometheus introduces a new data format and is not compatible with prometheus 1.x. It is recommended to install this as a new release, as updating existing releases will not work. See the [prometheus docs](https://prometheus.io/docs/prometheus/latest/migration/#storage) for instructions on retaining your old data. + +Prometheus version 2.x has made changes to alertmanager, storage and recording rules. Check out the migration guide [here](https://prometheus.io/docs/prometheus/2.0/migration/). + +Users of this chart will need to update their alerting rules to the new format before they can upgrade. + +### Example Migration + +Assuming you have an existing release of the prometheus chart, named `prometheus-old`. In order to update to prometheus 2.x while keeping your old data do the following: + +1. Update the `prometheus-old` release. Disable scraping on every component besides the prometheus server, similar to the configuration below: + + ```yaml + alertmanager: + enabled: false + alertmanagerFiles: + alertmanager.yml: "" + kubeStateMetrics: + enabled: false + nodeExporter: + enabled: false + pushgateway: + enabled: false + server: + extraArgs: + storage.local.retention: 720h + serverFiles: + alerts: "" + prometheus.yml: "" + rules: "" + ``` + +1. Deploy a new release of the chart with version 5.0+ using prometheus 2.x. In the values.yaml set the scrape config as usual, and also add the `prometheus-old` instance as a remote-read target. + + ```yaml + prometheus.yml: + ... + remote_read: + - url: http://prometheus-old/api/v1/read + ... + ``` + + Old data will be available when you query the new prometheus instance. + +## Configuration + +See [Customizing the Chart Before Installing](https://helm.sh/docs/intro/using_helm/#customizing-the-chart-before-installing). To see all configurable options with detailed comments, visit the chart's [values.yaml](./values.yaml), or run these configuration commands: + +```console +helm show values prometheus-community/prometheus +``` + +You may similarly use the above configuration commands on each chart [dependency](#dependencies) to see it's configurations. + +### Scraping Pod Metrics via Annotations + +This chart uses a default configuration that causes prometheus to scrape a variety of kubernetes resource types, provided they have the correct annotations. In this section we describe how to configure pods to be scraped; for information on how other resource types can be scraped you can do a `helm template` to get the kubernetes resource definitions, and then reference the prometheus configuration in the ConfigMap against the prometheus documentation for [relabel_config](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config) and [kubernetes_sd_config](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#kubernetes_sd_config). + +In order to get prometheus to scrape pods, you must add annotations to the the pods as below: + +```yaml +metadata: + annotations: + prometheus.io/scrape: "true" + prometheus.io/path: /metrics + prometheus.io/port: "8080" +``` + +You should adjust `prometheus.io/path` based on the URL that your pod serves metrics from. `prometheus.io/port` should be set to the port that your pod serves metrics from. Note that the values for `prometheus.io/scrape` and `prometheus.io/port` must be enclosed in double quotes. + +### Sharing Alerts Between Services + +Note that when [installing](#install-chart) or [upgrading](#upgrading-chart) you may use multiple values override files. This is particularly useful when you have alerts belonging to multiple services in the cluster. For example, + +```yaml +# values.yaml +# ... + +# service1-alert.yaml +serverFiles: + alerts: + service1: + - alert: anAlert + # ... + +# service2-alert.yaml +serverFiles: + alerts: + service2: + - alert: anAlert + # ... +``` + +```console +helm install [RELEASE_NAME] prometheus-community/prometheus -f values.yaml -f service1-alert.yaml -f service2-alert.yaml +``` + +### RBAC Configuration + +Roles and RoleBindings resources will be created automatically for `server` service. + +To manually setup RBAC you need to set the parameter `rbac.create=false` and specify the service account to be used for each service by setting the parameters: `serviceAccounts.{{ component }}.create` to `false` and `serviceAccounts.{{ component }}.name` to the name of a pre-existing service account. + +> **Tip**: You can refer to the default `*-clusterrole.yaml` and `*-clusterrolebinding.yaml` files in [templates](templates/) to customize your own. + +### ConfigMap Files + +AlertManager is configured through [alertmanager.yml](https://prometheus.io/docs/alerting/configuration/). This file (and any others listed in `alertmanagerFiles`) will be mounted into the `alertmanager` pod. + +Prometheus is configured through [prometheus.yml](https://prometheus.io/docs/operating/configuration/). This file (and any others listed in `serverFiles`) will be mounted into the `server` pod. + +### Ingress TLS + +If your cluster allows automatic creation/retrieval of TLS certificates (e.g. [cert-manager](https://github.com/jetstack/cert-manager)), please refer to the documentation for that mechanism. + +To manually configure TLS, first create/retrieve a key & certificate pair for the address(es) you wish to protect. Then create a TLS secret in the namespace: + +```console +kubectl create secret tls prometheus-server-tls --cert=path/to/tls.cert --key=path/to/tls.key +``` + +Include the secret's name, along with the desired hostnames, in the alertmanager/server Ingress TLS section of your custom `values.yaml` file: + +```yaml +server: + ingress: + ## If true, Prometheus server Ingress will be created + ## + enabled: true + + ## Prometheus server Ingress hostnames + ## Must be provided if Ingress is enabled + ## + hosts: + - prometheus.domain.com + + ## Prometheus server Ingress TLS configuration + ## Secrets must be manually created in the namespace + ## + tls: + - secretName: prometheus-server-tls + hosts: + - prometheus.domain.com +``` + +### NetworkPolicy + +Enabling Network Policy for Prometheus will secure connections to Alert Manager and Kube State Metrics by only accepting connections from Prometheus Server. All inbound connections to Prometheus Server are still allowed. + +To enable network policy for Prometheus, install a networking plugin that implements the Kubernetes NetworkPolicy spec, and set `networkPolicy.enabled` to true. + +If NetworkPolicy is enabled for Prometheus' scrape targets, you may also need to manually create a networkpolicy which allows it. diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/.helmignore b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/.helmignore new file mode 100644 index 0000000..f0c1319 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/.helmignore @@ -0,0 +1,21 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*~ +# Various IDEs +.project +.idea/ +*.tmproj diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/Chart.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/Chart.yaml new file mode 100644 index 0000000..e9e40c7 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/Chart.yaml @@ -0,0 +1,21 @@ +apiVersion: v2 +appVersion: 2.3.0 +description: Install kube-state-metrics to generate and expose cluster-level metrics +home: https://github.com/kubernetes/kube-state-metrics/ +keywords: +- metric +- monitoring +- prometheus +- kubernetes +maintainers: +- email: tariq.ibrahim@mulesoft.com + name: tariq1890 +- email: manuel@rueg.eu + name: mrueg +- email: davidcalvertfr@gmail.com + name: dotdc +name: kube-state-metrics +sources: +- https://github.com/kubernetes/kube-state-metrics/ +type: application +version: 4.4.3 diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/README.md b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/README.md new file mode 100644 index 0000000..7c2e169 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/README.md @@ -0,0 +1,68 @@ +# kube-state-metrics Helm Chart + +Installs the [kube-state-metrics agent](https://github.com/kubernetes/kube-state-metrics). + +## Get Repo Info + +```console +helm repo add prometheus-community https://prometheus-community.github.io/helm-charts +helm repo update +``` + +_See [helm repo](https://helm.sh/docs/helm/helm_repo/) for command documentation._ + +## Install Chart + +```console +helm install [RELEASE_NAME] prometheus-community/kube-state-metrics [flags] +``` + +_See [configuration](#configuration) below._ + +_See [helm install](https://helm.sh/docs/helm/helm_install/) for command documentation._ + +## Uninstall Chart + +```console +helm uninstall [RELEASE_NAME] +``` + +This removes all the Kubernetes components associated with the chart and deletes the release. + +_See [helm uninstall](https://helm.sh/docs/helm/helm_uninstall/) for command documentation._ + +## Upgrading Chart + +```console +helm upgrade [RELEASE_NAME] prometheus-community/kube-state-metrics [flags] +``` + +_See [helm upgrade](https://helm.sh/docs/helm/helm_upgrade/) for command documentation._ + +### Migrating from stable/kube-state-metrics and kubernetes/kube-state-metrics + +You can upgrade in-place: + +1. [get repo info](#get-repo-info) +1. [upgrade](#upgrading-chart) your existing release name using the new chart repo + + +## Upgrading to v3.0.0 + +v3.0.0 includes kube-state-metrics v2.0, see the [changelog](https://github.com/kubernetes/kube-state-metrics/blob/release-2.0/CHANGELOG.md) for major changes on the application-side. + +The upgraded chart now the following changes: +* Dropped support for helm v2 (helm v3 or later is required) +* collectors key was renamed to resources +* namespace key was renamed to namespaces + + +## Configuration + +See [Customizing the Chart Before Installing](https://helm.sh/docs/intro/using_helm/#customizing-the-chart-before-installing). To see all configurable options with detailed comments: + +```console +helm show values prometheus-community/kube-state-metrics +``` + +You may also run `helm show values` on this chart's [dependencies](#dependencies) for additional options. diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/templates/NOTES.txt b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/templates/NOTES.txt new file mode 100644 index 0000000..5a646e0 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/templates/NOTES.txt @@ -0,0 +1,10 @@ +kube-state-metrics is a simple service that listens to the Kubernetes API server and generates metrics about the state of the objects. +The exposed metrics can be found here: +https://github.com/kubernetes/kube-state-metrics/blob/master/docs/README.md#exposed-metrics + +The metrics are exported on the HTTP endpoint /metrics on the listening port. +In your case, {{ template "kube-state-metrics.fullname" . }}.{{ template "kube-state-metrics.namespace" . }}.svc.cluster.local:{{ .Values.service.port }}/metrics + +They are served either as plaintext or protobuf depending on the Accept header. +They are designed to be consumed either by Prometheus itself or by a scraper that is compatible with scraping a Prometheus client endpoint. + diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/templates/_helpers.tpl b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/templates/_helpers.tpl new file mode 100644 index 0000000..976b273 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/templates/_helpers.tpl @@ -0,0 +1,82 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "kube-state-metrics.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 "kube-state-metrics.fullname" -}} +{{- if .Values.fullnameOverride -}} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Create the name of the service account to use +*/}} +{{- define "kube-state-metrics.serviceAccountName" -}} +{{- if .Values.serviceAccount.create -}} + {{ default (include "kube-state-metrics.fullname" .) .Values.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +Allow the release namespace to be overridden for multi-namespace deployments in combined charts +*/}} +{{- define "kube-state-metrics.namespace" -}} + {{- if .Values.namespaceOverride -}} + {{- .Values.namespaceOverride -}} + {{- else -}} + {{- .Release.Namespace -}} + {{- end -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "kube-state-metrics.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Generate basic labels +*/}} +{{- define "kube-state-metrics.labels" }} +helm.sh/chart: {{ template "kube-state-metrics.chart" . }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +app.kubernetes.io/component: metrics +app.kubernetes.io/part-of: {{ template "kube-state-metrics.name" . }} +{{- include "kube-state-metrics.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +{{- if .Values.customLabels }} +{{ toYaml .Values.customLabels }} +{{- end }} +{{- if .Values.releaseLabel }} +release: {{ .Release.Name }} +{{- end }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "kube-state-metrics.selectorLabels" }} +app.kubernetes.io/name: {{ include "kube-state-metrics.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/templates/clusterrolebinding.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/templates/clusterrolebinding.yaml new file mode 100644 index 0000000..cf9f628 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/templates/clusterrolebinding.yaml @@ -0,0 +1,20 @@ +{{- if and .Values.rbac.create .Values.rbac.useClusterRole -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + {{- include "kube-state-metrics.labels" . | indent 4 }} + name: {{ template "kube-state-metrics.fullname" . }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole +{{- if .Values.rbac.useExistingRole }} + name: {{ .Values.rbac.useExistingRole }} +{{- else }} + name: {{ template "kube-state-metrics.fullname" . }} +{{- end }} +subjects: +- kind: ServiceAccount + name: {{ template "kube-state-metrics.serviceAccountName" . }} + namespace: {{ template "kube-state-metrics.namespace" . }} +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/templates/deployment.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/templates/deployment.yaml new file mode 100644 index 0000000..5e666c5 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/templates/deployment.yaml @@ -0,0 +1,148 @@ +apiVersion: apps/v1 +{{- if .Values.autosharding.enabled }} +kind: StatefulSet +{{- else }} +kind: Deployment +{{- end }} +metadata: + name: {{ template "kube-state-metrics.fullname" . }} + namespace: {{ template "kube-state-metrics.namespace" . }} + labels: + {{- include "kube-state-metrics.labels" . | indent 4 }} +spec: + selector: + matchLabels: + {{- include "kube-state-metrics.selectorLabels" . | indent 6 }} + replicas: {{ .Values.replicas }} + {{- if .Values.autosharding.enabled }} + serviceName: {{ template "kube-state-metrics.fullname" . }} + volumeClaimTemplates: [] + {{- end }} + template: + metadata: + labels: + {{- include "kube-state-metrics.labels" . | indent 8 }} + {{- if .Values.podAnnotations }} + annotations: +{{ toYaml .Values.podAnnotations | indent 8 }} + {{- end }} + spec: + hostNetwork: {{ .Values.hostNetwork }} + serviceAccountName: {{ template "kube-state-metrics.serviceAccountName" . }} + {{- if .Values.securityContext.enabled }} + securityContext: + fsGroup: {{ .Values.securityContext.fsGroup }} + runAsGroup: {{ .Values.securityContext.runAsGroup }} + runAsUser: {{ .Values.securityContext.runAsUser }} + {{- end }} + {{- if .Values.priorityClassName }} + priorityClassName: {{ .Values.priorityClassName }} + {{- end }} + containers: + - name: {{ .Chart.Name }} + {{- if .Values.autosharding.enabled }} + env: + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + {{- end }} + args: + {{- if .Values.extraArgs }} + {{- range .Values.extraArgs }} + - {{ . }} + {{- end }} + {{- end }} + {{- if .Values.service.port }} + - --port={{ .Values.service.port | default 8080}} + {{- end }} + {{- if .Values.collectors }} + - --resources={{ .Values.collectors | join "," }} + {{- end }} + {{- if .Values.metricLabelsAllowlist }} + - --metric-labels-allowlist={{ .Values.metricLabelsAllowlist | join "," }} + {{- end }} + {{- if .Values.metricAnnotationsAllowList }} + - --metric-annotations-allowlist={{ .Values.metricAnnotationsAllowList | join "," }} + {{- end }} + {{- if .Values.metricAllowlist }} + - --metric-allowlist={{ .Values.metricAllowlist | join "," }} + {{- end }} + {{- if .Values.metricDenylist }} + - --metric-denylist={{ .Values.metricDenylist | join "," }} + {{- end }} + {{- if .Values.namespaces }} + - --namespaces={{ tpl (.Values.namespaces | join ",") $ }} + {{- end }} + {{- if .Values.autosharding.enabled }} + - --pod=$(POD_NAME) + - --pod-namespace=$(POD_NAMESPACE) + {{- end }} + {{- if .Values.kubeconfig.enabled }} + - --kubeconfig=/opt/k8s/.kube/config + {{- end }} + {{- if .Values.selfMonitor.telemetryHost }} + - --telemetry-host={{ .Values.selfMonitor.telemetryHost }} + {{- end }} + - --telemetry-port={{ .Values.selfMonitor.telemetryPort | default 8081 }} + {{- if .Values.kubeconfig.enabled }} + volumeMounts: + - name: kubeconfig + mountPath: /opt/k8s/.kube/ + readOnly: true + {{- end }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + ports: + - containerPort: {{ .Values.service.port | default 8080}} + name: "http" + {{- if .Values.selfMonitor.enabled }} + - containerPort: {{ .Values.selfMonitor.telemetryPort | default 8081 }} + name: "metrics" + {{- end }} + livenessProbe: + httpGet: + path: /healthz + port: {{ .Values.service.port | default 8080}} + initialDelaySeconds: 5 + timeoutSeconds: 5 + readinessProbe: + httpGet: + path: / + port: {{ .Values.service.port | default 8080}} + initialDelaySeconds: 5 + timeoutSeconds: 5 + {{- if .Values.resources }} + resources: +{{ toYaml .Values.resources | indent 10 }} +{{- end }} +{{- if .Values.containerSecurityContext }} + securityContext: +{{ toYaml .Values.containerSecurityContext | indent 10 }} +{{- end }} +{{- if .Values.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | indent 8 }} + {{- end }} + {{- if .Values.affinity }} + affinity: +{{ toYaml .Values.affinity | indent 8 }} + {{- end }} + {{- if .Values.nodeSelector }} + nodeSelector: +{{ toYaml .Values.nodeSelector | indent 8 }} + {{- end }} + {{- if .Values.tolerations }} + tolerations: +{{ toYaml .Values.tolerations | indent 8 }} + {{- end }} + {{- if .Values.kubeconfig.enabled}} + volumes: + - name: kubeconfig + secret: + secretName: {{ template "kube-state-metrics.fullname" . }}-kubeconfig + {{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/templates/kubeconfig-secret.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/templates/kubeconfig-secret.yaml new file mode 100644 index 0000000..6af0084 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/templates/kubeconfig-secret.yaml @@ -0,0 +1,12 @@ +{{- if .Values.kubeconfig.enabled -}} +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "kube-state-metrics.fullname" . }}-kubeconfig + namespace: {{ template "kube-state-metrics.namespace" . }} + labels: + {{- include "kube-state-metrics.labels" . | indent 4 }} +type: Opaque +data: + config: '{{ .Values.kubeconfig.secret }}' +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/templates/pdb.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/templates/pdb.yaml new file mode 100644 index 0000000..cbcf3a3 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/templates/pdb.yaml @@ -0,0 +1,14 @@ +{{- if .Values.podDisruptionBudget -}} +apiVersion: policy/v1beta1 +kind: PodDisruptionBudget +metadata: + name: {{ template "kube-state-metrics.fullname" . }} + namespace: {{ template "kube-state-metrics.namespace" . }} + labels: + {{- include "kube-state-metrics.labels" . | indent 4 }} +spec: + selector: + matchLabels: + app.kubernetes.io/name: {{ template "kube-state-metrics.name" . }} +{{ toYaml .Values.podDisruptionBudget | indent 2 }} +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/templates/podsecuritypolicy.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/templates/podsecuritypolicy.yaml new file mode 100644 index 0000000..3299056 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/templates/podsecuritypolicy.yaml @@ -0,0 +1,39 @@ +{{- if .Values.podSecurityPolicy.enabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "kube-state-metrics.fullname" . }} + labels: + {{- include "kube-state-metrics.labels" . | indent 4 }} +{{- if .Values.podSecurityPolicy.annotations }} + annotations: +{{ toYaml .Values.podSecurityPolicy.annotations | indent 4 }} +{{- end }} +spec: + privileged: false + volumes: + - 'secret' +{{- if .Values.podSecurityPolicy.additionalVolumes }} +{{ toYaml .Values.podSecurityPolicy.additionalVolumes | indent 4 }} +{{- end }} + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + rule: 'MustRunAsNonRoot' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'MustRunAs' + ranges: + # Forbid adding the root group. + - min: 1 + max: 65535 + fsGroup: + rule: 'MustRunAs' + ranges: + # Forbid adding the root group. + - min: 1 + max: 65535 + readOnlyRootFilesystem: false +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/templates/psp-clusterrole.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/templates/psp-clusterrole.yaml new file mode 100644 index 0000000..69047d4 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/templates/psp-clusterrole.yaml @@ -0,0 +1,19 @@ +{{- if and .Values.podSecurityPolicy.enabled .Values.rbac.create -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "kube-state-metrics.labels" . | indent 4 }} + name: psp-{{ template "kube-state-metrics.fullname" . }} +rules: +{{- $kubeTargetVersion := default .Capabilities.KubeVersion.GitVersion .Values.kubeTargetVersionOverride }} +{{- if semverCompare "> 1.15.0-0" $kubeTargetVersion }} +- apiGroups: ['policy'] +{{- else }} +- apiGroups: ['extensions'] +{{- end }} + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ template "kube-state-metrics.fullname" . }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/templates/psp-clusterrolebinding.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/templates/psp-clusterrolebinding.yaml new file mode 100644 index 0000000..03c56d5 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/templates/psp-clusterrolebinding.yaml @@ -0,0 +1,16 @@ +{{- if and .Values.podSecurityPolicy.enabled .Values.rbac.create -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + {{- include "kube-state-metrics.labels" . | indent 4 }} + name: psp-{{ template "kube-state-metrics.fullname" . }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: psp-{{ template "kube-state-metrics.fullname" . }} +subjects: + - kind: ServiceAccount + name: {{ template "kube-state-metrics.serviceAccountName" . }} + namespace: {{ template "kube-state-metrics.namespace" . }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/templates/role.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/templates/role.yaml new file mode 100644 index 0000000..e514e3c --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/templates/role.yaml @@ -0,0 +1,187 @@ +{{- if and (eq .Values.rbac.create true) (not .Values.rbac.useExistingRole) -}} +{{- range (ternary (split "," .Values.namespaces) (list "") (eq $.Values.rbac.useClusterRole false)) }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +{{- if eq $.Values.rbac.useClusterRole false }} +kind: Role +{{- else }} +kind: ClusterRole +{{- end }} +metadata: + labels: + {{- include "kube-state-metrics.labels" $ | indent 4 }} + name: {{ template "kube-state-metrics.fullname" $ }} +{{- if eq $.Values.rbac.useClusterRole false }} + namespace: {{ . }} +{{- end }} +rules: +{{ if has "certificatesigningrequests" $.Values.collectors }} +- apiGroups: ["certificates.k8s.io"] + resources: + - certificatesigningrequests + verbs: ["list", "watch"] +{{ end -}} +{{ if has "configmaps" $.Values.collectors }} +- apiGroups: [""] + resources: + - configmaps + verbs: ["list", "watch"] +{{ end -}} +{{ if has "cronjobs" $.Values.collectors }} +- apiGroups: ["batch"] + resources: + - cronjobs + verbs: ["list", "watch"] +{{ end -}} +{{ if has "daemonsets" $.Values.collectors }} +- apiGroups: ["extensions", "apps"] + resources: + - daemonsets + verbs: ["list", "watch"] +{{ end -}} +{{ if has "deployments" $.Values.collectors }} +- apiGroups: ["extensions", "apps"] + resources: + - deployments + verbs: ["list", "watch"] +{{ end -}} +{{ if has "endpoints" $.Values.collectors }} +- apiGroups: [""] + resources: + - endpoints + verbs: ["list", "watch"] +{{ end -}} +{{ if has "horizontalpodautoscalers" $.Values.collectors }} +- apiGroups: ["autoscaling"] + resources: + - horizontalpodautoscalers + verbs: ["list", "watch"] +{{ end -}} +{{ if has "ingresses" $.Values.collectors }} +- apiGroups: ["extensions", "networking.k8s.io"] + resources: + - ingresses + verbs: ["list", "watch"] +{{ end -}} +{{ if has "jobs" $.Values.collectors }} +- apiGroups: ["batch"] + resources: + - jobs + verbs: ["list", "watch"] +{{ end -}} +{{ if has "limitranges" $.Values.collectors }} +- apiGroups: [""] + resources: + - limitranges + verbs: ["list", "watch"] +{{ end -}} +{{ if has "mutatingwebhookconfigurations" $.Values.collectors }} +- apiGroups: ["admissionregistration.k8s.io"] + resources: + - mutatingwebhookconfigurations + verbs: ["list", "watch"] +{{ end -}} +{{ if has "namespaces" $.Values.collectors }} +- apiGroups: [""] + resources: + - namespaces + verbs: ["list", "watch"] +{{ end -}} +{{ if has "networkpolicies" $.Values.collectors }} +- apiGroups: ["networking.k8s.io"] + resources: + - networkpolicies + verbs: ["list", "watch"] +{{ end -}} +{{ if has "nodes" $.Values.collectors }} +- apiGroups: [""] + resources: + - nodes + verbs: ["list", "watch"] +{{ end -}} +{{ if has "persistentvolumeclaims" $.Values.collectors }} +- apiGroups: [""] + resources: + - persistentvolumeclaims + verbs: ["list", "watch"] +{{ end -}} +{{ if has "persistentvolumes" $.Values.collectors }} +- apiGroups: [""] + resources: + - persistentvolumes + verbs: ["list", "watch"] +{{ end -}} +{{ if has "poddisruptionbudgets" $.Values.collectors }} +- apiGroups: ["policy"] + resources: + - poddisruptionbudgets + verbs: ["list", "watch"] +{{ end -}} +{{ if has "pods" $.Values.collectors }} +- apiGroups: [""] + resources: + - pods + verbs: ["list", "watch"] +{{ end -}} +{{ if has "replicasets" $.Values.collectors }} +- apiGroups: ["extensions", "apps"] + resources: + - replicasets + verbs: ["list", "watch"] +{{ end -}} +{{ if has "replicationcontrollers" $.Values.collectors }} +- apiGroups: [""] + resources: + - replicationcontrollers + verbs: ["list", "watch"] +{{ end -}} +{{ if has "resourcequotas" $.Values.collectors }} +- apiGroups: [""] + resources: + - resourcequotas + verbs: ["list", "watch"] +{{ end -}} +{{ if has "secrets" $.Values.collectors }} +- apiGroups: [""] + resources: + - secrets + verbs: ["list", "watch"] +{{ end -}} +{{ if has "services" $.Values.collectors }} +- apiGroups: [""] + resources: + - services + verbs: ["list", "watch"] +{{ end -}} +{{ if has "statefulsets" $.Values.collectors }} +- apiGroups: ["apps"] + resources: + - statefulsets + verbs: ["list", "watch"] +{{ end -}} +{{ if has "storageclasses" $.Values.collectors }} +- apiGroups: ["storage.k8s.io"] + resources: + - storageclasses + verbs: ["list", "watch"] +{{ end -}} +{{ if has "validatingwebhookconfigurations" $.Values.collectors }} +- apiGroups: ["admissionregistration.k8s.io"] + resources: + - validatingwebhookconfigurations + verbs: ["list", "watch"] +{{ end -}} +{{ if has "volumeattachments" $.Values.collectors }} +- apiGroups: ["storage.k8s.io"] + resources: + - volumeattachments + verbs: ["list", "watch"] +{{ end -}} +{{ if has "verticalpodautoscalers" $.Values.collectors }} +- apiGroups: ["autoscaling.k8s.io"] + resources: + - verticalpodautoscalers + verbs: ["list", "watch"] +{{ end -}} +{{- end -}} +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/templates/rolebinding.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/templates/rolebinding.yaml new file mode 100644 index 0000000..135094f --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/templates/rolebinding.yaml @@ -0,0 +1,24 @@ +{{- if and (eq .Values.rbac.create true) (eq .Values.rbac.useClusterRole false) -}} +{{- range (split "," $.Values.namespaces) }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + {{- include "kube-state-metrics.labels" $ | indent 4 }} + name: {{ template "kube-state-metrics.fullname" $ }} + namespace: {{ . }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role +{{- if (not $.Values.rbac.useExistingRole) }} + name: {{ template "kube-state-metrics.fullname" $ }} +{{- else }} + name: {{ $.Values.rbac.useExistingRole }} +{{- end }} +subjects: +- kind: ServiceAccount + name: {{ template "kube-state-metrics.serviceAccountName" $ }} + namespace: {{ template "kube-state-metrics.namespace" $ }} +{{- end -}} +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/templates/service.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/templates/service.yaml new file mode 100644 index 0000000..853cf46 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/templates/service.yaml @@ -0,0 +1,35 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ template "kube-state-metrics.fullname" . }} + namespace: {{ template "kube-state-metrics.namespace" . }} + labels: + {{- include "kube-state-metrics.labels" . | indent 4 }} + annotations: + {{- if .Values.prometheusScrape }} + prometheus.io/scrape: '{{ .Values.prometheusScrape }}' + {{- end }} + {{- if .Values.service.annotations }} + {{- toYaml .Values.service.annotations | nindent 4 }} + {{- end }} +spec: + type: "{{ .Values.service.type }}" + ports: + - name: "http" + protocol: TCP + port: {{ .Values.service.port | default 8080}} + {{- if .Values.service.nodePort }} + nodePort: {{ .Values.service.nodePort }} + {{- end }} + targetPort: {{ .Values.service.port | default 8080}} + {{ if .Values.selfMonitor.enabled }} + - name: "metrics" + protocol: TCP + port: {{ .Values.selfMonitor.telemetryPort | default 8081 }} + targetPort: {{ .Values.selfMonitor.telemetryPort | default 8081 }} + {{ end }} +{{- if .Values.service.loadBalancerIP }} + loadBalancerIP: "{{ .Values.service.loadBalancerIP }}" +{{- end }} + selector: + {{- include "kube-state-metrics.selectorLabels" . | indent 4 }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/templates/serviceaccount.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/templates/serviceaccount.yaml new file mode 100644 index 0000000..e1229eb --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/templates/serviceaccount.yaml @@ -0,0 +1,15 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + {{- include "kube-state-metrics.labels" . | indent 4 }} + name: {{ template "kube-state-metrics.serviceAccountName" . }} + namespace: {{ template "kube-state-metrics.namespace" . }} +{{- if .Values.serviceAccount.annotations }} + annotations: +{{ toYaml .Values.serviceAccount.annotations | indent 4 }} +{{- end }} +imagePullSecrets: +{{ toYaml .Values.serviceAccount.imagePullSecrets | indent 2 }} +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/templates/servicemonitor.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/templates/servicemonitor.yaml new file mode 100644 index 0000000..93a5870 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/templates/servicemonitor.yaml @@ -0,0 +1,66 @@ +{{- if .Values.prometheus.monitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "kube-state-metrics.fullname" . }} + namespace: {{ template "kube-state-metrics.namespace" . }} + labels: + {{- include "kube-state-metrics.labels" . | indent 4 }} + {{- with .Values.prometheus.monitor.additionalLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + jobLabel: {{ default "app.kubernetes.io/name" .Values.prometheus.monitor.jobLabel }} + selector: + matchLabels: + {{- if .Values.prometheus.monitor.selectorOverride -}} + {{ toYaml .Values.prometheus.monitor.selectorOverride | nindent 6 }} + {{ else }} + {{- include "kube-state-metrics.selectorLabels" . | indent 6 }} + {{- end }} + endpoints: + - port: http + {{- if .Values.prometheus.monitor.interval }} + interval: {{ .Values.prometheus.monitor.interval }} + {{- end }} + {{- if .Values.prometheus.monitor.scrapeTimeout }} + scrapeTimeout: {{ .Values.prometheus.monitor.scrapeTimeout }} + {{- end }} + {{- if .Values.prometheus.monitor.proxyUrl }} + proxyUrl: {{ .Values.prometheus.monitor.proxyUrl}} + {{- end }} + {{- if .Values.prometheus.monitor.honorLabels }} + honorLabels: true + {{- end }} + {{- if .Values.prometheus.monitor.metricRelabelings }} + metricRelabelings: + {{- toYaml .Values.prometheus.monitor.metricRelabelings | nindent 8 }} + {{- end }} + {{- if .Values.prometheus.monitor.relabelings }} + relabelings: + {{- toYaml .Values.prometheus.monitor.relabelings | nindent 8 }} + {{- end }} + {{- if .Values.selfMonitor.enabled }} + - port: metrics + {{- if .Values.prometheus.monitor.interval }} + interval: {{ .Values.prometheus.monitor.interval }} + {{- end }} + {{- if .Values.prometheus.monitor.scrapeTimeout }} + scrapeTimeout: {{ .Values.prometheus.monitor.scrapeTimeout }} + {{- end }} + {{- if .Values.prometheus.monitor.proxyUrl }} + proxyUrl: {{ .Values.prometheus.monitor.proxyUrl}} + {{- end }} + {{- if .Values.prometheus.monitor.honorLabels }} + honorLabels: true + {{- end }} + {{- if .Values.prometheus.monitor.metricRelabelings }} + metricRelabelings: + {{- toYaml .Values.prometheus.monitor.metricRelabelings | nindent 8 }} + {{- end }} + {{- if .Values.prometheus.monitor.relabelings }} + relabelings: + {{- toYaml .Values.prometheus.monitor.relabelings | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/templates/stsdiscovery-role.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/templates/stsdiscovery-role.yaml new file mode 100644 index 0000000..489de14 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/templates/stsdiscovery-role.yaml @@ -0,0 +1,26 @@ +{{- if and .Values.autosharding.enabled .Values.rbac.create -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: stsdiscovery-{{ template "kube-state-metrics.fullname" . }} + namespace: {{ template "kube-state-metrics.namespace" . }} + labels: + {{- include "kube-state-metrics.labels" . | indent 4 }} +rules: +- apiGroups: + - "" + resources: + - pods + verbs: + - get +- apiGroups: + - apps + resourceNames: + - {{ template "kube-state-metrics.fullname" . }} + resources: + - statefulsets + verbs: + - get + - list + - watch +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/templates/stsdiscovery-rolebinding.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/templates/stsdiscovery-rolebinding.yaml new file mode 100644 index 0000000..73b37a4 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/templates/stsdiscovery-rolebinding.yaml @@ -0,0 +1,17 @@ +{{- if and .Values.autosharding.enabled .Values.rbac.create -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: stsdiscovery-{{ template "kube-state-metrics.fullname" . }} + namespace: {{ template "kube-state-metrics.namespace" . }} + labels: + {{- include "kube-state-metrics.labels" . | indent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: stsdiscovery-{{ template "kube-state-metrics.fullname" . }} +subjects: + - kind: ServiceAccount + name: {{ template "kube-state-metrics.serviceAccountName" . }} + namespace: {{ template "kube-state-metrics.namespace" . }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/values.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/values.yaml new file mode 100644 index 0000000..aced5cf --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/charts/kube-state-metrics/values.yaml @@ -0,0 +1,224 @@ +# Default values for kube-state-metrics. +prometheusScrape: true +image: + repository: k8s.gcr.io/kube-state-metrics/kube-state-metrics + tag: v2.3.0 + pullPolicy: IfNotPresent + +imagePullSecrets: [] +# - name: "image-pull-secret" + +# If set to true, this will deploy kube-state-metrics as a StatefulSet and the data +# will be automatically sharded across <.Values.replicas> pods using the built-in +# autodiscovery feature: https://github.com/kubernetes/kube-state-metrics#automated-sharding +# This is an experimental feature and there are no stability guarantees. +autosharding: + enabled: false + +replicas: 1 + +# List of additional cli arguments to configure kube-state-metrics +# for example: --enable-gzip-encoding, --log-file, etc. +# all the possible args can be found here: https://github.com/kubernetes/kube-state-metrics/blob/master/docs/cli-arguments.md +extraArgs: [] + +service: + port: 8080 + # Default to clusterIP for backward compatibility + type: ClusterIP + nodePort: 0 + loadBalancerIP: "" + annotations: {} + +## Additional labels to add to all resources +customLabels: {} + # app: kube-state-metrics + +## set to true to add the release label so scraping of the servicemonitor with kube-prometheus-stack works out of the box +releaseLabel: false + +hostNetwork: false + +rbac: + # If true, create & use RBAC resources + create: true + + # Set to a rolename to use existing role - skipping role creating - but still doing serviceaccount and rolebinding to it, rolename set here. + # useExistingRole: your-existing-role + + # If set to false - Run without Cluteradmin privs needed - ONLY works if namespace is also set (if useExistingRole is set this name is used as ClusterRole or Role to bind to) + useClusterRole: true + +serviceAccount: + # Specifies whether a ServiceAccount should be created, require rbac true + create: true + # The name of the ServiceAccount to use. + # If not set and create is true, a name is generated using the fullname template + name: + # Reference to one or more secrets to be used when pulling images + # ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ + imagePullSecrets: [] + # ServiceAccount annotations. + # Use case: AWS EKS IAM roles for service accounts + # ref: https://docs.aws.amazon.com/eks/latest/userguide/specify-service-account-role.html + annotations: {} + +prometheus: + monitor: + enabled: false + additionalLabels: {} + namespace: "" + jobLabel: "" + interval: "" + scrapeTimeout: "" + proxyUrl: "" + selectorOverride: {} + honorLabels: false + metricRelabelings: [] + relabelings: [] + +## Specify if a Pod Security Policy for kube-state-metrics must be created +## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/ +## +podSecurityPolicy: + enabled: false + annotations: {} + ## Specify pod annotations + ## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#apparmor + ## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#seccomp + ## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#sysctl + ## + # seccomp.security.alpha.kubernetes.io/allowedProfileNames: '*' + # seccomp.security.alpha.kubernetes.io/defaultProfileName: 'docker/default' + # apparmor.security.beta.kubernetes.io/defaultProfileName: 'runtime/default' + + additionalVolumes: [] + +securityContext: + enabled: true + runAsGroup: 65534 + runAsUser: 65534 + fsGroup: 65534 + +## Specify security settings for a Container +## Allows overrides and additional options compared to (Pod) securityContext +## Ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container +containerSecurityContext: {} + +## Node labels for pod assignment +## Ref: https://kubernetes.io/docs/user-guide/node-selection/ +nodeSelector: {} + +## Affinity settings for pod assignment +## Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ +affinity: {} + +## Tolerations for pod assignment +## Ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ +tolerations: [] + +# Annotations to be added to the pod +podAnnotations: {} + +## Assign a PriorityClassName to pods if set +# priorityClassName: "" + +# Ref: https://kubernetes.io/docs/tasks/run-application/configure-pdb/ +podDisruptionBudget: {} + +# Comma-separated list of metrics to be exposed. +# This list comprises of exact metric names and/or regex patterns. +# The allowlist and denylist are mutually exclusive. +metricAllowlist: [] + +# Comma-separated list of metrics not to be enabled. +# This list comprises of exact metric names and/or regex patterns. +# The allowlist and denylist are mutually exclusive. +metricDenylist: [] + +# Comma-separated list of additional Kubernetes label keys that will be used in the resource's +# labels metric. By default the metric contains only name and namespace labels. +# To include additional labels, provide a list of resource names in their plural form and Kubernetes +# label keys you would like to allow for them (Example: '=namespaces=[k8s-label-1,k8s-label-n,...],pods=[app],...)'. +# A single '*' can be provided per resource instead to allow any labels, but that has +# severe performance implications (Example: '=pods=[*]'). +metricLabelsAllowlist: [] + # - namespaces=[k8s-label-1,k8s-label-n] + +# Comma-separated list of Kubernetes annotations keys that will be used in the resource' +# labels metric. By default the metric contains only name and namespace labels. +# To include additional annotations provide a list of resource names in their plural form and Kubernetes +# annotation keys you would like to allow for them (Example: '=namespaces=[kubernetes.io/team,...],pods=[kubernetes.io/team],...)'. +# A single '*' can be provided per resource instead to allow any annotations, but that has +# severe performance implications (Example: '=pods=[*]'). +metricAnnotationsAllowList: [] + # - pods=[k8s-annotation-1,k8s-annotation-n] + +# Available collectors for kube-state-metrics. +# By default, all available resources are enabled, comment out to disable. +collectors: + - certificatesigningrequests + - configmaps + - cronjobs + - daemonsets + - deployments + - endpoints + - horizontalpodautoscalers + - ingresses + - jobs + - limitranges + - mutatingwebhookconfigurations + - namespaces + - networkpolicies + - nodes + - persistentvolumeclaims + - persistentvolumes + - poddisruptionbudgets + - pods + - replicasets + - replicationcontrollers + - resourcequotas + - secrets + - services + - statefulsets + - storageclasses + - validatingwebhookconfigurations + - volumeattachments + # - verticalpodautoscalers # not a default resource, see also: https://github.com/kubernetes/kube-state-metrics#enabling-verticalpodautoscalers + +# Enabling kubeconfig will pass the --kubeconfig argument to the container +kubeconfig: + enabled: false + # base64 encoded kube-config file + secret: + +# Comma-separated list of namespaces to be enabled for collecting resources. By default all namespaces are collected. +namespaces: "" + +## Override the deployment namespace +## +namespaceOverride: "" + +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: 64Mi + # requests: + # cpu: 10m + # memory: 32Mi + +## Provide a k8s version to define apiGroups for podSecurityPolicy Cluster Role. +## For example: kubeTargetVersionOverride: 1.14.9 +## +kubeTargetVersionOverride: "" + +# Enable self metrics configuration for service and Service Monitor +# Default values for telemetry configuration can be overridden +selfMonitor: + enabled: false + # telemetryHost: 0.0.0.0 + # telemetryPort: 8081 diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/NOTES.txt b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/NOTES.txt new file mode 100644 index 0000000..0e8868f --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/NOTES.txt @@ -0,0 +1,112 @@ +{{- if .Values.server.enabled -}} +The Prometheus server can be accessed via port {{ .Values.server.service.servicePort }} on the following DNS name from within your cluster: +{{ template "prometheus.server.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local + +{{ if .Values.server.ingress.enabled -}} +From outside the cluster, the server URL(s) are: +{{- range .Values.server.ingress.hosts }} +http://{{ . }} +{{- end }} +{{- else }} +Get the Prometheus server URL by running these commands in the same shell: +{{- if contains "NodePort" .Values.server.service.type }} + export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "prometheus.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.server.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 svc --namespace {{ .Release.Namespace }} -w {{ template "prometheus.server.fullname" . }}' + + export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "prometheus.server.fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}') + echo http://$SERVICE_IP:{{ .Values.server.service.servicePort }} +{{- else if contains "ClusterIP" .Values.server.service.type }} + export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ template "prometheus.name" . }},component={{ .Values.server.name }}" -o jsonpath="{.items[0].metadata.name}") + kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 9090 +{{- end }} +{{- end }} + +{{- if .Values.server.persistentVolume.enabled }} +{{- else }} +################################################################################# +###### WARNING: Persistence is disabled!!! You will lose your data when ##### +###### the Server pod is terminated. ##### +################################################################################# +{{- end }} +{{- end }} + +{{ if .Values.alertmanager.enabled }} +The Prometheus alertmanager can be accessed via port {{ .Values.alertmanager.service.servicePort }} on the following DNS name from within your cluster: +{{ template "prometheus.alertmanager.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local + +{{ if .Values.alertmanager.ingress.enabled -}} +From outside the cluster, the alertmanager URL(s) are: +{{- range .Values.alertmanager.ingress.hosts }} +http://{{ . }} +{{- end }} +{{- else }} +Get the Alertmanager URL by running these commands in the same shell: +{{- if contains "NodePort" .Values.alertmanager.service.type }} + export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "prometheus.alertmanager.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.alertmanager.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 svc --namespace {{ .Release.Namespace }} -w {{ template "prometheus.alertmanager.fullname" . }}' + + export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "prometheus.alertmanager.fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}') + echo http://$SERVICE_IP:{{ .Values.alertmanager.service.servicePort }} +{{- else if contains "ClusterIP" .Values.alertmanager.service.type }} + export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ template "prometheus.name" . }},component={{ .Values.alertmanager.name }}" -o jsonpath="{.items[0].metadata.name}") + kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 9093 +{{- end }} +{{- end }} + +{{- if .Values.alertmanager.persistentVolume.enabled }} +{{- else }} +################################################################################# +###### WARNING: Persistence is disabled!!! You will lose your data when ##### +###### the AlertManager pod is terminated. ##### +################################################################################# +{{- end }} +{{- end }} + +{{- if .Values.nodeExporter.podSecurityPolicy.enabled }} +{{- else }} +################################################################################# +###### WARNING: Pod Security Policy has been moved to a global property. ##### +###### use .Values.podSecurityPolicy.enabled with pod-based ##### +###### annotations ##### +###### (e.g. .Values.nodeExporter.podSecurityPolicy.annotations) ##### +################################################################################# +{{- end }} + +{{ if .Values.pushgateway.enabled }} +The Prometheus PushGateway can be accessed via port {{ .Values.pushgateway.service.servicePort }} on the following DNS name from within your cluster: +{{ template "prometheus.pushgateway.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local + +{{ if .Values.pushgateway.ingress.enabled -}} +From outside the cluster, the pushgateway URL(s) are: +{{- range .Values.pushgateway.ingress.hosts }} +http://{{ . }} +{{- end }} +{{- else }} +Get the PushGateway URL by running these commands in the same shell: +{{- if contains "NodePort" .Values.pushgateway.service.type }} + export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "prometheus.pushgateway.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.pushgateway.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 svc --namespace {{ .Release.Namespace }} -w {{ template "prometheus.pushgateway.fullname" . }}' + + export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "prometheus.pushgateway.fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}') + echo http://$SERVICE_IP:{{ .Values.pushgateway.service.servicePort }} +{{- else if contains "ClusterIP" .Values.pushgateway.service.type }} + export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ template "prometheus.name" . }},component={{ .Values.pushgateway.name }}" -o jsonpath="{.items[0].metadata.name}") + kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 9091 +{{- end }} +{{- end }} +{{- end }} + +For more information on running Prometheus, visit: +https://prometheus.io/ diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/_helpers.tpl b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/_helpers.tpl new file mode 100644 index 0000000..065065c --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/_helpers.tpl @@ -0,0 +1,282 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "prometheus.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "prometheus.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create unified labels for prometheus components +*/}} +{{- define "prometheus.common.matchLabels" -}} +app: {{ template "prometheus.name" . }} +release: {{ .Release.Name }} +{{- end -}} + +{{- define "prometheus.common.metaLabels" -}} +chart: {{ template "prometheus.chart" . }} +heritage: {{ .Release.Service }} +{{- end -}} + +{{- define "prometheus.alertmanager.labels" -}} +{{ include "prometheus.alertmanager.matchLabels" . }} +{{ include "prometheus.common.metaLabels" . }} +{{- end -}} + +{{- define "prometheus.alertmanager.matchLabels" -}} +component: {{ .Values.alertmanager.name | quote }} +{{ include "prometheus.common.matchLabels" . }} +{{- end -}} + +{{- define "prometheus.nodeExporter.labels" -}} +{{ include "prometheus.nodeExporter.matchLabels" . }} +{{ include "prometheus.common.metaLabels" . }} +{{- end -}} + +{{- define "prometheus.nodeExporter.matchLabels" -}} +component: {{ .Values.nodeExporter.name | quote }} +{{ include "prometheus.common.matchLabels" . }} +{{- end -}} + +{{- define "prometheus.pushgateway.labels" -}} +{{ include "prometheus.pushgateway.matchLabels" . }} +{{ include "prometheus.common.metaLabels" . }} +{{- end -}} + +{{- define "prometheus.pushgateway.matchLabels" -}} +component: {{ .Values.pushgateway.name | quote }} +{{ include "prometheus.common.matchLabels" . }} +{{- end -}} + +{{- define "prometheus.server.labels" -}} +{{ include "prometheus.server.matchLabels" . }} +{{ include "prometheus.common.metaLabels" . }} +{{- end -}} + +{{- define "prometheus.server.matchLabels" -}} +component: {{ .Values.server.name | quote }} +{{ include "prometheus.common.matchLabels" . }} +{{- end -}} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +*/}} +{{- define "prometheus.fullname" -}} +{{- if .Values.fullnameOverride -}} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Create a fully qualified alertmanager name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +*/}} + +{{- define "prometheus.alertmanager.fullname" -}} +{{- if .Values.alertmanager.fullnameOverride -}} +{{- .Values.alertmanager.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- printf "%s-%s" .Release.Name .Values.alertmanager.name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s-%s" .Release.Name $name .Values.alertmanager.name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Create a fully qualified node-exporter name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +*/}} +{{- define "prometheus.nodeExporter.fullname" -}} +{{- if .Values.nodeExporter.fullnameOverride -}} +{{- .Values.nodeExporter.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- printf "%s-%s" .Release.Name .Values.nodeExporter.name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s-%s" .Release.Name $name .Values.nodeExporter.name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Create a fully qualified Prometheus server name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +*/}} +{{- define "prometheus.server.fullname" -}} +{{- if .Values.server.fullnameOverride -}} +{{- .Values.server.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- printf "%s-%s" .Release.Name .Values.server.name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s-%s" .Release.Name $name .Values.server.name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Create a fully qualified pushgateway name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +*/}} +{{- define "prometheus.pushgateway.fullname" -}} +{{- if .Values.pushgateway.fullnameOverride -}} +{{- .Values.pushgateway.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- printf "%s-%s" .Release.Name .Values.pushgateway.name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s-%s" .Release.Name $name .Values.pushgateway.name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Get KubeVersion removing pre-release information. +*/}} +{{- define "prometheus.kubeVersion" -}} + {{- default .Capabilities.KubeVersion.Version (regexFind "v[0-9]+\\.[0-9]+\\.[0-9]+" .Capabilities.KubeVersion.Version) -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for deployment. +*/}} +{{- define "prometheus.deployment.apiVersion" -}} +{{- print "apps/v1" -}} +{{- end -}} +{{/* +Return the appropriate apiVersion for daemonset. +*/}} +{{- define "prometheus.daemonset.apiVersion" -}} +{{- print "apps/v1" -}} +{{- end -}} +{{/* +Return the appropriate apiVersion for networkpolicy. +*/}} +{{- define "prometheus.networkPolicy.apiVersion" -}} +{{- print "networking.k8s.io/v1" -}} +{{- end -}} +{{/* +Return the appropriate apiVersion for podsecuritypolicy. +*/}} +{{- define "prometheus.podSecurityPolicy.apiVersion" -}} +{{- print "policy/v1beta1" -}} +{{- end -}} +{{/* +Return the appropriate apiVersion for rbac. +*/}} +{{- define "rbac.apiVersion" -}} +{{- if .Capabilities.APIVersions.Has "rbac.authorization.k8s.io/v1" }} +{{- print "rbac.authorization.k8s.io/v1" -}} +{{- else -}} +{{- print "rbac.authorization.k8s.io/v1beta1" -}} +{{- end -}} +{{- end -}} +{{/* +Return the appropriate apiVersion for ingress. +*/}} +{{- define "ingress.apiVersion" -}} + {{- if and (.Capabilities.APIVersions.Has "networking.k8s.io/v1") (semverCompare ">= 1.19.x" (include "prometheus.kubeVersion" .)) -}} + {{- print "networking.k8s.io/v1" -}} + {{- else if .Capabilities.APIVersions.Has "networking.k8s.io/v1beta1" -}} + {{- print "networking.k8s.io/v1beta1" -}} + {{- else -}} + {{- print "extensions/v1beta1" -}} + {{- end -}} +{{- end -}} + +{{/* +Return if ingress is stable. +*/}} +{{- define "ingress.isStable" -}} + {{- eq (include "ingress.apiVersion" .) "networking.k8s.io/v1" -}} +{{- end -}} + +{{/* +Return if ingress supports ingressClassName. +*/}} +{{- define "ingress.supportsIngressClassName" -}} + {{- or (eq (include "ingress.isStable" .) "true") (and (eq (include "ingress.apiVersion" .) "networking.k8s.io/v1beta1") (semverCompare ">= 1.18.x" (include "prometheus.kubeVersion" .))) -}} +{{- end -}} +{{/* +Return if ingress supports pathType. +*/}} +{{- define "ingress.supportsPathType" -}} + {{- or (eq (include "ingress.isStable" .) "true") (and (eq (include "ingress.apiVersion" .) "networking.k8s.io/v1beta1") (semverCompare ">= 1.18.x" (include "prometheus.kubeVersion" .))) -}} +{{- end -}} + +{{/* +Create the name of the service account to use for the alertmanager component +*/}} +{{- define "prometheus.serviceAccountName.alertmanager" -}} +{{- if .Values.serviceAccounts.alertmanager.create -}} + {{ default (include "prometheus.alertmanager.fullname" .) .Values.serviceAccounts.alertmanager.name }} +{{- else -}} + {{ default "default" .Values.serviceAccounts.alertmanager.name }} +{{- end -}} +{{- end -}} + +{{/* +Create the name of the service account to use for the nodeExporter component +*/}} +{{- define "prometheus.serviceAccountName.nodeExporter" -}} +{{- if .Values.serviceAccounts.nodeExporter.create -}} + {{ default (include "prometheus.nodeExporter.fullname" .) .Values.serviceAccounts.nodeExporter.name }} +{{- else -}} + {{ default "default" .Values.serviceAccounts.nodeExporter.name }} +{{- end -}} +{{- end -}} + +{{/* +Create the name of the service account to use for the pushgateway component +*/}} +{{- define "prometheus.serviceAccountName.pushgateway" -}} +{{- if .Values.serviceAccounts.pushgateway.create -}} + {{ default (include "prometheus.pushgateway.fullname" .) .Values.serviceAccounts.pushgateway.name }} +{{- else -}} + {{ default "default" .Values.serviceAccounts.pushgateway.name }} +{{- end -}} +{{- end -}} + +{{/* +Create the name of the service account to use for the server component +*/}} +{{- define "prometheus.serviceAccountName.server" -}} +{{- if .Values.serviceAccounts.server.create -}} + {{ default (include "prometheus.server.fullname" .) .Values.serviceAccounts.server.name }} +{{- else -}} + {{ default "default" .Values.serviceAccounts.server.name }} +{{- end -}} +{{- end -}} + +{{/* +Define the prometheus.namespace template if set with forceNamespace or .Release.Namespace is set +*/}} +{{- define "prometheus.namespace" -}} +{{- if .Values.forceNamespace -}} +{{ printf "namespace: %s" .Values.forceNamespace }} +{{- else -}} +{{ printf "namespace: %s" .Release.Namespace }} +{{- end -}} +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/alertmanager/clusterrole.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/alertmanager/clusterrole.yaml new file mode 100644 index 0000000..c732ff4 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/alertmanager/clusterrole.yaml @@ -0,0 +1,21 @@ +{{- if and .Values.alertmanager.enabled .Values.rbac.create .Values.alertmanager.useClusterRole (not .Values.alertmanager.useExistingRole) -}} +apiVersion: {{ template "rbac.apiVersion" . }} +kind: ClusterRole +metadata: + labels: + {{- include "prometheus.alertmanager.labels" . | nindent 4 }} + name: {{ template "prometheus.alertmanager.fullname" . }} +rules: +{{- if .Values.podSecurityPolicy.enabled }} + - apiGroups: + - extensions + resources: + - podsecuritypolicies + verbs: + - use + resourceNames: + - {{ template "prometheus.alertmanager.fullname" . }} +{{- else }} + [] +{{- end }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/alertmanager/clusterrolebinding.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/alertmanager/clusterrolebinding.yaml new file mode 100644 index 0000000..6f13e98 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/alertmanager/clusterrolebinding.yaml @@ -0,0 +1,20 @@ +{{- if and .Values.alertmanager.enabled .Values.rbac.create .Values.alertmanager.useClusterRole -}} +apiVersion: {{ template "rbac.apiVersion" . }} +kind: ClusterRoleBinding +metadata: + labels: + {{- include "prometheus.alertmanager.labels" . | nindent 4 }} + name: {{ template "prometheus.alertmanager.fullname" . }} +subjects: + - kind: ServiceAccount + name: {{ template "prometheus.serviceAccountName.alertmanager" . }} +{{ include "prometheus.namespace" . | indent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole +{{- if (not .Values.alertmanager.useExistingRole) }} + name: {{ template "prometheus.alertmanager.fullname" . }} +{{- else }} + name: {{ .Values.alertmanager.useExistingRole }} +{{- end }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/alertmanager/cm.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/alertmanager/cm.yaml new file mode 100644 index 0000000..cb09bf0 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/alertmanager/cm.yaml @@ -0,0 +1,19 @@ +{{- if and .Values.alertmanager.enabled (and (empty .Values.alertmanager.configMapOverrideName) (empty .Values.alertmanager.configFromSecret)) -}} +apiVersion: v1 +kind: ConfigMap +metadata: + labels: + {{- include "prometheus.alertmanager.labels" . | nindent 4 }} + name: {{ template "prometheus.alertmanager.fullname" . }} +{{ include "prometheus.namespace" . | indent 2 }} +data: +{{- $root := . -}} +{{- range $key, $value := .Values.alertmanagerFiles }} + {{- if $key | regexMatch ".*\\.ya?ml$" }} + {{ $key }}: | +{{ toYaml $value | default "{}" | indent 4 }} + {{- else }} + {{ $key }}: {{ toYaml $value | indent 4 }} + {{- end }} +{{- end -}} +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/alertmanager/deploy.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/alertmanager/deploy.yaml new file mode 100644 index 0000000..48a3c84 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/alertmanager/deploy.yaml @@ -0,0 +1,204 @@ +{{- if and .Values.alertmanager.enabled (not .Values.alertmanager.statefulSet.enabled) -}} +apiVersion: {{ template "prometheus.deployment.apiVersion" . }} +kind: Deployment +metadata: +{{- if .Values.alertmanager.deploymentAnnotations }} + annotations: + {{ toYaml .Values.alertmanager.deploymentAnnotations | nindent 4 }} +{{- end }} + labels: + {{- include "prometheus.alertmanager.labels" . | nindent 4 }} + name: {{ template "prometheus.alertmanager.fullname" . }} +{{ include "prometheus.namespace" . | indent 2 }} +spec: + selector: + matchLabels: + {{- include "prometheus.alertmanager.matchLabels" . | nindent 6 }} + replicas: {{ .Values.alertmanager.replicaCount }} + {{- if .Values.alertmanager.strategy }} + strategy: +{{ toYaml .Values.alertmanager.strategy | trim | indent 4 }} + {{ if eq .Values.alertmanager.strategy.type "Recreate" }}rollingUpdate: null{{ end }} +{{- end }} + template: + metadata: + {{- if .Values.alertmanager.podAnnotations }} + annotations: + {{ toYaml .Values.alertmanager.podAnnotations | nindent 8 }} + {{- end }} + labels: + {{- include "prometheus.alertmanager.labels" . | nindent 8 }} + {{- if .Values.alertmanager.podLabels}} + {{ toYaml .Values.alertmanager.podLabels | nindent 8 }} + {{- end}} + spec: +{{- if .Values.alertmanager.schedulerName }} + schedulerName: "{{ .Values.alertmanager.schedulerName }}" +{{- end }} + serviceAccountName: {{ template "prometheus.serviceAccountName.alertmanager" . }} + {{- if .Values.alertmanager.extraInitContainers }} + initContainers: +{{ toYaml .Values.alertmanager.extraInitContainers | indent 8 }} + {{- end }} +{{- if .Values.alertmanager.priorityClassName }} + priorityClassName: "{{ .Values.alertmanager.priorityClassName }}" +{{- end }} + containers: + - name: {{ template "prometheus.name" . }}-{{ .Values.alertmanager.name }} + image: "{{ .Values.alertmanager.image.repository }}:{{ .Values.alertmanager.image.tag }}" + imagePullPolicy: "{{ .Values.alertmanager.image.pullPolicy }}" + env: + {{- range $key, $value := .Values.alertmanager.extraEnv }} + - name: {{ $key }} + value: {{ $value }} + {{- end }} + - name: POD_IP + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: status.podIP + args: + - --config.file=/etc/config/{{ .Values.alertmanager.configFileName }} + - --storage.path={{ .Values.alertmanager.persistentVolume.mountPath }} + {{- if .Values.alertmanager.service.enableMeshPeer }} + - --cluster.listen-address=0.0.0.0:6783 + - --cluster.advertise-address=[$(POD_IP)]:6783 + {{- else }} + - --cluster.listen-address= + {{- end }} + {{- range $key, $value := .Values.alertmanager.extraArgs }} + - --{{ $key }}={{ $value }} + {{- end }} + {{- if .Values.alertmanager.baseURL }} + - --web.external-url={{ .Values.alertmanager.baseURL }} + {{- end }} + {{- range .Values.alertmanager.clusterPeers }} + - --cluster.peer={{ . }} + {{- end }} + + ports: + - containerPort: 9093 + readinessProbe: + httpGet: + path: {{ .Values.alertmanager.prefixURL }}/-/ready + port: 9093 + {{- if .Values.alertmanager.probeHeaders }} + httpHeaders: + {{- range .Values.alertmanager.probeHeaders }} + - name: {{ .name }} + value: {{ .value }} + {{- end }} + {{- end }} + initialDelaySeconds: 30 + timeoutSeconds: 30 + resources: +{{ toYaml .Values.alertmanager.resources | indent 12 }} + volumeMounts: + - name: config-volume + mountPath: /etc/config + - name: storage-volume + mountPath: "{{ .Values.alertmanager.persistentVolume.mountPath }}" + subPath: "{{ .Values.alertmanager.persistentVolume.subPath }}" + {{- range .Values.alertmanager.extraSecretMounts }} + - name: {{ .name }} + mountPath: {{ .mountPath }} + subPath: {{ .subPath }} + readOnly: {{ .readOnly }} + {{- end }} + {{- range .Values.alertmanager.extraConfigmapMounts }} + - name: {{ .name }} + mountPath: {{ .mountPath }} + subPath: {{ .subPath }} + readOnly: {{ .readOnly }} + {{- end }} + + {{- if .Values.configmapReload.alertmanager.enabled }} + - name: {{ template "prometheus.name" . }}-{{ .Values.alertmanager.name }}-{{ .Values.configmapReload.alertmanager.name }} + image: "{{ .Values.configmapReload.alertmanager.image.repository }}:{{ .Values.configmapReload.alertmanager.image.tag }}" + imagePullPolicy: "{{ .Values.configmapReload.alertmanager.image.pullPolicy }}" + args: + - --volume-dir=/etc/config + - --webhook-url=http://127.0.0.1:9093{{ .Values.alertmanager.prefixURL }}/-/reload + {{- range $key, $value := .Values.configmapReload.alertmanager.extraArgs }} + - --{{ $key }}={{ $value }} + {{- end }} + {{- range .Values.configmapReload.alertmanager.extraVolumeDirs }} + - --volume-dir={{ . }} + {{- end }} + resources: +{{ toYaml .Values.configmapReload.alertmanager.resources | indent 12 }} + volumeMounts: + - name: config-volume + mountPath: /etc/config + readOnly: true + {{- range .Values.configmapReload.alertmanager.extraConfigmapMounts }} + - name: {{ $.Values.configmapReload.alertmanager.name }}-{{ .name }} + mountPath: {{ .mountPath }} + subPath: {{ .subPath }} + readOnly: {{ .readOnly }} + {{- end }} + {{- end }} + {{- if .Values.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | indent 8 }} + {{- end }} + {{- if .Values.alertmanager.nodeSelector }} + nodeSelector: +{{ toYaml .Values.alertmanager.nodeSelector | indent 8 }} + {{- end }} + {{- with .Values.alertmanager.dnsConfig }} + dnsConfig: +{{ toYaml . | indent 8 }} + {{- end }} + {{- if .Values.alertmanager.securityContext }} + securityContext: +{{ toYaml .Values.alertmanager.securityContext | indent 8 }} + {{- end }} + {{- if .Values.alertmanager.tolerations }} + tolerations: +{{ toYaml .Values.alertmanager.tolerations | indent 8 }} + {{- end }} + {{- if .Values.alertmanager.affinity }} + affinity: +{{ toYaml .Values.alertmanager.affinity | indent 8 }} + {{- end }} + volumes: + - name: config-volume + {{- if empty .Values.alertmanager.configFromSecret }} + configMap: + name: {{ if .Values.alertmanager.configMapOverrideName }}{{ .Release.Name }}-{{ .Values.alertmanager.configMapOverrideName }}{{- else }}{{ template "prometheus.alertmanager.fullname" . }}{{- end }} + {{- else }} + secret: + secretName: {{ .Values.alertmanager.configFromSecret }} + {{- end }} + {{- range .Values.alertmanager.extraSecretMounts }} + - name: {{ .name }} + secret: + secretName: {{ .secretName }} + {{- with .optional }} + optional: {{ . }} + {{- end }} + {{- end }} + {{- range .Values.alertmanager.extraConfigmapMounts }} + - name: {{ .name }} + configMap: + name: {{ .configMap }} + {{- end }} + {{- range .Values.configmapReload.alertmanager.extraConfigmapMounts }} + - name: {{ $.Values.configmapReload.alertmanager.name }}-{{ .name }} + configMap: + name: {{ .configMap }} + {{- end }} + - name: storage-volume + {{- if .Values.alertmanager.persistentVolume.enabled }} + persistentVolumeClaim: + claimName: {{ if .Values.alertmanager.persistentVolume.existingClaim }}{{ .Values.alertmanager.persistentVolume.existingClaim }}{{- else }}{{ template "prometheus.alertmanager.fullname" . }}{{- end }} + {{- else }} + emptyDir: + {{- if .Values.alertmanager.emptyDir.sizeLimit }} + sizeLimit: {{ .Values.alertmanager.emptyDir.sizeLimit }} + {{- else }} + {} + {{- end -}} + {{- end -}} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/alertmanager/headless-svc.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/alertmanager/headless-svc.yaml new file mode 100644 index 0000000..8c402c4 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/alertmanager/headless-svc.yaml @@ -0,0 +1,31 @@ +{{- if and .Values.alertmanager.enabled .Values.alertmanager.statefulSet.enabled -}} +apiVersion: v1 +kind: Service +metadata: +{{- if .Values.alertmanager.statefulSet.headless.annotations }} + annotations: +{{ toYaml .Values.alertmanager.statefulSet.headless.annotations | indent 4 }} +{{- end }} + labels: + {{- include "prometheus.alertmanager.labels" . | nindent 4 }} +{{- if .Values.alertmanager.statefulSet.headless.labels }} +{{ toYaml .Values.alertmanager.statefulSet.headless.labels | indent 4 }} +{{- end }} + name: {{ template "prometheus.alertmanager.fullname" . }}-headless +{{ include "prometheus.namespace" . | indent 2 }} +spec: + clusterIP: None + ports: + - name: http + port: {{ .Values.alertmanager.statefulSet.headless.servicePort }} + protocol: TCP + targetPort: 9093 +{{- if .Values.alertmanager.statefulSet.headless.enableMeshPeer }} + - name: meshpeer + port: 6783 + protocol: TCP + targetPort: 6783 +{{- end }} + selector: + {{- include "prometheus.alertmanager.matchLabels" . | nindent 4 }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/alertmanager/ingress.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/alertmanager/ingress.yaml new file mode 100644 index 0000000..2a7b67c --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/alertmanager/ingress.yaml @@ -0,0 +1,57 @@ +{{- if and .Values.alertmanager.enabled .Values.alertmanager.ingress.enabled -}} +{{- $ingressApiIsStable := eq (include "ingress.isStable" .) "true" -}} +{{- $ingressSupportsIngressClassName := eq (include "ingress.supportsIngressClassName" .) "true" -}} +{{- $ingressSupportsPathType := eq (include "ingress.supportsPathType" .) "true" -}} +{{- $releaseName := .Release.Name -}} +{{- $serviceName := include "prometheus.alertmanager.fullname" . }} +{{- $servicePort := .Values.alertmanager.service.servicePort -}} +{{- $ingressPath := .Values.alertmanager.ingress.path -}} +{{- $ingressPathType := .Values.alertmanager.ingress.pathType -}} +{{- $extraPaths := .Values.alertmanager.ingress.extraPaths -}} +apiVersion: {{ template "ingress.apiVersion" . }} +kind: Ingress +metadata: +{{- if .Values.alertmanager.ingress.annotations }} + annotations: +{{ toYaml .Values.alertmanager.ingress.annotations | indent 4 }} +{{- end }} + labels: + {{- include "prometheus.alertmanager.labels" . | nindent 4 }} +{{- range $key, $value := .Values.alertmanager.ingress.extraLabels }} + {{ $key }}: {{ $value }} +{{- end }} + name: {{ template "prometheus.alertmanager.fullname" . }} +{{ include "prometheus.namespace" . | indent 2 }} +spec: + {{- if and $ingressSupportsIngressClassName .Values.alertmanager.ingress.ingressClassName }} + ingressClassName: {{ .Values.alertmanager.ingress.ingressClassName }} + {{- end }} + rules: + {{- range .Values.alertmanager.ingress.hosts }} + {{- $url := splitList "/" . }} + - host: {{ first $url }} + http: + paths: +{{ if $extraPaths }} +{{ toYaml $extraPaths | indent 10 }} +{{- end }} + - path: {{ $ingressPath }} + {{- if $ingressSupportsPathType }} + pathType: {{ $ingressPathType }} + {{- end }} + backend: + {{- if $ingressApiIsStable }} + service: + name: {{ $serviceName }} + port: + number: {{ $servicePort }} + {{- else }} + serviceName: {{ $serviceName }} + servicePort: {{ $servicePort }} + {{- end }} + {{- end -}} +{{- if .Values.alertmanager.ingress.tls }} + tls: +{{ toYaml .Values.alertmanager.ingress.tls | indent 4 }} + {{- end -}} +{{- end -}} \ No newline at end of file diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/alertmanager/netpol.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/alertmanager/netpol.yaml new file mode 100644 index 0000000..e44ade6 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/alertmanager/netpol.yaml @@ -0,0 +1,20 @@ +{{- if and .Values.alertmanager.enabled .Values.networkPolicy.enabled -}} +apiVersion: {{ template "prometheus.networkPolicy.apiVersion" . }} +kind: NetworkPolicy +metadata: + name: {{ template "prometheus.alertmanager.fullname" . }} +{{ include "prometheus.namespace" . | indent 2 }} + labels: + {{- include "prometheus.alertmanager.labels" . | nindent 4 }} +spec: + podSelector: + matchLabels: + {{- include "prometheus.alertmanager.matchLabels" . | nindent 6 }} + ingress: + - from: + - podSelector: + matchLabels: + {{- include "prometheus.server.matchLabels" . | nindent 12 }} + - ports: + - port: 9093 +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/alertmanager/pdb.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/alertmanager/pdb.yaml new file mode 100644 index 0000000..41a92f3 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/alertmanager/pdb.yaml @@ -0,0 +1,14 @@ +{{- if .Values.alertmanager.podDisruptionBudget.enabled }} +apiVersion: policy/v1beta1 +kind: PodDisruptionBudget +metadata: + name: {{ template "prometheus.alertmanager.fullname" . }} +{{ include "prometheus.namespace" . | indent 2 }} + labels: + {{- include "prometheus.alertmanager.labels" . | nindent 4 }} +spec: + maxUnavailable: {{ .Values.alertmanager.podDisruptionBudget.maxUnavailable }} + selector: + matchLabels: + {{- include "prometheus.alertmanager.labels" . | nindent 6 }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/alertmanager/psp.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/alertmanager/psp.yaml new file mode 100644 index 0000000..64fb130 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/alertmanager/psp.yaml @@ -0,0 +1,46 @@ +{{- if and .Values.alertmanager.enabled .Values.rbac.create .Values.podSecurityPolicy.enabled }} +apiVersion: {{ template "prometheus.podSecurityPolicy.apiVersion" . }} +kind: PodSecurityPolicy +metadata: + name: {{ template "prometheus.alertmanager.fullname" . }} + labels: + {{- include "prometheus.alertmanager.labels" . | nindent 4 }} + annotations: +{{- if .Values.alertmanager.podSecurityPolicy.annotations }} +{{ toYaml .Values.alertmanager.podSecurityPolicy.annotations | indent 4 }} +{{- end }} +spec: + privileged: false + allowPrivilegeEscalation: false + requiredDropCapabilities: + - ALL + volumes: + - 'configMap' + - 'persistentVolumeClaim' + - 'emptyDir' + - 'secret' + allowedHostPaths: + - pathPrefix: /etc + readOnly: true + - pathPrefix: {{ .Values.alertmanager.persistentVolume.mountPath }} + hostNetwork: false + hostPID: false + hostIPC: false + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'MustRunAs' + ranges: + # Forbid adding the root group. + - min: 1 + max: 65535 + fsGroup: + rule: 'MustRunAs' + ranges: + # Forbid adding the root group. + - min: 1 + max: 65535 + readOnlyRootFilesystem: true +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/alertmanager/pvc.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/alertmanager/pvc.yaml new file mode 100644 index 0000000..160e296 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/alertmanager/pvc.yaml @@ -0,0 +1,37 @@ +{{- if not .Values.alertmanager.statefulSet.enabled -}} +{{- if and .Values.alertmanager.enabled .Values.alertmanager.persistentVolume.enabled -}} +{{- if not .Values.alertmanager.persistentVolume.existingClaim -}} +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + {{- if .Values.alertmanager.persistentVolume.annotations }} + annotations: +{{ toYaml .Values.alertmanager.persistentVolume.annotations | indent 4 }} + {{- end }} + labels: + {{- include "prometheus.alertmanager.labels" . | nindent 4 }} + name: {{ template "prometheus.alertmanager.fullname" . }} +{{ include "prometheus.namespace" . | indent 2 }} +spec: + accessModes: +{{ toYaml .Values.alertmanager.persistentVolume.accessModes | indent 4 }} +{{- if .Values.alertmanager.persistentVolume.storageClass }} +{{- if (eq "-" .Values.alertmanager.persistentVolume.storageClass) }} + storageClassName: "" +{{- else }} + storageClassName: "{{ .Values.alertmanager.persistentVolume.storageClass }}" +{{- end }} +{{- end }} +{{- if .Values.alertmanager.persistentVolume.volumeBindingMode }} + volumeBindingMode: "{{ .Values.alertmanager.persistentVolume.volumeBindingMode }}" +{{- end }} + resources: + requests: + storage: "{{ .Values.alertmanager.persistentVolume.size }}" +{{- if .Values.alertmanager.persistentVolume.selector }} + selector: + {{- toYaml .Values.alertmanager.persistentVolume.selector | nindent 4 }} +{{- end -}} +{{- end -}} +{{- end -}} +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/alertmanager/role.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/alertmanager/role.yaml new file mode 100644 index 0000000..ce60eaf --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/alertmanager/role.yaml @@ -0,0 +1,24 @@ +{{- if and .Values.alertmanager.enabled .Values.rbac.create (eq .Values.alertmanager.useClusterRole false) (not .Values.alertmanager.useExistingRole) -}} +{{- range $.Values.alertmanager.namespaces }} +apiVersion: {{ template "rbac.apiVersion" . }} +kind: Role +metadata: + labels: + {{- include "prometheus.alertmanager.labels" $ | nindent 4 }} + name: {{ template "prometheus.alertmanager.fullname" $ }} + namespace: {{ . }} +rules: +{{- if $.Values.podSecurityPolicy.enabled }} + - apiGroups: + - extensions + resources: + - podsecuritypolicies + verbs: + - use + resourceNames: + - {{ template "prometheus.alertmanager.fullname" $ }} +{{- else }} + [] +{{- end }} +{{- end }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/alertmanager/rolebinding.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/alertmanager/rolebinding.yaml new file mode 100644 index 0000000..906d652 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/alertmanager/rolebinding.yaml @@ -0,0 +1,23 @@ +{{- if and .Values.alertmanager.enabled .Values.rbac.create (eq .Values.alertmanager.useClusterRole false) -}} +{{ range $.Values.alertmanager.namespaces }} +apiVersion: {{ template "rbac.apiVersion" . }} +kind: RoleBinding +metadata: + labels: + {{- include "prometheus.alertmanager.labels" $ | nindent 4 }} + name: {{ template "prometheus.alertmanager.fullname" $ }} + namespace: {{ . }} +subjects: + - kind: ServiceAccount + name: {{ template "prometheus.serviceAccountName.alertmanager" $ }} +{{ include "prometheus.namespace" $ | indent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role +{{- if (not $.Values.alertmanager.useExistingRole) }} + name: {{ template "prometheus.alertmanager.fullname" $ }} +{{- else }} + name: {{ $.Values.alertmanager.useExistingRole }} +{{- end }} +{{- end }} +{{ end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/alertmanager/service.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/alertmanager/service.yaml new file mode 100644 index 0000000..9edc9ac --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/alertmanager/service.yaml @@ -0,0 +1,53 @@ +{{- if .Values.alertmanager.enabled -}} +apiVersion: v1 +kind: Service +metadata: +{{- if .Values.alertmanager.service.annotations }} + annotations: +{{ toYaml .Values.alertmanager.service.annotations | indent 4 }} +{{- end }} + labels: + {{- include "prometheus.alertmanager.labels" . | nindent 4 }} +{{- if .Values.alertmanager.service.labels }} +{{ toYaml .Values.alertmanager.service.labels | indent 4 }} +{{- end }} + name: {{ template "prometheus.alertmanager.fullname" . }} +{{ include "prometheus.namespace" . | indent 2 }} +spec: +{{- if .Values.alertmanager.service.clusterIP }} + clusterIP: {{ .Values.alertmanager.service.clusterIP }} +{{- end }} +{{- if .Values.alertmanager.service.externalIPs }} + externalIPs: +{{ toYaml .Values.alertmanager.service.externalIPs | indent 4 }} +{{- end }} +{{- if .Values.alertmanager.service.loadBalancerIP }} + loadBalancerIP: {{ .Values.alertmanager.service.loadBalancerIP }} +{{- end }} +{{- if .Values.alertmanager.service.loadBalancerSourceRanges }} + loadBalancerSourceRanges: + {{- range $cidr := .Values.alertmanager.service.loadBalancerSourceRanges }} + - {{ $cidr }} + {{- end }} +{{- end }} + ports: + - name: http + port: {{ .Values.alertmanager.service.servicePort }} + protocol: TCP + targetPort: 9093 + {{- if .Values.alertmanager.service.nodePort }} + nodePort: {{ .Values.alertmanager.service.nodePort }} + {{- end }} +{{- if .Values.alertmanager.service.enableMeshPeer }} + - name: meshpeer + port: 6783 + protocol: TCP + targetPort: 6783 +{{- end }} + selector: + {{- include "prometheus.alertmanager.matchLabels" . | nindent 4 }} +{{- if .Values.alertmanager.service.sessionAffinity }} + sessionAffinity: {{ .Values.alertmanager.service.sessionAffinity }} +{{- end }} + type: "{{ .Values.alertmanager.service.type }}" +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/alertmanager/serviceaccount.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/alertmanager/serviceaccount.yaml new file mode 100644 index 0000000..a5d996a --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/alertmanager/serviceaccount.yaml @@ -0,0 +1,11 @@ +{{- if and .Values.alertmanager.enabled .Values.serviceAccounts.alertmanager.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + {{- include "prometheus.alertmanager.labels" . | nindent 4 }} + name: {{ template "prometheus.serviceAccountName.alertmanager" . }} +{{ include "prometheus.namespace" . | indent 2 }} + annotations: +{{ toYaml .Values.serviceAccounts.alertmanager.annotations | indent 4 }} +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/alertmanager/sts.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/alertmanager/sts.yaml new file mode 100644 index 0000000..4f247dc --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/alertmanager/sts.yaml @@ -0,0 +1,181 @@ +{{- if and .Values.alertmanager.enabled .Values.alertmanager.statefulSet.enabled -}} +apiVersion: apps/v1 +kind: StatefulSet +metadata: +{{- if .Values.alertmanager.statefulSet.annotations }} + annotations: + {{ toYaml .Values.alertmanager.statefulSet.annotations | nindent 4 }} +{{- end }} + labels: + {{- include "prometheus.alertmanager.labels" . | nindent 4 }} + {{- if .Values.alertmanager.statefulSet.labels}} + {{ toYaml .Values.alertmanager.statefulSet.labels | nindent 4 }} + {{- end}} + name: {{ template "prometheus.alertmanager.fullname" . }} +{{ include "prometheus.namespace" . | indent 2 }} +spec: + serviceName: {{ template "prometheus.alertmanager.fullname" . }}-headless + selector: + matchLabels: + {{- include "prometheus.alertmanager.matchLabels" . | nindent 6 }} + replicas: {{ .Values.alertmanager.replicaCount }} + podManagementPolicy: {{ .Values.alertmanager.statefulSet.podManagementPolicy }} + template: + metadata: + {{- if .Values.alertmanager.podAnnotations }} + annotations: + {{ toYaml .Values.alertmanager.podAnnotations | nindent 8 }} + {{- end }} + labels: + {{- include "prometheus.alertmanager.labels" . | nindent 8 }} + {{- if .Values.alertmanager.podLabels}} + {{ toYaml .Values.alertmanager.podLabels | nindent 8 }} + {{- end}} + spec: +{{- if .Values.alertmanager.affinity }} + affinity: +{{ toYaml .Values.alertmanager.affinity | indent 8 }} +{{- end }} +{{- if .Values.alertmanager.schedulerName }} + schedulerName: "{{ .Values.alertmanager.schedulerName }}" +{{- end }} + serviceAccountName: {{ template "prometheus.serviceAccountName.alertmanager" . }} +{{- if .Values.alertmanager.priorityClassName }} + priorityClassName: "{{ .Values.alertmanager.priorityClassName }}" +{{- end }} + containers: + - name: {{ template "prometheus.name" . }}-{{ .Values.alertmanager.name }} + image: "{{ .Values.alertmanager.image.repository }}:{{ .Values.alertmanager.image.tag }}" + imagePullPolicy: "{{ .Values.alertmanager.image.pullPolicy }}" + env: + {{- range $key, $value := .Values.alertmanager.extraEnv }} + - name: {{ $key }} + value: {{ $value }} + {{- end }} + - name: POD_IP + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: status.podIP + args: + - --config.file=/etc/config/alertmanager.yml + - --storage.path={{ .Values.alertmanager.persistentVolume.mountPath }} + {{- if .Values.alertmanager.statefulSet.headless.enableMeshPeer }} + - --cluster.advertise-address=[$(POD_IP)]:6783 + - --cluster.listen-address=0.0.0.0:6783 + {{- range $n := until (.Values.alertmanager.replicaCount | int) }} + - --cluster.peer={{ template "prometheus.alertmanager.fullname" $ }}-{{ $n }}.{{ template "prometheus.alertmanager.fullname" $ }}-headless:6783 + {{- end }} + {{- else }} + - --cluster.listen-address= + {{- end }} + {{- range $key, $value := .Values.alertmanager.extraArgs }} + - --{{ $key }}={{ $value }} + {{- end }} + {{- if .Values.alertmanager.baseURL }} + - --web.external-url={{ .Values.alertmanager.baseURL }} + {{- end }} + + ports: + - containerPort: 9093 + {{- if .Values.alertmanager.statefulSet.headless.enableMeshPeer }} + - containerPort: 6783 + {{- end }} + readinessProbe: + httpGet: + path: {{ .Values.alertmanager.prefixURL }}/#/status + port: 9093 + initialDelaySeconds: 30 + timeoutSeconds: 30 + resources: +{{ toYaml .Values.alertmanager.resources | indent 12 }} + volumeMounts: + - name: config-volume + mountPath: /etc/config + - name: storage-volume + mountPath: "{{ .Values.alertmanager.persistentVolume.mountPath }}" + subPath: "{{ .Values.alertmanager.persistentVolume.subPath }}" + {{- range .Values.alertmanager.extraSecretMounts }} + - name: {{ .name }} + mountPath: {{ .mountPath }} + subPath: {{ .subPath }} + readOnly: {{ .readOnly }} + {{- end }} + {{- if .Values.configmapReload.alertmanager.enabled }} + - name: {{ template "prometheus.name" . }}-{{ .Values.alertmanager.name }}-{{ .Values.configmapReload.alertmanager.name }} + image: "{{ .Values.configmapReload.alertmanager.image.repository }}:{{ .Values.configmapReload.alertmanager.image.tag }}" + imagePullPolicy: "{{ .Values.configmapReload.alertmanager.image.pullPolicy }}" + args: + - --volume-dir=/etc/config + - --webhook-url=http://localhost:9093{{ .Values.alertmanager.prefixURL }}/-/reload + resources: +{{ toYaml .Values.configmapReload.alertmanager.resources | indent 12 }} + volumeMounts: + - name: config-volume + mountPath: /etc/config + readOnly: true + {{- end }} + {{- if .Values.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | indent 8 }} + {{- end }} + {{- if .Values.alertmanager.nodeSelector }} + nodeSelector: +{{ toYaml .Values.alertmanager.nodeSelector | indent 8 }} + {{- end }} + {{- if .Values.alertmanager.securityContext }} + securityContext: +{{ toYaml .Values.alertmanager.securityContext | indent 8 }} + {{- end }} + {{- if .Values.alertmanager.tolerations }} + tolerations: +{{ toYaml .Values.alertmanager.tolerations | indent 8 }} + {{- end }} + volumes: + - name: config-volume + {{- if empty .Values.alertmanager.configFromSecret }} + configMap: + name: {{ if .Values.alertmanager.configMapOverrideName }}{{ .Release.Name }}-{{ .Values.alertmanager.configMapOverrideName }}{{- else }}{{ template "prometheus.alertmanager.fullname" . }}{{- end }} + {{- else }} + secret: + secretName: {{ .Values.alertmanager.configFromSecret }} + {{- end }} + {{- range .Values.alertmanager.extraSecretMounts }} + - name: {{ .name }} + secret: + secretName: {{ .secretName }} + {{- with .optional }} + optional: {{ . }} + {{- end }} + {{- end }} +{{- if .Values.alertmanager.persistentVolume.enabled }} + volumeClaimTemplates: + - metadata: + name: storage-volume + {{- if .Values.alertmanager.persistentVolume.annotations }} + annotations: +{{ toYaml .Values.alertmanager.persistentVolume.annotations | indent 10 }} + {{- end }} + spec: + accessModes: +{{ toYaml .Values.alertmanager.persistentVolume.accessModes | indent 10 }} + resources: + requests: + storage: "{{ .Values.alertmanager.persistentVolume.size }}" + {{- if .Values.server.persistentVolume.storageClass }} + {{- if (eq "-" .Values.server.persistentVolume.storageClass) }} + storageClassName: "" + {{- else }} + storageClassName: "{{ .Values.alertmanager.persistentVolume.storageClass }}" + {{- end }} + {{- end }} +{{- else }} + - name: storage-volume + emptyDir: + {{- if .Values.alertmanager.emptyDir.sizeLimit }} + sizeLimit: {{ .Values.alertmanager.emptyDir.sizeLimit }} + {{- else }} + {} + {{- end -}} +{{- end }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/node-exporter/daemonset.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/node-exporter/daemonset.yaml new file mode 100644 index 0000000..667be9f --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/node-exporter/daemonset.yaml @@ -0,0 +1,146 @@ +{{- if .Values.nodeExporter.enabled -}} +apiVersion: {{ template "prometheus.daemonset.apiVersion" . }} +kind: DaemonSet +metadata: +{{- if .Values.nodeExporter.deploymentAnnotations }} + annotations: +{{ toYaml .Values.nodeExporter.deploymentAnnotations | indent 4 }} +{{- end }} + labels: + {{- include "prometheus.nodeExporter.labels" . | nindent 4 }} + name: {{ template "prometheus.nodeExporter.fullname" . }} +{{ include "prometheus.namespace" . | indent 2 }} +spec: + selector: + matchLabels: + {{- include "prometheus.nodeExporter.matchLabels" . | nindent 6 }} + {{- if .Values.nodeExporter.updateStrategy }} + updateStrategy: +{{ toYaml .Values.nodeExporter.updateStrategy | indent 4 }} + {{- end }} + template: + metadata: + {{- if .Values.nodeExporter.podAnnotations }} + annotations: +{{ toYaml .Values.nodeExporter.podAnnotations | indent 8 }} + {{- end }} + labels: + {{- include "prometheus.nodeExporter.labels" . | nindent 8 }} +{{- if .Values.nodeExporter.pod.labels }} +{{ toYaml .Values.nodeExporter.pod.labels | indent 8 }} +{{- end }} + spec: + serviceAccountName: {{ template "prometheus.serviceAccountName.nodeExporter" . }} + {{- if .Values.nodeExporter.extraInitContainers }} + initContainers: +{{ toYaml .Values.nodeExporter.extraInitContainers | indent 8 }} + {{- end }} +{{- if .Values.nodeExporter.priorityClassName }} + priorityClassName: "{{ .Values.nodeExporter.priorityClassName }}" +{{- end }} + containers: + - name: {{ template "prometheus.name" . }}-{{ .Values.nodeExporter.name }} + image: "{{ .Values.nodeExporter.image.repository }}:{{ .Values.nodeExporter.image.tag }}" + imagePullPolicy: "{{ .Values.nodeExporter.image.pullPolicy }}" + args: + - --path.procfs=/host/proc + - --path.sysfs=/host/sys + {{- if .Values.nodeExporter.hostRootfs }} + - --path.rootfs=/host/root + {{- end }} + {{- if .Values.nodeExporter.hostNetwork }} + - --web.listen-address=:{{ .Values.nodeExporter.service.hostPort }} + {{- end }} + {{- range $key, $value := .Values.nodeExporter.extraArgs }} + {{- if $value }} + - --{{ $key }}={{ $value }} + {{- else }} + - --{{ $key }} + {{- end }} + {{- end }} + ports: + - name: metrics + {{- if .Values.nodeExporter.hostNetwork }} + containerPort: {{ .Values.nodeExporter.service.hostPort }} + {{- else }} + containerPort: 9100 + {{- end }} + hostPort: {{ .Values.nodeExporter.service.hostPort }} + resources: +{{ toYaml .Values.nodeExporter.resources | indent 12 }} + volumeMounts: + - name: proc + mountPath: /host/proc + readOnly: true + - name: sys + mountPath: /host/sys + readOnly: true + {{- if .Values.nodeExporter.hostRootfs }} + - name: root + mountPath: /host/root + mountPropagation: HostToContainer + readOnly: true + {{- end }} + {{- range .Values.nodeExporter.extraHostPathMounts }} + - name: {{ .name }} + mountPath: {{ .mountPath }} + readOnly: {{ .readOnly }} + {{- if .mountPropagation }} + mountPropagation: {{ .mountPropagation }} + {{- end }} + {{- end }} + {{- range .Values.nodeExporter.extraConfigmapMounts }} + - name: {{ .name }} + mountPath: {{ .mountPath }} + readOnly: {{ .readOnly }} + {{- end }} + {{- if .Values.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | indent 8 }} + {{- end }} + {{- if .Values.nodeExporter.hostNetwork }} + hostNetwork: true + {{- end }} + {{- if .Values.nodeExporter.hostPID }} + hostPID: true + {{- end }} + {{- if .Values.nodeExporter.tolerations }} + tolerations: +{{ toYaml .Values.nodeExporter.tolerations | indent 8 }} + {{- end }} + {{- if .Values.nodeExporter.nodeSelector }} + nodeSelector: +{{ toYaml .Values.nodeExporter.nodeSelector | indent 8 }} + {{- end }} + {{- with .Values.nodeExporter.dnsConfig }} + dnsConfig: +{{ toYaml . | indent 8 }} + {{- end }} + {{- if .Values.nodeExporter.securityContext }} + securityContext: +{{ toYaml .Values.nodeExporter.securityContext | indent 8 }} + {{- end }} + volumes: + - name: proc + hostPath: + path: /proc + - name: sys + hostPath: + path: /sys + {{- if .Values.nodeExporter.hostRootfs }} + - name: root + hostPath: + path: / + {{- end }} + {{- range .Values.nodeExporter.extraHostPathMounts }} + - name: {{ .name }} + hostPath: + path: {{ .hostPath }} + {{- end }} + {{- range .Values.nodeExporter.extraConfigmapMounts }} + - name: {{ .name }} + configMap: + name: {{ .configMap }} + {{- end }} + +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/node-exporter/psp.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/node-exporter/psp.yaml new file mode 100644 index 0000000..bd9c73b --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/node-exporter/psp.yaml @@ -0,0 +1,55 @@ +{{- if and .Values.nodeExporter.enabled .Values.rbac.create .Values.podSecurityPolicy.enabled }} +apiVersion: {{ template "prometheus.podSecurityPolicy.apiVersion" . }} +kind: PodSecurityPolicy +metadata: + name: {{ template "prometheus.nodeExporter.fullname" . }} + labels: + {{- include "prometheus.nodeExporter.labels" . | nindent 4 }} + annotations: +{{- if .Values.nodeExporter.podSecurityPolicy.annotations }} +{{ toYaml .Values.nodeExporter.podSecurityPolicy.annotations | indent 4 }} +{{- end }} +spec: + privileged: false + allowPrivilegeEscalation: false + requiredDropCapabilities: + - ALL + volumes: + - 'configMap' + - 'hostPath' + - 'secret' + allowedHostPaths: + - pathPrefix: /proc + readOnly: true + - pathPrefix: /sys + readOnly: true + - pathPrefix: / + readOnly: true + {{- range .Values.nodeExporter.extraHostPathMounts }} + - pathPrefix: {{ .hostPath }} + readOnly: {{ .readOnly }} + {{- end }} + hostNetwork: {{ .Values.nodeExporter.hostNetwork }} + hostPID: {{ .Values.nodeExporter.hostPID }} + hostIPC: false + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'MustRunAs' + ranges: + # Forbid adding the root group. + - min: 1 + max: 65535 + fsGroup: + rule: 'MustRunAs' + ranges: + # Forbid adding the root group. + - min: 1 + max: 65535 + readOnlyRootFilesystem: false + hostPorts: + - min: 1 + max: 65535 +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/node-exporter/role.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/node-exporter/role.yaml new file mode 100644 index 0000000..d8ef3ed --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/node-exporter/role.yaml @@ -0,0 +1,17 @@ +{{- if and .Values.nodeExporter.enabled .Values.rbac.create }} +{{- if or (default .Values.nodeExporter.podSecurityPolicy.enabled false) (.Values.podSecurityPolicy.enabled) }} +apiVersion: {{ template "rbac.apiVersion" . }} +kind: Role +metadata: + name: {{ template "prometheus.nodeExporter.fullname" . }} + labels: + {{- include "prometheus.nodeExporter.labels" . | nindent 4 }} +{{ include "prometheus.namespace" . | indent 2 }} +rules: +- apiGroups: ['extensions'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ template "prometheus.nodeExporter.fullname" . }} +{{- end }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/node-exporter/rolebinding.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/node-exporter/rolebinding.yaml new file mode 100644 index 0000000..06914b7 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/node-exporter/rolebinding.yaml @@ -0,0 +1,19 @@ +{{- if and .Values.nodeExporter.enabled .Values.rbac.create }} +{{- if .Values.podSecurityPolicy.enabled }} +apiVersion: {{ template "rbac.apiVersion" . }} +kind: RoleBinding +metadata: + name: {{ template "prometheus.nodeExporter.fullname" . }} + labels: + {{- include "prometheus.nodeExporter.labels" . | nindent 4 }} +{{ include "prometheus.namespace" . | indent 2 }} +roleRef: + kind: Role + name: {{ template "prometheus.nodeExporter.fullname" . }} + apiGroup: rbac.authorization.k8s.io +subjects: +- kind: ServiceAccount + name: {{ template "prometheus.serviceAccountName.nodeExporter" . }} +{{ include "prometheus.namespace" . | indent 2 }} +{{- end }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/node-exporter/serviceaccount.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/node-exporter/serviceaccount.yaml new file mode 100644 index 0000000..0cf91af --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/node-exporter/serviceaccount.yaml @@ -0,0 +1,11 @@ +{{- if and .Values.nodeExporter.enabled .Values.serviceAccounts.nodeExporter.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + {{- include "prometheus.nodeExporter.labels" . | nindent 4 }} + name: {{ template "prometheus.serviceAccountName.nodeExporter" . }} +{{ include "prometheus.namespace" . | indent 2 }} + annotations: +{{ toYaml .Values.serviceAccounts.nodeExporter.annotations | indent 4 }} +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/node-exporter/svc.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/node-exporter/svc.yaml new file mode 100644 index 0000000..26d1eaa --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/node-exporter/svc.yaml @@ -0,0 +1,47 @@ +{{- if .Values.nodeExporter.enabled -}} +apiVersion: v1 +kind: Service +metadata: +{{- if .Values.nodeExporter.service.annotations }} + annotations: +{{ toYaml .Values.nodeExporter.service.annotations | indent 4 }} +{{- end }} + labels: + {{- include "prometheus.nodeExporter.labels" . | nindent 4 }} +{{- if .Values.nodeExporter.service.labels }} +{{ toYaml .Values.nodeExporter.service.labels | indent 4 }} +{{- end }} + name: {{ template "prometheus.nodeExporter.fullname" . }} +{{ include "prometheus.namespace" . | indent 2 }} +spec: +{{- if .Values.nodeExporter.service.clusterIP }} + clusterIP: {{ .Values.nodeExporter.service.clusterIP }} +{{- end }} +{{- if .Values.nodeExporter.service.externalIPs }} + externalIPs: +{{ toYaml .Values.nodeExporter.service.externalIPs | indent 4 }} +{{- end }} +{{- if .Values.nodeExporter.service.loadBalancerIP }} + loadBalancerIP: {{ .Values.nodeExporter.service.loadBalancerIP }} +{{- end }} +{{- if .Values.nodeExporter.service.loadBalancerSourceRanges }} + loadBalancerSourceRanges: + {{- range $cidr := .Values.nodeExporter.service.loadBalancerSourceRanges }} + - {{ $cidr }} + {{- end }} +{{- end }} + ports: + - name: metrics + {{- if .Values.nodeExporter.hostNetwork }} + port: {{ .Values.nodeExporter.service.hostPort }} + protocol: TCP + targetPort: {{ .Values.nodeExporter.service.hostPort }} + {{- else }} + port: {{ .Values.nodeExporter.service.servicePort }} + protocol: TCP + targetPort: 9100 + {{- end }} + selector: + {{- include "prometheus.nodeExporter.matchLabels" . | nindent 4 }} + type: "{{ .Values.nodeExporter.service.type }}" +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/pushgateway/clusterrole.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/pushgateway/clusterrole.yaml new file mode 100644 index 0000000..76ecf05 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/pushgateway/clusterrole.yaml @@ -0,0 +1,21 @@ +{{- if and .Values.pushgateway.enabled .Values.rbac.create -}} +apiVersion: {{ template "rbac.apiVersion" . }} +kind: ClusterRole +metadata: + labels: + {{- include "prometheus.pushgateway.labels" . | nindent 4 }} + name: {{ template "prometheus.pushgateway.fullname" . }} +rules: +{{- if .Values.podSecurityPolicy.enabled }} + - apiGroups: + - extensions + resources: + - podsecuritypolicies + verbs: + - use + resourceNames: + - {{ template "prometheus.pushgateway.fullname" . }} +{{- else }} + [] +{{- end }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/pushgateway/clusterrolebinding.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/pushgateway/clusterrolebinding.yaml new file mode 100644 index 0000000..15770ee --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/pushgateway/clusterrolebinding.yaml @@ -0,0 +1,16 @@ +{{- if and .Values.pushgateway.enabled .Values.rbac.create -}} +apiVersion: {{ template "rbac.apiVersion" . }} +kind: ClusterRoleBinding +metadata: + labels: + {{- include "prometheus.pushgateway.labels" . | nindent 4 }} + name: {{ template "prometheus.pushgateway.fullname" . }} +subjects: + - kind: ServiceAccount + name: {{ template "prometheus.serviceAccountName.pushgateway" . }} +{{ include "prometheus.namespace" . | indent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "prometheus.pushgateway.fullname" . }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/pushgateway/deploy.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/pushgateway/deploy.yaml new file mode 100644 index 0000000..ffdbfcc --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/pushgateway/deploy.yaml @@ -0,0 +1,119 @@ +{{- if .Values.pushgateway.enabled -}} +apiVersion: {{ template "prometheus.deployment.apiVersion" . }} +kind: Deployment +metadata: +{{- if .Values.pushgateway.deploymentAnnotations }} + annotations: + {{ toYaml .Values.pushgateway.deploymentAnnotations | nindent 4 }} +{{- end }} + labels: + {{- include "prometheus.pushgateway.labels" . | nindent 4 }} + name: {{ template "prometheus.pushgateway.fullname" . }} +{{ include "prometheus.namespace" . | indent 2 }} +spec: + selector: + {{- if .Values.schedulerName }} + schedulerName: "{{ .Values.schedulerName }}" + {{- end }} + matchLabels: + {{- include "prometheus.pushgateway.matchLabels" . | nindent 6 }} + replicas: {{ .Values.pushgateway.replicaCount }} + {{- if .Values.pushgateway.strategy }} + strategy: +{{ toYaml .Values.pushgateway.strategy | trim | indent 4 }} + {{ if eq .Values.pushgateway.strategy.type "Recreate" }}rollingUpdate: null{{ end }} +{{- end }} + template: + metadata: + {{- if .Values.pushgateway.podAnnotations }} + annotations: + {{ toYaml .Values.pushgateway.podAnnotations | nindent 8 }} + {{- end }} + labels: + {{- include "prometheus.pushgateway.labels" . | nindent 8 }} + {{- if .Values.pushgateway.podLabels }} + {{ toYaml .Values.pushgateway.podLabels | nindent 8 }} + {{- end }} + spec: + serviceAccountName: {{ template "prometheus.serviceAccountName.pushgateway" . }} + {{- if .Values.pushgateway.extraInitContainers }} + initContainers: +{{ toYaml .Values.pushgateway.extraInitContainers | indent 8 }} + {{- end }} +{{- if .Values.pushgateway.priorityClassName }} + priorityClassName: "{{ .Values.pushgateway.priorityClassName }}" +{{- end }} + containers: + - name: {{ template "prometheus.name" . }}-{{ .Values.pushgateway.name }} + image: "{{ .Values.pushgateway.image.repository }}:{{ .Values.pushgateway.image.tag }}" + imagePullPolicy: "{{ .Values.pushgateway.image.pullPolicy }}" + args: + {{- range $key, $value := .Values.pushgateway.extraArgs }} + {{- $stringvalue := toString $value }} + {{- if eq $stringvalue "true" }} + - --{{ $key }} + {{- else }} + - --{{ $key }}={{ $value }} + {{- end }} + {{- end }} + ports: + - containerPort: 9091 + livenessProbe: + httpGet: + {{- if (index .Values "pushgateway" "extraArgs" "web.route-prefix") }} + path: /{{ index .Values "pushgateway" "extraArgs" "web.route-prefix" }}/-/healthy + {{- else }} + path: /-/healthy + {{- end }} + port: 9091 + initialDelaySeconds: 10 + timeoutSeconds: 10 + readinessProbe: + httpGet: + {{- if (index .Values "pushgateway" "extraArgs" "web.route-prefix") }} + path: /{{ index .Values "pushgateway" "extraArgs" "web.route-prefix" }}/-/ready + {{- else }} + path: /-/ready + {{- end }} + port: 9091 + initialDelaySeconds: 10 + timeoutSeconds: 10 + resources: +{{ toYaml .Values.pushgateway.resources | indent 12 }} + {{- if .Values.pushgateway.persistentVolume.enabled }} + volumeMounts: + - name: storage-volume + mountPath: "{{ .Values.pushgateway.persistentVolume.mountPath }}" + subPath: "{{ .Values.pushgateway.persistentVolume.subPath }}" + {{- end }} + {{- if .Values.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | indent 8 }} + {{- end }} + {{- if .Values.pushgateway.nodeSelector }} + nodeSelector: +{{ toYaml .Values.pushgateway.nodeSelector | indent 8 }} + {{- end }} + {{- with .Values.pushgateway.dnsConfig }} + dnsConfig: +{{ toYaml . | indent 8 }} + {{- end }} + {{- if .Values.pushgateway.securityContext }} + securityContext: +{{ toYaml .Values.pushgateway.securityContext | indent 8 }} + {{- end }} + {{- if .Values.pushgateway.tolerations }} + tolerations: +{{ toYaml .Values.pushgateway.tolerations | indent 8 }} + {{- end }} + {{- if .Values.pushgateway.affinity }} + affinity: +{{ toYaml .Values.pushgateway.affinity | indent 8 }} + {{- end }} + {{- if .Values.pushgateway.persistentVolume.enabled }} + volumes: + - name: storage-volume + persistentVolumeClaim: + claimName: {{ if .Values.pushgateway.persistentVolume.existingClaim }}{{ .Values.pushgateway.persistentVolume.existingClaim }}{{- else }}{{ template "prometheus.pushgateway.fullname" . }}{{- end }} + {{- end -}} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/pushgateway/ingress.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/pushgateway/ingress.yaml new file mode 100644 index 0000000..2ff72ab --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/pushgateway/ingress.yaml @@ -0,0 +1,54 @@ +{{- if and .Values.pushgateway.enabled .Values.pushgateway.ingress.enabled -}} +{{- $ingressApiIsStable := eq (include "ingress.isStable" .) "true" -}} +{{- $ingressSupportsIngressClassName := eq (include "ingress.supportsIngressClassName" .) "true" -}} +{{- $ingressSupportsPathType := eq (include "ingress.supportsPathType" .) "true" -}} +{{- $releaseName := .Release.Name -}} +{{- $serviceName := include "prometheus.pushgateway.fullname" . }} +{{- $servicePort := .Values.pushgateway.service.servicePort -}} +{{- $ingressPath := .Values.pushgateway.ingress.path -}} +{{- $ingressPathType := .Values.pushgateway.ingress.pathType -}} +{{- $extraPaths := .Values.pushgateway.ingress.extraPaths -}} +apiVersion: {{ template "ingress.apiVersion" . }} +kind: Ingress +metadata: +{{- if .Values.pushgateway.ingress.annotations }} + annotations: +{{ toYaml .Values.pushgateway.ingress.annotations | indent 4}} +{{- end }} + labels: + {{- include "prometheus.pushgateway.labels" . | nindent 4 }} + name: {{ template "prometheus.pushgateway.fullname" . }} +{{ include "prometheus.namespace" . | indent 2 }} +spec: + {{- if and $ingressSupportsIngressClassName .Values.pushgateway.ingress.ingressClassName }} + ingressClassName: {{ .Values.pushgateway.ingress.ingressClassName }} + {{- end }} + rules: + {{- range .Values.pushgateway.ingress.hosts }} + {{- $url := splitList "/" . }} + - host: {{ first $url }} + http: + paths: +{{ if $extraPaths }} +{{ toYaml $extraPaths | indent 10 }} +{{- end }} + - path: {{ $ingressPath }} + {{- if $ingressSupportsPathType }} + pathType: {{ $ingressPathType }} + {{- end }} + backend: + {{- if $ingressApiIsStable }} + service: + name: {{ $serviceName }} + port: + number: {{ $servicePort }} + {{- else }} + serviceName: {{ $serviceName }} + servicePort: {{ $servicePort }} + {{- end }} + {{- end -}} +{{- if .Values.pushgateway.ingress.tls }} + tls: +{{ toYaml .Values.pushgateway.ingress.tls | indent 4 }} + {{- end -}} +{{- end -}} \ No newline at end of file diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/pushgateway/netpol.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/pushgateway/netpol.yaml new file mode 100644 index 0000000..c8d1fb3 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/pushgateway/netpol.yaml @@ -0,0 +1,20 @@ +{{- if and .Values.pushgateway.enabled .Values.networkPolicy.enabled -}} +apiVersion: {{ template "prometheus.networkPolicy.apiVersion" . }} +kind: NetworkPolicy +metadata: + name: {{ template "prometheus.pushgateway.fullname" . }} +{{ include "prometheus.namespace" . | indent 2 }} + labels: + {{- include "prometheus.pushgateway.labels" . | nindent 4 }} +spec: + podSelector: + matchLabels: + {{- include "prometheus.pushgateway.matchLabels" . | nindent 6 }} + ingress: + - from: + - podSelector: + matchLabels: + {{- include "prometheus.server.matchLabels" . | nindent 12 }} + - ports: + - port: 9091 +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/pushgateway/pdb.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/pushgateway/pdb.yaml new file mode 100644 index 0000000..50beb48 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/pushgateway/pdb.yaml @@ -0,0 +1,14 @@ +{{- if .Values.pushgateway.podDisruptionBudget.enabled }} +apiVersion: policy/v1beta1 +kind: PodDisruptionBudget +metadata: + name: {{ template "prometheus.pushgateway.fullname" . }} +{{ include "prometheus.namespace" . | indent 2 }} + labels: + {{- include "prometheus.pushgateway.labels" . | nindent 4 }} +spec: + maxUnavailable: {{ .Values.pushgateway.podDisruptionBudget.maxUnavailable }} + selector: + matchLabels: + {{- include "prometheus.pushgateway.labels" . | nindent 6 }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/pushgateway/psp.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/pushgateway/psp.yaml new file mode 100644 index 0000000..1ca3267 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/pushgateway/psp.yaml @@ -0,0 +1,42 @@ +{{- if and .Values.pushgateway.enabled .Values.rbac.create .Values.podSecurityPolicy.enabled }} +apiVersion: {{ template "prometheus.podSecurityPolicy.apiVersion" . }} +kind: PodSecurityPolicy +metadata: + name: {{ template "prometheus.pushgateway.fullname" . }} + labels: + {{- include "prometheus.pushgateway.labels" . | nindent 4 }} + annotations: +{{- if .Values.pushgateway.podSecurityPolicy.annotations }} +{{ toYaml .Values.pushgateway.podSecurityPolicy.annotations | indent 4 }} +{{- end }} +spec: + privileged: false + allowPrivilegeEscalation: false + requiredDropCapabilities: + - ALL + volumes: + - 'persistentVolumeClaim' + - 'secret' + allowedHostPaths: + - pathPrefix: {{ .Values.pushgateway.persistentVolume.mountPath }} + hostNetwork: false + hostPID: false + hostIPC: false + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'MustRunAs' + ranges: + # Forbid adding the root group. + - min: 1 + max: 65535 + fsGroup: + rule: 'MustRunAs' + ranges: + # Forbid adding the root group. + - min: 1 + max: 65535 + readOnlyRootFilesystem: true +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/pushgateway/pvc.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/pushgateway/pvc.yaml new file mode 100644 index 0000000..d5d64dd --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/pushgateway/pvc.yaml @@ -0,0 +1,31 @@ +{{- if .Values.pushgateway.persistentVolume.enabled -}} +{{- if not .Values.pushgateway.persistentVolume.existingClaim -}} +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + {{- if .Values.pushgateway.persistentVolume.annotations }} + annotations: +{{ toYaml .Values.pushgateway.persistentVolume.annotations | indent 4 }} + {{- end }} + labels: + {{- include "prometheus.pushgateway.labels" . | nindent 4 }} + name: {{ template "prometheus.pushgateway.fullname" . }} +{{ include "prometheus.namespace" . | indent 2 }} +spec: + accessModes: +{{ toYaml .Values.pushgateway.persistentVolume.accessModes | indent 4 }} +{{- if .Values.pushgateway.persistentVolume.storageClass }} +{{- if (eq "-" .Values.pushgateway.persistentVolume.storageClass) }} + storageClassName: "" +{{- else }} + storageClassName: "{{ .Values.pushgateway.persistentVolume.storageClass }}" +{{- end }} +{{- end }} +{{- if .Values.pushgateway.persistentVolume.volumeBindingMode }} + volumeBindingMode: "{{ .Values.pushgateway.persistentVolume.volumeBindingMode }}" +{{- end }} + resources: + requests: + storage: "{{ .Values.pushgateway.persistentVolume.size }}" +{{- end -}} +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/pushgateway/service.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/pushgateway/service.yaml new file mode 100644 index 0000000..f05f17c --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/pushgateway/service.yaml @@ -0,0 +1,41 @@ +{{- if .Values.pushgateway.enabled -}} +apiVersion: v1 +kind: Service +metadata: +{{- if .Values.pushgateway.service.annotations }} + annotations: +{{ toYaml .Values.pushgateway.service.annotations | indent 4}} +{{- end }} + labels: + {{- include "prometheus.pushgateway.labels" . | nindent 4 }} +{{- if .Values.pushgateway.service.labels }} +{{ toYaml .Values.pushgateway.service.labels | indent 4}} +{{- end }} + name: {{ template "prometheus.pushgateway.fullname" . }} +{{ include "prometheus.namespace" . | indent 2 }} +spec: +{{- if .Values.pushgateway.service.clusterIP }} + clusterIP: {{ .Values.pushgateway.service.clusterIP }} +{{- end }} +{{- if .Values.pushgateway.service.externalIPs }} + externalIPs: +{{ toYaml .Values.pushgateway.service.externalIPs | indent 4 }} +{{- end }} +{{- if .Values.pushgateway.service.loadBalancerIP }} + loadBalancerIP: {{ .Values.pushgateway.service.loadBalancerIP }} +{{- end }} +{{- if .Values.pushgateway.service.loadBalancerSourceRanges }} + loadBalancerSourceRanges: + {{- range $cidr := .Values.pushgateway.service.loadBalancerSourceRanges }} + - {{ $cidr }} + {{- end }} +{{- end }} + ports: + - name: http + port: {{ .Values.pushgateway.service.servicePort }} + protocol: TCP + targetPort: 9091 + selector: + {{- include "prometheus.pushgateway.matchLabels" . | nindent 4 }} + type: "{{ .Values.pushgateway.service.type }}" +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/pushgateway/serviceaccount.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/pushgateway/serviceaccount.yaml new file mode 100644 index 0000000..8c0b876 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/pushgateway/serviceaccount.yaml @@ -0,0 +1,11 @@ +{{- if and .Values.pushgateway.enabled .Values.serviceAccounts.pushgateway.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + {{- include "prometheus.pushgateway.labels" . | nindent 4 }} + name: {{ template "prometheus.serviceAccountName.pushgateway" . }} +{{ include "prometheus.namespace" . | indent 2 }} + annotations: +{{ toYaml .Values.serviceAccounts.pushgateway.annotations | indent 4 }} +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/pushgateway/vpa.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/pushgateway/vpa.yaml new file mode 100644 index 0000000..0ac54f9 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/pushgateway/vpa.yaml @@ -0,0 +1,20 @@ +{{- if .Values.pushgateway.enabled -}} +{{- if .Values.pushgateway.verticalAutoscaler.enabled -}} +apiVersion: autoscaling.k8s.io/v1beta2 +kind: VerticalPodAutoscaler +metadata: + labels: + {{- include "prometheus.pushgateway.labels" . | nindent 4 }} + name: {{ template "prometheus.pushgateway.fullname" . }}-vpa +{{ include "prometheus.namespace" . | indent 2 }} +spec: + targetRef: + apiVersion: "apps/v1" + kind: Deployment + name: {{ template "prometheus.pushgateway.fullname" . }} + updatePolicy: + updateMode: {{ .Values.pushgateway.verticalAutoscaler.updateMode | default "Off" | quote }} + resourcePolicy: + containerPolicies: {{ .Values.pushgateway.verticalAutoscaler.containerPolicies | default list | toYaml | trim | nindent 4 }} +{{- end -}} {{/* if .Values.pushgateway.verticalAutoscaler.enabled */}} +{{- end -}} {{/* .Values.pushgateway.enabled */}} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/server/clusterrole.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/server/clusterrole.yaml new file mode 100644 index 0000000..2520235 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/server/clusterrole.yaml @@ -0,0 +1,48 @@ +{{- if and .Values.server.enabled .Values.rbac.create (empty .Values.server.useExistingClusterRoleName) -}} +apiVersion: {{ template "rbac.apiVersion" . }} +kind: ClusterRole +metadata: + labels: + {{- include "prometheus.server.labels" . | nindent 4 }} + name: {{ template "prometheus.server.fullname" . }} +rules: +{{- if .Values.podSecurityPolicy.enabled }} + - apiGroups: + - extensions + resources: + - podsecuritypolicies + verbs: + - use + resourceNames: + - {{ template "prometheus.server.fullname" . }} +{{- end }} + - apiGroups: + - "" + resources: + - nodes + - nodes/proxy + - nodes/metrics + - services + - endpoints + - pods + - ingresses + - configmaps + verbs: + - get + - list + - watch + - apiGroups: + - "extensions" + - "networking.k8s.io" + resources: + - ingresses/status + - ingresses + verbs: + - get + - list + - watch + - nonResourceURLs: + - "/metrics" + verbs: + - get +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/server/clusterrolebinding.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/server/clusterrolebinding.yaml new file mode 100644 index 0000000..5a79611 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/server/clusterrolebinding.yaml @@ -0,0 +1,16 @@ +{{- if and .Values.server.enabled .Values.rbac.create (empty .Values.server.namespaces) (empty .Values.server.useExistingClusterRoleName) -}} +apiVersion: {{ template "rbac.apiVersion" . }} +kind: ClusterRoleBinding +metadata: + labels: + {{- include "prometheus.server.labels" . | nindent 4 }} + name: {{ template "prometheus.server.fullname" . }} +subjects: + - kind: ServiceAccount + name: {{ template "prometheus.serviceAccountName.server" . }} +{{ include "prometheus.namespace" . | indent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "prometheus.server.fullname" . }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/server/cm.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/server/cm.yaml new file mode 100644 index 0000000..a0a813a --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/server/cm.yaml @@ -0,0 +1,85 @@ +{{- if .Values.server.enabled -}} +{{- if (empty .Values.server.configMapOverrideName) -}} +apiVersion: v1 +kind: ConfigMap +metadata: + labels: + {{- include "prometheus.server.labels" . | nindent 4 }} + name: {{ template "prometheus.server.fullname" . }} +{{ include "prometheus.namespace" . | indent 2 }} +data: +{{- $root := . -}} +{{- range $key, $value := .Values.ruleFiles }} + {{ $key }}: {{- toYaml $value | indent 2 }} +{{- end }} +{{- range $key, $value := .Values.serverFiles }} + {{ $key }}: | +{{- if eq $key "prometheus.yml" }} + global: +{{ $root.Values.server.global | toYaml | trimSuffix "\n" | indent 6 }} +{{- if $root.Values.server.remoteWrite }} + remote_write: +{{ $root.Values.server.remoteWrite | toYaml | indent 4 }} +{{- end }} +{{- if $root.Values.server.remoteRead }} + remote_read: +{{ $root.Values.server.remoteRead | toYaml | indent 4 }} +{{- end }} +{{- end }} +{{- if eq $key "alerts" }} +{{- if and (not (empty $value)) (empty $value.groups) }} + groups: +{{- range $ruleKey, $ruleValue := $value }} + - name: {{ $ruleKey -}}.rules + rules: +{{ $ruleValue | toYaml | trimSuffix "\n" | indent 6 }} +{{- end }} +{{- else }} +{{ toYaml $value | indent 4 }} +{{- end }} +{{- else }} +{{ toYaml $value | default "{}" | indent 4 }} +{{- end }} +{{- if eq $key "prometheus.yml" -}} +{{- if $root.Values.extraScrapeConfigs }} +{{ tpl $root.Values.extraScrapeConfigs $root | indent 4 }} +{{- end -}} +{{- if or ($root.Values.alertmanager.enabled) ($root.Values.server.alertmanagers) }} + alerting: +{{- if $root.Values.alertRelabelConfigs }} +{{ $root.Values.alertRelabelConfigs | toYaml | trimSuffix "\n" | indent 6 }} +{{- end }} + alertmanagers: +{{- if $root.Values.server.alertmanagers }} +{{ toYaml $root.Values.server.alertmanagers | indent 8 }} +{{- else }} + - kubernetes_sd_configs: + - role: pod + tls_config: + ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + {{- if $root.Values.alertmanager.prefixURL }} + path_prefix: {{ $root.Values.alertmanager.prefixURL }} + {{- end }} + relabel_configs: + - source_labels: [__meta_kubernetes_namespace] + regex: {{ $root.Release.Namespace }} + action: keep + - source_labels: [__meta_kubernetes_pod_label_app] + regex: {{ template "prometheus.name" $root }} + action: keep + - source_labels: [__meta_kubernetes_pod_label_component] + regex: alertmanager + action: keep + - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_probe] + regex: {{ index $root.Values.alertmanager.podAnnotations "prometheus.io/probe" | default ".*" }} + action: keep + - source_labels: [__meta_kubernetes_pod_container_port_number] + regex: "9093" + action: keep +{{- end -}} +{{- end -}} +{{- end -}} +{{- end -}} +{{- end -}} +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/server/deploy.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/server/deploy.yaml new file mode 100644 index 0000000..9b7aee0 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/server/deploy.yaml @@ -0,0 +1,316 @@ +{{- if .Values.server.enabled -}} +{{- if not .Values.server.statefulSet.enabled -}} +apiVersion: {{ template "prometheus.deployment.apiVersion" . }} +kind: Deployment +metadata: +{{- if .Values.server.deploymentAnnotations }} + annotations: + {{ toYaml .Values.server.deploymentAnnotations | nindent 4 }} +{{- end }} + labels: + {{- include "prometheus.server.labels" . | nindent 4 }} + name: {{ template "prometheus.server.fullname" . }} +{{ include "prometheus.namespace" . | indent 2 }} +spec: + selector: + matchLabels: + {{- include "prometheus.server.matchLabels" . | nindent 6 }} + replicas: {{ .Values.server.replicaCount }} + {{- if .Values.server.strategy }} + strategy: +{{ toYaml .Values.server.strategy | trim | indent 4 }} + {{ if eq .Values.server.strategy.type "Recreate" }}rollingUpdate: null{{ end }} +{{- end }} + template: + metadata: + {{- if .Values.server.podAnnotations }} + annotations: + {{ toYaml .Values.server.podAnnotations | nindent 8 }} + {{- end }} + labels: + {{- include "prometheus.server.labels" . | nindent 8 }} + {{- if .Values.server.podLabels}} + {{ toYaml .Values.server.podLabels | nindent 8 }} + {{- end}} + spec: +{{- if .Values.server.priorityClassName }} + priorityClassName: "{{ .Values.server.priorityClassName }}" +{{- end }} +{{- if .Values.server.schedulerName }} + schedulerName: "{{ .Values.server.schedulerName }}" +{{- end }} +{{- if semverCompare ">=1.13-0" .Capabilities.KubeVersion.GitVersion }} + {{- if or (.Values.server.enableServiceLinks) (eq (.Values.server.enableServiceLinks | toString) "") }} + enableServiceLinks: true + {{- else }} + enableServiceLinks: false + {{- end }} +{{- end }} + serviceAccountName: {{ template "prometheus.serviceAccountName.server" . }} + {{- if .Values.server.extraInitContainers }} + initContainers: +{{ toYaml .Values.server.extraInitContainers | indent 8 }} + {{- end }} + containers: + {{- if .Values.configmapReload.prometheus.enabled }} + - name: {{ template "prometheus.name" . }}-{{ .Values.server.name }}-{{ .Values.configmapReload.prometheus.name }} + image: "{{ .Values.configmapReload.prometheus.image.repository }}:{{ .Values.configmapReload.prometheus.image.tag }}" + imagePullPolicy: "{{ .Values.configmapReload.prometheus.image.pullPolicy }}" + args: + - --volume-dir=/etc/config + - --webhook-url=http://127.0.0.1:9090{{ .Values.server.prefixURL }}/-/reload + {{- range $key, $value := .Values.configmapReload.prometheus.extraArgs }} + - --{{ $key }}={{ $value }} + {{- end }} + {{- range .Values.configmapReload.prometheus.extraVolumeDirs }} + - --volume-dir={{ . }} + {{- end }} + resources: +{{ toYaml .Values.configmapReload.prometheus.resources | indent 12 }} + volumeMounts: + - name: config-volume + mountPath: /etc/config + readOnly: true + {{- range .Values.configmapReload.prometheus.extraConfigmapMounts }} + - name: {{ $.Values.configmapReload.prometheus.name }}-{{ .name }} + mountPath: {{ .mountPath }} + subPath: {{ .subPath }} + readOnly: {{ .readOnly }} + {{- end }} + {{- end }} + + - name: {{ template "prometheus.name" . }}-{{ .Values.server.name }} + image: "{{ .Values.server.image.repository }}:{{ .Values.server.image.tag }}" + imagePullPolicy: "{{ .Values.server.image.pullPolicy }}" + {{- if .Values.server.env }} + env: +{{ toYaml .Values.server.env | indent 12}} + {{- end }} + args: + {{- if .Values.server.defaultFlagsOverride }} + {{ toYaml .Values.server.defaultFlagsOverride | nindent 12}} + {{- else }} + {{- if .Values.server.retention }} + - --storage.tsdb.retention.time={{ .Values.server.retention }} + {{- end }} + - --config.file={{ .Values.server.configPath }} + {{- if .Values.server.storagePath }} + - --storage.tsdb.path={{ .Values.server.storagePath }} + {{- else }} + - --storage.tsdb.path={{ .Values.server.persistentVolume.mountPath }} + {{- end }} + - --web.console.libraries=/etc/prometheus/console_libraries + - --web.console.templates=/etc/prometheus/consoles + {{- range .Values.server.extraFlags }} + - --{{ . }} + {{- end }} + {{- range $key, $value := .Values.server.extraArgs }} + - --{{ $key }}={{ $value }} + {{- end }} + {{- if .Values.server.prefixURL }} + - --web.route-prefix={{ .Values.server.prefixURL }} + {{- end }} + {{- if .Values.server.baseURL }} + - --web.external-url={{ .Values.server.baseURL }} + {{- end }} + {{- end }} + ports: + - containerPort: 9090 + {{- if .Values.server.hostPort }} + hostPort: {{ .Values.server.hostPort }} + {{- end }} + readinessProbe: + {{- if not .Values.server.tcpSocketProbeEnabled }} + httpGet: + path: {{ .Values.server.prefixURL }}/-/ready + port: 9090 + scheme: {{ .Values.server.probeScheme }} + {{- if .Values.server.probeHeaders }} + httpHeaders: + {{- range .Values.server.probeHeaders}} + - name: {{ .name }} + value: {{ .value }} + {{- end }} + {{- end }} + {{- else }} + tcpSocket: + port: 9090 + {{- end }} + initialDelaySeconds: {{ .Values.server.readinessProbeInitialDelay }} + periodSeconds: {{ .Values.server.readinessProbePeriodSeconds }} + timeoutSeconds: {{ .Values.server.readinessProbeTimeout }} + failureThreshold: {{ .Values.server.readinessProbeFailureThreshold }} + successThreshold: {{ .Values.server.readinessProbeSuccessThreshold }} + livenessProbe: + {{- if not .Values.server.tcpSocketProbeEnabled }} + httpGet: + path: {{ .Values.server.prefixURL }}/-/healthy + port: 9090 + scheme: {{ .Values.server.probeScheme }} + {{- if .Values.server.probeHeaders }} + httpHeaders: + {{- range .Values.server.probeHeaders}} + - name: {{ .name }} + value: {{ .value }} + {{- end }} + {{- end }} + {{- else }} + tcpSocket: + port: 9090 + {{- end }} + initialDelaySeconds: {{ .Values.server.livenessProbeInitialDelay }} + periodSeconds: {{ .Values.server.livenessProbePeriodSeconds }} + timeoutSeconds: {{ .Values.server.livenessProbeTimeout }} + failureThreshold: {{ .Values.server.livenessProbeFailureThreshold }} + successThreshold: {{ .Values.server.livenessProbeSuccessThreshold }} + {{- if .Values.server.startupProbe.enabled }} + startupProbe: + {{- if not .Values.server.tcpSocketProbeEnabled }} + httpGet: + path: {{ .Values.server.prefixURL }}/-/healthy + port: 9090 + scheme: {{ .Values.server.probeScheme }} + {{- if .Values.server.probeHeaders }} + httpHeaders: + {{- range .Values.server.probeHeaders}} + - name: {{ .name }} + value: {{ .value }} + {{- end }} + {{- end }} + {{- else }} + tcpSocket: + port: 9090 + {{- end }} + failureThreshold: {{ .Values.server.startupProbe.failureThreshold }} + periodSeconds: {{ .Values.server.startupProbe.periodSeconds }} + timeoutSeconds: {{ .Values.server.startupProbe.timeoutSeconds }} + {{- end }} + resources: +{{ toYaml .Values.server.resources | indent 12 }} + volumeMounts: + - name: config-volume + mountPath: /etc/config + - name: storage-volume + mountPath: {{ .Values.server.persistentVolume.mountPath }} + subPath: "{{ .Values.server.persistentVolume.subPath }}" + {{- range .Values.server.extraHostPathMounts }} + - name: {{ .name }} + mountPath: {{ .mountPath }} + subPath: {{ .subPath }} + readOnly: {{ .readOnly }} + {{- end }} + {{- range .Values.server.extraConfigmapMounts }} + - name: {{ $.Values.server.name }}-{{ .name }} + mountPath: {{ .mountPath }} + subPath: {{ .subPath }} + readOnly: {{ .readOnly }} + {{- end }} + {{- range .Values.server.extraSecretMounts }} + - name: {{ .name }} + mountPath: {{ .mountPath }} + subPath: {{ .subPath }} + readOnly: {{ .readOnly }} + {{- end }} + {{- if .Values.server.extraVolumeMounts }} + {{ toYaml .Values.server.extraVolumeMounts | nindent 12 }} + {{- end }} + {{- if .Values.server.sidecarContainers }} + {{- range $name, $spec := .Values.server.sidecarContainers }} + - name: {{ $name }} + {{- if kindIs "string" $spec }} + {{- tpl $spec $ | nindent 10 }} + {{- else }} + {{- toYaml $spec | nindent 10 }} + {{- end }} + {{- end }} + {{- end }} + hostNetwork: {{ .Values.server.hostNetwork }} + {{- if .Values.server.dnsPolicy }} + dnsPolicy: {{ .Values.server.dnsPolicy }} + {{- end }} + {{- if .Values.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | indent 8 }} + {{- end }} + {{- if .Values.server.nodeSelector }} + nodeSelector: +{{ toYaml .Values.server.nodeSelector | indent 8 }} + {{- end }} + {{- if .Values.server.hostAliases }} + hostAliases: +{{ toYaml .Values.server.hostAliases | indent 8 }} + {{- end }} + {{- if .Values.server.dnsConfig }} + dnsConfig: +{{ toYaml .Values.server.dnsConfig | indent 8 }} + {{- end }} + {{- if .Values.server.securityContext }} + securityContext: +{{ toYaml .Values.server.securityContext | indent 8 }} + {{- end }} + {{- if .Values.server.tolerations }} + tolerations: +{{ toYaml .Values.server.tolerations | indent 8 }} + {{- end }} + {{- if .Values.server.affinity }} + affinity: +{{ toYaml .Values.server.affinity | indent 8 }} + {{- end }} + terminationGracePeriodSeconds: {{ .Values.server.terminationGracePeriodSeconds }} + volumes: + - name: config-volume + {{- if empty .Values.server.configFromSecret }} + configMap: + name: {{ if .Values.server.configMapOverrideName }}{{ .Release.Name }}-{{ .Values.server.configMapOverrideName }}{{- else }}{{ template "prometheus.server.fullname" . }}{{- end }} + {{- else }} + secret: + secretName: {{ .Values.server.configFromSecret }} + {{- end }} + {{- range .Values.server.extraHostPathMounts }} + - name: {{ .name }} + hostPath: + path: {{ .hostPath }} + {{- end }} + {{- range .Values.configmapReload.prometheus.extraConfigmapMounts }} + - name: {{ $.Values.configmapReload.prometheus.name }}-{{ .name }} + configMap: + name: {{ .configMap }} + {{- end }} + {{- range .Values.server.extraConfigmapMounts }} + - name: {{ $.Values.server.name }}-{{ .name }} + configMap: + name: {{ .configMap }} + {{- end }} + {{- range .Values.server.extraSecretMounts }} + - name: {{ .name }} + secret: + secretName: {{ .secretName }} + {{- with .optional }} + optional: {{ . }} + {{- end }} + {{- end }} + {{- range .Values.configmapReload.prometheus.extraConfigmapMounts }} + - name: {{ .name }} + configMap: + name: {{ .configMap }} + {{- with .optional }} + optional: {{ . }} + {{- end }} + {{- end }} +{{- if .Values.server.extraVolumes }} +{{ toYaml .Values.server.extraVolumes | indent 8}} +{{- end }} + - name: storage-volume + {{- if .Values.server.persistentVolume.enabled }} + persistentVolumeClaim: + claimName: {{ if .Values.server.persistentVolume.existingClaim }}{{ .Values.server.persistentVolume.existingClaim }}{{- else }}{{ template "prometheus.server.fullname" . }}{{- end }} + {{- else }} + emptyDir: + {{- if .Values.server.emptyDir.sizeLimit }} + sizeLimit: {{ .Values.server.emptyDir.sizeLimit }} + {{- else }} + {} + {{- end -}} + {{- end -}} +{{- end -}} +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/server/headless-svc.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/server/headless-svc.yaml new file mode 100644 index 0000000..d519f4e --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/server/headless-svc.yaml @@ -0,0 +1,37 @@ +{{- if .Values.server.enabled -}} +{{- if .Values.server.statefulSet.enabled -}} +apiVersion: v1 +kind: Service +metadata: +{{- if .Values.server.statefulSet.headless.annotations }} + annotations: +{{ toYaml .Values.server.statefulSet.headless.annotations | indent 4 }} +{{- end }} + labels: + {{- include "prometheus.server.labels" . | nindent 4 }} +{{- if .Values.server.statefulSet.headless.labels }} +{{ toYaml .Values.server.statefulSet.headless.labels | indent 4 }} +{{- end }} + name: {{ template "prometheus.server.fullname" . }}-headless +{{ include "prometheus.namespace" . | indent 2 }} +spec: + clusterIP: None + ports: + - name: http + port: {{ .Values.server.statefulSet.headless.servicePort }} + protocol: TCP + targetPort: 9090 + {{- if .Values.server.statefulSet.headless.gRPC.enabled }} + - name: grpc + port: {{ .Values.server.statefulSet.headless.gRPC.servicePort }} + protocol: TCP + targetPort: 10901 + {{- if .Values.server.statefulSet.headless.gRPC.nodePort }} + nodePort: {{ .Values.server.statefulSet.headless.gRPC.nodePort }} + {{- end }} + {{- end }} + + selector: + {{- include "prometheus.server.matchLabels" . | nindent 4 }} +{{- end -}} +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/server/ingress.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/server/ingress.yaml new file mode 100644 index 0000000..000f39c --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/server/ingress.yaml @@ -0,0 +1,59 @@ +{{- if .Values.server.enabled -}} +{{- if .Values.server.ingress.enabled -}} +{{- $ingressApiIsStable := eq (include "ingress.isStable" .) "true" -}} +{{- $ingressSupportsIngressClassName := eq (include "ingress.supportsIngressClassName" .) "true" -}} +{{- $ingressSupportsPathType := eq (include "ingress.supportsPathType" .) "true" -}} +{{- $releaseName := .Release.Name -}} +{{- $serviceName := include "prometheus.server.fullname" . }} +{{- $servicePort := .Values.server.service.servicePort -}} +{{- $ingressPath := .Values.server.ingress.path -}} +{{- $ingressPathType := .Values.server.ingress.pathType -}} +{{- $extraPaths := .Values.server.ingress.extraPaths -}} +apiVersion: {{ template "ingress.apiVersion" . }} +kind: Ingress +metadata: +{{- if .Values.server.ingress.annotations }} + annotations: +{{ toYaml .Values.server.ingress.annotations | indent 4 }} +{{- end }} + labels: + {{- include "prometheus.server.labels" . | nindent 4 }} +{{- range $key, $value := .Values.server.ingress.extraLabels }} + {{ $key }}: {{ $value }} +{{- end }} + name: {{ template "prometheus.server.fullname" . }} +{{ include "prometheus.namespace" . | indent 2 }} +spec: + {{- if and $ingressSupportsIngressClassName .Values.server.ingress.ingressClassName }} + ingressClassName: {{ .Values.server.ingress.ingressClassName }} + {{- end }} + rules: + {{- range .Values.server.ingress.hosts }} + {{- $url := splitList "/" . }} + - host: {{ first $url }} + http: + paths: +{{ if $extraPaths }} +{{ toYaml $extraPaths | indent 10 }} +{{- end }} + - path: {{ $ingressPath }} + {{- if $ingressSupportsPathType }} + pathType: {{ $ingressPathType }} + {{- end }} + backend: + {{- if $ingressApiIsStable }} + service: + name: {{ $serviceName }} + port: + number: {{ $servicePort }} + {{- else }} + serviceName: {{ $serviceName }} + servicePort: {{ $servicePort }} + {{- end }} + {{- end -}} +{{- if .Values.server.ingress.tls }} + tls: +{{ toYaml .Values.server.ingress.tls | indent 4 }} + {{- end -}} +{{- end -}} +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/server/netpol.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/server/netpol.yaml new file mode 100644 index 0000000..c8870e9 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/server/netpol.yaml @@ -0,0 +1,18 @@ +{{- if .Values.server.enabled -}} +{{- if .Values.networkPolicy.enabled }} +apiVersion: {{ template "prometheus.networkPolicy.apiVersion" . }} +kind: NetworkPolicy +metadata: + name: {{ template "prometheus.server.fullname" . }} +{{ include "prometheus.namespace" . | indent 2 }} + labels: + {{- include "prometheus.server.labels" . | nindent 4 }} +spec: + podSelector: + matchLabels: + {{- include "prometheus.server.matchLabels" . | nindent 6 }} + ingress: + - ports: + - port: 9090 +{{- end }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/server/pdb.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/server/pdb.yaml new file mode 100644 index 0000000..364cb5b --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/server/pdb.yaml @@ -0,0 +1,14 @@ +{{- if .Values.server.podDisruptionBudget.enabled }} +apiVersion: policy/v1beta1 +kind: PodDisruptionBudget +metadata: + name: {{ template "prometheus.server.fullname" . }} +{{ include "prometheus.namespace" . | indent 2 }} + labels: + {{- include "prometheus.server.labels" . | nindent 4 }} +spec: + maxUnavailable: {{ .Values.server.podDisruptionBudget.maxUnavailable }} + selector: + matchLabels: + {{- include "prometheus.server.labels" . | nindent 6 }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/server/psp.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/server/psp.yaml new file mode 100644 index 0000000..e2b885f --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/server/psp.yaml @@ -0,0 +1,51 @@ +{{- if and .Values.server.enabled .Values.rbac.create .Values.podSecurityPolicy.enabled }} +apiVersion: {{ template "prometheus.podSecurityPolicy.apiVersion" . }} +kind: PodSecurityPolicy +metadata: + name: {{ template "prometheus.server.fullname" . }} + labels: + {{- include "prometheus.server.labels" . | nindent 4 }} + annotations: +{{- if .Values.server.podSecurityPolicy.annotations }} +{{ toYaml .Values.server.podSecurityPolicy.annotations | indent 4 }} +{{- end }} +spec: + privileged: false + allowPrivilegeEscalation: false + allowedCapabilities: + - 'CHOWN' + volumes: + - 'configMap' + - 'persistentVolumeClaim' + - 'emptyDir' + - 'secret' + - 'hostPath' + allowedHostPaths: + - pathPrefix: /etc + readOnly: true + - pathPrefix: {{ .Values.server.persistentVolume.mountPath }} + {{- range .Values.server.extraHostPathMounts }} + - pathPrefix: {{ .hostPath }} + readOnly: {{ .readOnly }} + {{- end }} + hostNetwork: false + hostPID: false + hostIPC: false + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'MustRunAs' + ranges: + # Forbid adding the root group. + - min: 1 + max: 65535 + fsGroup: + rule: 'MustRunAs' + ranges: + # Forbid adding the root group. + - min: 1 + max: 65535 + readOnlyRootFilesystem: false +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/server/pvc.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/server/pvc.yaml new file mode 100644 index 0000000..a735536 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/server/pvc.yaml @@ -0,0 +1,39 @@ +{{- if .Values.server.enabled -}} +{{- if not .Values.server.statefulSet.enabled -}} +{{- if .Values.server.persistentVolume.enabled -}} +{{- if not .Values.server.persistentVolume.existingClaim -}} +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + {{- if .Values.server.persistentVolume.annotations }} + annotations: +{{ toYaml .Values.server.persistentVolume.annotations | indent 4 }} + {{- end }} + labels: + {{- include "prometheus.server.labels" . | nindent 4 }} + name: {{ template "prometheus.server.fullname" . }} +{{ include "prometheus.namespace" . | indent 2 }} +spec: + accessModes: +{{ toYaml .Values.server.persistentVolume.accessModes | indent 4 }} +{{- if .Values.server.persistentVolume.storageClass }} +{{- if (eq "-" .Values.server.persistentVolume.storageClass) }} + storageClassName: "" +{{- else }} + storageClassName: "{{ .Values.server.persistentVolume.storageClass }}" +{{- end }} +{{- end }} +{{- if .Values.server.persistentVolume.volumeBindingMode }} + volumeBindingMode: "{{ .Values.server.persistentVolume.volumeBindingMode }}" +{{- end }} + resources: + requests: + storage: "{{ .Values.server.persistentVolume.size }}" +{{- if .Values.server.persistentVolume.selector }} + selector: + {{- toYaml .Values.server.persistentVolume.selector | nindent 4 }} +{{- end -}} +{{- end -}} +{{- end -}} +{{- end -}} +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/server/rolebinding.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/server/rolebinding.yaml new file mode 100644 index 0000000..93ce3ee --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/server/rolebinding.yaml @@ -0,0 +1,20 @@ +{{- if and .Values.server.enabled .Values.rbac.create .Values.server.useExistingClusterRoleName .Values.server.namespaces -}} +{{ range $.Values.server.namespaces -}} +--- +apiVersion: {{ template "rbac.apiVersion" $ }} +kind: RoleBinding +metadata: + labels: + {{- include "prometheus.server.labels" $ | nindent 4 }} + name: {{ template "prometheus.server.fullname" $ }} + namespace: {{ . }} +subjects: + - kind: ServiceAccount + name: {{ template "prometheus.serviceAccountName.server" $ }} +{{ include "prometheus.namespace" $ | indent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ $.Values.server.useExistingClusterRoleName }} +{{ end -}} +{{ end -}} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/server/service.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/server/service.yaml new file mode 100644 index 0000000..68f9889 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/server/service.yaml @@ -0,0 +1,60 @@ +{{- if .Values.server.enabled -}} +apiVersion: v1 +kind: Service +metadata: +{{- if .Values.server.service.annotations }} + annotations: +{{ toYaml .Values.server.service.annotations | indent 4 }} +{{- end }} + labels: + {{- include "prometheus.server.labels" . | nindent 4 }} +{{- if .Values.server.service.labels }} +{{ toYaml .Values.server.service.labels | indent 4 }} +{{- end }} + name: {{ template "prometheus.server.fullname" . }} +{{ include "prometheus.namespace" . | indent 2 }} +spec: +{{- if .Values.server.service.clusterIP }} + clusterIP: {{ .Values.server.service.clusterIP }} +{{- end }} +{{- if .Values.server.service.externalIPs }} + externalIPs: +{{ toYaml .Values.server.service.externalIPs | indent 4 }} +{{- end }} +{{- if .Values.server.service.loadBalancerIP }} + loadBalancerIP: {{ .Values.server.service.loadBalancerIP }} +{{- end }} +{{- if .Values.server.service.loadBalancerSourceRanges }} + loadBalancerSourceRanges: + {{- range $cidr := .Values.server.service.loadBalancerSourceRanges }} + - {{ $cidr }} + {{- end }} +{{- end }} + ports: + - name: http + port: {{ .Values.server.service.servicePort }} + protocol: TCP + targetPort: 9090 + {{- if .Values.server.service.nodePort }} + nodePort: {{ .Values.server.service.nodePort }} + {{- end }} + {{- if .Values.server.service.gRPC.enabled }} + - name: grpc + port: {{ .Values.server.service.gRPC.servicePort }} + protocol: TCP + targetPort: 10901 + {{- if .Values.server.service.gRPC.nodePort }} + nodePort: {{ .Values.server.service.gRPC.nodePort }} + {{- end }} + {{- end }} + selector: + {{- if and .Values.server.statefulSet.enabled .Values.server.service.statefulsetReplica.enabled }} + statefulset.kubernetes.io/pod-name: {{ template "prometheus.server.fullname" . }}-{{ .Values.server.service.statefulsetReplica.replica }} + {{- else -}} + {{- include "prometheus.server.matchLabels" . | nindent 4 }} +{{- if .Values.server.service.sessionAffinity }} + sessionAffinity: {{ .Values.server.service.sessionAffinity }} +{{- end }} + {{- end }} + type: "{{ .Values.server.service.type }}" +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/server/serviceaccount.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/server/serviceaccount.yaml new file mode 100644 index 0000000..9c0502a --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/server/serviceaccount.yaml @@ -0,0 +1,13 @@ +{{- if .Values.server.enabled -}} +{{- if .Values.serviceAccounts.server.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + {{- include "prometheus.server.labels" . | nindent 4 }} + name: {{ template "prometheus.serviceAccountName.server" . }} +{{ include "prometheus.namespace" . | indent 2 }} + annotations: +{{ toYaml .Values.serviceAccounts.server.annotations | indent 4 }} +{{- end }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/server/sts.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/server/sts.yaml new file mode 100644 index 0000000..0bc3ff7 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/server/sts.yaml @@ -0,0 +1,298 @@ +{{- if .Values.server.enabled -}} +{{- if .Values.server.statefulSet.enabled -}} +apiVersion: apps/v1 +kind: StatefulSet +metadata: +{{- if .Values.server.statefulSet.annotations }} + annotations: + {{ toYaml .Values.server.statefulSet.annotations | nindent 4 }} +{{- end }} + labels: + {{- include "prometheus.server.labels" . | nindent 4 }} + {{- if .Values.server.statefulSet.labels}} + {{ toYaml .Values.server.statefulSet.labels | nindent 4 }} + {{- end}} + name: {{ template "prometheus.server.fullname" . }} +{{ include "prometheus.namespace" . | indent 2 }} +spec: + serviceName: {{ template "prometheus.server.fullname" . }}-headless + selector: + matchLabels: + {{- include "prometheus.server.matchLabels" . | nindent 6 }} + replicas: {{ .Values.server.replicaCount }} + podManagementPolicy: {{ .Values.server.statefulSet.podManagementPolicy }} + template: + metadata: + {{- if .Values.server.podAnnotations }} + annotations: + {{ toYaml .Values.server.podAnnotations | nindent 8 }} + {{- end }} + labels: + {{- include "prometheus.server.labels" . | nindent 8 }} + {{- if .Values.server.podLabels}} + {{ toYaml .Values.server.podLabels | nindent 8 }} + {{- end}} + spec: +{{- if .Values.server.priorityClassName }} + priorityClassName: "{{ .Values.server.priorityClassName }}" +{{- end }} +{{- if .Values.server.schedulerName }} + schedulerName: "{{ .Values.server.schedulerName }}" +{{- end }} +{{- if semverCompare ">=1.13-0" .Capabilities.KubeVersion.GitVersion }} + {{- if or (.Values.server.enableServiceLinks) (eq (.Values.server.enableServiceLinks | toString) "") }} + enableServiceLinks: true + {{- else }} + enableServiceLinks: false + {{- end }} +{{- end }} + serviceAccountName: {{ template "prometheus.serviceAccountName.server" . }} + {{- if .Values.server.extraInitContainers }} + initContainers: +{{ toYaml .Values.server.extraInitContainers | indent 8 }} + {{- end }} + containers: + {{- if .Values.configmapReload.prometheus.enabled }} + - name: {{ template "prometheus.name" . }}-{{ .Values.server.name }}-{{ .Values.configmapReload.prometheus.name }} + image: "{{ .Values.configmapReload.prometheus.image.repository }}:{{ .Values.configmapReload.prometheus.image.tag }}" + imagePullPolicy: "{{ .Values.configmapReload.prometheus.image.pullPolicy }}" + args: + - --volume-dir=/etc/config + - --webhook-url=http://127.0.0.1:9090{{ .Values.server.prefixURL }}/-/reload + {{- range $key, $value := .Values.configmapReload.prometheus.extraArgs }} + - --{{ $key }}={{ $value }} + {{- end }} + {{- range .Values.configmapReload.prometheus.extraVolumeDirs }} + - --volume-dir={{ . }} + {{- end }} + resources: +{{ toYaml .Values.configmapReload.prometheus.resources | indent 12 }} + volumeMounts: + - name: config-volume + mountPath: /etc/config + readOnly: true + {{- range .Values.configmapReload.prometheus.extraConfigmapMounts }} + - name: {{ $.Values.configmapReload.prometheus.name }}-{{ .name }} + mountPath: {{ .mountPath }} + subPath: {{ .subPath }} + readOnly: {{ .readOnly }} + {{- end }} + {{- end }} + + - name: {{ template "prometheus.name" . }}-{{ .Values.server.name }} + image: "{{ .Values.server.image.repository }}:{{ .Values.server.image.tag }}" + imagePullPolicy: "{{ .Values.server.image.pullPolicy }}" + {{- if .Values.server.env }} + env: +{{ toYaml .Values.server.env | indent 12}} + {{- end }} + args: + {{- if .Values.server.defaultFlagsOverride }} + {{ toYaml .Values.server.defaultFlagsOverride | nindent 12}} + {{- else }} + {{- if .Values.server.prefixURL }} + - --web.route-prefix={{ .Values.server.prefixURL }} + {{- end }} + {{- if .Values.server.retention }} + - --storage.tsdb.retention.time={{ .Values.server.retention }} + {{- end }} + - --config.file={{ .Values.server.configPath }} + {{- if .Values.server.storagePath }} + - --storage.tsdb.path={{ .Values.server.storagePath }} + {{- else }} + - --storage.tsdb.path={{ .Values.server.persistentVolume.mountPath }} + {{- end }} + - --web.console.libraries=/etc/prometheus/console_libraries + - --web.console.templates=/etc/prometheus/consoles + {{- range .Values.server.extraFlags }} + - --{{ . }} + {{- end }} + {{- range $key, $value := .Values.server.extraArgs }} + - --{{ $key }}={{ $value }} + {{- end }} + {{- if .Values.server.baseURL }} + - --web.external-url={{ .Values.server.baseURL }} + {{- end }} + {{- end }} + ports: + - containerPort: 9090 + {{- if .Values.server.hostPort }} + hostPort: {{ .Values.server.hostPort }} + {{- end }} + readinessProbe: + {{- if not .Values.server.tcpSocketProbeEnabled }} + httpGet: + path: {{ .Values.server.prefixURL }}/-/ready + port: 9090 + scheme: {{ .Values.server.probeScheme }} + {{- else }} + tcpSocket: + port: 9090 + {{- end }} + initialDelaySeconds: {{ .Values.server.readinessProbeInitialDelay }} + periodSeconds: {{ .Values.server.readinessProbePeriodSeconds }} + timeoutSeconds: {{ .Values.server.readinessProbeTimeout }} + failureThreshold: {{ .Values.server.readinessProbeFailureThreshold }} + successThreshold: {{ .Values.server.readinessProbeSuccessThreshold }} + livenessProbe: + {{- if not .Values.server.tcpSocketProbeEnabled }} + httpGet: + path: {{ .Values.server.prefixURL }}/-/healthy + port: 9090 + scheme: {{ .Values.server.probeScheme }} + {{- else }} + tcpSocket: + port: 9090 + {{- end }} + initialDelaySeconds: {{ .Values.server.livenessProbeInitialDelay }} + periodSeconds: {{ .Values.server.livenessProbePeriodSeconds }} + timeoutSeconds: {{ .Values.server.livenessProbeTimeout }} + failureThreshold: {{ .Values.server.livenessProbeFailureThreshold }} + successThreshold: {{ .Values.server.livenessProbeSuccessThreshold }} + resources: +{{ toYaml .Values.server.resources | indent 12 }} + volumeMounts: + - name: config-volume + mountPath: /etc/config + - name: storage-volume + mountPath: {{ .Values.server.persistentVolume.mountPath }} + subPath: "{{ .Values.server.persistentVolume.subPath }}" + {{- range .Values.server.extraHostPathMounts }} + - name: {{ .name }} + mountPath: {{ .mountPath }} + subPath: {{ .subPath }} + readOnly: {{ .readOnly }} + {{- end }} + {{- range .Values.server.extraConfigmapMounts }} + - name: {{ $.Values.server.name }}-{{ .name }} + mountPath: {{ .mountPath }} + subPath: {{ .subPath }} + readOnly: {{ .readOnly }} + {{- end }} + {{- range .Values.server.extraSecretMounts }} + - name: {{ .name }} + mountPath: {{ .mountPath }} + subPath: {{ .subPath }} + readOnly: {{ .readOnly }} + {{- end }} + {{- if .Values.server.extraVolumeMounts }} + {{ toYaml .Values.server.extraVolumeMounts | nindent 12 }} + {{- end }} + {{- if .Values.server.sidecarContainers }} + {{- range $name, $spec := .Values.server.sidecarContainers }} + - name: {{ $name }} + {{- if kindIs "string" $spec }} + {{- tpl $spec $ | nindent 10 }} + {{- else }} + {{- toYaml $spec | nindent 10 }} + {{- end }} + {{- end }} + {{- end }} + hostNetwork: {{ .Values.server.hostNetwork }} + {{- if .Values.server.dnsPolicy }} + dnsPolicy: {{ .Values.server.dnsPolicy }} + {{- end }} + {{- if .Values.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | indent 8 }} + {{- end }} + {{- if .Values.server.nodeSelector }} + nodeSelector: +{{ toYaml .Values.server.nodeSelector | indent 8 }} + {{- end }} + {{- if .Values.server.hostAliases }} + hostAliases: +{{ toYaml .Values.server.hostAliases | indent 8 }} + {{- end }} + {{- if .Values.server.dnsConfig }} + dnsConfig: +{{ toYaml .Values.server.dnsConfig | indent 8 }} + {{- end }} + {{- if .Values.server.securityContext }} + securityContext: +{{ toYaml .Values.server.securityContext | indent 8 }} + {{- end }} + {{- if .Values.server.tolerations }} + tolerations: +{{ toYaml .Values.server.tolerations | indent 8 }} + {{- end }} + {{- if .Values.server.affinity }} + affinity: +{{ toYaml .Values.server.affinity | indent 8 }} + {{- end }} + terminationGracePeriodSeconds: {{ .Values.server.terminationGracePeriodSeconds }} + volumes: + - name: config-volume + {{- if empty .Values.server.configFromSecret }} + configMap: + name: {{ if .Values.server.configMapOverrideName }}{{ .Release.Name }}-{{ .Values.server.configMapOverrideName }}{{- else }}{{ template "prometheus.server.fullname" . }}{{- end }} + {{- else }} + secret: + secretName: {{ .Values.server.configFromSecret }} + {{- end }} + {{- range .Values.server.extraHostPathMounts }} + - name: {{ .name }} + hostPath: + path: {{ .hostPath }} + {{- end }} + {{- range .Values.configmapReload.prometheus.extraConfigmapMounts }} + - name: {{ $.Values.configmapReload.prometheus.name }}-{{ .name }} + configMap: + name: {{ .configMap }} + {{- end }} + {{- range .Values.server.extraConfigmapMounts }} + - name: {{ $.Values.server.name }}-{{ .name }} + configMap: + name: {{ .configMap }} + {{- end }} + {{- range .Values.server.extraSecretMounts }} + - name: {{ .name }} + secret: + secretName: {{ .secretName }} + {{- with .optional }} + optional: {{ . }} + {{- end }} + {{- end }} + {{- range .Values.configmapReload.prometheus.extraConfigmapMounts }} + - name: {{ .name }} + configMap: + name: {{ .configMap }} + {{- with .optional }} + optional: {{ . }} + {{- end }} + {{- end }} +{{- if .Values.server.extraVolumes }} +{{ toYaml .Values.server.extraVolumes | indent 8}} +{{- end }} +{{- if .Values.server.persistentVolume.enabled }} + volumeClaimTemplates: + - metadata: + name: storage-volume + {{- if .Values.server.persistentVolume.annotations }} + annotations: +{{ toYaml .Values.server.persistentVolume.annotations | indent 10 }} + {{- end }} + spec: + accessModes: +{{ toYaml .Values.server.persistentVolume.accessModes | indent 10 }} + resources: + requests: + storage: "{{ .Values.server.persistentVolume.size }}" + {{- if .Values.server.persistentVolume.storageClass }} + {{- if (eq "-" .Values.server.persistentVolume.storageClass) }} + storageClassName: "" + {{- else }} + storageClassName: "{{ .Values.server.persistentVolume.storageClass }}" + {{- end }} + {{- end }} +{{- else }} + - name: storage-volume + emptyDir: + {{- if .Values.server.emptyDir.sizeLimit }} + sizeLimit: {{ .Values.server.emptyDir.sizeLimit }} + {{- else }} + {} + {{- end -}} +{{- end }} +{{- end }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/server/vpa.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/server/vpa.yaml new file mode 100644 index 0000000..981a9b4 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/templates/server/vpa.yaml @@ -0,0 +1,24 @@ +{{- if .Values.server.enabled -}} +{{- if .Values.server.verticalAutoscaler.enabled -}} +apiVersion: autoscaling.k8s.io/v1beta2 +kind: VerticalPodAutoscaler +metadata: + labels: + {{- include "prometheus.server.labels" . | nindent 4 }} + name: {{ template "prometheus.server.fullname" . }}-vpa +{{ include "prometheus.namespace" . | indent 2 }} +spec: + targetRef: + apiVersion: "apps/v1" +{{- if .Values.server.statefulSet.enabled }} + kind: StatefulSet +{{- else }} + kind: Deployment +{{- end }} + name: {{ template "prometheus.server.fullname" . }} + updatePolicy: + updateMode: {{ .Values.server.verticalAutoscaler.updateMode | default "Off" | quote }} + resourcePolicy: + containerPolicies: {{ .Values.server.verticalAutoscaler.containerPolicies | default list | toYaml | trim | nindent 4 }} +{{- end -}} {{/* if .Values.server.verticalAutoscaler.enabled */}} +{{- end -}} {{/* .Values.server.enabled */}} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/values.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/values.yaml new file mode 100644 index 0000000..eafb3e8 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/prometheus/values.yaml @@ -0,0 +1,1825 @@ +rbac: + create: true + +podSecurityPolicy: + enabled: false + +imagePullSecrets: +# - name: "image-pull-secret" + +## Define serviceAccount names for components. Defaults to component's fully qualified name. +## +serviceAccounts: + alertmanager: + create: true + name: + annotations: {} + nodeExporter: + create: true + name: + annotations: {} + pushgateway: + create: true + name: + annotations: {} + server: + create: true + name: + annotations: {} + +alertmanager: + ## If false, alertmanager will not be installed + ## + enabled: true + + ## Use a ClusterRole (and ClusterRoleBinding) + ## - If set to false - we define a Role and RoleBinding in the defined namespaces ONLY + ## This makes alertmanager work - for users who do not have ClusterAdmin privs, but wants alertmanager to operate on their own namespaces, instead of clusterwide. + useClusterRole: true + + ## Set to a rolename to use existing role - skipping role creating - but still doing serviceaccount and rolebinding to the rolename set here. + useExistingRole: false + + ## alertmanager container name + ## + name: alertmanager + + ## alertmanager container image + ## + image: + repository: quay.io/prometheus/alertmanager + tag: v0.23.0 + pullPolicy: IfNotPresent + + ## alertmanager priorityClassName + ## + priorityClassName: "" + + ## Custom HTTP headers for Readiness Probe + ## + ## Useful for providing HTTP Basic Auth to healthchecks + probeHeaders: [] + + ## Additional alertmanager container arguments + ## + extraArgs: {} + + ## Additional InitContainers to initialize the pod + ## + extraInitContainers: [] + + ## The URL prefix at which the container can be accessed. Useful in the case the '-web.external-url' includes a slug + ## so that the various internal URLs are still able to access as they are in the default case. + ## (Optional) + prefixURL: "" + + ## External URL which can access alertmanager + baseURL: "http://localhost:9093" + + ## Additional alertmanager container environment variable + ## For instance to add a http_proxy + ## + extraEnv: {} + + ## Additional alertmanager Secret mounts + # Defines additional mounts with secrets. Secrets must be manually created in the namespace. + extraSecretMounts: [] + # - name: secret-files + # mountPath: /etc/secrets + # subPath: "" + # secretName: alertmanager-secret-files + # readOnly: true + + ## Additional alertmanager Configmap mounts + extraConfigmapMounts: [] + # - name: template-files + # mountPath: /etc/config/templates.d + # configMap: alertmanager-template-files + # readOnly: true + + ## ConfigMap override where fullname is {{.Release.Name}}-{{.Values.alertmanager.configMapOverrideName}} + ## Defining configMapOverrideName will cause templates/alertmanager-configmap.yaml + ## to NOT generate a ConfigMap resource + ## + configMapOverrideName: "" + + ## The name of a secret in the same kubernetes namespace which contains the Alertmanager config + ## Defining configFromSecret will cause templates/alertmanager-configmap.yaml + ## to NOT generate a ConfigMap resource + ## + configFromSecret: "" + + ## The configuration file name to be loaded to alertmanager + ## Must match the key within configuration loaded from ConfigMap/Secret + ## + configFileName: alertmanager.yml + + ingress: + ## If true, alertmanager Ingress will be created + ## + enabled: false + + # For Kubernetes >= 1.18 you should specify the ingress-controller via the field ingressClassName + # See https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/#specifying-the-class-of-an-ingress + # ingressClassName: nginx + + ## alertmanager Ingress annotations + ## + annotations: {} + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: 'true' + + ## alertmanager Ingress additional labels + ## + extraLabels: {} + + ## alertmanager Ingress hostnames with optional path + ## Must be provided if Ingress is enabled + ## + hosts: [] + # - alertmanager.domain.com + # - domain.com/alertmanager + + path: / + + # pathType is only for k8s >= 1.18 + pathType: Prefix + + ## Extra paths to prepend to every host configuration. This is useful when working with annotation based services. + extraPaths: [] + # - path: /* + # backend: + # serviceName: ssl-redirect + # servicePort: use-annotation + + ## alertmanager Ingress TLS configuration + ## Secrets must be manually created in the namespace + ## + tls: [] + # - secretName: prometheus-alerts-tls + # hosts: + # - alertmanager.domain.com + + ## Alertmanager Deployment Strategy type + # strategy: + # type: Recreate + + ## Node tolerations for alertmanager scheduling to nodes with taints + ## Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ + ## + tolerations: [] + # - key: "key" + # operator: "Equal|Exists" + # value: "value" + # effect: "NoSchedule|PreferNoSchedule|NoExecute(1.6 only)" + + ## Node labels for alertmanager pod assignment + ## Ref: https://kubernetes.io/docs/user-guide/node-selection/ + ## + nodeSelector: {} + + ## Pod affinity + ## + affinity: {} + + ## PodDisruptionBudget settings + ## ref: https://kubernetes.io/docs/concepts/workloads/pods/disruptions/ + ## + podDisruptionBudget: + enabled: false + maxUnavailable: 1 + + ## Use an alternate scheduler, e.g. "stork". + ## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ + ## + # schedulerName: + + persistentVolume: + ## If true, alertmanager will create/use a Persistent Volume Claim + ## If false, use emptyDir + ## + enabled: true + + ## alertmanager data Persistent Volume access modes + ## Must match those of existing PV or dynamic provisioner + ## Ref: http://kubernetes.io/docs/user-guide/persistent-volumes/ + ## + accessModes: + - ReadWriteOnce + + ## alertmanager data Persistent Volume Claim annotations + ## + annotations: {} + + ## alertmanager data Persistent Volume existing claim name + ## Requires alertmanager.persistentVolume.enabled: true + ## If defined, PVC must be created manually before volume will be bound + existingClaim: "" + + ## alertmanager data Persistent Volume mount root path + ## + mountPath: /data + + ## alertmanager data Persistent Volume size + ## + size: 2Gi + + ## alertmanager data Persistent Volume Storage Class + ## If defined, storageClassName: + ## If set to "-", storageClassName: "", which disables dynamic provisioning + ## If undefined (the default) or set to null, no storageClassName spec is + ## set, choosing the default provisioner. (gp2 on AWS, standard on + ## GKE, AWS & OpenStack) + ## + # storageClass: "-" + + ## alertmanager data Persistent Volume Binding Mode + ## If defined, volumeBindingMode: + ## If undefined (the default) or set to null, no volumeBindingMode spec is + ## set, choosing the default mode. + ## + # volumeBindingMode: "" + + ## Subdirectory of alertmanager data Persistent Volume to mount + ## Useful if the volume's root directory is not empty + ## + subPath: "" + + ## Persistent Volume Claim Selector + ## Useful if Persistent Volumes have been provisioned in advance + ## Ref: https://kubernetes.io/docs/concepts/storage/persistent-volumes/#selector + ## + # selector: + # matchLabels: + # release: "stable" + # matchExpressions: + # - { key: environment, operator: In, values: [ dev ] } + + emptyDir: + ## alertmanager emptyDir volume size limit + ## + sizeLimit: "" + + ## Annotations to be added to alertmanager pods + ## + podAnnotations: {} + ## Tell prometheus to use a specific set of alertmanager pods + ## instead of all alertmanager pods found in the same namespace + ## Useful if you deploy multiple releases within the same namespace + ## + ## prometheus.io/probe: alertmanager-teamA + + ## Labels to be added to Prometheus AlertManager pods + ## + podLabels: {} + + ## Specify if a Pod Security Policy for node-exporter must be created + ## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/ + ## + podSecurityPolicy: + annotations: {} + ## Specify pod annotations + ## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#apparmor + ## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#seccomp + ## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#sysctl + ## + # seccomp.security.alpha.kubernetes.io/allowedProfileNames: '*' + # seccomp.security.alpha.kubernetes.io/defaultProfileName: 'docker/default' + # apparmor.security.beta.kubernetes.io/defaultProfileName: 'runtime/default' + + ## Use a StatefulSet if replicaCount needs to be greater than 1 (see below) + ## + replicaCount: 1 + + ## Annotations to be added to deployment + ## + deploymentAnnotations: {} + + statefulSet: + ## If true, use a statefulset instead of a deployment for pod management. + ## This allows to scale replicas to more than 1 pod + ## + enabled: false + + annotations: {} + labels: {} + podManagementPolicy: OrderedReady + + ## Alertmanager headless service to use for the statefulset + ## + headless: + annotations: {} + labels: {} + + ## Enabling peer mesh service end points for enabling the HA alert manager + ## Ref: https://github.com/prometheus/alertmanager/blob/master/README.md + enableMeshPeer: false + + servicePort: 80 + + ## alertmanager resource requests and limits + ## Ref: http://kubernetes.io/docs/user-guide/compute-resources/ + ## + resources: {} + # limits: + # cpu: 10m + # memory: 32Mi + # requests: + # cpu: 10m + # memory: 32Mi + + # Custom DNS configuration to be added to alertmanager pods + dnsConfig: {} + # nameservers: + # - 1.2.3.4 + # searches: + # - ns1.svc.cluster-domain.example + # - my.dns.search.suffix + # options: + # - name: ndots + # value: "2" + # - name: edns0 + + ## Security context to be added to alertmanager pods + ## + securityContext: + runAsUser: 65534 + runAsNonRoot: true + runAsGroup: 65534 + fsGroup: 65534 + + service: + annotations: {} + labels: {} + clusterIP: "" + + ## Enabling peer mesh service end points for enabling the HA alert manager + ## Ref: https://github.com/prometheus/alertmanager/blob/master/README.md + # enableMeshPeer : true + + ## List of IP addresses at which the alertmanager service is available + ## Ref: https://kubernetes.io/docs/user-guide/services/#external-ips + ## + externalIPs: [] + + loadBalancerIP: "" + loadBalancerSourceRanges: [] + servicePort: 80 + # nodePort: 30000 + sessionAffinity: None + type: ClusterIP + + ## List of initial peers + ## Ref: https://github.com/prometheus/alertmanager/blob/main/README.md#high-availability + clusterPeers: [] + +## Monitors ConfigMap changes and POSTs to a URL +## Ref: https://github.com/jimmidyson/configmap-reload +## +configmapReload: + prometheus: + ## If false, the configmap-reload container will not be deployed + ## + enabled: true + + ## configmap-reload container name + ## + name: configmap-reload + + ## configmap-reload container image + ## + image: + repository: jimmidyson/configmap-reload + tag: v0.5.0 + pullPolicy: IfNotPresent + + ## Additional configmap-reload container arguments + ## + extraArgs: {} + ## Additional configmap-reload volume directories + ## + extraVolumeDirs: [] + + + ## Additional configmap-reload mounts + ## + extraConfigmapMounts: [] + # - name: prometheus-alerts + # mountPath: /etc/alerts.d + # subPath: "" + # configMap: prometheus-alerts + # readOnly: true + + + ## configmap-reload resource requests and limits + ## Ref: http://kubernetes.io/docs/user-guide/compute-resources/ + ## + resources: {} + alertmanager: + ## If false, the configmap-reload container will not be deployed + ## + enabled: true + + ## configmap-reload container name + ## + name: configmap-reload + + ## configmap-reload container image + ## + image: + repository: jimmidyson/configmap-reload + tag: v0.5.0 + pullPolicy: IfNotPresent + + ## Additional configmap-reload container arguments + ## + extraArgs: {} + ## Additional configmap-reload volume directories + ## + extraVolumeDirs: [] + + + ## Additional configmap-reload mounts + ## + extraConfigmapMounts: [] + # - name: prometheus-alerts + # mountPath: /etc/alerts.d + # subPath: "" + # configMap: prometheus-alerts + # readOnly: true + + + ## configmap-reload resource requests and limits + ## Ref: http://kubernetes.io/docs/user-guide/compute-resources/ + ## + resources: {} + +kubeStateMetrics: + ## If false, kube-state-metrics sub-chart will not be installed + ## + enabled: true + +## kube-state-metrics sub-chart configurable values +## Please see https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-state-metrics +## +# kube-state-metrics: + +nodeExporter: + ## If false, node-exporter will not be installed + ## + enabled: true + + ## If true, node-exporter pods share the host network namespace + ## + hostNetwork: true + + ## If true, node-exporter pods share the host PID namespace + ## + hostPID: true + + ## If true, node-exporter pods mounts host / at /host/root + ## + hostRootfs: true + + ## node-exporter container name + ## + name: node-exporter + + ## node-exporter container image + ## + image: + repository: quay.io/prometheus/node-exporter + tag: v1.3.0 + pullPolicy: IfNotPresent + + ## Specify if a Pod Security Policy for node-exporter must be created + ## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/ + ## + podSecurityPolicy: + annotations: {} + ## Specify pod annotations + ## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#apparmor + ## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#seccomp + ## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#sysctl + ## + # seccomp.security.alpha.kubernetes.io/allowedProfileNames: '*' + # seccomp.security.alpha.kubernetes.io/defaultProfileName: 'docker/default' + # apparmor.security.beta.kubernetes.io/defaultProfileName: 'runtime/default' + + ## node-exporter priorityClassName + ## + priorityClassName: "" + + ## Custom Update Strategy + ## + updateStrategy: + type: RollingUpdate + + ## Additional node-exporter container arguments + ## + extraArgs: {} + + ## Additional InitContainers to initialize the pod + ## + extraInitContainers: [] + + ## Additional node-exporter hostPath mounts + ## + extraHostPathMounts: [] + # - name: textfile-dir + # mountPath: /srv/txt_collector + # hostPath: /var/lib/node-exporter + # readOnly: true + # mountPropagation: HostToContainer + + extraConfigmapMounts: [] + # - name: certs-configmap + # mountPath: /prometheus + # configMap: certs-configmap + # readOnly: true + + ## Node tolerations for node-exporter scheduling to nodes with taints + ## Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ + ## + tolerations: [] + # - key: "key" + # operator: "Equal|Exists" + # value: "value" + # effect: "NoSchedule|PreferNoSchedule|NoExecute(1.6 only)" + + ## Node labels for node-exporter pod assignment + ## Ref: https://kubernetes.io/docs/user-guide/node-selection/ + ## + nodeSelector: {} + + ## Annotations to be added to node-exporter pods + ## + podAnnotations: {} + + ## Labels to be added to node-exporter pods + ## + pod: + labels: {} + + ## PodDisruptionBudget settings + ## ref: https://kubernetes.io/docs/concepts/workloads/pods/disruptions/ + ## + podDisruptionBudget: + enabled: false + maxUnavailable: 1 + + ## node-exporter resource limits & requests + ## Ref: https://kubernetes.io/docs/user-guide/compute-resources/ + ## + resources: {} + # limits: + # cpu: 200m + # memory: 50Mi + # requests: + # cpu: 100m + # memory: 30Mi + + # Custom DNS configuration to be added to node-exporter pods + dnsConfig: {} + # nameservers: + # - 1.2.3.4 + # searches: + # - ns1.svc.cluster-domain.example + # - my.dns.search.suffix + # options: + # - name: ndots + # value: "2" + # - name: edns0 + + ## Security context to be added to node-exporter pods + ## + securityContext: + fsGroup: 65534 + runAsGroup: 65534 + runAsNonRoot: true + runAsUser: 65534 + + service: + annotations: + prometheus.io/scrape: "true" + labels: {} + + # Exposed as a headless service: + # https://kubernetes.io/docs/concepts/services-networking/service/#headless-services + clusterIP: None + + ## List of IP addresses at which the node-exporter service is available + ## Ref: https://kubernetes.io/docs/user-guide/services/#external-ips + ## + externalIPs: [] + + hostPort: 9100 + loadBalancerIP: "" + loadBalancerSourceRanges: [] + servicePort: 9100 + type: ClusterIP + +server: + ## Prometheus server container name + ## + enabled: true + + ## Use a ClusterRole (and ClusterRoleBinding) + ## - If set to false - we define a RoleBinding in the defined namespaces ONLY + ## + ## NB: because we need a Role with nonResourceURL's ("/metrics") - you must get someone with Cluster-admin privileges to define this role for you, before running with this setting enabled. + ## This makes prometheus work - for users who do not have ClusterAdmin privs, but wants prometheus to operate on their own namespaces, instead of clusterwide. + ## + ## You MUST also set namespaces to the ones you have access to and want monitored by Prometheus. + ## + # useExistingClusterRoleName: nameofclusterrole + + ## namespaces to monitor (instead of monitoring all - clusterwide). Needed if you want to run without Cluster-admin privileges. + # namespaces: + # - yournamespace + + name: server + + # sidecarContainers - add more containers to prometheus server + # Key/Value where Key is the sidecar `- name: ` + # Example: + # sidecarContainers: + # webserver: + # image: nginx + sidecarContainers: {} + + # sidecarTemplateValues - context to be used in template for sidecarContainers + # Example: + # sidecarTemplateValues: *your-custom-globals + # sidecarContainers: + # webserver: |- + # {{ include "webserver-container-template" . }} + # Template for `webserver-container-template` might looks like this: + # image: "{{ .Values.server.sidecarTemplateValues.repository }}:{{ .Values.server.sidecarTemplateValues.tag }}" + # ... + # + sidecarTemplateValues: {} + + ## Prometheus server container image + ## + image: + repository: quay.io/prometheus/prometheus + tag: v2.34.0 + pullPolicy: IfNotPresent + + ## prometheus server priorityClassName + ## + priorityClassName: "" + + ## EnableServiceLinks indicates whether information about services should be injected + ## into pod's environment variables, matching the syntax of Docker links. + ## WARNING: the field is unsupported and will be skipped in K8s prior to v1.13.0. + ## + enableServiceLinks: true + + ## The URL prefix at which the container can be accessed. Useful in the case the '-web.external-url' includes a slug + ## so that the various internal URLs are still able to access as they are in the default case. + ## (Optional) + prefixURL: "" + + ## External URL which can access prometheus + ## Maybe same with Ingress host name + baseURL: "" + + ## Additional server container environment variables + ## + ## You specify this manually like you would a raw deployment manifest. + ## This means you can bind in environment variables from secrets. + ## + ## e.g. static environment variable: + ## - name: DEMO_GREETING + ## value: "Hello from the environment" + ## + ## e.g. secret environment variable: + ## - name: USERNAME + ## valueFrom: + ## secretKeyRef: + ## name: mysecret + ## key: username + env: [] + + # List of flags to override default parameters, e.g: + # - --enable-feature=agent + # - --storage.agent.retention.max-time=30m + defaultFlagsOverride: [] + + extraFlags: + - web.enable-lifecycle + ## web.enable-admin-api flag controls access to the administrative HTTP API which includes functionality such as + ## deleting time series. This is disabled by default. + # - web.enable-admin-api + ## + ## storage.tsdb.no-lockfile flag controls BD locking + # - storage.tsdb.no-lockfile + ## + ## storage.tsdb.wal-compression flag enables compression of the write-ahead log (WAL) + # - storage.tsdb.wal-compression + + ## Path to a configuration file on prometheus server container FS + configPath: /etc/config/prometheus.yml + + ### The data directory used by prometheus to set --storage.tsdb.path + ### When empty server.persistentVolume.mountPath is used instead + storagePath: "" + + global: + ## How frequently to scrape targets by default + ## + scrape_interval: 1m + ## How long until a scrape request times out + ## + scrape_timeout: 10s + ## How frequently to evaluate rules + ## + evaluation_interval: 1m + ## https://prometheus.io/docs/prometheus/latest/configuration/configuration/#remote_write + ## + remoteWrite: [] + ## https://prometheus.io/docs/prometheus/latest/configuration/configuration/#remote_read + ## + remoteRead: [] + + ## Custom HTTP headers for Liveness/Readiness/Startup Probe + ## + ## Useful for providing HTTP Basic Auth to healthchecks + probeHeaders: [] + + ## Additional Prometheus server container arguments + ## + extraArgs: {} + + ## Additional InitContainers to initialize the pod + ## + extraInitContainers: [] + + ## Additional Prometheus server Volume mounts + ## + extraVolumeMounts: [] + + ## Additional Prometheus server Volumes + ## + extraVolumes: [] + + ## Additional Prometheus server hostPath mounts + ## + extraHostPathMounts: [] + # - name: certs-dir + # mountPath: /etc/kubernetes/certs + # subPath: "" + # hostPath: /etc/kubernetes/certs + # readOnly: true + + extraConfigmapMounts: [] + # - name: certs-configmap + # mountPath: /prometheus + # subPath: "" + # configMap: certs-configmap + # readOnly: true + + ## Additional Prometheus server Secret mounts + # Defines additional mounts with secrets. Secrets must be manually created in the namespace. + extraSecretMounts: [] + # - name: secret-files + # mountPath: /etc/secrets + # subPath: "" + # secretName: prom-secret-files + # readOnly: true + + ## ConfigMap override where fullname is {{.Release.Name}}-{{.Values.server.configMapOverrideName}} + ## Defining configMapOverrideName will cause templates/server-configmap.yaml + ## to NOT generate a ConfigMap resource + ## + configMapOverrideName: "" + + ingress: + ## If true, Prometheus server Ingress will be created + ## + enabled: false + + # For Kubernetes >= 1.18 you should specify the ingress-controller via the field ingressClassName + # See https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/#specifying-the-class-of-an-ingress + # ingressClassName: nginx + + ## Prometheus server Ingress annotations + ## + annotations: {} + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: 'true' + + ## Prometheus server Ingress additional labels + ## + extraLabels: {} + + ## Prometheus server Ingress hostnames with optional path + ## Must be provided if Ingress is enabled + ## + hosts: [] + # - prometheus.domain.com + # - domain.com/prometheus + + path: / + + # pathType is only for k8s >= 1.18 + pathType: Prefix + + ## Extra paths to prepend to every host configuration. This is useful when working with annotation based services. + extraPaths: [] + # - path: /* + # backend: + # serviceName: ssl-redirect + # servicePort: use-annotation + + ## Prometheus server Ingress TLS configuration + ## Secrets must be manually created in the namespace + ## + tls: [] + # - secretName: prometheus-server-tls + # hosts: + # - prometheus.domain.com + + ## Server Deployment Strategy type + # strategy: + # type: Recreate + + ## hostAliases allows adding entries to /etc/hosts inside the containers + hostAliases: [] + # - ip: "127.0.0.1" + # hostnames: + # - "example.com" + + ## Node tolerations for server scheduling to nodes with taints + ## Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ + ## + tolerations: [] + # - key: "key" + # operator: "Equal|Exists" + # value: "value" + # effect: "NoSchedule|PreferNoSchedule|NoExecute(1.6 only)" + + ## Node labels for Prometheus server pod assignment + ## Ref: https://kubernetes.io/docs/user-guide/node-selection/ + ## + nodeSelector: {} + + ## Pod affinity + ## + affinity: {} + + ## PodDisruptionBudget settings + ## ref: https://kubernetes.io/docs/concepts/workloads/pods/disruptions/ + ## + podDisruptionBudget: + enabled: false + maxUnavailable: 1 + + ## Use an alternate scheduler, e.g. "stork". + ## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ + ## + # schedulerName: + + persistentVolume: + ## If true, Prometheus server will create/use a Persistent Volume Claim + ## If false, use emptyDir + ## + enabled: true + + ## Prometheus server data Persistent Volume access modes + ## Must match those of existing PV or dynamic provisioner + ## Ref: http://kubernetes.io/docs/user-guide/persistent-volumes/ + ## + accessModes: + - ReadWriteOnce + + ## Prometheus server data Persistent Volume annotations + ## + annotations: {} + + ## Prometheus server data Persistent Volume existing claim name + ## Requires server.persistentVolume.enabled: true + ## If defined, PVC must be created manually before volume will be bound + existingClaim: "" + + ## Prometheus server data Persistent Volume mount root path + ## + mountPath: /data + + ## Prometheus server data Persistent Volume size + ## + size: 8Gi + + ## Prometheus server data Persistent Volume Storage Class + ## If defined, storageClassName: + ## If set to "-", storageClassName: "", which disables dynamic provisioning + ## If undefined (the default) or set to null, no storageClassName spec is + ## set, choosing the default provisioner. (gp2 on AWS, standard on + ## GKE, AWS & OpenStack) + ## + # storageClass: "-" + + ## Prometheus server data Persistent Volume Binding Mode + ## If defined, volumeBindingMode: + ## If undefined (the default) or set to null, no volumeBindingMode spec is + ## set, choosing the default mode. + ## + # volumeBindingMode: "" + + ## Subdirectory of Prometheus server data Persistent Volume to mount + ## Useful if the volume's root directory is not empty + ## + subPath: "" + + ## Persistent Volume Claim Selector + ## Useful if Persistent Volumes have been provisioned in advance + ## Ref: https://kubernetes.io/docs/concepts/storage/persistent-volumes/#selector + ## + # selector: + # matchLabels: + # release: "stable" + # matchExpressions: + # - { key: environment, operator: In, values: [ dev ] } + + emptyDir: + ## Prometheus server emptyDir volume size limit + ## + sizeLimit: "" + + ## Annotations to be added to Prometheus server pods + ## + podAnnotations: {} + # iam.amazonaws.com/role: prometheus + + ## Labels to be added to Prometheus server pods + ## + podLabels: {} + + ## Prometheus AlertManager configuration + ## + alertmanagers: [] + + ## Specify if a Pod Security Policy for node-exporter must be created + ## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/ + ## + podSecurityPolicy: + annotations: {} + ## Specify pod annotations + ## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#apparmor + ## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#seccomp + ## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#sysctl + ## + # seccomp.security.alpha.kubernetes.io/allowedProfileNames: '*' + # seccomp.security.alpha.kubernetes.io/defaultProfileName: 'docker/default' + # apparmor.security.beta.kubernetes.io/defaultProfileName: 'runtime/default' + + ## Use a StatefulSet if replicaCount needs to be greater than 1 (see below) + ## + replicaCount: 1 + + ## Annotations to be added to deployment + ## + deploymentAnnotations: {} + + statefulSet: + ## If true, use a statefulset instead of a deployment for pod management. + ## This allows to scale replicas to more than 1 pod + ## + enabled: false + + annotations: {} + labels: {} + podManagementPolicy: OrderedReady + + ## Alertmanager headless service to use for the statefulset + ## + headless: + annotations: {} + labels: {} + servicePort: 80 + ## Enable gRPC port on service to allow auto discovery with thanos-querier + gRPC: + enabled: false + servicePort: 10901 + # nodePort: 10901 + + ## Prometheus server readiness and liveness probe initial delay and timeout + ## Ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/ + ## + tcpSocketProbeEnabled: false + probeScheme: HTTP + readinessProbeInitialDelay: 30 + readinessProbePeriodSeconds: 5 + readinessProbeTimeout: 4 + readinessProbeFailureThreshold: 3 + readinessProbeSuccessThreshold: 1 + livenessProbeInitialDelay: 30 + livenessProbePeriodSeconds: 15 + livenessProbeTimeout: 10 + livenessProbeFailureThreshold: 3 + livenessProbeSuccessThreshold: 1 + startupProbe: + enabled: false + periodSeconds: 5 + failureThreshold: 30 + timeoutSeconds: 10 + + ## Prometheus server resource requests and limits + ## Ref: http://kubernetes.io/docs/user-guide/compute-resources/ + ## + resources: {} + # limits: + # cpu: 500m + # memory: 512Mi + # requests: + # cpu: 500m + # memory: 512Mi + + # Required for use in managed kubernetes clusters (such as AWS EKS) with custom CNI (such as calico), + # because control-plane managed by AWS cannot communicate with pods' IP CIDR and admission webhooks are not working + ## + hostNetwork: false + + # When hostNetwork is enabled, you probably want to set this to ClusterFirstWithHostNet + dnsPolicy: ClusterFirst + + # Use hostPort + # hostPort: 9090 + + ## Vertical Pod Autoscaler config + ## Ref: https://github.com/kubernetes/autoscaler/tree/master/vertical-pod-autoscaler + verticalAutoscaler: + ## If true a VPA object will be created for the controller (either StatefulSet or Deployemnt, based on above configs) + enabled: false + # updateMode: "Auto" + # containerPolicies: + # - containerName: 'prometheus-server' + + # Custom DNS configuration to be added to prometheus server pods + dnsConfig: {} + # nameservers: + # - 1.2.3.4 + # searches: + # - ns1.svc.cluster-domain.example + # - my.dns.search.suffix + # options: + # - name: ndots + # value: "2" + # - name: edns0 + ## Security context to be added to server pods + ## + securityContext: + runAsUser: 65534 + runAsNonRoot: true + runAsGroup: 65534 + fsGroup: 65534 + + service: + annotations: {} + labels: {} + clusterIP: "" + + ## List of IP addresses at which the Prometheus server service is available + ## Ref: https://kubernetes.io/docs/user-guide/services/#external-ips + ## + externalIPs: [] + + loadBalancerIP: "" + loadBalancerSourceRanges: [] + servicePort: 80 + sessionAffinity: None + type: ClusterIP + + ## Enable gRPC port on service to allow auto discovery with thanos-querier + gRPC: + enabled: false + servicePort: 10901 + # nodePort: 10901 + + ## If using a statefulSet (statefulSet.enabled=true), configure the + ## service to connect to a specific replica to have a consistent view + ## of the data. + statefulsetReplica: + enabled: false + replica: 0 + + ## Prometheus server pod termination grace period + ## + terminationGracePeriodSeconds: 300 + + ## Prometheus data retention period (default if not specified is 15 days) + ## + retention: "15d" + +pushgateway: + ## If false, pushgateway will not be installed + ## + enabled: true + + ## Use an alternate scheduler, e.g. "stork". + ## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ + ## + # schedulerName: + + ## pushgateway container name + ## + name: pushgateway + + ## pushgateway container image + ## + image: + repository: prom/pushgateway + tag: v1.4.2 + pullPolicy: IfNotPresent + + ## pushgateway priorityClassName + ## + priorityClassName: "" + + ## Additional pushgateway container arguments + ## + ## for example: persistence.file: /data/pushgateway.data + extraArgs: {} + + ## Additional InitContainers to initialize the pod + ## + extraInitContainers: [] + + ingress: + ## If true, pushgateway Ingress will be created + ## + enabled: false + + # For Kubernetes >= 1.18 you should specify the ingress-controller via the field ingressClassName + # See https://kubernetes.io/blog/2020/04/02/improvements-to-the-ingress-api-in-kubernetes-1.18/#specifying-the-class-of-an-ingress + # ingressClassName: nginx + + ## pushgateway Ingress annotations + ## + annotations: {} + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: 'true' + + ## pushgateway Ingress hostnames with optional path + ## Must be provided if Ingress is enabled + ## + hosts: [] + # - pushgateway.domain.com + # - domain.com/pushgateway + + path: / + + # pathType is only for k8s >= 1.18 + pathType: Prefix + + ## Extra paths to prepend to every host configuration. This is useful when working with annotation based services. + extraPaths: [] + # - path: /* + # backend: + # serviceName: ssl-redirect + # servicePort: use-annotation + + ## pushgateway Ingress TLS configuration + ## Secrets must be manually created in the namespace + ## + tls: [] + # - secretName: prometheus-alerts-tls + # hosts: + # - pushgateway.domain.com + + ## Node tolerations for pushgateway scheduling to nodes with taints + ## Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ + ## + tolerations: [] + # - key: "key" + # operator: "Equal|Exists" + # value: "value" + # effect: "NoSchedule|PreferNoSchedule|NoExecute(1.6 only)" + + ## Node labels for pushgateway pod assignment + ## Ref: https://kubernetes.io/docs/user-guide/node-selection/ + ## + nodeSelector: {} + + ## Annotations to be added to pushgateway pods + ## + podAnnotations: {} + + ## Labels to be added to pushgateway pods + ## + podLabels: {} + + ## Specify if a Pod Security Policy for node-exporter must be created + ## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/ + ## + podSecurityPolicy: + annotations: {} + ## Specify pod annotations + ## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#apparmor + ## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#seccomp + ## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/#sysctl + ## + # seccomp.security.alpha.kubernetes.io/allowedProfileNames: '*' + # seccomp.security.alpha.kubernetes.io/defaultProfileName: 'docker/default' + # apparmor.security.beta.kubernetes.io/defaultProfileName: 'runtime/default' + + replicaCount: 1 + + ## Annotations to be added to deployment + ## + deploymentAnnotations: {} + + ## PodDisruptionBudget settings + ## ref: https://kubernetes.io/docs/concepts/workloads/pods/disruptions/ + ## + podDisruptionBudget: + enabled: false + maxUnavailable: 1 + + ## pushgateway resource requests and limits + ## Ref: http://kubernetes.io/docs/user-guide/compute-resources/ + ## + resources: {} + # limits: + # cpu: 10m + # memory: 32Mi + # requests: + # cpu: 10m + # memory: 32Mi + + ## Vertical Pod Autoscaler config + ## Ref: https://github.com/kubernetes/autoscaler/tree/master/vertical-pod-autoscaler + verticalAutoscaler: + ## If true a VPA object will be created for the controller + enabled: false + # updateMode: "Auto" + # containerPolicies: + # - containerName: 'prometheus-pushgateway' + + # Custom DNS configuration to be added to push-gateway pods + dnsConfig: {} + # nameservers: + # - 1.2.3.4 + # searches: + # - ns1.svc.cluster-domain.example + # - my.dns.search.suffix + # options: + # - name: ndots + # value: "2" + # - name: edns0 + + ## Security context to be added to push-gateway pods + ## + securityContext: + runAsUser: 65534 + runAsNonRoot: true + + service: + annotations: + prometheus.io/probe: pushgateway + labels: {} + clusterIP: "" + + ## List of IP addresses at which the pushgateway service is available + ## Ref: https://kubernetes.io/docs/user-guide/services/#external-ips + ## + externalIPs: [] + + loadBalancerIP: "" + loadBalancerSourceRanges: [] + servicePort: 9091 + type: ClusterIP + + ## pushgateway Deployment Strategy type + # strategy: + # type: Recreate + + persistentVolume: + ## If true, pushgateway will create/use a Persistent Volume Claim + ## + enabled: false + + ## pushgateway data Persistent Volume access modes + ## Must match those of existing PV or dynamic provisioner + ## Ref: http://kubernetes.io/docs/user-guide/persistent-volumes/ + ## + accessModes: + - ReadWriteOnce + + ## pushgateway data Persistent Volume Claim annotations + ## + annotations: {} + + ## pushgateway data Persistent Volume existing claim name + ## Requires pushgateway.persistentVolume.enabled: true + ## If defined, PVC must be created manually before volume will be bound + existingClaim: "" + + ## pushgateway data Persistent Volume mount root path + ## + mountPath: /data + + ## pushgateway data Persistent Volume size + ## + size: 2Gi + + ## pushgateway data Persistent Volume Storage Class + ## If defined, storageClassName: + ## If set to "-", storageClassName: "", which disables dynamic provisioning + ## If undefined (the default) or set to null, no storageClassName spec is + ## set, choosing the default provisioner. (gp2 on AWS, standard on + ## GKE, AWS & OpenStack) + ## + # storageClass: "-" + + ## pushgateway data Persistent Volume Binding Mode + ## If defined, volumeBindingMode: + ## If undefined (the default) or set to null, no volumeBindingMode spec is + ## set, choosing the default mode. + ## + # volumeBindingMode: "" + + ## Subdirectory of pushgateway data Persistent Volume to mount + ## Useful if the volume's root directory is not empty + ## + subPath: "" + + +## alertmanager ConfigMap entries +## +alertmanagerFiles: + alertmanager.yml: + global: {} + # slack_api_url: '' + + receivers: + - name: default-receiver + # slack_configs: + # - channel: '@you' + # send_resolved: true + + route: + group_wait: 10s + group_interval: 5m + receiver: default-receiver + repeat_interval: 3h + +## Prometheus server ConfigMap entries for rule files (allow prometheus labels interpolation) +ruleFiles: {} + +## Prometheus server ConfigMap entries +## +serverFiles: + + ## Alerts configuration + ## Ref: https://prometheus.io/docs/prometheus/latest/configuration/alerting_rules/ + alerting_rules.yml: {} + # groups: + # - name: Instances + # rules: + # - alert: InstanceDown + # expr: up == 0 + # for: 5m + # labels: + # severity: page + # annotations: + # description: '{{ $labels.instance }} of job {{ $labels.job }} has been down for more than 5 minutes.' + # summary: 'Instance {{ $labels.instance }} down' + ## DEPRECATED DEFAULT VALUE, unless explicitly naming your files, please use alerting_rules.yml + alerts: {} + + ## Records configuration + ## Ref: https://prometheus.io/docs/prometheus/latest/configuration/recording_rules/ + recording_rules.yml: {} + ## DEPRECATED DEFAULT VALUE, unless explicitly naming your files, please use recording_rules.yml + rules: {} + + prometheus.yml: + rule_files: + - /etc/config/recording_rules.yml + - /etc/config/alerting_rules.yml + ## Below two files are DEPRECATED will be removed from this default values file + - /etc/config/rules + - /etc/config/alerts + + scrape_configs: + - job_name: prometheus + static_configs: + - targets: + - localhost:9090 + + # A scrape configuration for running Prometheus on a Kubernetes cluster. + # This uses separate scrape configs for cluster components (i.e. API server, node) + # and services to allow each to use different authentication configs. + # + # Kubernetes labels will be added as Prometheus labels on metrics via the + # `labelmap` relabeling action. + + # Scrape config for API servers. + # + # Kubernetes exposes API servers as endpoints to the default/kubernetes + # service so this uses `endpoints` role and uses relabelling to only keep + # the endpoints associated with the default/kubernetes service using the + # default named port `https`. This works for single API server deployments as + # well as HA API server deployments. + - job_name: 'kubernetes-apiservers' + + kubernetes_sd_configs: + - role: endpoints + + # Default to scraping over https. If required, just disable this or change to + # `http`. + scheme: https + + # This TLS & bearer token file config is used to connect to the actual scrape + # endpoints for cluster components. This is separate to discovery auth + # configuration because discovery & scraping are two separate concerns in + # Prometheus. The discovery auth config is automatic if Prometheus runs inside + # the cluster. Otherwise, more config options have to be provided within the + # . + tls_config: + ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + # If your node certificates are self-signed or use a different CA to the + # master CA, then disable certificate verification below. Note that + # certificate verification is an integral part of a secure infrastructure + # so this should only be disabled in a controlled environment. You can + # disable certificate verification by uncommenting the line below. + # + insecure_skip_verify: true + bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + + # Keep only the default/kubernetes service endpoints for the https port. This + # will add targets for each API server which Kubernetes adds an endpoint to + # the default/kubernetes service. + relabel_configs: + - source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name] + action: keep + regex: default;kubernetes;https + + - job_name: 'kubernetes-nodes' + + # Default to scraping over https. If required, just disable this or change to + # `http`. + scheme: https + + # This TLS & bearer token file config is used to connect to the actual scrape + # endpoints for cluster components. This is separate to discovery auth + # configuration because discovery & scraping are two separate concerns in + # Prometheus. The discovery auth config is automatic if Prometheus runs inside + # the cluster. Otherwise, more config options have to be provided within the + # . + tls_config: + ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + # If your node certificates are self-signed or use a different CA to the + # master CA, then disable certificate verification below. Note that + # certificate verification is an integral part of a secure infrastructure + # so this should only be disabled in a controlled environment. You can + # disable certificate verification by uncommenting the line below. + # + insecure_skip_verify: true + bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + + kubernetes_sd_configs: + - role: node + + relabel_configs: + - action: labelmap + regex: __meta_kubernetes_node_label_(.+) + - target_label: __address__ + replacement: kubernetes.default.svc:443 + - source_labels: [__meta_kubernetes_node_name] + regex: (.+) + target_label: __metrics_path__ + replacement: /api/v1/nodes/$1/proxy/metrics + + + - job_name: 'kubernetes-nodes-cadvisor' + + # Default to scraping over https. If required, just disable this or change to + # `http`. + scheme: https + + # This TLS & bearer token file config is used to connect to the actual scrape + # endpoints for cluster components. This is separate to discovery auth + # configuration because discovery & scraping are two separate concerns in + # Prometheus. The discovery auth config is automatic if Prometheus runs inside + # the cluster. Otherwise, more config options have to be provided within the + # . + tls_config: + ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt + # If your node certificates are self-signed or use a different CA to the + # master CA, then disable certificate verification below. Note that + # certificate verification is an integral part of a secure infrastructure + # so this should only be disabled in a controlled environment. You can + # disable certificate verification by uncommenting the line below. + # + insecure_skip_verify: true + bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token + + kubernetes_sd_configs: + - role: node + + # This configuration will work only on kubelet 1.7.3+ + # As the scrape endpoints for cAdvisor have changed + # if you are using older version you need to change the replacement to + # replacement: /api/v1/nodes/$1:4194/proxy/metrics + # more info here https://github.com/coreos/prometheus-operator/issues/633 + relabel_configs: + - action: labelmap + regex: __meta_kubernetes_node_label_(.+) + - target_label: __address__ + replacement: kubernetes.default.svc:443 + - source_labels: [__meta_kubernetes_node_name] + regex: (.+) + target_label: __metrics_path__ + replacement: /api/v1/nodes/$1/proxy/metrics/cadvisor + + # Scrape config for service endpoints. + # + # The relabeling allows the actual service scrape endpoint to be configured + # via the following annotations: + # + # * `prometheus.io/scrape`: Only scrape services that have a value of + # `true`, except if `prometheus.io/scrape-slow` is set to `true` as well. + # * `prometheus.io/scheme`: If the metrics endpoint is secured then you will need + # to set this to `https` & most likely set the `tls_config` of the scrape config. + # * `prometheus.io/path`: If the metrics path is not `/metrics` override this. + # * `prometheus.io/port`: If the metrics are exposed on a different port to the + # service then set this appropriately. + # * `prometheus.io/param_`: If the metrics endpoint uses parameters + # then you can set any parameter + - job_name: 'kubernetes-service-endpoints' + + kubernetes_sd_configs: + - role: endpoints + + relabel_configs: + - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape] + action: keep + regex: true + - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape_slow] + action: drop + regex: true + - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scheme] + action: replace + target_label: __scheme__ + regex: (https?) + - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_path] + action: replace + target_label: __metrics_path__ + regex: (.+) + - source_labels: [__address__, __meta_kubernetes_service_annotation_prometheus_io_port] + action: replace + target_label: __address__ + regex: ([^:]+)(?::\d+)?;(\d+) + replacement: $1:$2 + - action: labelmap + regex: __meta_kubernetes_service_annotation_prometheus_io_param_(.+) + replacement: __param_$1 + - action: labelmap + regex: __meta_kubernetes_service_label_(.+) + - source_labels: [__meta_kubernetes_namespace] + action: replace + target_label: namespace + - source_labels: [__meta_kubernetes_service_name] + action: replace + target_label: service + - source_labels: [__meta_kubernetes_pod_node_name] + action: replace + target_label: node + + # Scrape config for slow service endpoints; same as above, but with a larger + # timeout and a larger interval + # + # The relabeling allows the actual service scrape endpoint to be configured + # via the following annotations: + # + # * `prometheus.io/scrape-slow`: Only scrape services that have a value of `true` + # * `prometheus.io/scheme`: If the metrics endpoint is secured then you will need + # to set this to `https` & most likely set the `tls_config` of the scrape config. + # * `prometheus.io/path`: If the metrics path is not `/metrics` override this. + # * `prometheus.io/port`: If the metrics are exposed on a different port to the + # service then set this appropriately. + # * `prometheus.io/param_`: If the metrics endpoint uses parameters + # then you can set any parameter + - job_name: 'kubernetes-service-endpoints-slow' + + scrape_interval: 5m + scrape_timeout: 30s + + kubernetes_sd_configs: + - role: endpoints + + relabel_configs: + - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape_slow] + action: keep + regex: true + - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scheme] + action: replace + target_label: __scheme__ + regex: (https?) + - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_path] + action: replace + target_label: __metrics_path__ + regex: (.+) + - source_labels: [__address__, __meta_kubernetes_service_annotation_prometheus_io_port] + action: replace + target_label: __address__ + regex: ([^:]+)(?::\d+)?;(\d+) + replacement: $1:$2 + - action: labelmap + regex: __meta_kubernetes_service_annotation_prometheus_io_param_(.+) + replacement: __param_$1 + - action: labelmap + regex: __meta_kubernetes_service_label_(.+) + - source_labels: [__meta_kubernetes_namespace] + action: replace + target_label: namespace + - source_labels: [__meta_kubernetes_service_name] + action: replace + target_label: service + - source_labels: [__meta_kubernetes_pod_node_name] + action: replace + target_label: node + + - job_name: 'prometheus-pushgateway' + honor_labels: true + + kubernetes_sd_configs: + - role: service + + relabel_configs: + - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_probe] + action: keep + regex: pushgateway + + # Example scrape config for probing services via the Blackbox Exporter. + # + # The relabeling allows the actual service scrape endpoint to be configured + # via the following annotations: + # + # * `prometheus.io/probe`: Only probe services that have a value of `true` + - job_name: 'kubernetes-services' + + metrics_path: /probe + params: + module: [http_2xx] + + kubernetes_sd_configs: + - role: service + + relabel_configs: + - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_probe] + action: keep + regex: true + - source_labels: [__address__] + target_label: __param_target + - target_label: __address__ + replacement: blackbox + - source_labels: [__param_target] + target_label: instance + - action: labelmap + regex: __meta_kubernetes_service_label_(.+) + - source_labels: [__meta_kubernetes_namespace] + target_label: namespace + - source_labels: [__meta_kubernetes_service_name] + target_label: service + + # Example scrape config for pods + # + # The relabeling allows the actual pod scrape endpoint to be configured via the + # following annotations: + # + # * `prometheus.io/scrape`: Only scrape pods that have a value of `true`, + # except if `prometheus.io/scrape-slow` is set to `true` as well. + # * `prometheus.io/scheme`: If the metrics endpoint is secured then you will need + # to set this to `https` & most likely set the `tls_config` of the scrape config. + # * `prometheus.io/path`: If the metrics path is not `/metrics` override this. + # * `prometheus.io/port`: Scrape the pod on the indicated port instead of the default of `9102`. + - job_name: 'kubernetes-pods' + + kubernetes_sd_configs: + - role: pod + + relabel_configs: + - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape] + action: keep + regex: true + - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape_slow] + action: drop + regex: true + - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scheme] + action: replace + regex: (https?) + target_label: __scheme__ + - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path] + action: replace + target_label: __metrics_path__ + regex: (.+) + - source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port] + action: replace + regex: ([^:]+)(?::\d+)?;(\d+) + replacement: $1:$2 + target_label: __address__ + - action: labelmap + regex: __meta_kubernetes_pod_annotation_prometheus_io_param_(.+) + replacement: __param_$1 + - action: labelmap + regex: __meta_kubernetes_pod_label_(.+) + - source_labels: [__meta_kubernetes_namespace] + action: replace + target_label: namespace + - source_labels: [__meta_kubernetes_pod_name] + action: replace + target_label: pod + - source_labels: [__meta_kubernetes_pod_phase] + regex: Pending|Succeeded|Failed|Completed + action: drop + + # Example Scrape config for pods which should be scraped slower. An useful example + # would be stackriver-exporter which queries an API on every scrape of the pod + # + # The relabeling allows the actual pod scrape endpoint to be configured via the + # following annotations: + # + # * `prometheus.io/scrape-slow`: Only scrape pods that have a value of `true` + # * `prometheus.io/scheme`: If the metrics endpoint is secured then you will need + # to set this to `https` & most likely set the `tls_config` of the scrape config. + # * `prometheus.io/path`: If the metrics path is not `/metrics` override this. + # * `prometheus.io/port`: Scrape the pod on the indicated port instead of the default of `9102`. + - job_name: 'kubernetes-pods-slow' + + scrape_interval: 5m + scrape_timeout: 30s + + kubernetes_sd_configs: + - role: pod + + relabel_configs: + - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape_slow] + action: keep + regex: true + - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scheme] + action: replace + regex: (https?) + target_label: __scheme__ + - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path] + action: replace + target_label: __metrics_path__ + regex: (.+) + - source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port] + action: replace + regex: ([^:]+)(?::\d+)?;(\d+) + replacement: $1:$2 + target_label: __address__ + - action: labelmap + regex: __meta_kubernetes_pod_annotation_prometheus_io_param_(.+) + replacement: __param_$1 + - action: labelmap + regex: __meta_kubernetes_pod_label_(.+) + - source_labels: [__meta_kubernetes_namespace] + action: replace + target_label: namespace + - source_labels: [__meta_kubernetes_pod_name] + action: replace + target_label: pod + - source_labels: [__meta_kubernetes_pod_phase] + regex: Pending|Succeeded|Failed|Completed + action: drop + +# adds additional scrape configs to prometheus.yml +# must be a string so you have to add a | after extraScrapeConfigs: +# example adds prometheus-blackbox-exporter scrape config +extraScrapeConfigs: + # - job_name: 'prometheus-blackbox-exporter' + # metrics_path: /probe + # params: + # module: [http_2xx] + # static_configs: + # - targets: + # - https://example.com + # relabel_configs: + # - source_labels: [__address__] + # target_label: __param_target + # - source_labels: [__param_target] + # target_label: instance + # - target_label: __address__ + # replacement: prometheus-blackbox-exporter:9115 + +# Adds option to add alert_relabel_configs to avoid duplicate alerts in alertmanager +# useful in H/A prometheus with different external labels but the same alerts +alertRelabelConfigs: + # alert_relabel_configs: + # - source_labels: [dc] + # regex: (.+)\d+ + # target_label: dc + +networkPolicy: + ## Enable creation of NetworkPolicy resources. + ## + enabled: false + +# Force namespace of namespaced resources +forceNamespace: null diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/.helmignore b/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/.helmignore new file mode 100644 index 0000000..50af031 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/.helmignore @@ -0,0 +1,22 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/Chart.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/Chart.yaml new file mode 100644 index 0000000..756c128 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/Chart.yaml @@ -0,0 +1,17 @@ +apiVersion: v2 +appVersion: 2.4.2 +description: Promtail is an agent which ships the contents of local logs to a Loki + instance +home: https://grafana.com/loki +icon: https://raw.githubusercontent.com/grafana/loki/master/docs/sources/logo.png +maintainers: +- email: lokiproject@googlegroups.com + name: Loki Maintainers +- name: unguiculus +name: promtail +sources: +- https://github.com/grafana/loki +- https://grafana.com/oss/loki/ +- https://grafana.com/docs/loki/latest/ +type: application +version: 3.11.0 diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/README.md b/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/README.md new file mode 100644 index 0000000..4a68bd6 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/README.md @@ -0,0 +1,257 @@ +# promtail + +![Version: 3.11.0](https://img.shields.io/badge/Version-3.11.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 2.4.2](https://img.shields.io/badge/AppVersion-2.4.2-informational?style=flat-square) + +Promtail is an agent which ships the contents of local logs to a Loki instance + +## Source Code + +* +* +* + +## Chart Repo + +Add the following repo to use the chart: + +```console +helm repo add grafana https://grafana.github.io/helm-charts +``` + +## Upgrading + +A major chart version change indicates that there is an incompatible breaking change needing manual actions. + +### From Chart Versions < 3.0.0 + +#### Notable Changes + +* Helm 3 is required +* Labels have been updated to follow the official Kubernetes [label recommendations](https://kubernetes.io/docs/concepts/overview/working-with-objects/common-labels/) +* The default scrape configs have been updated to take new and old labels into consideration +* The config file must be specified as string which can be templated. + See below for details +* The config file is now stored in a Secret and no longer in a ConfigMap because it may contain sensitive data, such as basic auth credentials + +Due to the label changes, an existing installation cannot be upgraded without manual interaction. +There are basically two options: + +##### Option 1 + +Uninstall the old release and re-install the new one. +There will be no data loss. +Promtail will cleanly shut down and write the `positions.yaml`. +The new release which will pick up again from the existing `positions.yaml`. + +##### Option 2 + +* Add new selector labels to the existing pods: + + ``` + kubectl label pods -n -l app=promtail,release= app.kubernetes.io/name=promtail app.kubernetes.io/instance= + ``` + +* Perform a non-cascading deletion of the DaemonSet which will keep the pods running: + + ``` + kubectl delete daemonset -n -l app=promtail,release= --cascade=false + ``` + +* Perform a regular Helm upgrade on the existing release. + The new DaemonSet will pick up the existing pods and perform a rolling upgrade. + +## Values + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| affinity | object | `{}` | Affinity configuration for pods | +| annotations | object | `{}` | Annotations for the DaemonSet | +| config | object | See `values.yaml` | Section for crafting Promtails config file. The only directly relevant value is `config.file` which is a templated string that references the other values and snippets below this key. | +| config.file | string | See `values.yaml` | Config file contents for Promtail. Must be configured as string. It is templated so it can be assembled from reusable snippets in order to avoid redundancy. | +| config.logLevel | string | `"info"` | The log level of the Promtail server Must be reference in `config.file` to configure `server.log_level` See default config in `values.yaml` | +| config.lokiAddress | string | `"http://loki-gateway/loki/api/v1/push"` | The Loki address to post logs to. Must be reference in `config.file` to configure `client.url`. See default config in `values.yaml` | +| config.serverPort | int | `3101` | The port of the Promtail server Must be reference in `config.file` to configure `server.http_listen_port` See default config in `values.yaml` | +| config.snippets | object | See `values.yaml` | A section of reusable snippets that can be reference in `config.file`. Custom snippets may be added in order to reduce redundancy. This is especially helpful when multiple `kubernetes_sd_configs` are use which usually have large parts in common. | +| config.snippets.extraClientConfigs | string | empty | You can put here any keys that will be directly added to the config file's 'client' block. | +| config.snippets.extraRelabelConfigs | list | `[]` | You can put here any additional relabel_configs to "kubernetes-pods" job | +| config.snippets.extraScrapeConfigs | string | empty | You can put here any additional scrape configs you want to add to the config file. | +| containerSecurityContext | object | `{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]},"readOnlyRootFilesystem":true}` | The security context for containers | +| defaultVolumeMounts | list | See `values.yaml` | Default volume mounts. Corresponds to `volumes`. | +| defaultVolumes | list | See `values.yaml` | Default volumes that are mounted into pods. In most cases, these should not be changed. Use `extraVolumes`/`extraVolumeMounts` for additional custom volumes. | +| extraArgs | list | `[]` | | +| extraEnv | list | `[]` | Extra environment variables | +| extraEnvFrom | list | `[]` | Extra environment variables from secrets or configmaps | +| extraObjects | list | `[]` | Extra K8s manifests to deploy | +| extraPorts | object | `{}` | Configure additional ports and services. For each configured port, a corresponding service is created. See values.yaml for details | +| extraVolumeMounts | list | `[]` | | +| extraVolumes | list | `[]` | | +| fullnameOverride | string | `nil` | Overrides the chart's computed fullname | +| image.pullPolicy | string | `"IfNotPresent"` | Docker image pull policy | +| image.registry | string | `"docker.io"` | The Docker registry | +| image.repository | string | `"grafana/promtail"` | Docker image repository | +| image.tag | string | `nil` | Overrides the image tag whose default is the chart's appVersion | +| imagePullSecrets | list | `[]` | Image pull secrets for Docker images | +| initContainer.enabled | bool | `false` | Specifies whether the init container for setting inotify max user instances is to be enabled | +| initContainer.fsInotifyMaxUserInstances | int | `128` | The inotify max user instances to configure | +| initContainer.image.pullPolicy | string | `"IfNotPresent"` | Docker image pull policy for the init container image | +| initContainer.image.registry | string | `"docker.io"` | The Docker registry for the init container | +| initContainer.image.repository | string | `"busybox"` | Docker image repository for the init container | +| initContainer.image.tag | float | `1.33` | Docker tag for the init container | +| livenessProbe | object | `{}` | Liveness probe | +| nameOverride | string | `nil` | Overrides the chart's name | +| networkPolicy.enabled | bool | `false` | Specifies whether Network Policies should be created | +| networkPolicy.k8sApi.cidrs | list | `[]` | Specifies specific network CIDRs you want to limit access to | +| networkPolicy.k8sApi.port | int | `8443` | Specify the k8s API endpoint port | +| networkPolicy.metrics.cidrs | list | `[]` | Specifies specific network CIDRs which are allowed to access the metrics port. In case you use namespaceSelector, you also have to specify your kubelet networks here. The metrics ports are also used for probes. | +| networkPolicy.metrics.namespaceSelector | object | `{}` | Specifies the namespaces which are allowed to access the metrics port | +| networkPolicy.metrics.podSelector | object | `{}` | Specifies the Pods which are allowed to access the metrics port. As this is cross-namespace communication, you also neeed the namespaceSelector. | +| nodeSelector | object | `{}` | Node selector for pods | +| podAnnotations | object | `{}` | Pod annotations | +| podLabels | object | `{}` | Pod labels | +| podSecurityContext | object | `{"runAsGroup":0,"runAsUser":0}` | The security context for pods | +| podSecurityPolicy | object | See `values.yaml` | PodSecurityPolicy configuration. | +| priorityClassName | string | `nil` | The name of the PriorityClass | +| rbac.create | bool | `true` | Specifies whether RBAC resources are to be created | +| rbac.pspEnabled | bool | `false` | Specifies whether a PodSecurityPolicy is to be created | +| readinessProbe | object | See `values.yaml` | Readiness probe | +| resources | object | `{}` | Resource requests and limits | +| serviceAccount.annotations | object | `{}` | Annotations for the service account | +| serviceAccount.create | bool | `true` | Specifies whether a ServiceAccount should be created | +| serviceAccount.imagePullSecrets | list | `[]` | Image pull secrets for the service account | +| serviceAccount.name | string | `nil` | The name of the ServiceAccount to use. If not set and `create` is true, a name is generated using the fullname template | +| serviceMonitor.annotations | object | `{}` | ServiceMonitor annotations | +| serviceMonitor.enabled | bool | `false` | If enabled, ServiceMonitor resources for Prometheus Operator are created | +| serviceMonitor.interval | string | `nil` | ServiceMonitor scrape interval | +| serviceMonitor.labels | object | `{}` | Additional ServiceMonitor labels | +| serviceMonitor.namespace | string | `nil` | Alternative namespace for ServiceMonitor resources | +| serviceMonitor.namespaceSelector | object | `{}` | Namespace selector for ServiceMonitor resources | +| serviceMonitor.relabelings | list | `[]` | ServiceMonitor relabel configs to apply to samples before scraping https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#relabelconfig | +| serviceMonitor.scrapeTimeout | string | `nil` | ServiceMonitor scrape timeout in Go duration format (e.g. 15s) | +| tolerations | list | `[{"effect":"NoSchedule","key":"node-role.kubernetes.io/master","operator":"Exists"},{"effect":"NoSchedule","key":"node-role.kubernetes.io/control-plane","operator":"Exists"}]` | Tolerations for pods. By default, pods will be scheduled on master/control-plane nodes. | +| updateStrategy | object | `{}` | The update strategy for the DaemonSet | + +## Configuration + +The config file for Promtail must be configured as string. +This is necessary because the contents are passed through the `tpl` function. +With this, the file can be templated and assembled from reusable YAML snippets. +It is common to have multiple `kubernetes_sd_configs` that, in turn, usually need the same `pipeline_stages`. +Thus, extracting reusable snippets helps reduce redundancy and avoid copy/paste errors. +See `values.yaml´ for details. +Also, the following examples make use of this feature. + +For additional reference, please refer to Promtail's docs: + +https://grafana.com/docs/loki/latest/clients/promtail/configuration/ + +### Syslog Support + +```yaml +extraPorts: + syslog: + name: tcp-syslog + containerPort: 1514 + service: + port: 80 + type: LoadBalancer + externalTrafficPolicy: Local + loadBalancerIP: 123.234.123.234 + +config: + snippets: + extraScrapeConfigs: | + # Add an additional scrape config for syslog + - job_name: syslog + syslog: + listen_address: 0.0.0.0:{{ .Values.extraPorts.syslog.containerPort }} + labels: + job: syslog + relabel_configs: + - source_labels: + - __syslog_message_hostname + target_label: host +``` + +### Journald Support + +```yaml +config: + snippets: + extraScrapeConfigs: | + # Add an additional scrape config for syslog + - job_name: journal + journal: + path: /var/log/journal + max_age: 12h + labels: + job: systemd-journal + relabel_configs: + - source_labels: + - '__journal__systemd_unit' + target_label: 'unit' + - source_labels: + - '__journal__hostname' + target_label: 'hostname' + +# Mount journal directory into promtail pods +extraVolumes: + - name: journal + hostPath: + path: /var/log/journal + +extraVolumeMounts: + - name: journal + mountPath: /var/log/journal + readOnly: true +``` + +### Push API Support + +``` +extraPorts: + httpPush: + name: http-push + containerPort: 3500 + grpcPush: + name: grpc-push + containerPort: 3600 + +config: + file: | + server: + log_level: {{ .Values.config.logLevel }} + http_listen_port: {{ .Values.config.serverPort }} + + client: + url: {{ .Values.config.lokiAddress }} + + positions: + filename: /run/promtail/positions.yaml + + scrape_configs: + {{- tpl .Values.config.snippets.scrapeConfigs . | nindent 2 }} + + - job_name: push1 + loki_push_api: + server: + http_listen_port: {{ .Values.extraPorts.httpPush.containerPort }} + grpc_listen_port: {{ .Values.extraPorts.grpcPush.containerPort }} + labels: + pushserver: push1 +``` + +### Extra client config options + +If you want to add additional options to the `client` section of promtail's config, please use +the `extraClientConfigs` section. For example, to enable HTTP basic auth and include OrgID +header, you can use: + +```yaml +config: + snippets: + extraClientConfigs: | + basic_auth: + username: loki + password: secret + tenant_id: 1 +``` diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/README.md.gotmpl b/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/README.md.gotmpl new file mode 100644 index 0000000..068ba93 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/README.md.gotmpl @@ -0,0 +1,187 @@ +{{ template "chart.header" . }} + +{{ template "chart.versionBadge" . }}{{ template "chart.typeBadge" . }}{{ template "chart.appVersionBadge" . }} + +{{ template "chart.description" . }} + +{{ template "chart.sourcesSection" . }} + +{{ template "chart.requirementsSection" . }} + +## Chart Repo + +Add the following repo to use the chart: + +```console +helm repo add grafana https://grafana.github.io/helm-charts +``` + +## Upgrading + +A major chart version change indicates that there is an incompatible breaking change needing manual actions. + +### From Chart Versions < 3.0.0 + +#### Notable Changes + +* Helm 3 is required +* Labels have been updated to follow the official Kubernetes [label recommendations](https://kubernetes.io/docs/concepts/overview/working-with-objects/common-labels/) +* The default scrape configs have been updated to take new and old labels into consideration +* The config file must be specified as string which can be templated. + See below for details +* The config file is now stored in a Secret and no longer in a ConfigMap because it may contain sensitive data, such as basic auth credentials + +Due to the label changes, an existing installation cannot be upgraded without manual interaction. +There are basically two options: + +##### Option 1 + +Uninstall the old release and re-install the new one. +There will be no data loss. +Promtail will cleanly shut down and write the `positions.yaml`. +The new release which will pick up again from the existing `positions.yaml`. + +##### Option 2 + +* Add new selector labels to the existing pods: + + ``` + kubectl label pods -n -l app=promtail,release= app.kubernetes.io/name=promtail app.kubernetes.io/instance= + ``` + +* Perform a non-cascading deletion of the DaemonSet which will keep the pods running: + + ``` + kubectl delete daemonset -n -l app=promtail,release= --cascade=false + ``` + +* Perform a regular Helm upgrade on the existing release. + The new DaemonSet will pick up the existing pods and perform a rolling upgrade. + +{{ template "chart.valuesSection" . }} + +## Configuration + +The config file for Promtail must be configured as string. +This is necessary because the contents are passed through the `tpl` function. +With this, the file can be templated and assembled from reusable YAML snippets. +It is common to have multiple `kubernetes_sd_configs` that, in turn, usually need the same `pipeline_stages`. +Thus, extracting reusable snippets helps reduce redundancy and avoid copy/paste errors. +See `values.yaml´ for details. +Also, the following examples make use of this feature. + +For additional reference, please refer to Promtail's docs: + +https://grafana.com/docs/loki/latest/clients/promtail/configuration/ + +### Syslog Support + +```yaml +extraPorts: + syslog: + name: tcp-syslog + containerPort: 1514 + service: + port: 80 + type: LoadBalancer + externalTrafficPolicy: Local + loadBalancerIP: 123.234.123.234 + +config: + snippets: + extraScrapeConfigs: | + # Add an additional scrape config for syslog + - job_name: syslog + syslog: + listen_address: 0.0.0.0:{{"{{"}} .Values.extraPorts.syslog.containerPort {{"}}"}} + labels: + job: syslog + relabel_configs: + - source_labels: + - __syslog_message_hostname + target_label: host +``` + +### Journald Support + +```yaml +config: + snippets: + extraScrapeConfigs: | + # Add an additional scrape config for syslog + - job_name: journal + journal: + path: /var/log/journal + max_age: 12h + labels: + job: systemd-journal + relabel_configs: + - source_labels: + - '__journal__systemd_unit' + target_label: 'unit' + - source_labels: + - '__journal__hostname' + target_label: 'hostname' + +# Mount journal directory into promtail pods +extraVolumes: + - name: journal + hostPath: + path: /var/log/journal + +extraVolumeMounts: + - name: journal + mountPath: /var/log/journal + readOnly: true +``` + +### Push API Support + +``` +extraPorts: + httpPush: + name: http-push + containerPort: 3500 + grpcPush: + name: grpc-push + containerPort: 3600 + +config: + file: | + server: + log_level: {{"{{"}} .Values.config.logLevel {{"}}"}} + http_listen_port: {{"{{"}} .Values.config.serverPort {{"}}"}} + + client: + url: {{"{{"}} .Values.config.lokiAddress {{"}}"}} + + positions: + filename: /run/promtail/positions.yaml + + scrape_configs: + {{"{{"}}- tpl .Values.config.snippets.scrapeConfigs . | nindent 2 {{"}}"}} + + - job_name: push1 + loki_push_api: + server: + http_listen_port: {{"{{"}} .Values.extraPorts.httpPush.containerPort {{"}}"}} + grpc_listen_port: {{"{{"}} .Values.extraPorts.grpcPush.containerPort {{"}}"}} + labels: + pushserver: push1 +``` + +### Extra client config options + +If you want to add additional options to the `client` section of promtail's config, please use +the `extraClientConfigs` section. For example, to enable HTTP basic auth and include OrgID +header, you can use: + +```yaml +config: + snippets: + extraClientConfigs: | + basic_auth: + username: loki + password: secret + tenant_id: 1 +``` diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/ci/default-values.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/ci/default-values.yaml new file mode 100644 index 0000000..e69de29 diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/ci/netpol-values.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/ci/netpol-values.yaml new file mode 100644 index 0000000..70d31af --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/ci/netpol-values.yaml @@ -0,0 +1,53 @@ +extraPorts: + syslog: + name: tcp-syslog + containerPort: 1514 + service: + port: 1234 + type: NodePort + httpPush: + name: http-push + containerPort: 3500 + grpcPush: + name: grpc-push + containerPort: 3600 + +config: + snippets: + extraScrapeConfigs: | + - job_name: syslog + syslog: + listen_address: 0.0.0.0:{{ .Values.extraPorts.syslog.containerPort }} + labels: + job: syslog + relabel_configs: + - source_labels: + - __syslog_message_hostname + target_label: host + + - job_name: push1 + loki_push_api: + server: + http_listen_port: {{ .Values.extraPorts.httpPush.containerPort }} + grpc_listen_port: {{ .Values.extraPorts.grpcPush.containerPort }} + labels: + pushserver: push1 + +networkPolicy: + # -- Specifies whether Network Policies should be created + enabled: true + metrics: + # -- Specifies the Pods which are allowed to access the metrics port. + # As this is cross-namespace communication, you also neeed the namespaceSelector. + podSelector: {} + # -- Specifies the namespaces which are allowed to access the metrics port + namespaceSelector: {} + # -- Specifies specific network CIDRs which are allowed to access the metrics port. + # In case you use namespaceSelector, you also have to specify your kubelet networks here. + # The metrics ports are also used for probes. + cidrs: [] + k8sApi: + # -- Specify the k8s API endpoint port + port: 8443 + # -- Specifies specific network CIDRs you want to limit access to + cidrs: [] diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/ci/service-values.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/ci/service-values.yaml new file mode 100644 index 0000000..fd065c9 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/ci/service-values.yaml @@ -0,0 +1,34 @@ +extraPorts: + syslog: + name: tcp-syslog + containerPort: 1514 + service: + port: 1234 + type: NodePort + httpPush: + name: http-push + containerPort: 3500 + grpcPush: + name: grpc-push + containerPort: 3600 + +config: + snippets: + extraScrapeConfigs: | + - job_name: syslog + syslog: + listen_address: 0.0.0.0:{{ .Values.extraPorts.syslog.containerPort }} + labels: + job: syslog + relabel_configs: + - source_labels: + - __syslog_message_hostname + target_label: host + + - job_name: push1 + loki_push_api: + server: + http_listen_port: {{ .Values.extraPorts.httpPush.containerPort }} + grpc_listen_port: {{ .Values.extraPorts.grpcPush.containerPort }} + labels: + pushserver: push1 diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/templates/NOTES.txt b/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/templates/NOTES.txt new file mode 100644 index 0000000..df74044 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/templates/NOTES.txt @@ -0,0 +1,10 @@ +*********************************************************************** + Welcome to Grafana Promtail + Chart version: {{ .Chart.Version }} + Promtail version: {{ .Values.image.tag | default .Chart.AppVersion }} +*********************************************************************** + +Verify the application is working by running these commands: + +* kubectl --namespace {{ .Release.Namespace }} port-forward daemonset/{{ include "promtail.fullname" . }} {{ .Values.config.serverPort }} +* curl http://127.0.0.1:{{ .Values.config.serverPort }}/metrics diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/templates/_helpers.tpl b/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/templates/_helpers.tpl new file mode 100644 index 0000000..36b2c56 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/templates/_helpers.tpl @@ -0,0 +1,80 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "promtail.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 "promtail.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 "promtail.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Common labels +*/}} +{{- define "promtail.labels" -}} +helm.sh/chart: {{ include "promtail.chart" . }} +{{ include "promtail.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "promtail.selectorLabels" -}} +app.kubernetes.io/name: {{ include "promtail.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account +*/}} +{{- define "promtail.serviceAccountName" -}} +{{- if .Values.serviceAccount.create -}} + {{ default (include "promtail.fullname" .) .Values.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +The service name to connect to Loki. Defaults to the same logic as "loki.fullname" +*/}} +{{- define "loki.serviceName" -}} +{{- if .Values.loki.serviceName -}} +{{- .Values.loki.serviceName -}} +{{- else if .Values.loki.fullnameOverride -}} +{{- .Values.loki.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default "loki" .Values.loki.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/templates/clusterrole.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/templates/clusterrole.yaml new file mode 100644 index 0000000..4702e60 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/templates/clusterrole.yaml @@ -0,0 +1,21 @@ +{{- if .Values.rbac.create }} +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ include "promtail.fullname" . }} + labels: + {{- include "promtail.labels" . | nindent 4 }} +rules: + - apiGroups: + - "" + resources: + - nodes + - nodes/proxy + - services + - endpoints + - pods + verbs: + - get + - watch + - list +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/templates/clusterrolebinding.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/templates/clusterrolebinding.yaml new file mode 100644 index 0000000..06054e3 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/templates/clusterrolebinding.yaml @@ -0,0 +1,16 @@ +{{- if .Values.rbac.create }} +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ include "promtail.fullname" . }} + labels: + {{- include "promtail.labels" . | nindent 4 }} +subjects: + - kind: ServiceAccount + name: {{ include "promtail.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: {{ include "promtail.fullname" . }} + apiGroup: rbac.authorization.k8s.io +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/templates/daemonset.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/templates/daemonset.yaml new file mode 100644 index 0000000..f55c162 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/templates/daemonset.yaml @@ -0,0 +1,132 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: {{ include "promtail.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "promtail.labels" . | nindent 4 }} + {{- with .Values.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + selector: + matchLabels: + {{- include "promtail.selectorLabels" . | nindent 6 }} + updateStrategy: + {{- toYaml .Values.updateStrategy | nindent 4 }} + template: + metadata: + labels: + {{- include "promtail.selectorLabels" . | nindent 8 }} + {{- with .Values.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + annotations: + checksum/config: {{ include (print .Template.BasePath "/secret.yaml") . | sha256sum }} + {{- with .Values.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + serviceAccountName: {{ include "promtail.serviceAccountName" . }} + {{- with .Values.priorityClassName }} + priorityClassName: {{ . }} + {{- end }} + {{- if .Values.initContainer.enabled }} + initContainers: + - name: init + image: "{{ .Values.initContainer.image.registry }}/{{ .Values.initContainer.image.repository }}:{{ .Values.initContainer.image.tag }}" + imagePullPolicy: {{ .Values.initContainer.image.pullPolicy }} + command: + - sh + - -c + - sysctl -w fs.inotify.max_user_instances={{ .Values.initContainer.fsInotifyMaxUserInstances }} + securityContext: + privileged: true + {{- end }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: promtail + image: "{{ .Values.image.registry }}/{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + args: + - "-config.file=/etc/promtail/promtail.yaml" + {{- with .Values.extraArgs }} + {{- toYaml . | nindent 12 }} + {{- end }} + volumeMounts: + - name: config + mountPath: /etc/promtail + - name: run + mountPath: /run/promtail + {{- with .Values.defaultVolumeMounts }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.extraVolumeMounts }} + {{- toYaml . | nindent 12 }} + {{- end }} + env: + - name: HOSTNAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + {{- with .Values.extraEnv }} + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.extraEnvFrom }} + envFrom: + {{- toYaml . | nindent 12 }} + {{- end }} + ports: + - name: http-metrics + containerPort: {{ .Values.config.serverPort }} + protocol: TCP + {{- range $key, $values := .Values.extraPorts }} + - name: {{ .name | default $key }} + containerPort: {{ $values.containerPort }} + protocol: {{ $values.protocol | default "TCP" }} + {{- end }} + securityContext: + {{- toYaml .Values.containerSecurityContext | nindent 12 }} + {{- with .Values.livenessProbe }} + livenessProbe: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.readinessProbe }} + readinessProbe: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} + volumes: + - name: config + secret: + secretName: {{ include "promtail.fullname" . }} + - name: run + hostPath: + path: /run/promtail + {{- with .Values.defaultVolumes }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.extraVolumes }} + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/templates/extra-manifests.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/templates/extra-manifests.yaml new file mode 100644 index 0000000..a9bb3b6 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/templates/extra-manifests.yaml @@ -0,0 +1,4 @@ +{{ range .Values.extraObjects }} +--- +{{ tpl (toYaml .) $ }} +{{ end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/templates/networkpolicy.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/templates/networkpolicy.yaml new file mode 100644 index 0000000..103dcc1 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/templates/networkpolicy.yaml @@ -0,0 +1,126 @@ +{{- if .Values.networkPolicy.enabled }} +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ template "promtail.name" . }}-namespace-only + namespace: {{ .Release.Namespace }} + labels: + {{- include "promtail.labels" . | nindent 4 }} +spec: + podSelector: {} + policyTypes: + - Ingress + - Egress + egress: + - to: + - podSelector: {} + ingress: + - from: + - podSelector: {} + + +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ template "promtail.name" . }}-egress-dns + namespace: {{ .Release.Namespace }} + labels: + {{- include "promtail.labels" . | nindent 4 }} +spec: + podSelector: + matchLabels: + {{- include "promtail.selectorLabels" . | nindent 6 }} + policyTypes: + - Egress + egress: + - ports: + - port: 53 + protocol: UDP + to: + - namespaceSelector: {} + +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ template "promtail.name" . }}-egress-k8s-api + namespace: {{ .Release.Namespace }} + labels: + {{- include "promtail.labels" . | nindent 4 }} +spec: + podSelector: + matchLabels: + {{- include "promtail.selectorLabels" . | nindent 6 }} + policyTypes: + - Egress + egress: + - ports: + - port: {{ .Values.networkPolicy.k8sApi.port }} + protocol: TCP + {{- if len .Values.networkPolicy.k8sApi.cidrs }} + to: + {{- range $cidr := .Values.networkPolicy.k8sApi.cidrs }} + - ipBlock: + cidr: {{ $cidr }} + {{- end }} + {{- end }} + +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ template "promtail.name" . }}-ingress-metrics + namespace: {{ .Release.Namespace }} + labels: + {{- include "promtail.labels" . | nindent 4 }} +spec: + podSelector: + matchLabels: + {{- include "promtail.selectorLabels" . | nindent 6 }} + policyTypes: + - Ingress + ingress: + - ports: + - port: http-metrics + protocol: TCP + {{- if len .Values.networkPolicy.metrics.cidrs }} + from: + {{- range $cidr := .Values.networkPolicy.metrics.cidrs }} + - ipBlock: + cidr: {{ $cidr }} + {{- end }} + {{- if .Values.networkPolicy.metrics.namespaceSelector }} + - namespaceSelector: + {{- toYaml .Values.networkPolicy.metrics.namespaceSelector | nindent 12 }} + {{- if .Values.networkPolicy.metrics.podSelector }} + podSelector: + {{- toYaml .Values.networkPolicy.metrics.podSelector | nindent 12 }} + {{- end }} + {{- end }} + {{- end }} + +{{- if .Values.extraPorts }} +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ template "promtail.name" . }}-egress-extra-ports + namespace: {{ .Release.Namespace }} + labels: + {{- include "promtail.labels" . | nindent 4 }} +spec: + podSelector: + matchLabels: + {{- include "promtail.selectorLabels" . | nindent 6 }} + policyTypes: + - Egress + egress: + - ports: + {{- range $extraPortConfig := .Values.extraPorts }} + - port: {{ $extraPortConfig.containerPort }} + protocol: {{ $extraPortConfig.protocol }} + {{- end }} +{{- end }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/templates/podsecuritypolicy.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/templates/podsecuritypolicy.yaml new file mode 100644 index 0000000..b8287cd --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/templates/podsecuritypolicy.yaml @@ -0,0 +1,10 @@ +{{- if and .Values.rbac.create .Values.rbac.pspEnabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ include "promtail.fullname" . }} + labels: + {{- include "promtail.labels" . | nindent 4 }} +spec: + {{- toYaml .Values.podSecurityPolicy | nindent 2 }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/templates/role.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/templates/role.yaml new file mode 100644 index 0000000..02b4a1a --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/templates/role.yaml @@ -0,0 +1,18 @@ +{{- if and .Values.rbac.create .Values.rbac.pspEnabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ include "promtail.fullname" . }}-psp + namespace: {{ .Release.Namespace }} + labels: + {{- include "promtail.labels" . | nindent 4 }} +rules: + - apiGroups: + - policy + resources: + - podsecuritypolicies + verbs: + - use + resourceNames: + - {{ include "promtail.fullname" . }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/templates/rolebinding.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/templates/rolebinding.yaml new file mode 100644 index 0000000..1fdda96 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/templates/rolebinding.yaml @@ -0,0 +1,16 @@ +{{- if and .Values.rbac.create .Values.rbac.pspEnabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ include "promtail.fullname" . }}-psp + namespace: {{ .Release.Namespace }} + labels: + {{- include "promtail.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ include "promtail.fullname" . }}-psp +subjects: + - kind: ServiceAccount + name: {{ include "promtail.serviceAccountName" . }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/templates/secret.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/templates/secret.yaml new file mode 100644 index 0000000..aa519d1 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/templates/secret.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "promtail.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "promtail.labels" . | nindent 4 }} +stringData: + promtail.yaml: | + {{- tpl .Values.config.file . | nindent 4 }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/templates/service-extra.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/templates/service-extra.yaml new file mode 100644 index 0000000..1287d1f --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/templates/service-extra.yaml @@ -0,0 +1,52 @@ +{{- range $key, $values := .Values.extraPorts }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "promtail.fullname" $ }}-{{ $key | lower }} + namespace: {{ $.Release.Namespace }} + labels: + {{- include "promtail.labels" $ | nindent 4 }} + {{- with .labels }} + {{- toYaml $ | nindent 4 }} + {{- end }} + {{- with .annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- with $values.service }} + type: {{ .type | default "ClusterIP" }} + {{- with .clusterIP }} + clusterIP: {{ . }} + {{- end }} + {{- with .loadBalancerIP }} + loadBalancerIP: {{ . }} + {{- end }} + {{- with .loadBalancerSourceRanges }} + loadBalancerSourceRanges: + {{- toYaml . | nindent 4 }} + {{- end -}} + {{- with .externalIPs }} + externalIPs: + {{- toYaml . | nindent 4 }} + {{- end }} + {{- with .externalTrafficPolicy }} + externalTrafficPolicy: {{ . }} + {{- end }} + {{- end }} + ports: + - name: {{ .name | default $key }} + targetPort: {{ .name | default $key }} + protocol: TCP + {{- if $values.service }} + port: {{ $values.service.port | default $values.containerPort }} + {{- if $values.service.nodePort }} + nodePort: {{ $values.service.nodePort }} + {{- end }} + {{- else }} + port: {{ $values.containerPort }} + {{- end }} + selector: + {{- include "promtail.selectorLabels" $ | nindent 4 }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/templates/service-metrics.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/templates/service-metrics.yaml new file mode 100644 index 0000000..bc29a81 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/templates/service-metrics.yaml @@ -0,0 +1,18 @@ +{{- if .Values.serviceMonitor.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "promtail.fullname" . }}-metrics + namespace: {{ .Release.Namespace }} + labels: + {{- include "promtail.labels" . | nindent 4 }} +spec: + clusterIP: None + ports: + - name: http-metrics + port: {{ .Values.config.serverPort }} + targetPort: http-metrics + protocol: TCP + selector: + {{- include "promtail.selectorLabels" . | nindent 4 }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/templates/serviceaccount.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/templates/serviceaccount.yaml new file mode 100644 index 0000000..d566aec --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/templates/serviceaccount.yaml @@ -0,0 +1,17 @@ +{{- if .Values.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "promtail.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "promtail.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- with .Values.serviceAccount.imagePullSecrets }} +imagePullSecrets: + {{- toYaml . | nindent 2 }} +{{- end }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/templates/servicemonitor.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/templates/servicemonitor.yaml new file mode 100644 index 0000000..06235f4 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/templates/servicemonitor.yaml @@ -0,0 +1,40 @@ +{{- if .Values.serviceMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ include "promtail.fullname" $ }} + {{- if .Values.serviceMonitor.namespace }} + namespace: {{ .Values.serviceMonitor.namespace }} + {{- else }} + namespace: {{ .Release.Namespace }} + {{- end }} + {{- with .Values.serviceMonitor.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "promtail.labels" $ | nindent 4 }} + {{- with .Values.serviceMonitor.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- with .Values.serviceMonitor.namespaceSelector }} + namespaceSelector: + {{- toYaml . | nindent 4 }} + {{- end }} + selector: + matchLabels: + {{- include "promtail.selectorLabels" . | nindent 6 }} + endpoints: + - port: http-metrics + {{- with .Values.serviceMonitor.interval }} + interval: {{ . }} + {{- end }} + {{- with .Values.serviceMonitor.scrapeTimeout }} + scrapeTimeout: {{ . }} + {{- end }} + {{- with .Values.serviceMonitor.relabelings }} + relabelings: + {{- toYaml . | nindent 8 }} + {{- end }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/values.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/values.yaml new file mode 100644 index 0000000..c4c6a04 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/charts/promtail/values.yaml @@ -0,0 +1,387 @@ +# -- Overrides the chart's name +nameOverride: null + +# -- Overrides the chart's computed fullname +fullnameOverride: null + +initContainer: + # -- Specifies whether the init container for setting inotify max user instances is to be enabled + enabled: false + image: + # -- The Docker registry for the init container + registry: docker.io + # -- Docker image repository for the init container + repository: busybox + # -- Docker tag for the init container + tag: 1.33 + # -- Docker image pull policy for the init container image + pullPolicy: IfNotPresent + # -- The inotify max user instances to configure + fsInotifyMaxUserInstances: 128 + +image: + # -- The Docker registry + registry: docker.io + # -- Docker image repository + repository: grafana/promtail + # -- Overrides the image tag whose default is the chart's appVersion + tag: null + # -- Docker image pull policy + pullPolicy: IfNotPresent + +# -- Image pull secrets for Docker images +imagePullSecrets: [] + +# -- Annotations for the DaemonSet +annotations: {} + +# -- The update strategy for the DaemonSet +updateStrategy: {} + +# -- Pod labels +podLabels: {} + +# -- Pod annotations +podAnnotations: {} +# prometheus.io/scrape: "true" +# prometheus.io/port: "http-metrics" + +# -- The name of the PriorityClass +priorityClassName: null + +# -- Liveness probe +livenessProbe: {} + +# -- Readiness probe +# @default -- See `values.yaml` +readinessProbe: + failureThreshold: 5 + httpGet: + path: /ready + port: http-metrics + initialDelaySeconds: 10 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 1 + +# -- Resource requests and limits +resources: {} +# limits: +# cpu: 200m +# memory: 128Mi +# requests: +# cpu: 100m +# memory: 128Mi + +# -- The security context for pods +podSecurityContext: + runAsUser: 0 + runAsGroup: 0 + +# -- The security context for containers +containerSecurityContext: + readOnlyRootFilesystem: true + capabilities: + drop: + - ALL + allowPrivilegeEscalation: false + +rbac: + # -- Specifies whether RBAC resources are to be created + create: true + # -- Specifies whether a PodSecurityPolicy is to be created + pspEnabled: false + +serviceAccount: + # -- Specifies whether a ServiceAccount should be created + create: true + # -- The name of the ServiceAccount to use. + # If not set and `create` is true, a name is generated using the fullname template + name: null + # -- Image pull secrets for the service account + imagePullSecrets: [] + # -- Annotations for the service account + annotations: {} + +# -- Node selector for pods +nodeSelector: {} + +# -- Affinity configuration for pods +affinity: {} + +# -- Tolerations for pods. By default, pods will be scheduled on master/control-plane nodes. +tolerations: + - key: node-role.kubernetes.io/master + operator: Exists + effect: NoSchedule + - key: node-role.kubernetes.io/control-plane + operator: Exists + effect: NoSchedule + +# -- Default volumes that are mounted into pods. In most cases, these should not be changed. +# Use `extraVolumes`/`extraVolumeMounts` for additional custom volumes. +# @default -- See `values.yaml` +defaultVolumes: + - name: containers + hostPath: + path: /var/lib/docker/containers + - name: pods + hostPath: + path: /var/log/pods + +# -- Default volume mounts. Corresponds to `volumes`. +# @default -- See `values.yaml` +defaultVolumeMounts: + - name: containers + mountPath: /var/lib/docker/containers + readOnly: true + - name: pods + mountPath: /var/log/pods + readOnly: true + +# Extra volumes to be added in addition to those specified under `defaultVolumes`. +extraVolumes: [] + +# Extra volume mounts together. Corresponds to `extraVolumes`. +extraVolumeMounts: [] + +# Extra args for the Promtail container. +extraArgs: [] +# -- Example: +# -- extraArgs: +# -- - -client.external-labels=hostname=$(HOSTNAME) + +# -- Extra environment variables +extraEnv: [] + +# -- Extra environment variables from secrets or configmaps +extraEnvFrom: [] + +# ServiceMonitor configuration +serviceMonitor: + # -- If enabled, ServiceMonitor resources for Prometheus Operator are created + enabled: false + # -- Alternative namespace for ServiceMonitor resources + namespace: null + # -- Namespace selector for ServiceMonitor resources + namespaceSelector: {} + # -- ServiceMonitor annotations + annotations: {} + # -- Additional ServiceMonitor labels + labels: {} + # -- ServiceMonitor scrape interval + interval: null + # -- ServiceMonitor scrape timeout in Go duration format (e.g. 15s) + scrapeTimeout: null + # -- ServiceMonitor relabel configs to apply to samples before scraping + # https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#relabelconfig + relabelings: [] + +# -- Configure additional ports and services. For each configured port, a corresponding service is created. +# See values.yaml for details +extraPorts: {} +# syslog: +# name: tcp-syslog +# containerPort: 1514 +# protocol: TCP +# service: +# type: ClusterIP +# clusterIP: null +# port: 1514 +# externalIPs: [] +# nodePort: null +# annotations: {} +# labels: {} +# loadBalancerIP: null +# loadBalancerSourceRanges: [] +# externalTrafficPolicy: null + +# -- PodSecurityPolicy configuration. +# @default -- See `values.yaml` +podSecurityPolicy: + privileged: true + allowPrivilegeEscalation: true + volumes: + - 'secret' + - 'hostPath' + - 'downwardAPI' + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'RunAsAny' + fsGroup: + rule: 'RunAsAny' + readOnlyRootFilesystem: true + requiredDropCapabilities: + - ALL + +# -- Section for crafting Promtails config file. The only directly relevant value is `config.file` +# which is a templated string that references the other values and snippets below this key. +# @default -- See `values.yaml` +config: + # -- The log level of the Promtail server + # Must be reference in `config.file` to configure `server.log_level` + # See default config in `values.yaml` + logLevel: info + # -- The port of the Promtail server + # Must be reference in `config.file` to configure `server.http_listen_port` + # See default config in `values.yaml` + serverPort: 3101 + # -- The Loki address to post logs to. + # Must be reference in `config.file` to configure `client.url`. + # See default config in `values.yaml` + lokiAddress: http://loki-gateway/loki/api/v1/push + # -- A section of reusable snippets that can be reference in `config.file`. + # Custom snippets may be added in order to reduce redundancy. + # This is especially helpful when multiple `kubernetes_sd_configs` are use which usually have large parts in common. + # @default -- See `values.yaml` + snippets: + pipelineStages: + - cri: {} + common: + - action: replace + source_labels: + - __meta_kubernetes_pod_node_name + target_label: node_name + - action: replace + source_labels: + - __meta_kubernetes_namespace + target_label: namespace + - action: replace + replacement: $1 + separator: / + source_labels: + - namespace + - app + target_label: job + - action: replace + source_labels: + - __meta_kubernetes_pod_name + target_label: pod + - action: replace + source_labels: + - __meta_kubernetes_pod_container_name + target_label: container + - action: replace + replacement: /var/log/pods/*$1/*.log + separator: / + source_labels: + - __meta_kubernetes_pod_uid + - __meta_kubernetes_pod_container_name + target_label: __path__ + - action: replace + replacement: /var/log/pods/*$1/*.log + regex: true/(.*) + separator: / + source_labels: + - __meta_kubernetes_pod_annotationpresent_kubernetes_io_config_hash + - __meta_kubernetes_pod_annotation_kubernetes_io_config_hash + - __meta_kubernetes_pod_container_name + target_label: __path__ + + # If set to true, adds an additional label for the scrape job. + # This helps debug the Promtail config. + addScrapeJobLabel: false + + # -- You can put here any keys that will be directly added to the config file's 'client' block. + # @default -- empty + extraClientConfigs: "" + + # -- You can put here any additional scrape configs you want to add to the config file. + # @default -- empty + extraScrapeConfigs: "" + + # -- You can put here any additional relabel_configs to "kubernetes-pods" job + extraRelabelConfigs: [] + + scrapeConfigs: | + # See also https://github.com/grafana/loki/blob/master/production/ksonnet/promtail/scrape_config.libsonnet for reference + - job_name: kubernetes-pods + pipeline_stages: + {{- toYaml .Values.config.snippets.pipelineStages | nindent 4 }} + kubernetes_sd_configs: + - role: pod + relabel_configs: + - source_labels: + - __meta_kubernetes_pod_controller_name + regex: ([0-9a-z-.]+?)(-[0-9a-f]{8,10})? + action: replace + target_label: __tmp_controller_name + - source_labels: + - __meta_kubernetes_pod_label_app_kubernetes_io_name + - __meta_kubernetes_pod_label_app + - __tmp_controller_name + - __meta_kubernetes_pod_name + regex: ^;*([^;]+)(;.*)?$ + action: replace + target_label: app + - source_labels: + - __meta_kubernetes_pod_label_app_kubernetes_io_component + - __meta_kubernetes_pod_label_component + regex: ^;*([^;]+)(;.*)?$ + action: replace + target_label: component + {{- if .Values.config.snippets.addScrapeJobLabel }} + - replacement: kubernetes-pods + target_label: scrape_job + {{- end }} + {{- toYaml .Values.config.snippets.common | nindent 4 }} + {{- with .Values.config.snippets.extraRelabelConfigs }} + {{- toYaml . | nindent 4 }} + {{- end }} + + # -- Config file contents for Promtail. + # Must be configured as string. + # It is templated so it can be assembled from reusable snippets in order to avoid redundancy. + # @default -- See `values.yaml` + file: | + server: + log_level: {{ .Values.config.logLevel }} + http_listen_port: {{ .Values.config.serverPort }} + + client: + url: {{ tpl .Values.config.lokiAddress . }} + {{- tpl .Values.config.snippets.extraClientConfigs . | nindent 2 }} + + positions: + filename: /run/promtail/positions.yaml + + scrape_configs: + {{- tpl .Values.config.snippets.scrapeConfigs . | nindent 2 }} + {{- tpl .Values.config.snippets.extraScrapeConfigs . | nindent 2 }} + +networkPolicy: + # -- Specifies whether Network Policies should be created + enabled: false + metrics: + # -- Specifies the Pods which are allowed to access the metrics port. + # As this is cross-namespace communication, you also neeed the namespaceSelector. + podSelector: {} + # -- Specifies the namespaces which are allowed to access the metrics port + namespaceSelector: {} + # -- Specifies specific network CIDRs which are allowed to access the metrics port. + # In case you use namespaceSelector, you also have to specify your kubelet networks here. + # The metrics ports are also used for probes. + cidrs: [] + k8sApi: + # -- Specify the k8s API endpoint port + port: 8443 + # -- Specifies specific network CIDRs you want to limit access to + cidrs: [] + +# -- Extra K8s manifests to deploy +extraObjects: [] + # - apiVersion: "kubernetes-client.io/v1" + # kind: ExternalSecret + # metadata: + # name: promtail-secrets + # spec: + # backendType: gcpSecretsManager + # data: + # - key: promtail-oauth2-creds + # name: client_secret diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/requirements.lock b/helm/openebs/charts/mayastor/charts/loki-stack/requirements.lock new file mode 100644 index 0000000..e218666 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/requirements.lock @@ -0,0 +1,24 @@ +dependencies: +- name: loki + repository: https://grafana.github.io/helm-charts + version: 2.11.0 +- name: promtail + repository: https://grafana.github.io/helm-charts + version: 3.11.0 +- name: fluent-bit + repository: https://grafana.github.io/helm-charts + version: 2.3.1 +- name: grafana + repository: https://grafana.github.io/helm-charts + version: 6.24.1 +- name: prometheus + repository: https://prometheus-community.github.io/helm-charts + version: 15.5.4 +- name: filebeat + repository: https://helm.elastic.co + version: 7.17.1 +- name: logstash + repository: https://helm.elastic.co + version: 7.17.1 +digest: sha256:70bb0bb4d7242cc6be5b31627e1df0e14b7f5a2155eedee00dabce2ba8783308 +generated: "2022-04-15T19:59:54.756674848Z" diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/requirements.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/requirements.yaml new file mode 100644 index 0000000..02519bc --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/requirements.yaml @@ -0,0 +1,29 @@ +dependencies: +- name: "loki" + condition: loki.enabled + repository: "https://grafana.github.io/helm-charts" + version: "^2.10.1" +- name: "promtail" + condition: promtail.enabled + repository: "https://grafana.github.io/helm-charts" + version: "^3.11.0" +- name: "fluent-bit" + condition: fluent-bit.enabled + repository: "https://grafana.github.io/helm-charts" + version: "^2.3.0" +- name: "grafana" + condition: grafana.enabled + version: "~6.24.1" + repository: "https://grafana.github.io/helm-charts" +- name: "prometheus" + condition: prometheus.enabled + version: "~15.5.3" + repository: "https://prometheus-community.github.io/helm-charts" +- name: "filebeat" + condition: filebeat.enabled + version: "~7.17.1" + repository: "https://helm.elastic.co" +- name: "logstash" + condition: logstash.enabled + version: "~7.17.1" + repository: "https://helm.elastic.co" diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/templates/NOTES.txt b/helm/openebs/charts/mayastor/charts/loki-stack/templates/NOTES.txt new file mode 100644 index 0000000..d9cdccb --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/templates/NOTES.txt @@ -0,0 +1,3 @@ +The Loki stack has been deployed to your cluster. Loki can now be added as a datasource in Grafana. + +See http://docs.grafana.org/features/datasources/loki/ for more detail. diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/templates/_helpers.tpl b/helm/openebs/charts/mayastor/charts/loki-stack/templates/_helpers.tpl new file mode 100644 index 0000000..1cb7269 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/templates/_helpers.tpl @@ -0,0 +1,58 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "loki-stack.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 "loki-stack.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 "loki-stack.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Override the naming defined by the prometheus chart. +Added as a fix for https://github.com/grafana/loki/issues/1169 +*/}} +{{- define "prometheus.fullname" -}} +{{- printf "%s-%s" .Release.Name "prometheus-server" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +The service name to connect to Loki. Defaults to the same logic as "loki.fullname" +*/}} +{{- define "loki.serviceName" -}} +{{- if .Values.loki.serviceName -}} +{{- .Values.loki.serviceName -}} +{{- else if .Values.loki.fullnameOverride -}} +{{- .Values.loki.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default "loki" .Values.loki.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/templates/datasources.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/templates/datasources.yaml new file mode 100644 index 0000000..7931619 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/templates/datasources.yaml @@ -0,0 +1,35 @@ +{{- if .Values.grafana.sidecar.datasources.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "loki-stack.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "loki-stack.name" . }} + chart: {{ template "loki-stack.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + grafana_datasource: "1" +data: + loki-stack-datasource.yaml: |- + apiVersion: 1 + datasources: +{{- if .Values.loki.enabled }} + - name: Loki + type: loki + access: proxy + url: http://{{(include "loki.serviceName" .)}}:{{ .Values.loki.service.port }} + version: 1 + isDefault: {{ .Values.loki.isDefault }} + jsonData: + maxLines: {{ .Values.grafana.sidecar.datasources.maxLines }} +{{- end }} +{{- if .Values.prometheus.enabled }} + - name: Prometheus + type: prometheus + access: proxy + url: http://{{ include "prometheus.fullname" .}}:{{ .Values.prometheus.server.service.servicePort }}{{ .Values.prometheus.server.prefixURL }} + version: 1 + isDefault: {{ .Values.prometheus.isDefault }} +{{- end }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/templates/tests/loki-test-configmap.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/templates/tests/loki-test-configmap.yaml new file mode 100644 index 0000000..3e53cfd --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/templates/tests/loki-test-configmap.yaml @@ -0,0 +1,52 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "loki-stack.fullname" . }}-test + labels: + app: {{ template "loki-stack.name" . }} + chart: {{ template "loki-stack.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +data: + test.sh: | + #!/usr/bin/env bash + + LOKI_URI="http://${LOKI_SERVICE}:${LOKI_PORT}" + + function setup() { + apk add -u curl jq + until (curl -s ${LOKI_URI}/api/prom/label/app/values | jq -e '.values[] | select(. == "loki")'); do + sleep 1 + done + } + + @test "Has labels" { + curl -s ${LOKI_URI}/api/prom/label | \ + jq -e '.values[] | select(. == "app")' + } + + @test "Query log entry" { + curl -sG ${LOKI_URI}/api/prom/query?limit=10 --data-urlencode 'query={app="loki"}' | \ + jq -e '.streams[].entries | length >= 1' + } + + @test "Push log entry legacy" { + local timestamp=$(date -Iseconds -u | sed 's/UTC/.000000000+00:00/') + local data=$(jq -n --arg timestamp "${timestamp}" '{"streams": [{"labels": "{app=\"loki-test\"}", "entries": [{"ts": $timestamp, "line": "foobar"}]}]}') + + curl -s -X POST -H "Content-Type: application/json" ${LOKI_URI}/api/prom/push -d "${data}" + + curl -sG ${LOKI_URI}/api/prom/query?limit=1 --data-urlencode 'query={app="loki-test"}' | \ + jq -e '.streams[].entries[].line == "foobar"' + } + + @test "Push log entry" { + local timestamp=$(date +%s000000000) + local data=$(jq -n --arg timestamp "${timestamp}" '{"streams": [{"stream": {"app": "loki-test"}, "values": [[$timestamp, "foobar"]]}]}') + + curl -s -X POST -H "Content-Type: application/json" ${LOKI_URI}/loki/api/v1/push -d "${data}" + + curl -sG ${LOKI_URI}/api/prom/query?limit=1 --data-urlencode 'query={app="loki-test"}' | \ + jq -e '.streams[].entries[].line == "foobar"' + } + diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/templates/tests/loki-test-pod.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/templates/tests/loki-test-pod.yaml new file mode 100644 index 0000000..a153a05 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/templates/tests/loki-test-pod.yaml @@ -0,0 +1,30 @@ +apiVersion: v1 +kind: Pod +metadata: + annotations: + "helm.sh/hook": test-success + labels: + app: {{ template "loki-stack.name" . }} + chart: {{ template "loki-stack.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + name: {{ template "loki-stack.fullname" . }}-test +spec: + containers: + - name: test + image: bats/bats:v1.1.0 + args: + - /var/lib/loki/test.sh + env: + - name: LOKI_SERVICE + value: {{ template "loki.serviceName" . }} + - name: LOKI_PORT + value: "{{ .Values.loki.service.port }}" + volumeMounts: + - name: tests + mountPath: /var/lib/loki + restartPolicy: Never + volumes: + - name: tests + configMap: + name: {{ template "loki-stack.fullname" . }}-test diff --git a/helm/openebs/charts/mayastor/charts/loki-stack/values.yaml b/helm/openebs/charts/mayastor/charts/loki-stack/values.yaml new file mode 100644 index 0000000..afc84c3 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/loki-stack/values.yaml @@ -0,0 +1,74 @@ +loki: + enabled: true + isDefault: true + +promtail: + enabled: true + config: + lokiAddress: http://{{ .Release.Name }}:3100/loki/api/v1/push + +fluent-bit: + enabled: false + +grafana: + enabled: false + sidecar: + datasources: + enabled: true + maxLines: 1000 + image: + tag: 8.3.5 + +prometheus: + enabled: false + isDefault: false + +filebeat: + enabled: false + filebeatConfig: + filebeat.yml: | + # logging.level: debug + filebeat.inputs: + - type: container + paths: + - /var/log/containers/*.log + processors: + - add_kubernetes_metadata: + host: ${NODE_NAME} + matchers: + - logs_path: + logs_path: "/var/log/containers/" + output.logstash: + hosts: ["logstash-loki:5044"] + +logstash: + enabled: false + image: grafana/logstash-output-loki + imageTag: 1.0.1 + filters: + main: |- + filter { + if [kubernetes] { + mutate { + add_field => { + "container_name" => "%{[kubernetes][container][name]}" + "namespace" => "%{[kubernetes][namespace]}" + "pod" => "%{[kubernetes][pod][name]}" + } + replace => { "host" => "%{[kubernetes][node][name]}"} + } + } + mutate { + remove_field => ["tags"] + } + } + outputs: + main: |- + output { + loki { + url => "http://loki:3100/loki/api/v1/push" + #username => "test" + #password => "test" + } + # stdout { codec => rubydebug } + } diff --git a/helm/openebs/charts/mayastor/charts/nats/.helmignore b/helm/openebs/charts/mayastor/charts/nats/.helmignore new file mode 100644 index 0000000..50af031 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/nats/.helmignore @@ -0,0 +1,22 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/helm/openebs/charts/mayastor/charts/nats/Chart.yaml b/helm/openebs/charts/mayastor/charts/nats/Chart.yaml new file mode 100644 index 0000000..0a2626c --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/nats/Chart.yaml @@ -0,0 +1,16 @@ +apiVersion: v2 +appVersion: 2.9.17 +description: A Helm chart for the NATS.io High Speed Cloud Native Distributed Communications + Technology. +home: http://github.com/nats-io/k8s +icon: https://nats.io/img/nats-icon-color.png +keywords: +- nats +- messaging +- cncf +maintainers: +- email: info@nats.io + name: The NATS Authors + url: https://github.com/nats-io +name: nats +version: 0.19.14 diff --git a/helm/openebs/charts/mayastor/charts/nats/README.md b/helm/openebs/charts/mayastor/charts/nats/README.md new file mode 100644 index 0000000..5c8aed2 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/nats/README.md @@ -0,0 +1,918 @@ +# NATS Server + +[NATS](https://nats.io) is a simple, secure and performant communications system for digital systems, services and devices. NATS is part of the Cloud Native Computing Foundation ([CNCF](https://cncf.io)). NATS has over [30 client language implementations](https://nats.io/download/), and its server can run on-premise, in the cloud, at the edge, and even on a Raspberry Pi. NATS can secure and simplify design and operation of modern distributed systems. + +## TL;DR; + +```console +helm repo add nats https://nats-io.github.io/k8s/helm/charts/ +helm install my-nats nats/nats +``` + +## Breaking Change Log + +- **0.15.0**: For users with JetStream enabled (`nats.jetstream.enabled = true`): `nats.jetstream.fileStorage.enabled` now defaults to `true` and `nats.jetstream.fileStorage.size` now defaults to `10Gi`. This updates the StatefulSet `spec.volumeClaimTemplates` field, which is immutable and cannot be changed on an existing StatefulSet; to upgrade from an older chart version, add the value: + ```yaml + nats: + jetstream: + fileStorage: + # add if enabled was previously the default setting + # not recommended; it would be better to migrate to a StatefulSet with storage enabled + enabled: false + # add if size was previously the default setting + size: 1Gi + ``` +- **0.12.0**: The `podManagementPolicy` value was introduced and set to `Parallel` by default, which controls the StatefulSet `spec.podManagementPolicy` field. This field is immutable and cannot be changed on an existing StatefulSet; to upgrade from an older chart version, add the value: + ```yaml + podManagementPolicy: OrderedReady + ``` + +## Configuration + +### Server Image + +```yaml +# use a specific versions +nats: + image: + tag: X.Y.Z-alpine + +# fully custom location +nats: + image: + registry: my.custom.registry + repository: my-nats + tag: latest + pullPolicy: Always +``` + +### Limits + +```yaml +nats: + # The number of connect attempts against discovered routes. + connectRetries: 30 + + # How many seconds should pass before sending a PING + # to a client that has no activity. + pingInterval: + + # Server settings. + limits: + maxConnections: + maxSubscriptions: + maxControlLine: + maxPayload: + + writeDeadline: + maxPending: + maxPings: + lameDuckDuration: + + # Number of seconds to wait for client connections to end after the pod termination is requested + terminationGracePeriodSeconds: 60 +``` + +#### Setting Go Memory Limit (Recommended) + +Since NATS Server v2.9 release, it is possible to use the `GOMEMLIMIT` environment variable to signal memory limits to the Go runtime (which is by default unaware of cgroups memory limits). You should set this to about 90% of the intended available memory resources for the NATS Server container. + +```yaml +nats: + gomemlimit: "4GiB" +``` + +### Logging + +*Note*: It is not recommended to enable trace or debug in production since enabling it will significantly degrade performance. + +```yaml +nats: + logging: + debug: + trace: + logtime: + connectErrorReports: + reconnectErrorReports: +``` + +### TLS setup for client connections + +You can find more on how to setup and trouble shoot TLS connnections at: +https://docs.nats.io/nats-server/configuration/securing_nats/tls + +```yaml +nats: + tls: + secret: + name: nats-client-tls + ca: "ca.crt" + cert: "tls.crt" + key: "tls.key" +``` + +## Clustering + +If clustering is enabled, then a 3-node cluster will be setup. More info at: +https://docs.nats.io/nats-server/configuration/clustering#nats-server-clustering + +```yaml +cluster: + enabled: true + replicas: 3 + + tls: + secret: + name: nats-server-tls + ca: "ca.crt" + cert: "tls.crt" + key: "tls.key" +``` + +Example: + +```sh +$ helm install nats nats/nats --set cluster.enabled=true +``` + +## Leafnodes + +Leafnode connections to extend a cluster. More info at: +https://docs.nats.io/nats-server/configuration/leafnodes + +```yaml +leafnodes: + enabled: true + remotes: + - url: "tls://connect.ngs.global:7422" + # credentials: + # secret: + # name: leafnode-creds + # key: TA.creds + # tls: + # secret: + # name: nats-leafnode-tls + # ca: "ca.crt" + # cert: "tls.crt" + # key: "tls.key" + + ####################### + # # + # TLS Configuration # + # # + ####################### + # + # # You can find more on how to setup and trouble shoot TLS connnections at: + # + # # https://docs.nats.io/nats-server/configuration/securing_nats/tls + # + tls: + secret: + name: nats-client-tls + ca: "ca.crt" + cert: "tls.crt" + key: "tls.key" +``` + +## Setting up External Access + +### Using HostPorts + +In case of both external access and advertisements being enabled, an +initializer container will be used to gather the public ips. This +container will required to have enough RBAC policy to be able to make a +look up of the public ip of the node where it is running. + +For example, to setup external access for a cluster and advertise the public ip to clients: + +```yaml +nats: + # Toggle whether to enable external access. + # This binds a host port for clients, gateways and leafnodes. + externalAccess: true + + # Toggle to disable client advertisements (connect_urls), + # in case of running behind a load balancer + # it might be required to disable advertisements. + advertise: true + + # In case both external access and advertise are enabled + # then a service account would be required to be able to + # gather the public ip from a node. + serviceAccount: "nats-server" +``` + +Where the service account named `nats-server` has the following RBAC policy for example: + +```yaml +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: nats-server + namespace: default +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: nats-server +rules: +- apiGroups: [""] + resources: + - nodes + verbs: ["get"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: nats-server-binding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: nats-server +subjects: +- kind: ServiceAccount + name: nats-server + namespace: default +``` + +The container image of the initializer can be customized via: + +```yaml +bootconfig: + image: + tag: X.Y.Z +``` + +### Using LoadBalancers + +In case of using a load balancer for external access, it is recommended to disable no advertise +so that internal ips from the NATS Servers are not advertised to the clients connecting through +the load balancer. + +```yaml +cluster: + enabled: true + noAdvertise: true + +leafnodes: + enabled: true + noAdvertise: true + +natsbox: + enabled: true +``` + +Then could use an L4 enabled load balancer to connect to NATS, for example: + +```yaml +apiVersion: v1 +kind: Service +metadata: + name: nats-lb +spec: + type: LoadBalancer + selector: + app.kubernetes.io/name: nats + ports: + - protocol: TCP + port: 4222 + targetPort: 4222 + name: nats + - protocol: TCP + port: 7422 + targetPort: 7422 + name: leafnodes + - protocol: TCP + port: 7522 + targetPort: 7522 + name: gateways +``` + +### Using NATS Chart as a Dependency + +In order to fully manage your deployment through Helm, you can use `nats` as a [helm dependency](https://helm.sh/docs/helm/helm_dependency/#helm-dependency). This is our recommend approach for exposing your NATS deployment with Services or WebSocket Ingresses. + +1. Example uses a helm chart named `mynats` (example: `helm create mynats`) +2. In `Chart.yaml` add the following dependencies block + ```yaml + dependencies: + - name: nats + version: 0.18.0 + repository: https://nats-io.github.io/k8s/helm/charts/ + ``` +3. Run `helm dep update` now (and any time you update the `nats` dependency version) +4. Add `nats` settings to the `values.yaml` file: + ```yaml + # notice the extra nats key here, must match the dependency name in Chart.yaml + nats: + nats: + jetstream: + enabled: true + cluster: + enabled: true + # disable cluster advertisements when running behind a load balancer + noAdvertise: true + + # add whatever other nats settings you need here + ``` +5. Add a template for your service to `templates/service-lb.yaml`: + ```yaml + apiVersion: v1 + kind: Service + metadata: + name: {{ include "mynats.fullname" . }}-lb + labels: + {{- include "mynats.labels" . | nindent 4 }} + spec: + type: LoadBalancer + selector: + {{- include "nats.selectorLabels" .Subcharts.nats | nindent 4 }} + ports: + - name: nats + port: 4222 + protocol: TCP + targetPort: 4222 + ``` + +## Gateways + +A super cluster can be formed by pointing to remote gateways. +You can find more about gateways in the NATS documentation: +https://docs.nats.io/nats-server/configuration/gateways + +> ⚠️ Note: When using Gateways and JetStream make sure that the deployment name is different so that the generated server names do not collide. + +```yaml +gateway: + enabled: false + name: 'default' + + ############################# + # # + # List of remote gateways # + # # + ############################# + # gateways: + # - name: other + # url: nats://my-gateway-url:7522 + + ####################### + # # + # TLS Configuration # + # # + ####################### + # + # # You can find more on how to setup and trouble shoot TLS connnections at: + # + # # https://docs.nats.io/nats-server/configuration/securing_nats/tls + # + # tls: + # secret: + # name: nats-client-tls + # ca: "ca.crt" + # cert: "tls.crt" + # key: "tls.key" +``` + +## Auth setup + +### Auth with a Memory Resolver + +```yaml +auth: + enabled: true + + # Reference to the Operator JWT. + operatorjwt: + configMap: + name: operator-jwt + key: KO.jwt + + # Public key of the System Account + systemAccount: + + resolver: + ############################ + # # + # Memory resolver settings # + # # + ############################## + type: memory + + # + # Use a configmap reference which will be mounted + # into the container. + # + configMap: + name: nats-accounts + key: resolver.conf +``` + +### Auth using an Account Server Resolver + +```yaml +auth: + enabled: true + + # Reference to the Operator JWT. + operatorjwt: + configMap: + name: operator-jwt + key: KO.jwt + + # Public key of the System Account + systemAccount: + + resolver: + ########################## + # # + # URL resolver settings # + # # + ########################## + type: URL + url: "http://nats-account-server:9090/jwt/v1/accounts/" +``` + +## JetStream + +### Setting up Memory and File Storage + +File Storage is **always** recommended, since JetStream's RAFT Meta Group will be persisted to file storage. The Storage Class used should be block storage. NFS is not recommended. + +```yaml +nats: + jetstream: + enabled: true + + memStorage: + enabled: true + size: 2Gi + + fileStorage: + enabled: true + size: 10Gi + # storageClassName: gp2 # NOTE: AWS setup but customize as needed for your infra. +``` + +### Using with an existing PersistentVolumeClaim + +For example, given the following `PersistentVolumeClaim`: + +```yaml +--- +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: + name: nats-js-disk + annotations: + volume.beta.kubernetes.io/storage-class: "default" +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 3Gi +``` + +You can start JetStream so that one pod is bounded to it: + +```yaml +nats: + jetstream: + enabled: true + + fileStorage: + enabled: true + storageDirectory: /data/ + existingClaim: nats-js-disk + claimStorageSize: 3Gi +``` + +### Clustering example + +```yaml + +nats: + jetstream: + enabled: true + + memStorage: + enabled: true + size: "2Gi" + + fileStorage: + enabled: true + size: "10Gi" + +cluster: + enabled: true + # Cluster name is required, by default will be release name. + # name: "nats" + replicas: 3 +``` + +### Basic Authentication and JetStream + +```yaml +nats: + jetstream: + enabled: true + + memStorage: + enabled: true + size: "2Gi" + + fileStorage: + enabled: true + size: "10Gi" + # storageClassName: gp2 # NOTE: AWS setup but customize as needed for your infra. + +cluster: + enabled: true + # Can set a custom cluster name + # name: "nats" + replicas: 3 + +auth: + enabled: true + + systemAccount: "$SYS" + + basic: + accounts: + $SYS: + users: + - user: sys + pass: sys + js: + jetstream: true + users: + - user: foo +``` + +### NATS Resolver setup example + +As of NATS v2.2, the server now has a built-in NATS resolver of accounts. +The following is an example guide of how to get it configured. + +```sh +# Create a working directory to keep the creds. +mkdir nats-creds +cd nats-creds + +# This just creates some accounts for you to get started. +curl -fSl https://nats-io.github.io/k8s/setup/nsc-setup.sh | sh +source .nsc.env + +# You should have some accounts now, at least the following. +nsc list accounts ++-------------------------------------------------------------------+ +| Accounts | ++--------+----------------------------------------------------------+ +| Name | Public Key | ++--------+----------------------------------------------------------+ +| A | ABJ4OIKBBFCNXZDP25C7EWXCXOVCYYAGBEHFAG7F5XYCOYPHZLNSJYDF | +| B | ACVRK7GFBRQUCB3NEABGQ7XPNED2BSPT27GOX5QBDYW2NOFMQKK755DJ | +| SYS | ADGFH4NYV5V75SVM5DYSW5AWOD7H2NRUWAMO6XLZKIDGUWYEXCZG5D6N | ++--------+----------------------------------------------------------+ + +# Now create an account with JetStream support +export account=JS1 +nsc add account --name $account +nsc edit account --name $account --js-disk-storage -1 --js-consumer -1 --js-streams -1 +nsc add user -a $account js-user +``` + +Next, generate the NATS resolver config. This will be used to fill in the values of the YAML in the Helm template. +For example the result of generating this: + +```sh +nsc generate config --sys-account SYS --nats-resolver + +# Operator named KO +operator: eyJ0eXAiOiJKV1QiLCJhbGciOiJlZDI1NTE5LW5rZXkifQ.eyJqdGkiOiJDRlozRlE0WURNTUc1Q1UzU0FUWVlHWUdQUDJaQU1QUzVNRUdNWFdWTUJFWUdIVzc2WEdBIiwiaWF0IjoxNjMyNzgzMDk2LCJpc3MiOiJPQ0lWMlFGSldJTlpVQVQ1VDJZSkJJUkMzQjZKS01TWktRTkY1S0dQNE4zS1o0RkZEVkFXWVhDTCIsIm5hbWUiOiJLTyIsInN1YiI6Ik9DSVYyUUZKV0lOWlVBVDVUMllKQklSQzNCNkpLTVNaS1FORjVLR1A0TjNLWjRGRkRWQVdZWENMIiwibmF0cyI6eyJ0eXBlIjoib3BlcmF0b3IiLCJ2ZXJzaW9uIjoyfX0.e3gvJ-C1IBznmbUljeT_wbLRl1akv5IGBS3rbxs6mzzTvf3zlqQI4wDKVE8Gvb8qfTX6TIwocClfOqNaN3k3CQ + +# System Account named SYS +system_account: ADGFH4NYV5V75SVM5DYSW5AWOD7H2NRUWAMO6XLZKIDGUWYEXCZG5D6N + +resolver_preload: { + ADGFH4NYV5V75SVM5DYSW5AWOD7H2NRUWAMO6XLZKIDGUWYEXCZG5D6N: eyJ0eXAiOiJKV1QiLCJhbGciOiJlZDI1NTE5LW5rZXkifQ.eyJqdGkiOiJDR0tWVzJGQUszUE5XQTRBWkhHT083UTdZWUVPQkJYNDZaTU1VSFc1TU5QSUFVSFE0RVRRIiwiaWF0IjoxNjMyNzgzMDk2LCJpc3MiOiJPQ0lWMlFGSldJTlpVQVQ1VDJZSkJJUkMzQjZKS01TWktRTkY1S0dQNE4zS1o0RkZEVkFXWVhDTCIsIm5hbWUiOiJTWVMiLCJzdWIiOiJBREdGSDROWVY1Vjc1U1ZNNURZU1c1QVdPRDdIMk5SVVdBTU82WExaS0lER1VXWUVYQ1pHNUQ2TiIsIm5hdHMiOnsibGltaXRzIjp7InN1YnMiOi0xLCJkYXRhIjotMSwicGF5bG9hZCI6LTEsImltcG9ydHMiOi0xLCJleHBvcnRzIjotMSwid2lsZGNhcmRzIjp0cnVlLCJjb25uIjotMSwibGVhZiI6LTF9LCJkZWZhdWx0X3Blcm1pc3Npb25zIjp7InB1YiI6e30sInN1YiI6e319LCJ0eXBlIjoiYWNjb3VudCIsInZlcnNpb24iOjJ9fQ.J7g73TEn-ZT13owq4cVWl4l0hZnGK4DJtH2WWOZmGbefcCQ1xsx4cIagKc1cZTCwUpELVAYnSkmPp4LsQOspBg, +} +``` + +In the YAML would be configured as follows: + +``` +auth: + enabled: true + + timeout: "5s" + + resolver: + type: full + + operator: eyJ0eXAiOiJKV1QiLCJhbGciOiJlZDI1NTE5LW5rZXkifQ.eyJqdGkiOiJDRlozRlE0WURNTUc1Q1UzU0FUWVlHWUdQUDJaQU1QUzVNRUdNWFdWTUJFWUdIVzc2WEdBIiwiaWF0IjoxNjMyNzgzMDk2LCJpc3MiOiJPQ0lWMlFGSldJTlpVQVQ1VDJZSkJJUkMzQjZKS01TWktRTkY1S0dQNE4zS1o0RkZEVkFXWVhDTCIsIm5hbWUiOiJLTyIsInN1YiI6Ik9DSVYyUUZKV0lOWlVBVDVUMllKQklSQzNCNkpLTVNaS1FORjVLR1A0TjNLWjRGRkRWQVdZWENMIiwibmF0cyI6eyJ0eXBlIjoib3BlcmF0b3IiLCJ2ZXJzaW9uIjoyfX0.e3gvJ-C1IBznmbUljeT_wbLRl1akv5IGBS3rbxs6mzzTvf3zlqQI4wDKVE8Gvb8qfTX6TIwocClfOqNaN3k3CQ + + systemAccount: ADGFH4NYV5V75SVM5DYSW5AWOD7H2NRUWAMO6XLZKIDGUWYEXCZG5D6N + + store: + dir: "/etc/nats-config/accounts/jwt" + size: "1Gi" + + resolverPreload: + ADGFH4NYV5V75SVM5DYSW5AWOD7H2NRUWAMO6XLZKIDGUWYEXCZG5D6N: eyJ0eXAiOiJKV1QiLCJhbGciOiJlZDI1NTE5LW5rZXkifQ.eyJqdGkiOiJDR0tWVzJGQUszUE5XQTRBWkhHT083UTdZWUVPQkJYNDZaTU1VSFc1TU5QSUFVSFE0RVRRIiwiaWF0IjoxNjMyNzgzMDk2LCJpc3MiOiJPQ0lWMlFGSldJTlpVQVQ1VDJZSkJJUkMzQjZKS01TWktRTkY1S0dQNE4zS1o0RkZEVkFXWVhDTCIsIm5hbWUiOiJTWVMiLCJzdWIiOiJBREdGSDROWVY1Vjc1U1ZNNURZU1c1QVdPRDdIMk5SVVdBTU82WExaS0lER1VXWUVYQ1pHNUQ2TiIsIm5hdHMiOnsibGltaXRzIjp7InN1YnMiOi0xLCJkYXRhIjotMSwicGF5bG9hZCI6LTEsImltcG9ydHMiOi0xLCJleHBvcnRzIjotMSwid2lsZGNhcmRzIjp0cnVlLCJjb25uIjotMSwibGVhZiI6LTF9LCJkZWZhdWx0X3Blcm1pc3Npb25zIjp7InB1YiI6e30sInN1YiI6e319LCJ0eXBlIjoiYWNjb3VudCIsInZlcnNpb24iOjJ9fQ.J7g73TEn-ZT13owq4cVWl4l0hZnGK4DJtH2WWOZmGbefcCQ1xsx4cIagKc1cZTCwUpELVAYnSkmPp4LsQOspBg +``` + +Now we start the server with the NATS Account Resolver (`auth.resolver.type=full`): + +```yaml +nats: + logging: + debug: false + trace: false + + jetstream: + enabled: true + + memStorage: + enabled: true + size: "2Gi" + + fileStorage: + enabled: true + size: "10Gi" + # storageClassName: gp2 # NOTE: AWS setup but customize as needed for your infra. + +cluster: + enabled: true + # Can set a custom cluster name + name: "nats" + replicas: 3 + +auth: + enabled: true + + timeout: "5s" + + resolver: + type: full + + operator: eyJ0eXAiOiJKV1QiLCJhbGciOiJlZDI1NTE5LW5rZXkifQ.eyJqdGkiOiJDRlozRlE0WURNTUc1Q1UzU0FUWVlHWUdQUDJaQU1QUzVNRUdNWFdWTUJFWUdIVzc2WEdBIiwiaWF0IjoxNjMyNzgzMDk2LCJpc3MiOiJPQ0lWMlFGSldJTlpVQVQ1VDJZSkJJUkMzQjZKS01TWktRTkY1S0dQNE4zS1o0RkZEVkFXWVhDTCIsIm5hbWUiOiJLTyIsInN1YiI6Ik9DSVYyUUZKV0lOWlVBVDVUMllKQklSQzNCNkpLTVNaS1FORjVLR1A0TjNLWjRGRkRWQVdZWENMIiwibmF0cyI6eyJ0eXBlIjoib3BlcmF0b3IiLCJ2ZXJzaW9uIjoyfX0.e3gvJ-C1IBznmbUljeT_wbLRl1akv5IGBS3rbxs6mzzTvf3zlqQI4wDKVE8Gvb8qfTX6TIwocClfOqNaN3k3CQ + + systemAccount: ADGFH4NYV5V75SVM5DYSW5AWOD7H2NRUWAMO6XLZKIDGUWYEXCZG5D6N + + store: + dir: "/etc/nats-config/accounts/jwt" + size: "1Gi" + + resolverPreload: + ADGFH4NYV5V75SVM5DYSW5AWOD7H2NRUWAMO6XLZKIDGUWYEXCZG5D6N: eyJ0eXAiOiJKV1QiLCJhbGciOiJlZDI1NTE5LW5rZXkifQ.eyJqdGkiOiJDR0tWVzJGQUszUE5XQTRBWkhHT083UTdZWUVPQkJYNDZaTU1VSFc1TU5QSUFVSFE0RVRRIiwiaWF0IjoxNjMyNzgzMDk2LCJpc3MiOiJPQ0lWMlFGSldJTlpVQVQ1VDJZSkJJUkMzQjZKS01TWktRTkY1S0dQNE4zS1o0RkZEVkFXWVhDTCIsIm5hbWUiOiJTWVMiLCJzdWIiOiJBREdGSDROWVY1Vjc1U1ZNNURZU1c1QVdPRDdIMk5SVVdBTU82WExaS0lER1VXWUVYQ1pHNUQ2TiIsIm5hdHMiOnsibGltaXRzIjp7InN1YnMiOi0xLCJkYXRhIjotMSwicGF5bG9hZCI6LTEsImltcG9ydHMiOi0xLCJleHBvcnRzIjotMSwid2lsZGNhcmRzIjp0cnVlLCJjb25uIjotMSwibGVhZiI6LTF9LCJkZWZhdWx0X3Blcm1pc3Npb25zIjp7InB1YiI6e30sInN1YiI6e319LCJ0eXBlIjoiYWNjb3VudCIsInZlcnNpb24iOjJ9fQ.J7g73TEn-ZT13owq4cVWl4l0hZnGK4DJtH2WWOZmGbefcCQ1xsx4cIagKc1cZTCwUpELVAYnSkmPp4LsQOspBg +``` + +Finally, using a local port-forward make it possible to establish a connection to one of the servers and upload the accounts. + +```sh +nsc push --system-account SYS -u nats://localhost:4222 -A +[ OK ] push to nats-server "nats://localhost:4222" using system account "SYS": + [ OK ] push JS1 to nats-server with nats account resolver: + [ OK ] pushed "JS1" to nats-server nats-0: jwt updated + [ OK ] pushed "JS1" to nats-server nats-1: jwt updated + [ OK ] pushed "JS1" to nats-server nats-2: jwt updated + [ OK ] pushed to a total of 3 nats-server +``` + +Now you should be able to use JetStream and the NATS based account resolver: + +```sh +nats stream ls -s localhost --creds ./nsc/nkeys/creds/KO/JS1/js-user.creds +No Streams defined +``` + +## Misc + +### NATS Box + +A lightweight container with NATS and NATS Streaming utilities that is deployed along the cluster to confirm the setup. +You can find the image at: https://github.com/nats-io/nats-box + +```yaml +natsbox: + enabled: true + image: + tag: X.Y.Z + + # credentials: + # secret: + # name: nats-sys-creds + # key: sys.creds +``` + +You can also add volumes to nats-box, for example given a PVC like: + +```yaml +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: nsc-pvc +spec: + accessModes: + - ReadWriteOnce + volumeMode: Filesystem + resources: + requests: + storage: 1Gi +``` + +You can give state to nats-box by using the `extraVolumes` and `extraVolumeMounts` options: + +```yaml +natsbox: + enabled: true + extraVolumes: + - name: nsc + persistentVolumeClaim: + claimName: nsc-pvc + extraVolumeMounts: + - mountPath: /nsc + name: nsc +``` + +example: + +```sh +$ helm install nats-nsc nats/nats -f examples/nats-box-persistent.yaml +$ kubectl exec -it deployment/nats-nsc-box -- /bin/sh + +# cd /nsc +/nsc # curl -fSl https://nats-io.github.io/k8s/setup/nsc-setup.sh | sh +/nsc # source .nsc.env +/nsc # nsc list accounts +``` + +### Configuration Checksum + +A configuration checksum annotation is enabled by default on StatefulSet Pods in order to force a rollout when the NATS configuration changes. This checksum is only applied by `helm` commands, and will not change if configuration is modified outside of setting `helm` values. + +```yaml +nats: + configChecksumAnnotation: true +``` + +### Configuration Reload sidecar + +The NATS configuration reload sidecar is enabled by default; it passes the configuration reload signal to the NATS server when it detects configuration changes: + +```yaml +reloader: + enabled: true + image: + tag: X.Y.Z +``` + +### Prometheus Exporter sidecar + +The Prometheus Exporter sidecar is enabled by default; it can be used to feed metrics to Prometheus: + +```yaml +exporter: + enabled: true + image: + tag: X.Y.Z +``` + +### Prometheus operator ServiceMonitor support + +You can enable prometheus operator ServiceMonitor: + +```yaml +exporter: + # You have to enable exporter first + enabled: true + serviceMonitor: + enabled: true + ## Specify the namespace where Prometheus Operator is running + # namespace: monitoring + # ... +``` + +### Pod Customizations + +#### Security Context + +```yaml + # Toggle whether to use setup a Pod Security Context + # ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ +securityContext: + fsGroup: 1000 + runAsUser: 1000 + runAsNonRoot: true +``` + +#### Affinity + + + +`matchExpressions` must be configured according to your setup + +```yaml +affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: node.kubernetes.io/purpose + operator: In + values: + - nats + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: app + operator: In + values: + - nats + - stan + topologyKey: "kubernetes.io/hostname" +``` + +#### Service topology + +[Service topology](https://kubernetes.io/docs/concepts/services-networking/service-topology/) is disabled by default, but can be enabled by setting `topologyKeys`. For example: + +```yaml +topologyKeys: + - "kubernetes.io/hostname" + - "topology.kubernetes.io/zone" + - "topology.kubernetes.io/region" +``` + +#### CPU/Memory Resource Requests/Limits +Sets the pods cpu/memory requests/limits + +```yaml +nats: + resources: + requests: + cpu: 4 + memory: 8Gi + limits: + cpu: 6 + memory: 10Gi +``` + +No resources are set by default. It is recommended for NATS JetStream deployments to allocate at least 8Gi of memory and 4 cpus. + +#### Annotations + + + +```yaml +podAnnotations: + key1 : "value1", + key2 : "value2" +``` + +### Name Overides + +Can change the name of the resources as needed with: + +```yaml +nameOverride: "my-nats" +``` + +### Image Pull Secrets + +```yaml +imagePullSecrets: +- name: myRegistry +``` + +Adds this to the StatefulSet: + +```yaml +spec: + imagePullSecrets: + - name: myRegistry +``` + +### Mixed TLS and non TLS mode + +You can use the `nats.tls.allowNonTLS` option to allow a cluster to use TLS connections +and plain connections: + +```yaml +nats: + client: + port: 4222 + + tls: + allowNonTLS: true + secret: + name: nats-server-tls + ca: "ca.crt" + cert: "tls.crt" + key: "tls.key" + timeout: "5s" +``` diff --git a/helm/openebs/charts/mayastor/charts/nats/templates/NOTES.txt b/helm/openebs/charts/mayastor/charts/nats/templates/NOTES.txt new file mode 100644 index 0000000..694dc67 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/nats/templates/NOTES.txt @@ -0,0 +1,26 @@ + +{{- if or .Values.nats.logging.debug .Values.nats.logging.trace }} +*WARNING*: Keep in mind that running the server with +debug and/or trace enabled significantly affects the +performance of the server! +{{- end }} + +You can find more information about running NATS on Kubernetes +in the NATS documentation website: + + https://docs.nats.io/nats-on-kubernetes/nats-kubernetes + +{{- if .Values.natsbox.enabled }} + +NATS Box has been deployed into your cluster, you can +now use the NATS tools within the container as follows: + + kubectl exec -n {{ template "nats.namespace" . }} -it deployment/{{ template "nats.fullname" . }}-box -- /bin/sh -l + + nats-box:~# nats sub test & + nats-box:~# nats pub test hi + nats-box:~# nc {{ template "nats.fullname" . }} {{ .Values.nats.client.port }} + +{{- end }} + +Thanks for using NATS! diff --git a/helm/openebs/charts/mayastor/charts/nats/templates/_helpers.tpl b/helm/openebs/charts/mayastor/charts/nats/templates/_helpers.tpl new file mode 100644 index 0000000..9f177b8 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/nats/templates/_helpers.tpl @@ -0,0 +1,256 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "nats.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{- define "nats.namespace" -}} +{{- default .Release.Namespace .Values.namespaceOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + + +{{- define "nats.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 "nats.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "nats.labels" -}} +helm.sh/chart: {{ include "nats.chart" . }} +{{- range $name, $value := .Values.commonLabels }} +{{ $name }}: {{ tpl $value $ }} +{{- end }} +{{ include "nats.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "nats.selectorLabels" -}} +{{- if .Values.nats.selectorLabels }} +{{ tpl (toYaml .Values.nats.selectorLabels) . }} +{{- else -}} +app.kubernetes.io/name: {{ include "nats.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} +{{- end }} + + +{{/* +Return the proper NATS image name +*/}} +{{- define "nats.clusterAdvertise" -}} +{{- if $.Values.useFQDN }} +{{- printf "$(POD_NAME).%s.$(POD_NAMESPACE).svc.%s" (include "nats.fullname" . ) $.Values.k8sClusterDomain }} +{{- else }} +{{- printf "$(POD_NAME).%s.$(POD_NAMESPACE)" (include "nats.fullname" . ) }} +{{- end }} +{{- end }} + +{{/* +Return the NATS cluster auth. +*/}} +{{- define "nats.clusterAuth" -}} +{{- if $.Values.cluster.authorization }} +{{- printf "%s:%s@" (urlquery $.Values.cluster.authorization.user) (urlquery $.Values.cluster.authorization.password) -}} +{{- else }} +{{- end }} +{{- end }} + +{{/* +Return the NATS cluster routes. +*/}} +{{- define "nats.clusterRoutes" -}} +{{- $name := (include "nats.fullname" . ) -}} +{{- $namespace := (include "nats.namespace" . ) -}} +{{- $clusterAuth := (include "nats.clusterAuth" . ) -}} +{{- range $i, $e := until (.Values.cluster.replicas | int) -}} +{{- if $.Values.useFQDN }} +{{- printf "nats://%s%s-%d.%s.%s.svc.%s:6222," $clusterAuth $name $i $name $namespace $.Values.k8sClusterDomain -}} +{{- else }} +{{- printf "nats://%s%s-%d.%s.%s:6222," $clusterAuth $name $i $name $namespace -}} +{{- end }} +{{- end -}} +{{- end }} + +{{- define "nats.extraRoutes" -}} +{{- range $i, $url := .Values.cluster.extraRoutes -}} +{{- printf "%s," $url -}} +{{- end -}} +{{- end }} + +{{- define "nats.tlsConfig" -}} +tls { +{{- if .cert }} + cert_file: {{ .secretPath }}/{{ .secret.name }}/{{ .cert }} +{{- end }} +{{- if .key }} + key_file: {{ .secretPath }}/{{ .secret.name }}/{{ .key }} +{{- end }} +{{- if .ca }} + ca_file: {{ .secretPath }}/{{ .secret.name }}/{{ .ca }} +{{- end }} +{{- if .insecure }} + insecure: {{ .insecure }} +{{- end }} +{{- if .verify }} + verify: {{ .verify }} +{{- end }} +{{- if .verifyAndMap }} + verify_and_map: {{ .verifyAndMap }} +{{- end }} +{{- if .verifyCertAndCheckKnownUrls }} + verify_cert_and_check_known_urls: {{ .verifyCertAndCheckKnownUrls }} +{{- end }} +{{- if .curvePreferences }} + curve_preferences: {{ .curvePreferences }} +{{- end }} +{{- if .timeout }} + timeout: {{ .timeout }} +{{- end }} +{{- if .cipherSuites }} + cipher_suites: {{ toRawJson .cipherSuites }} +{{- end }} +} +{{- end }} + +{{- define "nats.tlsReloaderArgs" -}} +{{ $secretName := .secret.name }} +{{ $secretPath := .secretPath }} +{{- with .ca }} +- -config +- {{ $secretPath }}/{{ $secretName }}/{{ . }} +{{- end }} +{{- with .cert }} +- -config +- {{ $secretPath }}/{{ $secretName }}/{{ . }} +{{- end }} +{{- with .key }} +- -config +- {{ $secretPath }}/{{ $secretName }}/{{ . }} +{{- end }} +{{- end }} + +{{- define "nats.tlsVolumeMounts" -}} +{{- with .Values.nats.tls }} +####################### +# # +# TLS Volumes Mounts # +# # +####################### +{{ $secretName := tpl .secret.name $ }} +- name: {{ $secretName }}-clients-volume + mountPath: /etc/nats-certs/clients/{{ $secretName }} +{{- end }} +{{- with .Values.mqtt.tls }} +{{ $secretName := tpl .secret.name $ }} +- name: {{ $secretName }}-mqtt-volume + mountPath: /etc/nats-certs/mqtt/{{ $secretName }} +{{- end }} +{{- with .Values.cluster.tls }} +{{- if not .custom }} +{{ $secretName := tpl .secret.name $ }} +- name: {{ $secretName }}-cluster-volume + mountPath: /etc/nats-certs/cluster/{{ $secretName }} +{{- end }} +{{- end }} +{{- with .Values.leafnodes.tls }} +{{- if not .custom }} +{{ $secretName := tpl .secret.name $ }} +- name: {{ $secretName }}-leafnodes-volume + mountPath: /etc/nats-certs/leafnodes/{{ $secretName }} +{{- end }} +{{- end }} +{{- with .Values.gateway.tls }} +{{ $secretName := tpl .secret.name $ }} +- name: {{ $secretName }}-gateways-volume + mountPath: /etc/nats-certs/gateways/{{ $secretName }} +{{- end }} +{{- with .Values.websocket.tls }} +{{ $secretName := tpl .secret.name $ }} +- name: {{ $secretName }}-ws-volume + mountPath: /etc/nats-certs/ws/{{ $secretName }} +{{- end }} +{{- end }} + +{{/* +Return the appropriate apiVersion for networkpolicy. +*/}} +{{- define "networkPolicy.apiVersion" -}} +{{- if semverCompare ">=1.4-0, <1.7-0" .Capabilities.KubeVersion.GitVersion -}} +{{- print "extensions/v1beta1" -}} +{{- else -}} +{{- print "networking.k8s.io/v1" -}} +{{- end -}} +{{- end -}} + +{{/* +Renders a value that contains template. +Usage: +{{ include "tplvalues.render" ( dict "value" .Values.path.to.the.Value "context" $) }} +*/}} +{{- define "tplvalues.render" -}} + {{- if typeIs "string" .value }} + {{- tpl .value .context }} + {{- else }} + {{- tpl (toYaml .value) .context }} + {{- end }} +{{- end -}} + + +{{/* +Create the name of the service account to use +*/}} +{{- define "nats.serviceAccountName" -}} +{{- if .Values.nats.serviceAccount.create }} +{{- default (include "nats.fullname" .) .Values.nats.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.nats.serviceAccount.name }} +{{- end }} +{{- end }} + +{{/* +Fix image keys for chart versions <= 0.18.3 +*/}} +{{- define "nats.fixImage" -}} +{{- if kindIs "string" .image }} +{{- $_ := set . "image" (dict "repository" (split ":" .image)._0 "tag" ((split ":" .image)._1 | default "latest") "pullPolicy" "IfNotPresent") }} +{{- end }} +{{- if kindIs "string" .pullPolicy }} +{{- $_ := set .image "pullPolicy" .pullPolicy }} +{{- $_ := unset . "pullPolicy" }} +{{- end }} +{{- end }} + +{{/* +Print the image +*/}} +{{- define "nats.image" -}} +{{- $image := printf "%s:%s" .repository .tag }} +{{- if .registry }} +{{- $image = printf "%s/%s" .registry $image }} +{{- end }} +{{- $image -}} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/nats/templates/configmap.yaml b/helm/openebs/charts/mayastor/charts/nats/templates/configmap.yaml new file mode 100644 index 0000000..d2f4cc3 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/nats/templates/configmap.yaml @@ -0,0 +1,614 @@ +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "nats.fullname" . }}-config + namespace: {{ include "nats.namespace" . }} + labels: + {{- include "nats.labels" . | nindent 4 }} +data: + nats.conf: | + # NATS Clients Port + port: {{ .Values.nats.client.port }} + + # PID file shared with configuration reloader. + pid_file: "/var/run/nats/nats.pid" + + {{- if .Values.nats.config }} + ########### + # # + # Imports # + # # + ########### + {{- range .Values.nats.config }} + include ./{{ .name }}/{{ .name }}.conf + {{- end}} + {{- end }} + + ############### + # # + # Monitoring # + # # + ############### + http: 8222 + server_name: {{- if .Values.nats.serverNamePrefix }}$SERVER_NAME{{- else }}$POD_NAME{{- end }} + + {{- if .Values.nats.serverTags }} + server_tags: [ + {{- range .Values.nats.serverTags }} + "{{ . }}", + {{- end }} + ] + {{- end }} + + {{- if .Values.nats.tls }} + ##################### + # # + # TLS Configuration # + # # + ##################### + {{- with .Values.nats.tls }} + {{- $nats_tls := merge (dict) . }} + {{- $_ := set $nats_tls "secretPath" "/etc/nats-certs/clients" }} + {{- tpl (include "nats.tlsConfig" $nats_tls) $ | nindent 4}} + {{- end }} + + {{- if .Values.nats.tls.allowNonTLS }} + allow_non_tls: {{ .Values.nats.tls.allowNonTLS }} + {{- end }} + + {{- end }} + + {{- if .Values.nats.jetstream.enabled }} + ################################### + # # + # NATS JetStream # + # # + ################################### + jetstream { + {{- if .Values.nats.jetstream.encryption }} + {{- if .Values.nats.jetstream.encryption.key }} + key: {{ .Values.nats.jetstream.encryption.key | quote }} + {{- else if .Values.nats.jetstream.encryption.secret }} + key: $JS_KEY + {{- end}} + {{- if .Values.nats.jetstream.encryption.cipher }} + cipher: {{ .Values.nats.jetstream.encryption.cipher }} + {{- end}} + {{- end}} + + {{- if .Values.nats.jetstream.memStorage.enabled }} + max_mem: {{ .Values.nats.jetstream.memStorage.size }} + {{- end }} + + {{- if .Values.nats.jetstream.domain }} + domain: {{ .Values.nats.jetstream.domain }} + {{- end }} + + {{- if .Values.nats.jetstream.fileStorage.enabled }} + store_dir: {{ .Values.nats.jetstream.fileStorage.storageDirectory }} + + max_file: + {{- if .Values.nats.jetstream.fileStorage.existingClaim }} + {{- .Values.nats.jetstream.fileStorage.claimStorageSize }} + {{- else }} + {{- .Values.nats.jetstream.fileStorage.size }} + {{- end }} + {{- else }} + {{- if .Values.nats.jetstream.store_dir }} + store_dir: {{ .Values.nats.jetstream.store_dir }} + {{- end }} + {{- if .Values.nats.jetstream.max_file }} + max_file: {{ .Values.nats.jetstream.max_file }} + {{- end }} + {{- end }} + + {{- if .Values.nats.jetstream.uniqueTag }} + unique_tag: {{ .Values.nats.jetstream.uniqueTag }} + {{- end }} + + {{- if .Values.nats.jetstream.maxOutstandingCatchup }} + max_outstanding_catchup: {{ .Values.nats.jetstream.maxOutstandingCatchup }} + {{- end }} + } + {{- end }} + + {{- if .Values.nats.mappings }} + ################################### + # # + # Mappings # + # # + ################################### + mappings: {{ toRawJson .Values.nats.mappings }} + {{- end }} + + {{- if .Values.mqtt.enabled }} + ################################### + # # + # NATS MQTT # + # # + ################################### + mqtt { + port: 1883 + + {{- with .Values.mqtt.tls }} + {{- $mqtt_tls := merge (dict) . }} + {{- $_ := set $mqtt_tls "secretPath" "/etc/nats-certs/mqtt" }} + {{- tpl (include "nats.tlsConfig" $mqtt_tls) $ | nindent 6}} + {{- end }} + + {{- if .Values.mqtt.noAuthUser }} + no_auth_user: {{ .Values.mqtt.noAuthUser | quote }} + {{- end }} + + ack_wait: {{ .Values.mqtt.ackWait | quote }} + max_ack_pending: {{ .Values.mqtt.maxAckPending }} + } + {{- end }} + + {{- if .Values.cluster.enabled }} + ################################### + # # + # NATS Full Mesh Clustering Setup # + # # + ################################### + cluster { + port: 6222 + + {{- if .Values.nats.jetstream.enabled }} + {{- if .Values.cluster.name }} + name: {{ .Values.cluster.name }} + {{- else }} + name: {{ template "nats.name" . }} + {{- end }} + {{- else }} + {{- with .Values.cluster.name }} + name: {{ . }} + {{- end }} + {{- end }} + + {{- with .Values.cluster.tls }} + {{- $cluster_tls := merge (dict) . }} + {{- $_ := set $cluster_tls "secretPath" "/etc/nats-certs/cluster" }} + {{- tpl (include "nats.tlsConfig" $cluster_tls) $ | nindent 6}} + {{- end }} + + {{- if .Values.cluster.authorization }} + authorization { + {{- with .Values.cluster.authorization.user }} + user: {{ . }} + {{- end }} + {{- with .Values.cluster.authorization.password }} + password: {{ . }} + {{- end }} + {{- with .Values.cluster.authorization.timeout }} + timeout: {{ . }} + {{- end }} + } + {{- end }} + + routes = [ + {{ include "nats.clusterRoutes" . }} + {{ include "nats.extraRoutes" . }} + ] + cluster_advertise: $CLUSTER_ADVERTISE + + {{- with .Values.cluster.noAdvertise }} + no_advertise: {{ . }} + {{- end }} + + connect_retries: {{ .Values.nats.connectRetries }} + } + {{- end }} + + {{- if and .Values.nats.advertise .Values.nats.externalAccess }} + include "advertise/client_advertise.conf" + {{- end }} + + {{- if or .Values.leafnodes.enabled .Values.leafnodes.remotes }} + ################# + # # + # NATS Leafnode # + # # + ################# + leafnodes { + {{- if .Values.leafnodes.enabled }} + listen: "0.0.0.0:{{ .Values.leafnodes.port }}" + {{- end }} + + {{- if and .Values.nats.advertise .Values.nats.externalAccess }} + include "advertise/gateway_advertise.conf" + {{- end }} + + {{- with .Values.leafnodes.noAdvertise }} + no_advertise: {{ . }} + {{- end }} + + {{- with .Values.leafnodes.authorization }} + authorization: { + {{- with .user }} + user: {{ . }} + {{- end }} + {{- with .password }} + password: {{ . }} + {{- end }} + {{- with .account }} + account: {{ . | quote }} + {{- end }} + {{- with .timeout }} + timeout: {{ . }} + {{- end }} + {{- with .users }} + users: [ + {{- range . }} + {{- toRawJson . | nindent 10 }}, + {{- end }} + ] + {{- end }} + } + {{- end }} + + {{- with .Values.leafnodes.tls }} + {{- if .custom }} + tls { + {{- .custom | nindent 8 }} + } + {{- else }} + {{- $leafnode_tls := merge (dict) . }} + {{- $_ := set $leafnode_tls "secretPath" "/etc/nats-certs/leafnodes" }} + {{- tpl (include "nats.tlsConfig" $leafnode_tls) $ | nindent 6}} + {{- end }} + {{- end }} + + remotes: [ + {{- range .Values.leafnodes.remotes }} + { + {{- with .url }} + url: {{ . | quote }} + {{- end }} + + {{- with .urls }} + urls: {{ toRawJson . }} + {{- end }} + + {{- with .account }} + account: {{ . | quote }} + {{- end }} + + {{- with .credentials }} + credentials: "/etc/nats-creds/{{ .secret.name }}/{{ .secret.key }}" + {{- end }} + + {{- with .tls }} + tls: { + {{- if .custom }} + {{- .custom | nindent 10 }} + {{- else }} + {{ $secretName := tpl .secret.name $ }} + {{- with .cert }} + cert_file: /etc/nats-certs/leafnodes/{{ $secretName }}/{{ . }} + {{- end }} + + {{- with .key }} + key_file: /etc/nats-certs/leafnodes/{{ $secretName }}/{{ . }} + {{- end }} + + {{- with .ca }} + ca_file: /etc/nats-certs/leafnodes/{{ $secretName }}/{{ . }} + {{- end }} + {{- end }} + } + {{- end }} + } + {{- end }} + ] + } + {{- end }} + + {{- if .Values.gateway.enabled }} + ################# + # # + # NATS Gateways # + # # + ################# + gateway { + name: {{ .Values.gateway.name }} + port: {{ .Values.gateway.port }} + + {{- if .Values.gateway.advertise }} + advertise: {{ .Values.gateway.advertise }} + {{- end }} + + {{- if .Values.gateway.rejectUnknownCluster }} + reject_unknown_cluster: {{ .Values.gateway.rejectUnknownCluster }} + {{- end }} + + {{- if .Values.gateway.authorization }} + authorization { + {{- with .Values.gateway.authorization.user }} + user: {{ . }} + {{- end }} + {{- with .Values.gateway.authorization.password }} + password: {{ . }} + {{- end }} + {{- with .Values.gateway.authorization.timeout }} + timeout: {{ . }} + {{- end }} + } + {{- end }} + + {{- if and .Values.nats.advertise .Values.nats.externalAccess }} + include "advertise/gateway_advertise.conf" + {{- end }} + + {{- if .Values.gateway.connectRetries }} + connect_retries: {{ .Values.gateway.connectRetries }} + {{- end }} + + {{- with .Values.gateway.tls }} + {{- $gateway_tls := merge (dict) . }} + {{- $_ := set $gateway_tls "secretPath" "/etc/nats-certs/gateways" }} + {{- tpl (include "nats.tlsConfig" $gateway_tls) $ | nindent 6}} + {{- end }} + + # Gateways array here + gateways: [ + {{- range .Values.gateway.gateways }} + { + {{- with .name }} + name: {{ . }} + {{- end }} + + {{- with .url }} + url: {{ . | quote }} + {{- end }} + + {{- with .urls }} + urls: [{{ join "," . }}] + {{- end }} + }, + {{- end }} + ] + } + {{- end }} + + {{- with .Values.nats.logging.debug }} + debug: {{ . }} + {{- end }} + + {{- with .Values.nats.logging.trace }} + trace: {{ . }} + {{- end }} + + {{- with .Values.nats.logging.logtime }} + logtime: {{ . }} + {{- end }} + + {{- with .Values.nats.logging.connectErrorReports }} + connect_error_reports: {{ . }} + {{- end }} + + {{- with .Values.nats.logging.reconnectErrorReports }} + reconnect_error_reports: {{ . }} + {{- end }} + + {{- with .Values.nats.limits.maxConnections }} + max_connections: {{ . }} + {{- end }} + + {{- with .Values.nats.limits.maxSubscriptions }} + max_subscriptions: {{ . }} + {{- end }} + + {{- with .Values.nats.limits.maxPending }} + max_pending: {{ . }} + {{- end }} + + {{- with .Values.nats.limits.maxControlLine }} + max_control_line: {{ . }} + {{- end }} + + {{- with .Values.nats.limits.maxPayload }} + max_payload: {{ . }} + {{- end }} + + {{- with .Values.nats.limits.pingInterval }} + ping_interval: {{ . }} + {{- end }} + + {{- with .Values.nats.limits.maxPings }} + ping_max: {{ . }} + {{- end }} + + {{- with .Values.nats.limits.writeDeadline }} + write_deadline: {{ . }} + {{- end }} + + {{- with .Values.nats.limits.lameDuckGracePeriod }} + lame_duck_grace_period: {{ . }} + {{- end }} + + {{- with .Values.nats.limits.lameDuckDuration }} + lame_duck_duration: {{ . }} + {{- end }} + + {{- if .Values.websocket.enabled }} + ################## + # # + # Websocket # + # # + ################## + websocket { + port: {{ .Values.websocket.port }} + {{- with .Values.websocket.tls }} + {{ $secretName := tpl .secret.name $ }} + tls { + {{- with .cert }} + cert_file: /etc/nats-certs/ws/{{ $secretName }}/{{ . }} + {{- end }} + + {{- with .key }} + key_file: /etc/nats-certs/ws/{{ $secretName }}/{{ . }} + {{- end }} + + {{- with .ca }} + ca_file: /etc/nats-certs/ws/{{ $secretName }}/{{ . }} + {{- end }} + } + {{- else }} + no_tls: {{ .Values.websocket.noTLS }} + {{- end }} + same_origin: {{ .Values.websocket.sameOrigin }} + {{- with .Values.websocket.allowedOrigins }} + allowed_origins: {{ toRawJson . }} + {{- end }} + {{- with .Values.websocket.advertise }} + advertise: {{ . }} + {{- end }} + {{- with .Values.websocket.handshakeTimeout }} + handshake_timeout: {{ . | quote }} + {{- end }} + } + {{- end }} + + {{- if .Values.auth.enabled }} + ################## + # # + # Authorization # + # # + ################## + {{- if .Values.auth.resolver }} + {{- if eq .Values.auth.resolver.type "memory" }} + resolver: MEMORY + include "accounts/{{ .Values.auth.resolver.configMap.key }}" + {{- end }} + + {{- if eq .Values.auth.resolver.type "full" }} + {{- if .Values.auth.resolver.configMap }} + include "accounts/{{ .Values.auth.resolver.configMap.key }}" + {{- else }} + {{- with .Values.auth.resolver }} + {{- if $.Values.auth.timeout }} + authorization { + timeout: {{ $.Values.auth.timeout }} + } + {{- end }} + + {{- if .operator }} + operator: {{ .operator }} + {{- end }} + + {{- if .systemAccount }} + system_account: {{ .systemAccount | quote }} + {{- end }} + {{- end }} + + resolver: { + type: full + {{- with .Values.auth.resolver }} + dir: {{ .store.dir | quote }} + + allow_delete: {{ .allowDelete }} + + interval: {{ .interval | quote }} + {{- end }} + } + {{- end }} + {{- end }} + + {{- if .Values.auth.resolver.resolverPreload }} + resolver_preload: {{ toRawJson .Values.auth.resolver.resolverPreload }} + {{- end }} + + {{- if eq .Values.auth.resolver.type "URL" }} + {{- with .Values.auth.resolver.url }} + resolver: URL({{ . }}) + {{- end }} + operator: /etc/nats-config/operator/{{ .Values.auth.operatorjwt.configMap.key }} + {{- end }} + {{- end }} + + {{- with .Values.auth.systemAccount }} + system_account: {{ . | quote }} + {{- end }} + + {{- with .Values.auth.token }} + authorization { + token: "{{ . }}" + + + {{- if $.Values.auth.timeout }} + timeout: {{ $.Values.auth.timeout }} + {{- end }} + } + {{- end }} + + {{- with .Values.auth.nkeys }} + {{- with .users }} + authorization { + {{- if $.Values.auth.timeout }} + timeout: {{ $.Values.auth.timeout }} + {{- end }} + + users: [ + {{- range . }} + {{- toRawJson . | nindent 8 }}, + {{- end }} + ] + } + {{- end }} + {{- end }} + + {{- with .Values.auth.basic }} + + {{- with .noAuthUser }} + no_auth_user: {{ . }} + {{- end }} + + {{- if or .users (or .timeout .defaultPermissions) }} + authorization { + {{- if $.Values.auth.timeout }} + timeout: {{ $.Values.auth.timeout }} + {{- end }} + + {{- with .users }} + users: [ + {{- range . }} + {{- toRawJson . | nindent 8 }}, + {{- end }} + ] + {{- end }} + + {{- with $.Values.auth.basic.defaultPermissions }} + default_permissions: { + {{- if .publish }} + publish: [ + {{- range .publish }} + {{- toRawJson . | nindent 10 }}, + {{- end }} + ], + {{- end }} + {{- if .subscribe }} + subscribe: [ + {{- range .subscribe }} + {{- toRawJson . | nindent 10 }}, + {{- end }} + ], + {{- end }} + } + {{- end }} + } + {{- end }} + + {{- with .accounts }} + authorization { + {{- if $.Values.auth.timeout }} + timeout: {{ $.Values.auth.timeout }} + {{- end }} + } + accounts: {{- toRawJson . }} + {{- end }} + + {{- end }} + + {{- end }} diff --git a/helm/openebs/charts/mayastor/charts/nats/templates/nats-box.yaml b/helm/openebs/charts/mayastor/charts/nats/templates/nats-box.yaml new file mode 100644 index 0000000..e94362f --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/nats/templates/nats-box.yaml @@ -0,0 +1,121 @@ +{{- if .Values.natsbox.enabled }} +{{- include "nats.fixImage" .Values.natsbox -}} +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "nats.fullname" . }}-box + namespace: {{ include "nats.namespace" . }} + labels: + app: {{ include "nats.fullname" . }}-box + chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + {{- if .Values.natsbox.additionalLabels }} + {{- tpl (toYaml .Values.natsbox.additionalLabels) $ | nindent 4 }} + {{- end }} + {{- if .Values.natsbox.annotations }} + annotations: + {{- toYaml .Values.natsbox.annotations | nindent 4 }} + {{- end }} +spec: + replicas: 1 + selector: + matchLabels: + app: {{ include "nats.fullname" . }}-box + template: + metadata: + labels: + app: {{ include "nats.fullname" . }}-box + {{- if .Values.natsbox.podLabels }} + {{- tpl (toYaml .Values.natsbox.podLabels) $ | nindent 8 }} + {{- end }} + {{- if .Values.natsbox.podAnnotations }} + annotations: + {{- toYaml .Values.natsbox.podAnnotations | nindent 8 }} + {{- end }} + spec: + {{- with .Values.natsbox.affinity }} + affinity: + {{- tpl (toYaml .) $ | nindent 8 }} + {{- end }} + {{- with .Values.natsbox.nodeSelector }} + nodeSelector: {{ toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.natsbox.tolerations }} + tolerations: {{ toYaml . | nindent 8 }} + {{- end }} + volumes: + {{- if .Values.natsbox.credentials }} + - name: nats-sys-creds + secret: + secretName: {{ .Values.natsbox.credentials.secret.name }} + {{- end }} + {{- if .Values.natsbox.extraVolumes }} + {{- toYaml .Values.natsbox.extraVolumes | nindent 6}} + {{- end }} + {{- with .Values.nats.tls }} + {{ $secretName := tpl .secret.name $ }} + - name: {{ $secretName }}-clients-volume + secret: + secretName: {{ $secretName }} + {{- end }} + {{- with .Values.securityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if hasKey .Values.natsbox "automountServiceAccountToken" }} + automountServiceAccountToken: {{ .Values.natsbox.automountServiceAccountToken }} + {{- end }} + containers: + - name: nats-box + image: {{ include "nats.image" .Values.natsbox.image }} + imagePullPolicy: {{ .Values.natsbox.image.pullPolicy }} + {{- if .Values.natsbox.securityContext }} + securityContext: + {{- toYaml .Values.natsbox.securityContext | nindent 10 }} + {{- end }} + resources: + {{- toYaml .Values.natsbox.resources | nindent 10 }} + env: + - name: NATS_URL + value: {{ template "nats.fullname" . }} + {{- if .Values.natsbox.credentials }} + - name: NATS_CREDS + value: /etc/nats-config/creds/{{ .Values.natsbox.credentials.secret.key }} + {{- end }} + {{- with .Values.nats.tls }} + {{ $secretName := tpl .secret.name $ }} + lifecycle: + postStart: + exec: + command: + - /bin/sh + - -c + - cp /etc/nats-certs/clients/{{ $secretName }}/* /usr/local/share/ca-certificates && update-ca-certificates + {{- end }} + command: + - "tail" + - "-f" + - "/dev/null" + volumeMounts: + {{- if .Values.natsbox.credentials }} + - name: nats-sys-creds + mountPath: /etc/nats-config/creds + {{- end }} + {{- if .Values.natsbox.extraVolumeMounts }} + {{- toYaml .Values.natsbox.extraVolumeMounts | nindent 8 }} + {{- end }} + {{- with .Values.nats.tls }} + ####################### + # # + # TLS Volumes Mounts # + # # + ####################### + {{ $secretName := tpl .secret.name $ }} + - name: {{ $secretName }}-clients-volume + mountPath: /etc/nats-certs/clients/{{ $secretName }} + {{- end }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/nats/templates/networkpolicy.yaml b/helm/openebs/charts/mayastor/charts/nats/templates/networkpolicy.yaml new file mode 100644 index 0000000..9951441 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/nats/templates/networkpolicy.yaml @@ -0,0 +1,79 @@ +{{- if .Values.networkPolicy.enabled }} +kind: NetworkPolicy +apiVersion: {{ template "networkPolicy.apiVersion" . }} +metadata: + name: {{ include "nats.fullname" . }} + namespace: {{ include "nats.namespace" . }} + labels: + {{- include "nats.labels" . | nindent 4 }} +spec: + podSelector: + matchLabels: + {{- include "nats.selectorLabels" . | nindent 6 }} + policyTypes: + - Ingress + - Egress + egress: + # Allow dns resolution + - ports: + - port: 53 + protocol: UDP + # Allow outbound connections to other cluster pods + - ports: + - port: {{ .Values.nats.client.port }} + protocol: TCP + - port: 6222 + protocol: TCP + - port: 8222 + protocol: TCP + - port: 7777 + protocol: TCP + - port: {{ .Values.leafnodes.port }} + protocol: TCP + - port: {{ .Values.gateway.port }} + protocol: TCP + to: + - podSelector: + matchLabels: + {{- include "nats.selectorLabels" . | nindent 10 }} + {{- if .Values.networkPolicy.extraEgress }} + {{- include "tplvalues.render" ( dict "value" .Values.networkPolicy.extraEgress "context" $ ) | nindent 2 }} + {{- end }} + ingress: + # Allow inbound connections + - ports: + - port: {{ .Values.nats.client.port }} + protocol: TCP + - port: 6222 + protocol: TCP + - port: 8222 + protocol: TCP + - port: 7777 + protocol: TCP + - port: {{ .Values.leafnodes.port }} + protocol: TCP + - port: {{ .Values.gateway.port }} + protocol: TCP + {{- if not .Values.networkPolicy.allowExternal }} + from: + - podSelector: + matchLabels: + {{ include "nats.fullname" . }}-client: "true" + - podSelector: + matchLabels: + {{- include "nats.selectorLabels" . | nindent 10 }} + {{- if .Values.networkPolicy.ingressNSMatchLabels }} + - namespaceSelector: + matchLabels: + {{- toYaml .Values.networkPolicy.ingressNSMatchLabels | nindent 10 }} + {{- if .Values.networkPolicy.ingressNSPodMatchLabels }} + podSelector: + matchLabels: + {{- toYaml .Values.networkPolicy.ingressNSPodMatchLabels | nindent 10 }} + {{- end }} + {{- end }} + {{- end }} + {{- if .Values.networkPolicy.extraIngress }} + {{- include "tplvalues.render" ( dict "value" .Values.networkPolicy.extraIngress "context" $ ) | nindent 2 }} + {{- end }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/nats/templates/pdb.yaml b/helm/openebs/charts/mayastor/charts/nats/templates/pdb.yaml new file mode 100644 index 0000000..5a7cb43 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/nats/templates/pdb.yaml @@ -0,0 +1,20 @@ +{{- if .Values.podDisruptionBudget.enabled }} +--- +apiVersion: {{ .Capabilities.APIVersions.Has "policy/v1" | ternary "policy/v1" "policy/v1beta1" }} +kind: PodDisruptionBudget +metadata: + name: {{ include "nats.fullname" . }} + namespace: {{ include "nats.namespace" . }} + labels: + {{- include "nats.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 "nats.selectorLabels" . | nindent 6 }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/nats/templates/rbac.yaml b/helm/openebs/charts/mayastor/charts/nats/templates/rbac.yaml new file mode 100644 index 0000000..7b55aeb --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/nats/templates/rbac.yaml @@ -0,0 +1,39 @@ +{{- if or (.Values.nats.serviceAccount.create) (and .Values.nats.externalAccess .Values.nats.advertise) }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "nats.serviceAccountName" . }} + namespace: {{ include "nats.namespace" . }} + labels: + {{- include "nats.labels" . | nindent 4 }} + {{- with .Values.nats.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} +{{- if and .Values.nats.externalAccess .Values.nats.advertise }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "nats.serviceAccountName" . }} +rules: +- apiGroups: [""] + resources: + - nodes + verbs: ["get"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "nats.serviceAccountName" . }}-binding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ include "nats.serviceAccountName" . }} +subjects: +- kind: ServiceAccount + name: {{ include "nats.serviceAccountName" . }} + namespace: {{ include "nats.namespace" . }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/nats/templates/service.yaml b/helm/openebs/charts/mayastor/charts/nats/templates/service.yaml new file mode 100644 index 0000000..361e725 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/nats/templates/service.yaml @@ -0,0 +1,74 @@ +{{- $appProtocol := semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "nats.fullname" . }} + namespace: {{ include "nats.namespace" . }} + labels: + {{- include "nats.labels" . | nindent 4 }} + {{- if .Values.serviceAnnotations}} + annotations: + {{- toYaml .Values.serviceAnnotations | nindent 4 }} + {{- end }} +spec: + selector: + {{- include "nats.selectorLabels" . | nindent 4 }} + clusterIP: None + publishNotReadyAddresses: true + {{- if .Values.topologyKeys }} + topologyKeys: + {{- toYaml .Values.topologyKeys | nindent 4 }} + {{- end }} + ports: + {{- if .Values.websocket.enabled }} + - name: websocket + port: {{ .Values.websocket.port }} + {{- if $appProtocol }} + appProtocol: tcp + {{- end }} + {{- end }} + {{- if .Values.nats.profiling.enabled }} + - name: profiling + port: {{ .Values.nats.profiling.port }} + {{- if $appProtocol }} + appProtocol: http + {{- end }} + {{- end }} + - name: {{ .Values.nats.client.portName }} + port: {{ .Values.nats.client.port }} + {{- if $appProtocol }} + appProtocol: tcp + {{- end }} + - name: cluster + port: 6222 + {{- if $appProtocol }} + appProtocol: tcp + {{- end }} + - name: monitor + port: 8222 + {{- if $appProtocol }} + appProtocol: http + {{- end }} + - name: {{ .Values.exporter.portName }} + port: 7777 + {{- if $appProtocol }} + appProtocol: http + {{- end }} + - name: leafnodes + port: {{ .Values.leafnodes.port }} + {{- if $appProtocol }} + appProtocol: tcp + {{- end }} + - name: gateways + port: {{ .Values.gateway.port }} + {{- if $appProtocol }} + appProtocol: tcp + {{- end }} + {{- if .Values.mqtt.enabled }} + - name: mqtt + port: 1883 + {{- if $appProtocol }} + appProtocol: tcp + {{- end }} + {{- end }} diff --git a/helm/openebs/charts/mayastor/charts/nats/templates/serviceMonitor.yaml b/helm/openebs/charts/mayastor/charts/nats/templates/serviceMonitor.yaml new file mode 100644 index 0000000..282f50f --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/nats/templates/serviceMonitor.yaml @@ -0,0 +1,36 @@ +{{ if and .Values.exporter.enabled .Values.exporter.serviceMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "nats.fullname" . }} + {{- if .Values.exporter.serviceMonitor.namespace }} + namespace: {{ .Values.exporter.serviceMonitor.namespace }} + {{- else }} + namespace: {{ include "nats.namespace" . }} + {{- end }} + {{- if .Values.exporter.serviceMonitor.labels }} + labels: + {{- toYaml .Values.exporter.serviceMonitor.labels | nindent 4 }} + {{- end }} + {{- if .Values.exporter.serviceMonitor.annotations }} + annotations: + {{- toYaml .Values.exporter.serviceMonitor.annotations | nindent 4 }} + {{- end }} +spec: + endpoints: + - port: {{ .Values.exporter.portName }} + {{- if .Values.exporter.serviceMonitor.path }} + path: {{ .Values.exporter.serviceMonitor.path }} + {{- end }} + {{- if .Values.exporter.serviceMonitor.interval }} + interval: {{ .Values.exporter.serviceMonitor.interval }} + {{- end }} + {{- if .Values.exporter.serviceMonitor.scrapeTimeout }} + scrapeTimeout: {{ .Values.exporter.serviceMonitor.scrapeTimeout }} + {{- end }} + namespaceSelector: + any: true + selector: + matchLabels: + {{- include "nats.selectorLabels" . | nindent 6 }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/charts/nats/templates/statefulset.yaml b/helm/openebs/charts/mayastor/charts/nats/templates/statefulset.yaml new file mode 100644 index 0000000..1ea285f --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/nats/templates/statefulset.yaml @@ -0,0 +1,650 @@ +{{- include "nats.fixImage" .Values.nats -}} +{{- include "nats.fixImage" .Values.bootconfig -}} +{{- include "nats.fixImage" .Values.reloader -}} +{{- include "nats.fixImage" .Values.exporter -}} +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ include "nats.fullname" . }} + namespace: {{ include "nats.namespace" . }} + labels: + {{- include "nats.labels" . | nindent 4 }} + {{- if .Values.statefulSetAnnotations }} + annotations: + {{- toYaml .Values.statefulSetAnnotations | nindent 4 }} + {{- end }} +spec: + selector: + matchLabels: + {{- include "nats.selectorLabels" . | nindent 6 }} + {{- if .Values.cluster.enabled }} + replicas: {{ .Values.cluster.replicas }} + {{- else }} + replicas: 1 + {{- end }} + serviceName: {{ include "nats.fullname" . }} + + podManagementPolicy: {{ .Values.podManagementPolicy }} + + template: + metadata: + {{- if or .Values.exporter.enabled .Values.nats.configChecksumAnnotation .Values.podAnnotations }} + annotations: + {{- if .Values.exporter.enabled }} + prometheus.io/path: /metrics + prometheus.io/port: "7777" + prometheus.io/scrape: "true" + {{- end }} + {{- if .Values.nats.configChecksumAnnotation }} + checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} + {{- end }} + {{- if .Values.podAnnotations }} + {{- toYaml .Values.podAnnotations | nindent 8 }} + {{- end }} + {{- end }} + labels: + {{- include "nats.selectorLabels" . | nindent 8 }} + {{- if .Values.statefulSetPodLabels }} + {{- tpl (toYaml .Values.statefulSetPodLabels) . | nindent 8 }} + {{- end }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.securityContext }} + securityContext: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- tpl (toYaml .) $ | nindent 8 }} + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: {{ toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: {{ toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.topologySpreadConstraints }} + topologySpreadConstraints: + {{- range .Values.topologySpreadConstraints }} + {{- if and .maxSkew .topologyKey }} + - maxSkew: {{ .maxSkew }} + topologyKey: {{ .topologyKey }} + {{- if .whenUnsatisfiable }} + whenUnsatisfiable: {{ .whenUnsatisfiable }} + {{- end }} + labelSelector: + matchLabels: + {{- include "nats.selectorLabels" $ | nindent 12 }} + {{- end }} + {{- end }} + {{- end }} + {{- if .Values.priorityClassName }} + priorityClassName: {{ .Values.priorityClassName | quote }} + {{- end }} + {{- with .Values.nats.dnsPolicy }} + dnsPolicy: {{ . }} + {{- end }} + {{- with .Values.nats.hostNetwork }} + hostNetwork: {{ . }} + {{- end }} + # Common volumes for the containers. + volumes: + - name: config-volume + {{- if .Values.nats.customConfigSecret }} + secret: + secretName: {{ .Values.nats.customConfigSecret.name }} + {{- else }} + configMap: + name: {{ include "nats.fullname" . }}-config + {{- end }} + + {{- /* User extended config volumes*/}} + {{- if .Values.nats.config }} + # User extended config volumes + {{- with .Values.nats.config }} + {{- toYaml . | nindent 6 }} + {{- end }} + {{- end }} + + # Local volume shared with the reloader. + - name: pid + {{- toYaml .Values.pidVolume | nindent 8 }} + + {{- if and .Values.auth.enabled .Values.auth.resolver }} + {{- if .Values.auth.resolver.configMap }} + - name: resolver-volume + configMap: + name: {{ .Values.auth.resolver.configMap.name }} + {{- end }} + + {{- if eq .Values.auth.resolver.type "URL" }} + - name: operator-jwt-volume + configMap: + name: {{ .Values.auth.operatorjwt.configMap.name }} + {{- end }} + {{- end }} + + {{- if and .Values.nats.externalAccess .Values.nats.advertise }} + # Local volume shared with the advertise config initializer. + - name: advertiseconfig + {{- toYaml .Values.advertiseconfigVolume | nindent 8 }} + {{- end }} + + {{- if and .Values.nats.jetstream.enabled .Values.nats.jetstream.fileStorage.enabled .Values.nats.jetstream.fileStorage.existingClaim }} + # Persistent volume for jetstream running with file storage option + - name: {{ include "nats.fullname" . }}-js-pvc + persistentVolumeClaim: + claimName: {{ .Values.nats.jetstream.fileStorage.existingClaim | quote }} + {{- end }} + + ################# + # # + # TLS Volumes # + # # + ################# + {{- with .Values.nats.tls }} + {{ $secretName := tpl .secret.name $ }} + - name: {{ $secretName }}-clients-volume + secret: + secretName: {{ $secretName }} + {{- end }} + {{- with .Values.mqtt.tls }} + {{ $secretName := tpl .secret.name $ }} + - name: {{ $secretName }}-mqtt-volume + secret: + secretName: {{ $secretName }} + {{- end }} + {{- with .Values.cluster.tls }} + {{ $secretName := tpl .secret.name $ }} + - name: {{ $secretName }}-cluster-volume + secret: + secretName: {{ $secretName }} + {{- end }} + {{- with .Values.leafnodes.tls }} + {{- if not .custom }} + {{ $secretName := tpl .secret.name $ }} + - name: {{ $secretName }}-leafnodes-volume + secret: + secretName: {{ $secretName }} + {{- end }} + {{- end }} + {{- with .Values.gateway.tls }} + {{ $secretName := tpl .secret.name $ }} + - name: {{ $secretName }}-gateways-volume + secret: + secretName: {{ $secretName }} + {{- end }} + {{- with .Values.websocket.tls }} + {{ $secretName := tpl .secret.name $ }} + - name: {{ $secretName }}-ws-volume + secret: + secretName: {{ $secretName }} + {{- end }} + {{- if .Values.leafnodes.enabled }} + # + # Leafnode credential volumes + # + {{- range .Values.leafnodes.remotes }} + {{- with .credentials }} + - name: {{ .secret.name }}-volume + secret: + secretName: {{ .secret.name }} + {{- end }} + {{- with .tls }} + - name: {{ .secret.name }}-volume + secret: + secretName: {{ .secret.name }} + {{- end }} + {{- end }} + {{- end }} + + {{- if .Values.additionalVolumes }} + {{- toYaml .Values.additionalVolumes | nindent 6 }} + {{- end }} + + serviceAccountName: {{ include "nats.serviceAccountName" . }} + {{- if hasKey .Values.nats "automountServiceAccountToken" }} + automountServiceAccountToken: {{ .Values.nats.automountServiceAccountToken }} + {{- end }} + + # Required to be able to HUP signal and apply config + # reload to the server without restarting the pod. + shareProcessNamespace: true + + {{- if and .Values.nats.externalAccess .Values.nats.advertise }} + # Initializer container required to be able to lookup + # the external ip on which this node is running. + initContainers: + - name: bootconfig + command: + - nats-pod-bootconfig + - -f + - /etc/nats-config/advertise/client_advertise.conf + - -gf + - /etc/nats-config/advertise/gateway_advertise.conf + env: + - name: KUBERNETES_NODE_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: spec.nodeName + image: {{ include "nats.image" .Values.bootconfig.image }} + imagePullPolicy: {{ .Values.bootconfig.image.pullPolicy }} + {{- if .Values.bootconfig.securityContext }} + securityContext: + {{- toYaml .Values.bootconfig.securityContext | nindent 10 }} + {{- end }} + resources: + {{- toYaml .Values.bootconfig.resources | nindent 10 }} + volumeMounts: + - mountPath: /etc/nats-config/advertise + name: advertiseconfig + subPath: advertise + {{- end }} + + ################# + # # + # NATS Server # + # # + ################# + terminationGracePeriodSeconds: {{ .Values.nats.terminationGracePeriodSeconds }} + containers: + - name: nats + image: {{ include "nats.image" .Values.nats.image }} + imagePullPolicy: {{ .Values.nats.image.pullPolicy }} + {{- if .Values.nats.securityContext }} + securityContext: + {{- toYaml .Values.nats.securityContext | nindent 10 }} + {{- end }} + resources: + {{- toYaml .Values.nats.resources | nindent 10 }} + ports: + - containerPort: {{ .Values.nats.client.port }} + name: {{ .Values.nats.client.portName }} + {{- if .Values.nats.externalAccess }} + hostPort: {{ .Values.nats.client.port }} + {{- end }} + {{- if .Values.leafnodes.enabled }} + - containerPort: {{ .Values.leafnodes.port }} + name: leafnodes + {{- if .Values.nats.externalAccess }} + hostPort: {{ .Values.leafnodes.port }} + {{- end }} + {{- end }} + {{- if .Values.gateway.enabled }} + - containerPort: {{ .Values.gateway.port }} + name: gateways + {{- if .Values.nats.externalAccess }} + hostPort: {{ .Values.gateway.port }} + {{- end }} + {{- end }} + - containerPort: 6222 + name: cluster + - containerPort: 8222 + name: monitor + {{- if .Values.mqtt.enabled }} + - containerPort: 1883 + name: mqtt + {{- if .Values.nats.externalAccess }} + hostPort: 1883 + {{- end }} + {{- end }} + {{- if .Values.websocket.enabled }} + - containerPort: {{ .Values.websocket.port }} + name: websocket + {{- if .Values.nats.externalAccess }} + hostPort: {{ .Values.websocket.port }} + {{- end }} + {{- end }} + {{- if .Values.nats.profiling.enabled }} + - containerPort: {{ .Values.nats.profiling.port }} + name: profiling + {{- end }} + + command: + - "nats-server" + - "--config" + - "/etc/nats-config/nats.conf" + {{- if .Values.nats.profiling.enabled }} + - "--profile={{ .Values.nats.profiling.port }}" + {{- end }} + + # Required to be able to define an environment variable + # that refers to other environment variables. This env var + # is later used as part of the configuration file. + env: + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: SERVER_NAME + value: {{ .Values.nats.serverNamePrefix }}$(POD_NAME) + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: CLUSTER_ADVERTISE + value: {{ include "nats.clusterAdvertise" . }} + {{- if .Values.nats.gomemlimit }} + - name: GOMEMLIMIT + value: {{ .Values.nats.gomemlimit | quote }} + {{- end }} + {{- if .Values.nats.extraEnv }} + {{- toYaml .Values.nats.extraEnv | nindent 8 }} + {{- end }} + + {{- if .Values.nats.jetstream.enabled }} + {{- with .Values.nats.jetstream.encryption }} + {{- with .secret }} + - name: JS_KEY + valueFrom: + secretKeyRef: + name: {{ .name }} + key: {{ .key }} + {{- end }} + {{- end }} + {{- end }} + volumeMounts: + - name: config-volume + mountPath: /etc/nats-config + - name: pid + mountPath: /var/run/nats + {{- if and .Values.nats.externalAccess .Values.nats.advertise }} + - mountPath: /etc/nats-config/advertise + name: advertiseconfig + subPath: advertise + {{- end }} + + {{- /* User extended config volumes*/}} + {{- range .Values.nats.config }} + # User extended config volumes + - name: {{ .name }} + mountPath: /etc/nats-config/{{ .name }} + {{- end }} + + + {{- if and .Values.auth.enabled .Values.auth.resolver }} + {{- if eq .Values.auth.resolver.type "memory" }} + - name: resolver-volume + mountPath: /etc/nats-config/accounts + {{- end }} + + {{- if eq .Values.auth.resolver.type "full" }} + {{- if .Values.auth.resolver.configMap }} + - name: resolver-volume + mountPath: /etc/nats-config/accounts + {{- end }} + {{- if and .Values.auth.resolver .Values.auth.resolver.store }} + - name: nats-jwt-pvc + mountPath: {{ .Values.auth.resolver.store.dir }} + {{- end }} + {{- end }} + + {{- if eq .Values.auth.resolver.type "URL" }} + - name: operator-jwt-volume + mountPath: /etc/nats-config/operator + {{- end }} + {{- end }} + + {{- if and .Values.nats.jetstream.enabled .Values.nats.jetstream.fileStorage.enabled }} + - name: {{ include "nats.fullname" . }}-js-pvc + mountPath: {{ .Values.nats.jetstream.fileStorage.storageDirectory }} + {{- end }} + + {{- include "nats.tlsVolumeMounts" . | nindent 8 }} + + {{- if .Values.leafnodes.enabled }} + # + # Leafnode credential volumes + # + {{- range .Values.leafnodes.remotes }} + {{- with .credentials }} + - name: {{ .secret.name }}-volume + mountPath: /etc/nats-creds/{{ .secret.name }} + {{- end }} + {{- with .tls }} + - name: {{ .secret.name }}-volume + mountPath: /etc/nats-certs/leafnodes/{{ .secret.name }} + {{- end }} + {{- end }} + {{- end }} + + {{- if .Values.additionalVolumeMounts }} + {{- toYaml .Values.additionalVolumeMounts | nindent 8 }} + {{- end }} + + ####################### + # # + # Healthcheck Probes # + # # + ####################### + {{- if .Values.nats.healthcheck }} + {{- $serverVersion := .Values.nats.image.tag | regexFind "\\d+(\\.\\d+)?(\\.\\d+)?" | default "2.9.0" }} + {{- $enableHealthzStartup := and .Values.nats.healthcheck.enableHealthz (or (not .Values.nats.healthcheck.detectHealthz) (semverCompare ">=2.7.1" $serverVersion)) }} + {{- $enableHealthzLivenessReadiness := and .Values.nats.healthcheck.enableHealthzLivenessReadiness (or (not .Values.nats.healthcheck.detectHealthz) (semverCompare ">=2.9.0" $serverVersion)) }} + {{- $healthzStartupEndpoint := "/healthz" }} + {{- $healthzLivenessEndpoint := "/healthz?js-enabled-only=true" }} + {{- $healthzReadinessEndpoint := "/healthz?js-server-only=true" }} + + {{- /* healthz options behaved differently in 2.9.0 - 2.9.9 https://github.com/nats-io/nats-server/pull/3704 */}} + {{- if (semverCompare "<=2.9.9" $serverVersion) }} + {{- $healthzLivenessEndpoint = "/healthz?js-server-only=true" }} + {{- $healthzReadinessEndpoint = "/healthz?js-server-only=true" }} + {{- if .Values.nats.jetstream.enabled }} + {{- $healthzLivenessEndpoint = print $healthzLivenessEndpoint "&js-enabled=true" }} + {{- $healthzReadinessEndpoint = print $healthzReadinessEndpoint "&js-enabled=true" }} + {{- end }} + {{- end }} + + {{- with .Values.nats.healthcheck.liveness }} + {{- if .enabled }} + livenessProbe: + {{- $probe := merge (dict) . }} + {{- $_ := unset $probe "enabled" }} + {{- $probeDefault := dict "httpGet" (dict "path" "/" "port" 8222) }} + {{- if $enableHealthzLivenessReadiness }} + # for NATS server versions >=2.9.0, {{ $healthzLivenessEndpoint }} will be enabled + # liveness probe checks that the JS server is enabled + {{- $_ := set $probeDefault.httpGet "path" $healthzLivenessEndpoint }} + {{- end }} + {{- $probe := merge $probe $probeDefault }} + {{- toYaml $probe | nindent 10}} + {{- end }} + {{- end }} + + {{- with .Values.nats.healthcheck.readiness }} + {{- if .enabled }} + readinessProbe: + {{- $probe := merge (dict) . }} + {{- $_ := unset $probe "enabled" }} + {{- $probeDefault := dict "httpGet" (dict "path" "/" "port" 8222) }} + {{- if $enableHealthzLivenessReadiness }} + # for NATS server versions >=2.9.0, {{ $healthzReadinessEndpoint }} will be enabled + # readiness probe checks that the JS server is enabled, and is current with the meta leader + {{- $_ := set $probeDefault.httpGet "path" $healthzReadinessEndpoint }} + {{- end }} + {{- $probe := merge $probe $probeDefault }} + {{- toYaml $probe | nindent 10}} + {{- end }} + {{- end }} + + {{- with .Values.nats.healthcheck.startup }} + {{- if .enabled }} + startupProbe: + {{- $probe := merge (dict) . }} + {{- $_ := unset $probe "enabled" }} + {{- $probeDefault := dict "httpGet" (dict "path" "/" "port" 8222) }} + {{- if $enableHealthzStartup }} + # for NATS server versions >=2.7.1, {{ $healthzStartupEndpoint}} will be enabled + # startup probe checks that the JS server is enabled, is current with the meta leader, + # and that all streams and consumers assigned to this JS server are current + {{- $_ := set $probeDefault.httpGet "path" $healthzStartupEndpoint }} + {{- end }} + {{- $probe := merge $probe $probeDefault }} + {{- toYaml $probe | nindent 10}} + {{- end }} + {{- end }} + + {{- end }} + + # Gracefully stop NATS Server on pod deletion or image upgrade. + # + lifecycle: + preStop: + exec: + # send the lame duck shutdown signal to trigger a graceful shutdown + # nats-server will ignore the TERM signal it receives after this + # + command: + - "nats-server" + - "-sl=ldm=/var/run/nats/nats.pid" + + ################################# + # # + # NATS Configuration Reloader # + # # + ################################# + {{- if .Values.reloader.enabled }} + - name: reloader + image: {{ include "nats.image" .Values.reloader.image }} + imagePullPolicy: {{ .Values.reloader.image.pullPolicy }} + {{- if .Values.reloader.securityContext }} + securityContext: + {{- toYaml .Values.reloader.securityContext | nindent 10 }} + {{- end }} + resources: + {{- toYaml .Values.reloader.resources | nindent 10 }} + command: + - "nats-server-config-reloader" + - "-pid" + - "/var/run/nats/nats.pid" + - "-config" + - "/etc/nats-config/nats.conf" + {{- with .Values.nats.tls }} + {{- $nats_tls := merge (dict) . }} + {{- $_ := set $nats_tls "secretPath" "/etc/nats-certs/clients" }} + {{- tpl (include "nats.tlsReloaderArgs" $nats_tls) $ | nindent 8}} + {{- end }} + {{- with .Values.cluster.tls }} + {{- $nats_tls := merge (dict) . }} + {{- $_ := set $nats_tls "secretPath" "/etc/nats-certs/cluster" }} + {{- tpl (include "nats.tlsReloaderArgs" $nats_tls) $ | nindent 8}} + {{- end }} + {{- range .Values.reloader.extraConfigs }} + - "-config" + - {{ . | quote }} + {{- end }} + {{- range .Values.nats.config }} + - "-config" + - "/etc/nats-config/{{ .name }}/{{ .name }}.conf" + {{- end}} + volumeMounts: + - name: config-volume + mountPath: /etc/nats-config + - name: pid + mountPath: /var/run/nats + {{- include "nats.tlsVolumeMounts" . | nindent 8 }} + {{- if .Values.additionalVolumeMounts }} + {{- toYaml .Values.additionalVolumeMounts | nindent 8 }} + {{- end }} + {{- /* User extended config volumes*/}} + {{- range .Values.nats.config }} + # User extended config volumes + - name: {{ .name }} + mountPath: /etc/nats-config/{{ .name }} + {{- end }} + {{- end }} + + ############################## + # # + # NATS Prometheus Exporter # + # # + ############################## + {{- if .Values.exporter.enabled }} + - name: metrics + image: {{ include "nats.image" .Values.exporter.image }} + imagePullPolicy: {{ .Values.exporter.image.pullPolicy }} + {{- if .Values.exporter.securityContext }} + securityContext: + {{- toYaml .Values.exporter.securityContext | nindent 10 }} + {{- end }} + resources: + {{- toYaml .Values.exporter.resources | nindent 10 }} + args: + {{- if .Values.exporter.args }} + {{- toYaml .Values.exporter.args | nindent 8 }} + {{- else }} + - -connz + - -routez + - -subz + - -varz + - -prefix=nats + - -use_internal_server_id + {{- if .Values.nats.jetstream.enabled }} + - -jsz=all + {{- end }} + {{- if .Values.leafnodes.enabled }} + - -leafz + {{- end }} + {{- if .Values.gateway.enabled }} + - -gatewayz + {{- end }} + - http://localhost:8222/ + {{- end }} + ports: + - containerPort: 7777 + name: {{ .Values.exporter.portName }} + {{- end }} + + {{- if .Values.additionalContainers }} + {{- toYaml .Values.additionalContainers | nindent 6 }} + {{- end }} + + volumeClaimTemplates: + {{- if eq .Values.auth.resolver.type "full" }} + {{- if and .Values.auth.resolver .Values.auth.resolver.store }} + ##################################### + # # + # Account Server Embedded JWT # + # # + ##################################### + - metadata: + name: nats-jwt-pvc + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: {{ .Values.auth.resolver.store.size }} + {{- if .Values.auth.resolver.store.storageClassName }} + storageClassName: {{ .Values.auth.resolver.store.storageClassName | quote }} + {{- end }} + {{- end }} + {{- end }} + + {{- if and .Values.nats.jetstream.enabled .Values.nats.jetstream.fileStorage.enabled (not .Values.nats.jetstream.fileStorage.existingClaim) }} + ##################################### + # # + # Jetstream New Persistent Volume # + # # + ##################################### + - metadata: + name: {{ include "nats.fullname" . }}-js-pvc + {{- if .Values.nats.jetstream.fileStorage.annotations }} + annotations: + {{- toYaml .Values.nats.jetstream.fileStorage.annotations | nindent 10 }} + {{- end }} + spec: + accessModes: + {{- toYaml .Values.nats.jetstream.fileStorage.accessModes | nindent 10 }} + resources: + requests: + storage: {{ .Values.nats.jetstream.fileStorage.size }} + {{- if .Values.nats.jetstream.fileStorage.storageClassName }} + storageClassName: {{ .Values.nats.jetstream.fileStorage.storageClassName | quote }} + {{- end }} + {{- end }} diff --git a/helm/openebs/charts/mayastor/charts/nats/templates/tests/test-request-reply.yaml b/helm/openebs/charts/mayastor/charts/nats/templates/tests/test-request-reply.yaml new file mode 100644 index 0000000..829aca2 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/nats/templates/tests/test-request-reply.yaml @@ -0,0 +1,31 @@ +apiVersion: v1 +kind: Pod +metadata: + name: "{{ include "nats.fullname" . }}-test-request-reply" + labels: + chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + app: {{ include "nats.fullname" . }}-test-request-reply + annotations: + "helm.sh/hook": test +spec: + containers: + - name: nats-box + image: {{ include "nats.image" .Values.natsbox.image }} + env: + - name: NATS_HOST + value: {{ template "nats.fullname" . }} + command: + - /bin/sh + - -ec + - | + nats reply -s nats://$NATS_HOST:{{ .Values.nats.client.port }} 'name.>' --command "echo {{1}}" & + - | + "&&" + - | + name=$(nats request -s nats://$NATS_HOST:{{ .Values.nats.client.port }} name.test '' 2>/dev/null) + - | + "&&" + - | + [ $name = test ] + + restartPolicy: Never diff --git a/helm/openebs/charts/mayastor/charts/nats/values.yaml b/helm/openebs/charts/mayastor/charts/nats/values.yaml new file mode 100644 index 0000000..8812d58 --- /dev/null +++ b/helm/openebs/charts/mayastor/charts/nats/values.yaml @@ -0,0 +1,827 @@ +############################### +# # +# NATS Server Configuration # +# # +############################### +nats: + image: + repository: nats + tag: 2.9.17-alpine + pullPolicy: IfNotPresent + # registry: docker.io + + # The servers name prefix, must be used for example when we want a NATS cluster + # spanning multiple Kubernetes clusters. + serverNamePrefix: "" + + # Server Tags + serverTags: + # - "foo" + # - "bar" + + # Sets GOMEMLIMIT environment variable which makes the Go GC be aware of memory limits + # from the container. Recommended to be set to about 90% of the resource memory limits. + # + # More info about the Go GC: https://go.dev/doc/gc-guide + # + # gomemlimit: "4GiB" + + # Toggle profiling. + # This enables nats-server pprof (profiling) port, so you can see goroutines + # stacks, memory heap sizes, etc. + profiling: + enabled: false + port: 6000 + + # Toggle using health check probes to better detect failures. + healthcheck: + # /healthz health check endpoint was introduced in NATS Server 2.7.1 + # Attempt to detect /healthz support by inspecting if tag is >=2.7.1 + detectHealthz: true + # Enable /healthz startupProbe for controlled upgrades of NATS JetStream + enableHealthz: true + # Enable /healthz liveness and readiness probes (supported in >=2.9.0) + # This is a feature flag and will be removed in future releases + enableHealthzLivenessReadiness: false + + # Enable liveness checks. If this fails, then the NATS Server will restarted. + liveness: + enabled: true + + initialDelaySeconds: 10 + timeoutSeconds: 5 + # NOTE: liveness check + terminationGracePeriodSeconds can introduce unnecessarily long outages + # due to the coupling between liveness probe and terminationGracePeriodSeconds. + # To avoid this, we make the periodSeconds of the liveness check to be about half the default + # time that it takes for lame duck graceful stop. + # + # In case of using Kubernetes +1.22 with probe-level terminationGracePeriodSeconds + # we could revise this but for now keep a minimal liveness check. + # + # More info: + # + # https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#probe-level-terminationgraceperiodseconds + # https://github.com/kubernetes/kubernetes/issues/64715 + # + periodSeconds: 30 + successThreshold: 1 + failureThreshold: 3 + + # Override the health check path + # httpGet: + # path: /healthz?js-enabled=true + + # Only for Kubernetes +1.22 that have pod level probes enabled. + # terminationGracePeriodSeconds: 5 + + # Periodically check for the server to be ready for connections while + # the NATS container is running. + readiness: + enabled: true + + initialDelaySeconds: 10 + timeoutSeconds: 5 + periodSeconds: 10 + successThreshold: 1 + failureThreshold: 3 + + # Override the health check path + # httpGet: + # path: /healthz?js-server-only=true + + # Enable startup checks to confirm server is ready for traffic. + # This is recommended for JetStream deployments since in cluster mode + # it will try to ensure that the server is ready to serve streams. + startup: + enabled: true + + initialDelaySeconds: 10 + timeoutSeconds: 5 + periodSeconds: 10 + successThreshold: 1 + failureThreshold: 90 + + # Override the health check path + # httpGet: + # path: /healthz + + ## hostNetwork + hostNetwork: false + + ## Pod Dns Policy. Default is ClusterFirst + ## ref: https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pod-s-dns-policy + dnsPolicy: ClusterFirst + + # Adds a hash of the ConfigMap as a pod annotation + # This will cause the StatefulSet to roll when the ConfigMap is updated + configChecksumAnnotation: true + + # securityContext for the nats container + securityContext: {} + + # Toggle whether to enable external access. + # This binds a host port for clients, gateways and leafnodes. + externalAccess: false + + # Toggle to disable client advertisements (connect_urls), + # in case of running behind a load balancer + # it might be required to disable advertisements. + advertise: true + + # In case both external access and advertise are enabled + # then a service account would be required to be able to + # gather the public ip from a node. + 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: "" + + # Toggle whether to automatically mount Service Account token in the pod + # not set means default value, boolean true/false overrides default value + # automountServiceAccountToken: true + + # The number of connect attempts against discovered routes. + connectRetries: 120 + + # selector matchLabels for the server and service. + # If left empty defaults are used. + # This is helpful if you are updating from Chart version <=7.4 + selectorLabels: {} + + # Resources to add to the container + # ref: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + resources: {} + + client: + port: 4222 + portName: "client" + + # extraEnv is the list of environment variables to add to the nats-server container + extraEnv: [] + + # Server settings. + limits: + maxConnections: + maxSubscriptions: + maxControlLine: + maxPayload: + + writeDeadline: + maxPending: + maxPings: + + # How many seconds should pass before sending a PING + # to a client that has no activity. + pingInterval: + + # grace period after pod begins shutdown before starting to close client connections + lameDuckGracePeriod: "10s" + + # duration over which to slowly close close client connections after lameDuckGracePeriod has passed + lameDuckDuration: "30s" + + # terminationGracePeriodSeconds determines how long to wait for graceful shutdown + # this should be at least `lameDuckGracePeriod` + `lameDuckDuration` + 20s shutdown overhead + terminationGracePeriodSeconds: 60 + + logging: + debug: + trace: + logtime: + connectErrorReports: + reconnectErrorReports: + + # customConfigSecret can be used to use an custom secret for the config + # of the NATS Server. + # NOTE: For this to work the name of the configuration has to be + # called `nats.conf`. + # + # e.g. kubectl create secret generic custom-nats-conf --from-file nats.conf + # + # customConfigSecret: + # name: + # + # Alternately, the generated config can be extended with extra imports using the below syntax. + # The benefit of this is that cluster settings can be built up via helm values, but external + # secrets can be referenced and imported alongside it. + # + # config: + # : + # + # name: "" + # + # e.g: + # + # config: + # - name: ssh-key + # secret: + # secretName: ssh-key + # - name: config-vol + # configMap: + # name: log-config + + # mappings is used to configure subject mapping + # https://docs.nats.io/running-a-nats-service/configuration/configuring_subject_mapping + # e.g: + # mappings: + # foo: bar + # foo.cluster.scoped: + # - destination: bar.cluster.scoped + # weight: 70% + # cluster: us-west-1 + # - destination: foobar.cluster.scoped + # weight: 30% + # cluster: us-east-1 + mappings: {} + + jetstream: + enabled: false + + # Jetstream Domain + domain: + + # Jetstream Unique Tag prevent placing a stream in the same availability zone twice. + uniqueTag: + + max_outstanding_catchup: + + ########################## + # # + # Jetstream Encryption # + # # + ########################## + encryption: + # Use key if you want to provide the key via Helm Values + # key: random_key + + # Use a secret reference if you want to get a key from a secret + # secret: + # name: "nats-jetstream-encryption" + # key: "key" + + # Use cipher if you want to choose a different cipher from the default. + # cipher: aes + + ############################# + # # + # Jetstream Memory Storage # + # # + ############################# + memStorage: + enabled: true + size: 1Gi + + ############################ + # # + # Jetstream File Storage # + # # + ############################ + fileStorage: + enabled: true + storageDirectory: /data + + # Set for use with existing PVC + # existingClaim: jetstream-pvc + # claimStorageSize: 10Gi + + # Use below block to create new persistent volume + # only used if existingClaim is not specified + size: 10Gi + # storageClassName: "" + accessModes: + - ReadWriteOnce + annotations: + # key: "value" + + # Use below if fileStorage is not enabled but you are persisting + # data using an alternative to PVC (e.g. hostPath) + # These set the corresponding jetstream configuration in nats.conf. + # store_dir: "/data" + # max_file: "10Gi" + + ####################### + # # + # TLS Configuration # + # # + ####################### + # + # # You can find more on how to setup and trouble shoot TLS connnections at: + # + # # https://docs.nats.io/nats-server/configuration/securing_nats/tls + # + + # tls: + # allowNonTLS: false + # secret: + # name: nats-client-tls + # ca: "ca.crt" + # cert: "tls.crt" + # key: "tls.key" + +mqtt: + enabled: false + ackWait: 1m + maxAckPending: 100 + + ####################### + # # + # TLS Configuration # + # # + ####################### + # + # # You can find more on how to setup and trouble shoot TLS connnections at: + # + # # https://docs.nats.io/nats-server/configuration/securing_nats/tls + # + + # + # tls: + # secret: + # name: nats-mqtt-tls + # ca: "ca.crt" + # cert: "tls.crt" + # key: "tls.key" + +nameOverride: "" +namespaceOverride: "" + +# An array of imagePullSecrets, and they have to be created manually in the same namespace +# ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ +imagePullSecrets: [] + +# Toggle whether to use setup a Pod Security Context +# ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ +securityContext: {} +# securityContext: +# fsGroup: 1000 +# runAsUser: 1000 +# runAsNonRoot: true + +# Affinity for pod assignment +# ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity +affinity: {} + +## Pod priority class name +## ref: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/#priorityclass +priorityClassName: null + +# Service topology +# ref: https://kubernetes.io/docs/concepts/services-networking/service-topology/ +topologyKeys: [] + +# Pod Topology Spread Constraints +# ref https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ +topologySpreadConstraints: [] +# - maxSkew: 1 +# topologyKey: zone +# whenUnsatisfiable: DoNotSchedule + +# Annotations to add to the NATS pods +# ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ +podAnnotations: {} +# key: "value" + +# Define a Pod Disruption Budget for the stateful set +# ref: https://kubernetes.io/docs/concepts/workloads/pods/disruptions/ +podDisruptionBudget: + enabled: true + maxUnavailable: 1 + # minAvailable: 1 + +# Node labels for pod assignment +# Ref: https://kubernetes.io/docs/user-guide/node-selection/ +nodeSelector: {} + +# Node tolerations for server scheduling to nodes with taints +# Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ +# +tolerations: [] +# - key: "key" +# operator: "Equal|Exists" +# value: "value" +# effect: "NoSchedule|PreferNoSchedule|NoExecute(1.6 only)" + +# Annotations to add to the NATS StatefulSet +statefulSetAnnotations: {} + +# Labels to add to the pods of the NATS StatefulSet +statefulSetPodLabels: {} + +# Annotations to add to the NATS Service +serviceAnnotations: {} + +# additionalContainers are the sidecar containers to add to the NATS StatefulSet +additionalContainers: [] + +# additionalVolumes are the additional volumes to add to the NATS StatefulSet +additionalVolumes: [] + +# additionalVolumeMounts are the additional volume mounts to add to the nats-server and nats-server-config-reloader containers +additionalVolumeMounts: [] + +cluster: + enabled: false + replicas: 3 + noAdvertise: false + + # Explicitly set routes for clustering. + # When JetStream is enabled, the serverName must be unique in the cluster. + extraRoutes: [] + + # authorization: + # user: foo + # password: pwd + # timeout: 0.5 + +# Leafnode connections to extend a cluster: +# +# https://docs.nats.io/nats-server/configuration/leafnodes +# +leafnodes: + enabled: false + port: 7422 + noAdvertise: false + # remotes: + # - url: "tls://connect.ngs.global:7422" + + ####################### + # # + # TLS Configuration # + # # + ####################### + # + # # You can find more on how to setup and trouble shoot TLS connnections at: + # + # # https://docs.nats.io/nats-server/configuration/securing_nats/tls + # + + # + # tls: + # secret: + # name: nats-client-tls + # ca: "ca.crt" + # cert: "tls.crt" + # key: "tls.key" + +# Gateway connections to create a super cluster +# +# https://docs.nats.io/nats-server/configuration/gateways +# +gateway: + enabled: false + port: 7522 + name: "default" + # authorization: + # user: foo + # password: pwd + # timeout: 0.5 + # rejectUnknownCluster: false + + # You can add an implicit advertise address instead of using from Node's IP + # could also be a fqdn address + # advertise: "nats.example.com" + + ############################# + # # + # List of remote gateways # + # # + ############################# + # gateways: + # - name: other + # url: nats://my-gateway-url:7522 + + ####################### + # # + # TLS Configuration # + # # + ####################### + # + # # You can find more on how to setup and trouble shoot TLS connnections at: + # + # # https://docs.nats.io/nats-server/configuration/securing_nats/tls + # + # tls: + # secret: + # name: nats-client-tls + # ca: "ca.crt" + # cert: "tls.crt" + # key: "tls.key" + +# In case of both external access and advertisements being +# enabled, an initializer container will be used to gather +# the public ips. +bootconfig: + image: + repository: natsio/nats-boot-config + tag: 0.10.1 + pullPolicy: IfNotPresent + # registry: docker.io + + securityContext: {} + + # Resources to add to the container + # ref: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + resources: {} + +# NATS Box +# +# https://github.com/nats-io/nats-box +# +natsbox: + enabled: true + image: + repository: natsio/nats-box + tag: 0.13.8 + pullPolicy: IfNotPresent + # registry: docker.io + + securityContext: {} + + # Resources to add to the container + # ref: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + resources: {} + + # Annotations to add to the natsbox deployment + # ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ + annotations: {} + # key: "value" + + # Labels to add to the natsbox deployment + # ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ + additionalLabels: {} + + # An array of imagePullSecrets, and they have to be created manually in the same namespace + # ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ + imagePullSecrets: [] + # - name: dockerhub + + # credentials: + # secret: + # name: nats-sys-creds + # key: sys.creds + + # Annotations to add to the box pods + # ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ + podAnnotations: {} + # key: "value" + + # Labels to add to the box pods + # ref: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ + podLabels: {} + # key: "value" + + # Affinity for nats box pod assignment + # ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity + affinity: {} + + # Node labels for pod assignment + # Ref: https://kubernetes.io/docs/user-guide/node-selection/ + nodeSelector: {} + + # Node tolerations for server scheduling to nodes with taints + # Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ + # + tolerations: [] + # - key: "key" + # operator: "Equal|Exists" + # value: "value" + # effect: "NoSchedule|PreferNoSchedule|NoExecute(1.6 only)" + + # Additional nats-box server Volume mounts + extraVolumeMounts: [] + + # Additional nats-box server Volumes + extraVolumes: [] + + # Toggle whether to automatically mount Service Account token in the pod + # not set means default value, boolean true/false overrides default value + # automountServiceAccountToken: true + +# The NATS config reloader image to use. +reloader: + enabled: true + image: + repository: natsio/nats-server-config-reloader + tag: 0.10.1 + pullPolicy: IfNotPresent + # registry: docker.io + + securityContext: {} + + # Resources to add to the container + # ref: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + resources: {} + + extraConfigs: [] + +# Prometheus NATS Exporter configuration. +exporter: + enabled: true + image: + repository: natsio/prometheus-nats-exporter + tag: 0.11.0 + pullPolicy: IfNotPresent + # registry: docker.io + + portName: metrics + securityContext: {} + + # Resources to add to the container + # ref: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + resources: {} + + # override the default args passed to the exporter + # see https://github.com/nats-io/prometheus-nats-exporter#usage + # make sure to pass HTTP monitoring port URL as last arg, e.g ["-connz", "http://localhost:8222/"] + args: [] + # Prometheus operator ServiceMonitor support. Exporter has to be enabled + serviceMonitor: + enabled: false + ## Specify the namespace where Prometheus Operator is running + ## + # namespace: monitoring + labels: {} + annotations: {} + path: /metrics + # interval: + # scrapeTimeout: + +# Authentication setup +auth: + enabled: false + + # basic: + # noAuthUser: + # # List of users that can connect with basic auth, + # # that belong to the global account. + # users: + + # defaultPermissions: + # publish: ["SANDBOX.*"] + # subscribe: ["SANDBOX.>"] + + # # List of accounts with users that can connect + # # using basic auth. + # accounts: + + # Reference to the Operator JWT. + # operatorjwt: + # configMap: + # name: operator-jwt + # key: KO.jwt + + # Token authentication + # token: + + # NKey authentication + # nkeys: + # users: + + # Public key of the System Account + # systemAccount: + + resolver: + # Disables the resolver by default + type: none + + ########################################## + # # + # Embedded NATS Account Server Resolver # + # # + ########################################## + # type: full + + # If the resolver type is 'full', delete when enabled will rename the jwt. + allowDelete: false + + # Interval at which a nats-server with a nats based account resolver will compare + # it's state with one random nats based account resolver in the cluster and if needed, + # exchange jwt and converge on the same set of jwt. + interval: 2m + + # Operator JWT + operator: + + # System Account Public NKEY + systemAccount: + + # resolverPreload: + # : + + # Directory in which the account JWTs will be stored. + store: + dir: "/accounts/jwt" + + # Size of the account JWT storage. + size: 1Gi + + # StorageClass of JWT storage claim. + # storageClassName: "" + + ############################## + # # + # Memory resolver settings # + # # + ############################## + # type: memory + # + # Use a configmap reference which will be mounted + # into the container. + # + # configMap: + # name: nats-accounts + # key: resolver.conf + + ########################## + # # + # URL resolver settings # + # # + ########################## + # type: URL + # url: "http://nats-account-server:9090/jwt/v1/accounts/" + +websocket: + enabled: false + port: 443 + noTLS: true + + sameOrigin: false + allowedOrigins: [] + + # This will optionally specify what host:port for websocket + # connections to be advertised in the cluster. + # advertise: "host:port" + + # Set the handshake timeout for websocket connections + # handshakeTimeout: 5s + +# Network Policy configuration +networkPolicy: + enabled: false + # Don't require client label for connections + # When set to false, only pods with the correct client label will have network access to the ports + # NATS is listening on. When true, NATS will accept connections from any source + # (with the correct destination port). + allowExternal: true + # Add extra ingress rules to the NetworkPolicy + # e.g: + # extraIngress: + # - ports: + # - port: 1234 + # from: + # - podSelector: + # - matchLabels: + # - role: frontend + # - podSelector: + # - matchExpressions: + # - key: role + # operator: In + # values: + # - frontend + extraIngress: [] + # Add extra ingress rules to the NetworkPolicy + # e.g: + # extraEgress: + # - ports: + # - port: 1234 + # to: + # - podSelector: + # - matchLabels: + # - role: frontend + # - podSelector: + # - matchExpressions: + # - key: role + # operator: In + # values: + # - frontend + extraEgress: [] + # Labels to match to allow traffic from other namespaces + ingressNSMatchLabels: {} + # Pod labels to match to allow traffic from other namespaces + ingressNSPodMatchLabels: {} + +# Cluster Domain configured on the kubelets +# https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/ +k8sClusterDomain: cluster.local + +# Define if NATS is using FQDN name for clustering (i.e. nats-0.nats.default.svc.cluster.local) or short name (i.e. nats-0.nats.default). +useFQDN: true + +# Add labels to all the deployed resources +commonLabels: {} + +# podManagementPolicy controls how pods are created during initial scale up, +# when replacing pods on nodes, or when scaling down. +podManagementPolicy: Parallel + +# Shared volume to be mounted in pods for pid +pidVolume: + emptyDir: {} + +# Shared volume to be mounted in pods for advertiseconfig +advertiseconfigVolume: + emptyDir: {} diff --git a/helm/openebs/charts/mayastor/crds/csi-volume-snapshot-class.yaml b/helm/openebs/charts/mayastor/crds/csi-volume-snapshot-class.yaml new file mode 100644 index 0000000..684986b --- /dev/null +++ b/helm/openebs/charts/mayastor/crds/csi-volume-snapshot-class.yaml @@ -0,0 +1,147 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-csi/external-snapshotter/pull/814 + controller-gen.kubebuilder.io/version: v0.11.3 + creationTimestamp: null + name: volumesnapshotclasses.snapshot.storage.k8s.io +spec: + group: snapshot.storage.k8s.io + names: + kind: VolumeSnapshotClass + listKind: VolumeSnapshotClassList + plural: volumesnapshotclasses + shortNames: + - vsclass + - vsclasses + singular: volumesnapshotclass + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .driver + name: Driver + type: string + - description: Determines whether a VolumeSnapshotContent created through the + VolumeSnapshotClass should be deleted when its bound VolumeSnapshot is deleted. + jsonPath: .deletionPolicy + name: DeletionPolicy + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: VolumeSnapshotClass specifies parameters that a underlying storage + system uses when creating a volume snapshot. A specific VolumeSnapshotClass + is used by specifying its name in a VolumeSnapshot object. VolumeSnapshotClasses + are non-namespaced + 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 + deletionPolicy: + description: deletionPolicy determines whether a VolumeSnapshotContent + created through the VolumeSnapshotClass should be deleted when its bound + VolumeSnapshot is deleted. Supported values are "Retain" and "Delete". + "Retain" means that the VolumeSnapshotContent and its physical snapshot + on underlying storage system are kept. "Delete" means that the VolumeSnapshotContent + and its physical snapshot on underlying storage system are deleted. + Required. + enum: + - Delete + - Retain + type: string + driver: + description: driver is the name of the storage driver that handles this + VolumeSnapshotClass. Required. + 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 + parameters: + additionalProperties: + type: string + description: parameters is a key-value map with storage driver specific + parameters for creating snapshots. These values are opaque to Kubernetes. + type: object + required: + - deletionPolicy + - driver + type: object + served: true + storage: true + subresources: {} + - additionalPrinterColumns: + - jsonPath: .driver + name: Driver + type: string + - description: Determines whether a VolumeSnapshotContent created through the + VolumeSnapshotClass should be deleted when its bound VolumeSnapshot is deleted. + jsonPath: .deletionPolicy + name: DeletionPolicy + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + deprecated: true + deprecationWarning: snapshot.storage.k8s.io/v1beta1 VolumeSnapshotClass is deprecated; + use snapshot.storage.k8s.io/v1 VolumeSnapshotClass + name: v1beta1 + schema: + openAPIV3Schema: + description: VolumeSnapshotClass specifies parameters that a underlying storage + system uses when creating a volume snapshot. A specific VolumeSnapshotClass + is used by specifying its name in a VolumeSnapshot object. VolumeSnapshotClasses + are non-namespaced + 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 + deletionPolicy: + description: deletionPolicy determines whether a VolumeSnapshotContent + created through the VolumeSnapshotClass should be deleted when its bound + VolumeSnapshot is deleted. Supported values are "Retain" and "Delete". + "Retain" means that the VolumeSnapshotContent and its physical snapshot + on underlying storage system are kept. "Delete" means that the VolumeSnapshotContent + and its physical snapshot on underlying storage system are deleted. + Required. + enum: + - Delete + - Retain + type: string + driver: + description: driver is the name of the storage driver that handles this + VolumeSnapshotClass. Required. + 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 + parameters: + additionalProperties: + type: string + description: parameters is a key-value map with storage driver specific + parameters for creating snapshots. These values are opaque to Kubernetes. + type: object + required: + - deletionPolicy + - driver + type: object + served: false + storage: false + subresources: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/helm/openebs/charts/mayastor/crds/csi-volume-snapshot-content.yaml b/helm/openebs/charts/mayastor/crds/csi-volume-snapshot-content.yaml new file mode 100644 index 0000000..41feca9 --- /dev/null +++ b/helm/openebs/charts/mayastor/crds/csi-volume-snapshot-content.yaml @@ -0,0 +1,485 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-csi/external-snapshotter/pull/814 + controller-gen.kubebuilder.io/version: v0.11.3 + creationTimestamp: null + name: volumesnapshotcontents.snapshot.storage.k8s.io +spec: + group: snapshot.storage.k8s.io + names: + kind: VolumeSnapshotContent + listKind: VolumeSnapshotContentList + plural: volumesnapshotcontents + shortNames: + - vsc + - vscs + singular: volumesnapshotcontent + scope: Cluster + versions: + - additionalPrinterColumns: + - description: Indicates if the snapshot is ready to be used to restore a volume. + jsonPath: .status.readyToUse + name: ReadyToUse + type: boolean + - description: Represents the complete size of the snapshot in bytes + jsonPath: .status.restoreSize + name: RestoreSize + type: integer + - description: Determines whether this VolumeSnapshotContent and its physical + snapshot on the underlying storage system should be deleted when its bound + VolumeSnapshot is deleted. + jsonPath: .spec.deletionPolicy + name: DeletionPolicy + type: string + - description: Name of the CSI driver used to create the physical snapshot on + the underlying storage system. + jsonPath: .spec.driver + name: Driver + type: string + - description: Name of the VolumeSnapshotClass to which this snapshot belongs. + jsonPath: .spec.volumeSnapshotClassName + name: VolumeSnapshotClass + type: string + - description: Name of the VolumeSnapshot object to which this VolumeSnapshotContent + object is bound. + jsonPath: .spec.volumeSnapshotRef.name + name: VolumeSnapshot + type: string + - description: Namespace of the VolumeSnapshot object to which this VolumeSnapshotContent + object is bound. + jsonPath: .spec.volumeSnapshotRef.namespace + name: VolumeSnapshotNamespace + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: VolumeSnapshotContent represents the actual "on-disk" snapshot + object in the underlying storage system + 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 + spec: + description: spec defines properties of a VolumeSnapshotContent created + by the underlying storage system. Required. + properties: + deletionPolicy: + description: deletionPolicy determines whether this VolumeSnapshotContent + and its physical snapshot on the underlying storage system should + be deleted when its bound VolumeSnapshot is deleted. Supported values + are "Retain" and "Delete". "Retain" means that the VolumeSnapshotContent + and its physical snapshot on underlying storage system are kept. + "Delete" means that the VolumeSnapshotContent and its physical snapshot + on underlying storage system are deleted. For dynamically provisioned + snapshots, this field will automatically be filled in by the CSI + snapshotter sidecar with the "DeletionPolicy" field defined in the + corresponding VolumeSnapshotClass. For pre-existing snapshots, users + MUST specify this field when creating the VolumeSnapshotContent + object. Required. + enum: + - Delete + - Retain + type: string + driver: + description: driver is the name of the CSI driver used to create the + physical snapshot on the underlying storage system. This MUST be + the same as the name returned by the CSI GetPluginName() call for + that driver. Required. + type: string + source: + description: source specifies whether the snapshot is (or should be) + dynamically provisioned or already exists, and just requires a Kubernetes + object representation. This field is immutable after creation. Required. + oneOf: + - required: + - snapshotHandle + - required: + - volumeHandle + properties: + snapshotHandle: + description: snapshotHandle specifies the CSI "snapshot_id" of + a pre-existing snapshot on the underlying storage system for + which a Kubernetes object representation was (or should be) + created. This field is immutable. + type: string + volumeHandle: + description: volumeHandle specifies the CSI "volume_id" of the + volume from which a snapshot should be dynamically taken from. + This field is immutable. + type: string + type: object + sourceVolumeMode: + description: SourceVolumeMode is the mode of the volume whose snapshot + is taken. Can be either “Filesystem” or “Block”. If not specified, + it indicates the source volume's mode is unknown. This field is + immutable. This field is an alpha field. + type: string + volumeSnapshotClassName: + description: name of the VolumeSnapshotClass from which this snapshot + was (or will be) created. Note that after provisioning, the VolumeSnapshotClass + may be deleted or recreated with different set of values, and as + such, should not be referenced post-snapshot creation. + type: string + volumeSnapshotRef: + description: volumeSnapshotRef specifies the VolumeSnapshot object + to which this VolumeSnapshotContent object is bound. VolumeSnapshot.Spec.VolumeSnapshotContentName + field must reference to this VolumeSnapshotContent's name for the + bidirectional binding to be valid. For a pre-existing VolumeSnapshotContent + object, name and namespace of the VolumeSnapshot object MUST be + provided for binding to happen. This field is immutable after creation. + Required. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: 'If referring to a piece of an object instead of + an entire object, this string should contain a valid JSON/Go + field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within + a pod, this would take on a value like: "spec.containers{name}" + (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" + (container with index 2 in this pod). This syntax is chosen + only to have some well-defined way of referencing a part of + an object. TODO: this design is not final and this field is + subject to change in the future.' + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: 'Specific resourceVersion to which this reference + is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + x-kubernetes-map-type: atomic + required: + - deletionPolicy + - driver + - source + - volumeSnapshotRef + type: object + status: + description: status represents the current information of a snapshot. + properties: + creationTime: + description: creationTime is the timestamp when the point-in-time + snapshot is taken by the underlying storage system. In dynamic snapshot + creation case, this field will be filled in by the CSI snapshotter + sidecar with the "creation_time" value returned from CSI "CreateSnapshot" + gRPC call. For a pre-existing snapshot, this field will be filled + with the "creation_time" value returned from the CSI "ListSnapshots" + gRPC call if the driver supports it. If not specified, it indicates + the creation time is unknown. The format of this field is a Unix + nanoseconds time encoded as an int64. On Unix, the command `date + +%s%N` returns the current time in nanoseconds since 1970-01-01 + 00:00:00 UTC. + format: int64 + type: integer + error: + description: error is the last observed error during snapshot creation, + if any. Upon success after retry, this error field will be cleared. + properties: + message: + description: 'message is a string detailing the encountered error + during snapshot creation if specified. NOTE: message may be + logged, and it should not contain sensitive information.' + type: string + time: + description: time is the timestamp when the error was encountered. + format: date-time + type: string + type: object + readyToUse: + description: readyToUse indicates if a snapshot is ready to be used + to restore a volume. In dynamic snapshot creation case, this field + will be filled in by the CSI snapshotter sidecar with the "ready_to_use" + value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing + snapshot, this field will be filled with the "ready_to_use" value + returned from the CSI "ListSnapshots" gRPC call if the driver supports + it, otherwise, this field will be set to "True". If not specified, + it means the readiness of a snapshot is unknown. + type: boolean + restoreSize: + description: restoreSize represents the complete size of the snapshot + in bytes. In dynamic snapshot creation case, this field will be + filled in by the CSI snapshotter sidecar with the "size_bytes" value + returned from CSI "CreateSnapshot" gRPC call. For a pre-existing + snapshot, this field will be filled with the "size_bytes" value + returned from the CSI "ListSnapshots" gRPC call if the driver supports + it. When restoring a volume from this snapshot, the size of the + volume MUST NOT be smaller than the restoreSize if it is specified, + otherwise the restoration will fail. If not specified, it indicates + that the size is unknown. + format: int64 + minimum: 0 + type: integer + snapshotHandle: + description: snapshotHandle is the CSI "snapshot_id" of a snapshot + on the underlying storage system. If not specified, it indicates + that dynamic snapshot creation has either failed or it is still + in progress. + type: string + volumeGroupSnapshotContentName: + description: VolumeGroupSnapshotContentName is the name of the VolumeGroupSnapshotContent + of which this VolumeSnapshotContent is a part of. + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} + - additionalPrinterColumns: + - description: Indicates if the snapshot is ready to be used to restore a volume. + jsonPath: .status.readyToUse + name: ReadyToUse + type: boolean + - description: Represents the complete size of the snapshot in bytes + jsonPath: .status.restoreSize + name: RestoreSize + type: integer + - description: Determines whether this VolumeSnapshotContent and its physical + snapshot on the underlying storage system should be deleted when its bound + VolumeSnapshot is deleted. + jsonPath: .spec.deletionPolicy + name: DeletionPolicy + type: string + - description: Name of the CSI driver used to create the physical snapshot on + the underlying storage system. + jsonPath: .spec.driver + name: Driver + type: string + - description: Name of the VolumeSnapshotClass to which this snapshot belongs. + jsonPath: .spec.volumeSnapshotClassName + name: VolumeSnapshotClass + type: string + - description: Name of the VolumeSnapshot object to which this VolumeSnapshotContent + object is bound. + jsonPath: .spec.volumeSnapshotRef.name + name: VolumeSnapshot + type: string + - description: Namespace of the VolumeSnapshot object to which this VolumeSnapshotContent + object is bound. + jsonPath: .spec.volumeSnapshotRef.namespace + name: VolumeSnapshotNamespace + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + deprecated: true + deprecationWarning: snapshot.storage.k8s.io/v1beta1 VolumeSnapshotContent is deprecated; + use snapshot.storage.k8s.io/v1 VolumeSnapshotContent + name: v1beta1 + schema: + openAPIV3Schema: + description: VolumeSnapshotContent represents the actual "on-disk" snapshot + object in the underlying storage system + 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 + spec: + description: spec defines properties of a VolumeSnapshotContent created + by the underlying storage system. Required. + properties: + deletionPolicy: + description: deletionPolicy determines whether this VolumeSnapshotContent + and its physical snapshot on the underlying storage system should + be deleted when its bound VolumeSnapshot is deleted. Supported values + are "Retain" and "Delete". "Retain" means that the VolumeSnapshotContent + and its physical snapshot on underlying storage system are kept. + "Delete" means that the VolumeSnapshotContent and its physical snapshot + on underlying storage system are deleted. For dynamically provisioned + snapshots, this field will automatically be filled in by the CSI + snapshotter sidecar with the "DeletionPolicy" field defined in the + corresponding VolumeSnapshotClass. For pre-existing snapshots, users + MUST specify this field when creating the VolumeSnapshotContent + object. Required. + enum: + - Delete + - Retain + type: string + driver: + description: driver is the name of the CSI driver used to create the + physical snapshot on the underlying storage system. This MUST be + the same as the name returned by the CSI GetPluginName() call for + that driver. Required. + type: string + source: + description: source specifies whether the snapshot is (or should be) + dynamically provisioned or already exists, and just requires a Kubernetes + object representation. This field is immutable after creation. Required. + properties: + snapshotHandle: + description: snapshotHandle specifies the CSI "snapshot_id" of + a pre-existing snapshot on the underlying storage system for + which a Kubernetes object representation was (or should be) + created. This field is immutable. + type: string + volumeHandle: + description: volumeHandle specifies the CSI "volume_id" of the + volume from which a snapshot should be dynamically taken from. + This field is immutable. + type: string + type: object + volumeSnapshotClassName: + description: name of the VolumeSnapshotClass from which this snapshot + was (or will be) created. Note that after provisioning, the VolumeSnapshotClass + may be deleted or recreated with different set of values, and as + such, should not be referenced post-snapshot creation. + type: string + volumeSnapshotRef: + description: volumeSnapshotRef specifies the VolumeSnapshot object + to which this VolumeSnapshotContent object is bound. VolumeSnapshot.Spec.VolumeSnapshotContentName + field must reference to this VolumeSnapshotContent's name for the + bidirectional binding to be valid. For a pre-existing VolumeSnapshotContent + object, name and namespace of the VolumeSnapshot object MUST be + provided for binding to happen. This field is immutable after creation. + Required. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: 'If referring to a piece of an object instead of + an entire object, this string should contain a valid JSON/Go + field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within + a pod, this would take on a value like: "spec.containers{name}" + (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" + (container with index 2 in this pod). This syntax is chosen + only to have some well-defined way of referencing a part of + an object. TODO: this design is not final and this field is + subject to change in the future.' + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: 'Specific resourceVersion to which this reference + is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + required: + - deletionPolicy + - driver + - source + - volumeSnapshotRef + type: object + status: + description: status represents the current information of a snapshot. + properties: + creationTime: + description: creationTime is the timestamp when the point-in-time + snapshot is taken by the underlying storage system. In dynamic snapshot + creation case, this field will be filled in by the CSI snapshotter + sidecar with the "creation_time" value returned from CSI "CreateSnapshot" + gRPC call. For a pre-existing snapshot, this field will be filled + with the "creation_time" value returned from the CSI "ListSnapshots" + gRPC call if the driver supports it. If not specified, it indicates + the creation time is unknown. The format of this field is a Unix + nanoseconds time encoded as an int64. On Unix, the command `date + +%s%N` returns the current time in nanoseconds since 1970-01-01 + 00:00:00 UTC. + format: int64 + type: integer + error: + description: error is the last observed error during snapshot creation, + if any. Upon success after retry, this error field will be cleared. + properties: + message: + description: 'message is a string detailing the encountered error + during snapshot creation if specified. NOTE: message may be + logged, and it should not contain sensitive information.' + type: string + time: + description: time is the timestamp when the error was encountered. + format: date-time + type: string + type: object + readyToUse: + description: readyToUse indicates if a snapshot is ready to be used + to restore a volume. In dynamic snapshot creation case, this field + will be filled in by the CSI snapshotter sidecar with the "ready_to_use" + value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing + snapshot, this field will be filled with the "ready_to_use" value + returned from the CSI "ListSnapshots" gRPC call if the driver supports + it, otherwise, this field will be set to "True". If not specified, + it means the readiness of a snapshot is unknown. + type: boolean + restoreSize: + description: restoreSize represents the complete size of the snapshot + in bytes. In dynamic snapshot creation case, this field will be + filled in by the CSI snapshotter sidecar with the "size_bytes" value + returned from CSI "CreateSnapshot" gRPC call. For a pre-existing + snapshot, this field will be filled with the "size_bytes" value + returned from the CSI "ListSnapshots" gRPC call if the driver supports + it. When restoring a volume from this snapshot, the size of the + volume MUST NOT be smaller than the restoreSize if it is specified, + otherwise the restoration will fail. If not specified, it indicates + that the size is unknown. + format: int64 + minimum: 0 + type: integer + snapshotHandle: + description: snapshotHandle is the CSI "snapshot_id" of a snapshot + on the underlying storage system. If not specified, it indicates + that dynamic snapshot creation has either failed or it is still + in progress. + type: string + type: object + required: + - spec + type: object + served: false + storage: false + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/helm/openebs/charts/mayastor/crds/csi-volume-snapshot.yaml b/helm/openebs/charts/mayastor/crds/csi-volume-snapshot.yaml new file mode 100644 index 0000000..ee4b547 --- /dev/null +++ b/helm/openebs/charts/mayastor/crds/csi-volume-snapshot.yaml @@ -0,0 +1,387 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + api-approved.kubernetes.io: https://github.com/kubernetes-csi/external-snapshotter/pull/814 + controller-gen.kubebuilder.io/version: v0.11.3 + creationTimestamp: null + name: volumesnapshots.snapshot.storage.k8s.io +spec: + group: snapshot.storage.k8s.io + names: + kind: VolumeSnapshot + listKind: VolumeSnapshotList + plural: volumesnapshots + shortNames: + - vs + singular: volumesnapshot + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Indicates if the snapshot is ready to be used to restore a volume. + jsonPath: .status.readyToUse + name: ReadyToUse + type: boolean + - description: If a new snapshot needs to be created, this contains the name of + the source PVC from which this snapshot was (or will be) created. + jsonPath: .spec.source.persistentVolumeClaimName + name: SourcePVC + type: string + - description: If a snapshot already exists, this contains the name of the existing + VolumeSnapshotContent object representing the existing snapshot. + jsonPath: .spec.source.volumeSnapshotContentName + name: SourceSnapshotContent + type: string + - description: Represents the minimum size of volume required to rehydrate from + this snapshot. + jsonPath: .status.restoreSize + name: RestoreSize + type: string + - description: The name of the VolumeSnapshotClass requested by the VolumeSnapshot. + jsonPath: .spec.volumeSnapshotClassName + name: SnapshotClass + type: string + - description: Name of the VolumeSnapshotContent object to which the VolumeSnapshot + object intends to bind to. Please note that verification of binding actually + requires checking both VolumeSnapshot and VolumeSnapshotContent to ensure + both are pointing at each other. Binding MUST be verified prior to usage of + this object. + jsonPath: .status.boundVolumeSnapshotContentName + name: SnapshotContent + type: string + - description: Timestamp when the point-in-time snapshot was taken by the underlying + storage system. + jsonPath: .status.creationTime + name: CreationTime + type: date + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: VolumeSnapshot is a user's request for either creating a point-in-time + snapshot of a persistent volume, or binding to a pre-existing snapshot. + 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 + spec: + description: 'spec defines the desired characteristics of a snapshot requested + by a user. More info: https://kubernetes.io/docs/concepts/storage/volume-snapshots#volumesnapshots + Required.' + properties: + source: + description: source specifies where a snapshot will be created from. + This field is immutable after creation. Required. + oneOf: + - required: + - persistentVolumeClaimName + - required: + - volumeSnapshotContentName + properties: + persistentVolumeClaimName: + description: persistentVolumeClaimName specifies the name of the + PersistentVolumeClaim object representing the volume from which + a snapshot should be created. This PVC is assumed to be in the + same namespace as the VolumeSnapshot object. This field should + be set if the snapshot does not exists, and needs to be created. + This field is immutable. + type: string + volumeSnapshotContentName: + description: volumeSnapshotContentName specifies the name of a + pre-existing VolumeSnapshotContent object representing an existing + volume snapshot. This field should be set if the snapshot already + exists and only needs a representation in Kubernetes. This field + is immutable. + type: string + type: object + volumeSnapshotClassName: + description: 'VolumeSnapshotClassName is the name of the VolumeSnapshotClass + requested by the VolumeSnapshot. VolumeSnapshotClassName may be + left nil to indicate that the default SnapshotClass should be used. + A given cluster may have multiple default Volume SnapshotClasses: + one default per CSI Driver. If a VolumeSnapshot does not specify + a SnapshotClass, VolumeSnapshotSource will be checked to figure + out what the associated CSI Driver is, and the default VolumeSnapshotClass + associated with that CSI Driver will be used. If more than one VolumeSnapshotClass + exist for a given CSI Driver and more than one have been marked + as default, CreateSnapshot will fail and generate an event. Empty + string is not allowed for this field.' + type: string + required: + - source + type: object + status: + description: status represents the current information of a snapshot. + Consumers must verify binding between VolumeSnapshot and VolumeSnapshotContent + objects is successful (by validating that both VolumeSnapshot and VolumeSnapshotContent + point at each other) before using this object. + properties: + boundVolumeSnapshotContentName: + description: 'boundVolumeSnapshotContentName is the name of the VolumeSnapshotContent + object to which this VolumeSnapshot object intends to bind to. If + not specified, it indicates that the VolumeSnapshot object has not + been successfully bound to a VolumeSnapshotContent object yet. NOTE: + To avoid possible security issues, consumers must verify binding + between VolumeSnapshot and VolumeSnapshotContent objects is successful + (by validating that both VolumeSnapshot and VolumeSnapshotContent + point at each other) before using this object.' + type: string + creationTime: + description: creationTime is the timestamp when the point-in-time + snapshot is taken by the underlying storage system. In dynamic snapshot + creation case, this field will be filled in by the snapshot controller + with the "creation_time" value returned from CSI "CreateSnapshot" + gRPC call. For a pre-existing snapshot, this field will be filled + with the "creation_time" value returned from the CSI "ListSnapshots" + gRPC call if the driver supports it. If not specified, it may indicate + that the creation time of the snapshot is unknown. + format: date-time + type: string + error: + description: error is the last observed error during snapshot creation, + if any. This field could be helpful to upper level controllers(i.e., + application controller) to decide whether they should continue on + waiting for the snapshot to be created based on the type of error + reported. The snapshot controller will keep retrying when an error + occurs during the snapshot creation. Upon success, this error field + will be cleared. + properties: + message: + description: 'message is a string detailing the encountered error + during snapshot creation if specified. NOTE: message may be + logged, and it should not contain sensitive information.' + type: string + time: + description: time is the timestamp when the error was encountered. + format: date-time + type: string + type: object + readyToUse: + description: readyToUse indicates if the snapshot is ready to be used + to restore a volume. In dynamic snapshot creation case, this field + will be filled in by the snapshot controller with the "ready_to_use" + value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing + snapshot, this field will be filled with the "ready_to_use" value + returned from the CSI "ListSnapshots" gRPC call if the driver supports + it, otherwise, this field will be set to "True". If not specified, + it means the readiness of a snapshot is unknown. + type: boolean + restoreSize: + description: restoreSize represents the minimum size of volume required + to create a volume from this snapshot. In dynamic snapshot creation + case, this field will be filled in by the snapshot controller with + the "size_bytes" value returned from CSI "CreateSnapshot" gRPC call. + For a pre-existing snapshot, this field will be filled with the + "size_bytes" value returned from the CSI "ListSnapshots" gRPC call + if the driver supports it. When restoring a volume from this snapshot, + the size of the volume MUST NOT be smaller than the restoreSize + if it is specified, otherwise the restoration will fail. If not + specified, it indicates that the size is unknown. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + type: string + x-kubernetes-int-or-string: true + volumeGroupSnapshotName: + description: VolumeGroupSnapshotName is the name of the VolumeGroupSnapshot + of which this VolumeSnapshot is a part of. + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} + - additionalPrinterColumns: + - description: Indicates if the snapshot is ready to be used to restore a volume. + jsonPath: .status.readyToUse + name: ReadyToUse + type: boolean + - description: If a new snapshot needs to be created, this contains the name of + the source PVC from which this snapshot was (or will be) created. + jsonPath: .spec.source.persistentVolumeClaimName + name: SourcePVC + type: string + - description: If a snapshot already exists, this contains the name of the existing + VolumeSnapshotContent object representing the existing snapshot. + jsonPath: .spec.source.volumeSnapshotContentName + name: SourceSnapshotContent + type: string + - description: Represents the minimum size of volume required to rehydrate from + this snapshot. + jsonPath: .status.restoreSize + name: RestoreSize + type: string + - description: The name of the VolumeSnapshotClass requested by the VolumeSnapshot. + jsonPath: .spec.volumeSnapshotClassName + name: SnapshotClass + type: string + - description: Name of the VolumeSnapshotContent object to which the VolumeSnapshot + object intends to bind to. Please note that verification of binding actually + requires checking both VolumeSnapshot and VolumeSnapshotContent to ensure + both are pointing at each other. Binding MUST be verified prior to usage of + this object. + jsonPath: .status.boundVolumeSnapshotContentName + name: SnapshotContent + type: string + - description: Timestamp when the point-in-time snapshot was taken by the underlying + storage system. + jsonPath: .status.creationTime + name: CreationTime + type: date + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + deprecated: true + deprecationWarning: snapshot.storage.k8s.io/v1beta1 VolumeSnapshot is deprecated; + use snapshot.storage.k8s.io/v1 VolumeSnapshot + name: v1beta1 + schema: + openAPIV3Schema: + description: VolumeSnapshot is a user's request for either creating a point-in-time + snapshot of a persistent volume, or binding to a pre-existing snapshot. + 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 + spec: + description: 'spec defines the desired characteristics of a snapshot requested + by a user. More info: https://kubernetes.io/docs/concepts/storage/volume-snapshots#volumesnapshots + Required.' + properties: + source: + description: source specifies where a snapshot will be created from. + This field is immutable after creation. Required. + properties: + persistentVolumeClaimName: + description: persistentVolumeClaimName specifies the name of the + PersistentVolumeClaim object representing the volume from which + a snapshot should be created. This PVC is assumed to be in the + same namespace as the VolumeSnapshot object. This field should + be set if the snapshot does not exists, and needs to be created. + This field is immutable. + type: string + volumeSnapshotContentName: + description: volumeSnapshotContentName specifies the name of a + pre-existing VolumeSnapshotContent object representing an existing + volume snapshot. This field should be set if the snapshot already + exists and only needs a representation in Kubernetes. This field + is immutable. + type: string + type: object + volumeSnapshotClassName: + description: 'VolumeSnapshotClassName is the name of the VolumeSnapshotClass + requested by the VolumeSnapshot. VolumeSnapshotClassName may be + left nil to indicate that the default SnapshotClass should be used. + A given cluster may have multiple default Volume SnapshotClasses: + one default per CSI Driver. If a VolumeSnapshot does not specify + a SnapshotClass, VolumeSnapshotSource will be checked to figure + out what the associated CSI Driver is, and the default VolumeSnapshotClass + associated with that CSI Driver will be used. If more than one VolumeSnapshotClass + exist for a given CSI Driver and more than one have been marked + as default, CreateSnapshot will fail and generate an event. Empty + string is not allowed for this field.' + type: string + required: + - source + type: object + status: + description: status represents the current information of a snapshot. + Consumers must verify binding between VolumeSnapshot and VolumeSnapshotContent + objects is successful (by validating that both VolumeSnapshot and VolumeSnapshotContent + point at each other) before using this object. + properties: + boundVolumeSnapshotContentName: + description: 'boundVolumeSnapshotContentName is the name of the VolumeSnapshotContent + object to which this VolumeSnapshot object intends to bind to. If + not specified, it indicates that the VolumeSnapshot object has not + been successfully bound to a VolumeSnapshotContent object yet. NOTE: + To avoid possible security issues, consumers must verify binding + between VolumeSnapshot and VolumeSnapshotContent objects is successful + (by validating that both VolumeSnapshot and VolumeSnapshotContent + point at each other) before using this object.' + type: string + creationTime: + description: creationTime is the timestamp when the point-in-time + snapshot is taken by the underlying storage system. In dynamic snapshot + creation case, this field will be filled in by the snapshot controller + with the "creation_time" value returned from CSI "CreateSnapshot" + gRPC call. For a pre-existing snapshot, this field will be filled + with the "creation_time" value returned from the CSI "ListSnapshots" + gRPC call if the driver supports it. If not specified, it may indicate + that the creation time of the snapshot is unknown. + format: date-time + type: string + error: + description: error is the last observed error during snapshot creation, + if any. This field could be helpful to upper level controllers(i.e., + application controller) to decide whether they should continue on + waiting for the snapshot to be created based on the type of error + reported. The snapshot controller will keep retrying when an error + occurs during the snapshot creation. Upon success, this error field + will be cleared. + properties: + message: + description: 'message is a string detailing the encountered error + during snapshot creation if specified. NOTE: message may be + logged, and it should not contain sensitive information.' + type: string + time: + description: time is the timestamp when the error was encountered. + format: date-time + type: string + type: object + readyToUse: + description: readyToUse indicates if the snapshot is ready to be used + to restore a volume. In dynamic snapshot creation case, this field + will be filled in by the snapshot controller with the "ready_to_use" + value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing + snapshot, this field will be filled with the "ready_to_use" value + returned from the CSI "ListSnapshots" gRPC call if the driver supports + it, otherwise, this field will be set to "True". If not specified, + it means the readiness of a snapshot is unknown. + type: boolean + restoreSize: + description: restoreSize represents the minimum size of volume required + to create a volume from this snapshot. In dynamic snapshot creation + case, this field will be filled in by the snapshot controller with + the "size_bytes" value returned from CSI "CreateSnapshot" gRPC call. + For a pre-existing snapshot, this field will be filled with the + "size_bytes" value returned from the CSI "ListSnapshots" gRPC call + if the driver supports it. When restoring a volume from this snapshot, + the size of the volume MUST NOT be smaller than the restoreSize + if it is specified, otherwise the restoration will fail. If not + specified, it indicates that the size is unknown. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + type: string + x-kubernetes-int-or-string: true + type: object + required: + - spec + type: object + served: false + storage: false + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/helm/openebs/charts/mayastor/crds/jaeger.yaml b/helm/openebs/charts/mayastor/crds/jaeger.yaml new file mode 100644 index 0000000..36f9fb8 --- /dev/null +++ b/helm/openebs/charts/mayastor/crds/jaeger.yaml @@ -0,0 +1,44 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: jaegers.jaegertracing.io + labels: + app: jaeger-operator +spec: + group: jaegertracing.io + names: + kind: Jaeger + listKind: JaegerList + plural: jaegers + singular: jaeger + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + x-kubernetes-preserve-unknown-fields: true + type: object + additionalPrinterColumns: + - description: Jaeger instance's status + jsonPath: .status.phase + name: Status + type: string + - description: Jaeger Version + jsonPath: .status.version + name: Version + type: string + - description: Jaeger deployment strategy + jsonPath: .spec.strategy + name: Strategy + type: string + - description: Jaeger storage type + jsonPath: .spec.storage.type + name: Storage + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + served: true + storage: true + subresources: + status: {} diff --git a/helm/openebs/charts/mayastor/doc.yaml b/helm/openebs/charts/mayastor/doc.yaml new file mode 100644 index 0000000..b161af4 --- /dev/null +++ b/helm/openebs/charts/mayastor/doc.yaml @@ -0,0 +1,19 @@ +project: + name: OpenEBS Mayastor + shortName: Mayastor + url: https://openebs.io/mayastor + description: Fast NVMe backed storage for enterprise users on Kubernetes +repository: + url: https://openebs.github.io/mayastor-extensions/ + name: mayastor +chart: + name: mayastor + version: 2.4.0 + values: "-- generate from values file --" + valuesExample: "-- generate from values file --" +prerequisites: + - "Kubernetes v1.21+" + - Linux Kernel 5.4+ on Worker Nodes with required nvme modules loaded +release: + name: mayastor + namespace: mayastor diff --git a/helm/openebs/charts/mayastor/product.yaml b/helm/openebs/charts/mayastor/product.yaml new file mode 100644 index 0000000..56d86b7 --- /dev/null +++ b/helm/openebs/charts/mayastor/product.yaml @@ -0,0 +1,3 @@ +name: Mayastor +project: OpenEBS +domain: openebs.io \ No newline at end of file diff --git a/helm/openebs/charts/mayastor/templates/NOTES.txt b/helm/openebs/charts/mayastor/templates/NOTES.txt new file mode 100644 index 0000000..eec7098 --- /dev/null +++ b/helm/openebs/charts/mayastor/templates/NOTES.txt @@ -0,0 +1,4 @@ +OpenEBS Mayastor has been installed. Check its status by running: +$ kubectl get pods -n {{ .Release.Namespace }} + +For more information or to view the documentation, visit our website at https://mayastor.gitbook.io/introduction/. diff --git a/helm/openebs/charts/mayastor/templates/_helpers.tpl b/helm/openebs/charts/mayastor/templates/_helpers.tpl new file mode 100644 index 0000000..dad5394 --- /dev/null +++ b/helm/openebs/charts/mayastor/templates/_helpers.tpl @@ -0,0 +1,209 @@ +{{/* vim: set filetype=mustache: */}} + +{{/* +Renders a value that contains template. +Usage: +{{ include "render" ( dict "value" .Values.path.to.the.Value "context" $) }} +*/}} +{{- define "render" -}} + {{- if typeIs "string" .value }} + {{- tpl .value .context }} + {{- else }} + {{- tpl (.value | toYaml) .context }} + {{- end }} +{{- end -}} + +{{/* +Renders the CORE server init container, if enabled +Usage: +{{ include "base_init_core_containers" . }} +*/}} +{{- define "base_init_core_containers" -}} + {{- if .Values.base.initCoreContainers.enabled }} + {{- include "render" (dict "value" .Values.base.initCoreContainers.containers "context" $) | nindent 8 }} + {{- end }} +{{- end -}} + +{{/* +Renders the HA NODE AGENT init container, if enabled +Usage: +{{ include "base_init_ha_node_containers" . }} +*/}} +{{- define "base_init_ha_node_containers" -}} + {{- if .Values.base.initHaNodeContainers.enabled }} + {{- include "render" (dict "value" .Values.base.initHaNodeContainers.containers "context" $) | nindent 8 }} + {{- end }} +{{- end -}} + +{{/* +Renders the base init containers for all deployments, if any +Usage: +{{ include "base_init_containers" . }} +*/}} +{{- define "base_init_containers" -}} + {{- if .Values.base.initContainers.enabled }} + {{- include "render" (dict "value" .Values.base.initContainers.containers "context" $) | nindent 8 }} + {{- end }} + {{- include "jaeger_agent_init_container" . }} +{{- end -}} + +{{/* +Renders the jaeger agent init container, if enabled +Usage: +{{ include "jaeger_agent_init_container" . }} +*/}} +{{- define "jaeger_agent_init_container" -}} + {{- if .Values.base.jaeger.enabled }} + {{- if .Values.base.jaeger.initContainer }} + {{- include "render" (dict "value" .Values.base.jaeger.agent.initContainer "context" $) | nindent 8 }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +Renders the base image pull secrets for all deployments, if any +Usage: +{{ include "base_pull_secrets" . }} +*/}} +{{- define "base_pull_secrets" -}} + {{- if .Values.base.imagePullSecrets.enabled }} + {{- include "render" (dict "value" .Values.base.imagePullSecrets.secrets "context" $) | nindent 8 }} + {{- end }} +{{- end -}} + +{{/* +Renders the REST server init container, if enabled +Usage: +{{- include "rest_agent_init_container" . }} +*/}} +{{- define "rest_agent_init_container" -}} + {{- if .Values.base.initRestContainer.enabled }} + {{- include "render" (dict "value" .Values.base.initRestContainer.initContainer "context" $) | nindent 8 }} + {{- end }} +{{- end -}} + +{{/* +Renders the jaeger scheduling rules, if any +Usage: +{{ include "jaeger_scheduling" . }} +*/}} +{{- define "jaeger_scheduling" -}} + {{- if index .Values "jaeger-operator" "affinity" }} + affinity: + {{- include "render" (dict "value" (index .Values "jaeger-operator" "affinity") "context" $) | nindent 4 }} + {{- end }} + {{- if index .Values "jaeger-operator" "tolerations" }} + tolerations: + {{- include "render" (dict "value" (index .Values "jaeger-operator" "tolerations") "context" $) | nindent 4 }} + {{- end }} +{{- end -}} + +{{/* Generate Core list specification (-l param of io-engine) */}} +{{- define "cpuFlag" -}} +{{- include "coreListUniq" . -}} +{{- end -}} + +{{/* Get the number of cores from the coreList */}} +{{- define "coreCount" -}} +{{- include "coreListUniq" . | split "," | len -}} +{{- end -}} + +{{/* Get a list of cores as a comma-separated list */}} +{{- define "coreListUniq" -}} +{{- if .Values.io_engine.coreList -}} +{{- $cores_pre := .Values.io_engine.coreList -}} +{{- if not (kindIs "slice" .Values.io_engine.coreList) -}} +{{- $cores_pre = list $cores_pre -}} +{{- end -}} +{{- $cores := list -}} +{{- range $index, $value := $cores_pre | uniq -}} +{{- $value = $value | toString | replace " " "" }} +{{- if eq ($value | int | toString) $value -}} +{{- $cores = append $cores $value -}} +{{- end -}} +{{- end -}} +{{- $first := first $cores | required (print "At least one core must be specified in io_engine.coreList") -}} +{{- $cores | join "," -}} +{{- else -}} +{{- if gt 1 (.Values.io_engine.cpuCount | int) -}} +{{- fail ".Values.io_engine.cpuCount must be >= 1" -}} +{{- end -}} +{{- untilStep 1 (add 1 .Values.io_engine.cpuCount | int) 1 | join "," -}} +{{- end -}} +{{- end }} + +{{/* +Adds the project domain to labels +Usage: +{{ include "label_prefix" . }}/release: {{ .Release.Name }} +*/}} +{{- define "label_prefix" -}} + {{ $product := .Files.Get "product.yaml" | fromYaml }} + {{- print $product.domain -}} +{{- end -}} + +<<<<<<< HEAD + +{{/* +Creates the tolerations based on the global and component wise tolerations, with early eviction +Usage: +{{ include "tolerations_with_early_eviction" (dict "template" . "localTolerations" .Values.path.to.local.tolerations) }} +*/}} +{{- define "tolerations_with_early_eviction" -}} +{{- toYaml .template.Values.earlyEvictionTolerations | nindent 8 }} +{{- if .localTolerations }} + {{- toYaml .localTolerations | nindent 8 }} +{{- else if .template.Values.tolerations }} + {{- toYaml .template.Values.tolerations | nindent 8 }} +{{- end }} +{{- end }} + + +{{/* +Creates the tolerations based on the global and component wise tolerations +Usage: +{{ include "tolerations" (dict "template" . "localTolerations" .Values.path.to.local.tolerations) }} +*/}} +{{- define "tolerations" -}} +{{- if .localTolerations }} + {{- toYaml .localTolerations | nindent 8 }} +{{- else if .template.Values.tolerations }} + {{- toYaml .template.Values.tolerations | nindent 8 }} +{{- end }} +{{- end }} + +{{/* +Generates the priority class name, with the given `template` and the `localPriorityClass` +Usage: +{{ include "priority_class" (dict "template" . "localPriorityClass" .Values.path.to.local.priorityClassName) }} +*/}} +{{- define "priority_class" -}} + {{- if typeIs "string" .localPriorityClass }} + {{- if .localPriorityClass -}} + {{ printf "%s" .localPriorityClass -}} + {{- else if .template.Values.priorityClassName -}} + {{ printf "%s" .template.Values.priorityClassName -}} + {{- else -}} + {{ printf "" -}} + {{- end -}} + {{- end -}} +{{- end -}} + + +{{/* +Generates the priority class name, with the given `template` and the `localPriorityClass`, sets to mayastor default priority class +if both are empty +Usage: +{{ include "priority_class_with_default" (dict "template" . "localPriorityClass" .Values.path.to.local.priorityClassName) }} +*/}} +{{- define "priority_class_with_default" -}} + {{- if typeIs "string" .localPriorityClass }} + {{- if .localPriorityClass -}} + {{ printf "%s" .localPriorityClass -}} + {{- else if .template.Values.priorityClassName -}} + {{ printf "%s" .template.Values.priorityClassName -}} + {{- else -}} + {{ printf "%s-cluster-critical" .template.Release.Name -}} + {{- end -}} + {{- end -}} +{{- end -}} diff --git a/helm/openebs/charts/mayastor/templates/etcd/storage/localpv-storageclass.yaml b/helm/openebs/charts/mayastor/templates/etcd/storage/localpv-storageclass.yaml new file mode 100644 index 0000000..0f16148 --- /dev/null +++ b/helm/openebs/charts/mayastor/templates/etcd/storage/localpv-storageclass.yaml @@ -0,0 +1,16 @@ +{{ if and (index .Values "localpv-provisioner" "enabled") .Values.etcd.persistence.enabled }} +apiVersion: storage.k8s.io/v1 +kind: StorageClass +metadata: + annotations: + cas.openebs.io/config: | + - name: StorageType + value: "hostpath" + - name: BasePath + value: {{ tpl (.Values.etcd.localpvScConfig.basePath | quote) . }} + openebs.io/cas-type: local + name: {{ (tpl (.Values.etcd.localpvScConfig.name) .) | required (print "StorageClass name for etcd localpv storage cannot be empty") }} +provisioner: openebs.io/local +reclaimPolicy: {{ .Values.etcd.localpvScConfig.reclaimPolicy }} +volumeBindingMode: {{ .Values.etcd.localpvScConfig.volumeBindingMode }} +{{ end }} diff --git a/helm/openebs/charts/mayastor/templates/etcd/storage/localpv.yaml b/helm/openebs/charts/mayastor/templates/etcd/storage/localpv.yaml new file mode 100644 index 0000000..f690dda --- /dev/null +++ b/helm/openebs/charts/mayastor/templates/etcd/storage/localpv.yaml @@ -0,0 +1,22 @@ +--- +{{ if and .Values.etcd.persistence.enabled (eq .Values.etcd.persistence.storageClass "manual") }} +{{- range $index, $end := until (.Values.etcd.replicaCount | int) }} +apiVersion: v1 +kind: PersistentVolume +metadata: + name: etcd-volume-{{ $index }} + labels: + statefulset.kubernetes.io/pod-name: {{ print $.Release.Name }}-etcd-{{ $index }} +spec: + storageClassName: manual + # You must also delete the hostpath on the node + persistentVolumeReclaimPolicy: {{ $.Values.etcd.persistence.reclaimPolicy }} + capacity: + storage: {{ $.Values.etcd.persistence.size | quote }} + accessModes: + - ReadWriteOnce + hostPath: + path: "/var/local/{{ $.Release.Name }}/etcd/pod-{{ $index }}" +--- +{{- end }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/templates/jaeger-operator/jaeger.yaml b/helm/openebs/charts/mayastor/templates/jaeger-operator/jaeger.yaml new file mode 100644 index 0000000..5face13 --- /dev/null +++ b/helm/openebs/charts/mayastor/templates/jaeger-operator/jaeger.yaml @@ -0,0 +1,23 @@ +{{- if .Values.base.jaeger.enabled }} +apiVersion: jaegertracing.io/v1 +kind: Jaeger +metadata: + name: jaeger + namespace: {{ .Release.Namespace }} +labels: + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + {{ include "label_prefix" . }}/version: {{ .Chart.Version }} +spec: + strategy: allInOne + ingress: + enabled: false + {{- include "jaeger_scheduling" . }} + query: + serviceType: NodePort + nodePort: 30012 + storage: + type: memory + options: + memory: + max-traces: 100000 +{{- end }} diff --git a/helm/openebs/charts/mayastor/templates/loki-stack/storage/localpv-storageclass.yaml b/helm/openebs/charts/mayastor/templates/loki-stack/storage/localpv-storageclass.yaml new file mode 100644 index 0000000..57c457b --- /dev/null +++ b/helm/openebs/charts/mayastor/templates/loki-stack/storage/localpv-storageclass.yaml @@ -0,0 +1,16 @@ +{{ if and (index .Values "localpv-provisioner" "enabled") (index .Values "loki-stack" "loki" "persistence" "enabled") (index .Values "loki-stack" "enabled") }} +apiVersion: storage.k8s.io/v1 +kind: StorageClass +metadata: + annotations: + cas.openebs.io/config: | + - name: StorageType + value: "hostpath" + - name: BasePath + value: {{ tpl (( index .Values "loki-stack" "localpvScConfig" "basePath" ) | quote ) . }} + openebs.io/cas-type: local + name: {{ (tpl (index .Values "loki-stack" "localpvScConfig" "name") .) | required (print "StorageClass name for loki localpv storage cannot be empty") }} +provisioner: openebs.io/local +reclaimPolicy: {{ (index .Values "loki-stack" "localpvScConfig" "reclaimPolicy") }} +volumeBindingMode: {{ (index .Values "loki-stack" "localpvScConfig" "volumeBindingMode") }} +{{ end }} diff --git a/helm/openebs/charts/mayastor/templates/loki-stack/storage/localpv.yaml b/helm/openebs/charts/mayastor/templates/loki-stack/storage/localpv.yaml new file mode 100644 index 0000000..5a672af --- /dev/null +++ b/helm/openebs/charts/mayastor/templates/loki-stack/storage/localpv.yaml @@ -0,0 +1,20 @@ +--- + +{{ if and (eq ( index .Values "loki-stack" "loki" "persistence" "storageClassName" ) "manual") ( index .Values "loki-stack" "loki" "persistence" "enabled" ) ( index .Values "loki-stack" "enabled" ) }} +apiVersion: v1 +kind: PersistentVolume +metadata: + name: loki-volume-0 + labels: + statefulset.kubernetes.io/pod-name: {{ .Release.Name }}-loki-0 +spec: + storageClassName: manual + persistentVolumeReclaimPolicy: {{ index .Values "loki-stack" "loki" "persistence" "reclaimPolicy" }} + capacity: + storage: {{ index .Values "loki-stack" "loki" "persistence" "size" }} + accessModes: + - ReadWriteOnce + hostPath: + path: "/var/local/{{ .Release.Name }}/loki" +--- +{{- end }} diff --git a/helm/openebs/charts/mayastor/templates/mayastor/agents/core/agent-core-deployment.yaml b/helm/openebs/charts/mayastor/templates/mayastor/agents/core/agent-core-deployment.yaml new file mode 100644 index 0000000..0dbed16 --- /dev/null +++ b/helm/openebs/charts/mayastor/templates/mayastor/agents/core/agent-core-deployment.yaml @@ -0,0 +1,108 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Release.Name }}-agent-core + labels: + app: agent-core + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + {{ include "label_prefix" . }}/version: {{ .Chart.Version }} +spec: + replicas: 1 + selector: + matchLabels: + app: agent-core + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + template: + metadata: + labels: + app: agent-core + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + {{ include "label_prefix" . }}/version: {{ .Chart.Version }} + {{ include "label_prefix" . }}/logging: "true" + spec: + serviceAccount: {{ .Release.Name }}-service-account + imagePullSecrets: + {{- include "base_pull_secrets" . }} + initContainers: + {{- include "base_init_core_containers" . }} + {{- if $pcName := include "priority_class_with_default" (dict "template" . "localPriorityClass" .Values.agents.core.priorityClassName) }} + priorityClassName: {{ $pcName }} + {{- end }} + {{- if .Values.nodeSelector }} + nodeSelector: {{- toYaml .Values.nodeSelector | nindent 8 }} + {{- end }} + {{- if $tolerations := include "tolerations_with_early_eviction" (dict "template" . "localTolerations" .Values.agents.core.tolerations) }} + tolerations: {{ $tolerations }} + {{- end }} + containers: + - name: agent-core + resources: + limits: + cpu: {{ .Values.agents.core.resources.limits.cpu | quote }} + memory: {{ .Values.agents.core.resources.limits.memory | quote }} + requests: + cpu: {{ .Values.agents.core.resources.requests.cpu | quote }} + memory: {{ .Values.agents.core.resources.requests.memory | quote }} + image: "{{ .Values.image.registry }}/{{ .Values.image.repo }}/{{ .Chart.Name }}-agent-core:{{ default .Values.image.tag .Values.image.repoTags.controlPlane }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + args: + - "-s{{ .Release.Name }}-etcd:{{ .Values.etcd.service.port }}" + - "--request-timeout={{ .Values.base.default_req_timeout }}" + - "--cache-period={{ .Values.base.cache_poll_period }}"{{ if .Values.base.jaeger.enabled }} + - "--jaeger={{ .Values.base.jaeger.agent.name }}:{{ .Values.base.jaeger.agent.port }}"{{ end }} + - "--grpc-server-addr=0.0.0.0:50051" + - "--pool-commitment={{ .Values.agents.core.capacity.thin.poolCommitment }}" + - "--snapshot-commitment={{ .Values.agents.core.capacity.thin.snapshotCommitment }}" + - "--volume-commitment-initial={{ .Values.agents.core.capacity.thin.volumeCommitmentInitial }}" + - "--volume-commitment={{ .Values.agents.core.capacity.thin.volumeCommitment }}"{{ if .Values.agents.core.partialRebuildWaitPeriod }} + - "--faulted-child-wait-period={{ .Values.agents.core.partialRebuildWaitPeriod }}"{{ end }}{{ if .Values.eventing.enabled }} + - "--events-url=nats://{{ .Release.Name }}-nats:4222"{{ end }} + ports: + - containerPort: 50051 + env: + - name: RUST_LOG + value: {{ .Values.agents.core.logLevel }} + {{- if default .Values.base.logSilenceLevel .Values.agents.core.logSilenceLevel }} + - name: RUST_LOG_SILENCE + value: {{ default .Values.base.logSilenceLevel .Values.agents.core.logSilenceLevel }} + {{- end }} + - name: MY_POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: MY_POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: agent-ha-cluster + resources: + limits: + cpu: {{ .Values.agents.ha.cluster.resources.limits.cpu | quote }} + memory: {{ .Values.agents.ha.cluster.resources.limits.memory | quote }} + requests: + cpu: {{ .Values.agents.ha.cluster.resources.requests.cpu | quote }} + memory: {{ .Values.agents.ha.cluster.resources.requests.memory | quote }} + image: "{{ .Values.image.registry }}/{{ .Values.image.repo }}/{{ .Chart.Name }}-agent-ha-cluster:{{ default .Values.image.tag .Values.image.repoTags.controlPlane }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + args: + - "-g=0.0.0.0:50052" + - "--store=http://{{ .Release.Name }}-etcd:{{ .Values.etcd.service.port }}" + - "--core-grpc=https://{{ .Release.Name }}-agent-core:50051"{{ if .Values.base.jaeger.enabled }} + - "--jaeger={{ .Values.base.jaeger.agent.name }}:{{ .Values.base.jaeger.agent.port }}"{{ end }} + ports: + - containerPort: 50052 + env: + - name: RUST_LOG + value: {{ .Values.agents.core.logLevel }} + {{- if default .Values.base.logSilenceLevel .Values.agents.core.logSilenceLevel }} + - name: RUST_LOG_SILENCE + value: {{ default .Values.base.logSilenceLevel .Values.agents.core.logSilenceLevel }} + {{- end }} + - name: MY_POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: MY_POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace diff --git a/helm/openebs/charts/mayastor/templates/mayastor/agents/core/agent-core-service.yaml b/helm/openebs/charts/mayastor/templates/mayastor/agents/core/agent-core-service.yaml new file mode 100644 index 0000000..52b39a4 --- /dev/null +++ b/helm/openebs/charts/mayastor/templates/mayastor/agents/core/agent-core-service.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ .Release.Name }}-agent-core + labels: + app: agent-core + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + {{ include "label_prefix" . }}/version: {{ .Chart.Version }} +spec: + selector: + app: agent-core + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + ports: + - name: grpc + port: 50051 + - name: ha-cluster + port: 50052 diff --git a/helm/openebs/charts/mayastor/templates/mayastor/agents/ha/ha-node-daemonset.yaml b/helm/openebs/charts/mayastor/templates/mayastor/agents/ha/ha-node-daemonset.yaml new file mode 100644 index 0000000..3b1d550 --- /dev/null +++ b/helm/openebs/charts/mayastor/templates/mayastor/agents/ha/ha-node-daemonset.yaml @@ -0,0 +1,115 @@ +{{- if .Values.agents.ha.enabled }} +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: {{ .Release.Name }}-agent-ha-node + labels: + app: agent-ha-node + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + {{ include "label_prefix" . }}/version: {{ .Chart.Version }} +spec: + selector: + matchLabels: + app: agent-ha-node + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + updateStrategy: + type: RollingUpdate + rollingUpdate: + maxUnavailable: 1 + minReadySeconds: 10 + template: + metadata: + labels: + app: agent-ha-node + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + {{ include "label_prefix" . }}/version: {{ .Chart.Version }} + {{ include "label_prefix" . }}/logging: "true" + spec: + hostNetwork: true + dnsPolicy: ClusterFirstWithHostNet + initContainers: + {{- include "base_init_ha_node_containers" . }} + imagePullSecrets: + {{- include "base_pull_secrets" . }} + {{- if $pcName := include "priority_class" (dict "template" . "localPriorityClass" .Values.agents.ha.node.priorityClassName) }} + priorityClassName: {{ $pcName }} + {{- end }} + nodeSelector: + {{- if .Values.nodeSelector }} + {{- toYaml .Values.nodeSelector | nindent 8 }} + {{- end }} + {{- if .Values.csi.node.topology.nodeSelector }} + {{- range $key, $val := .Values.csi.node.topology.segments }} + {{ $key }}: {{ $val }} + {{- end }} + {{- end }} + {{- if $tolerations := include "tolerations" (dict "template" . "localTolerations" .Values.agents.ha.node.tolerations) }} + tolerations: {{ $tolerations }} + {{- end }} + containers: + - name: agent-ha-node + image: "{{ .Values.image.registry }}/{{ .Values.image.repo }}/{{ .Chart.Name }}-agent-ha-node:{{ default .Values.image.tag .Values.image.repoTags.controlPlane }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + securityContext: + privileged: true + env: + - name: RUST_LOG + value: {{ .Values.agents.ha.node.logLevel }} + {{- if default .Values.base.logSilenceLevel .Values.agents.ha.node.logSilenceLevel }} + - name: RUST_LOG_SILENCE + value: {{ default .Values.base.logSilenceLevel .Values.agents.ha.node.logSilenceLevel }} + {{- end }} + - name: MY_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: MY_POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: RUST_BACKTRACE + value: "1" + args: + - "--node-name=$(MY_NODE_NAME)" + - "--csi-socket={{ .Values.csi.node.pluginMounthPath }}/{{ .Values.csi.node.socketPath }}" + - "--grpc-endpoint=$(MY_POD_IP):50053" + - "--cluster-agent=https://{{ .Release.Name }}-agent-core:50052"{{ if .Values.base.jaeger.enabled }} + - "--jaeger={{ .Values.base.jaeger.agent.name }}:{{ .Values.base.jaeger.agent.port }}"{{ end }} + volumeMounts: + - name: device + mountPath: /dev + - name: sys + mountPath: /sys + - name: run-udev + mountPath: /run/udev + - name: plugin-dir + mountPath: {{ .Values.csi.node.pluginMounthPath }} + resources: + limits: + cpu: {{ .Values.agents.ha.node.resources.limits.cpu | quote }} + memory: {{ .Values.agents.ha.node.resources.limits.memory | quote }} + requests: + cpu: {{ .Values.agents.ha.node.resources.requests.cpu | quote }} + memory: {{ .Values.agents.ha.node.resources.requests.memory | quote }} + ports: + - containerPort: 50053 + protocol: TCP + name: ha-node + volumes: + - name: device + hostPath: + path: /dev + type: Directory + - name: sys + hostPath: + path: /sys + type: Directory + - name: run-udev + hostPath: + path: /run/udev + type: Directory + - name: plugin-dir + hostPath: + path: {{ .Values.csi.node.kubeletDir }}/plugins/io.openebs.mayastor/ + type: DirectoryOrCreate +{{- end }} diff --git a/helm/openebs/charts/mayastor/templates/mayastor/apis/api-rest-deployment.yaml b/helm/openebs/charts/mayastor/templates/mayastor/apis/api-rest-deployment.yaml new file mode 100644 index 0000000..6e360ec --- /dev/null +++ b/helm/openebs/charts/mayastor/templates/mayastor/apis/api-rest-deployment.yaml @@ -0,0 +1,63 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Release.Name }}-api-rest + labels: + app: api-rest + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + {{ include "label_prefix" . }}/version: {{ .Chart.Version }} +spec: + replicas: {{ .Values.apis.rest.replicaCount }} + selector: + matchLabels: + app: api-rest + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + template: + metadata: + labels: + app: api-rest + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + {{ include "label_prefix" . }}/version: {{ .Chart.Version }} + {{ include "label_prefix" . }}/logging: "true" + spec: + imagePullSecrets: + {{- include "base_pull_secrets" . }} + initContainers: + {{- include "base_init_containers" . }} + {{- if $pcName := include "priority_class_with_default" (dict "template" . "localPriorityClass" .Values.apis.rest.priorityClassName) }} + priorityClassName: {{ $pcName }} + {{- end }} + {{- if .Values.nodeSelector }} + nodeSelector: {{- toYaml .Values.nodeSelector | nindent 8 }} + {{- end }} + {{- if $tolerations := include "tolerations_with_early_eviction" (dict "template" . "localTolerations" .Values.apis.rest.tolerations) }} + tolerations: {{ $tolerations }} + {{- end }} + containers: + - name: api-rest + resources: + limits: + cpu: {{ .Values.apis.rest.resources.limits.cpu | quote }} + memory: {{ .Values.apis.rest.resources.limits.memory | quote }} + requests: + cpu: {{ .Values.apis.rest.resources.requests.cpu | quote }} + memory: {{ .Values.apis.rest.resources.requests.memory | quote }} + image: "{{ .Values.image.registry }}/{{ .Values.image.repo }}/{{ .Chart.Name }}-api-rest:{{ default .Values.image.tag .Values.image.repoTags.controlPlane }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + args: + - "--dummy-certificates" + - "--no-auth" + - "--http=0.0.0.0:8081" + - "--request-timeout={{ .Values.base.default_req_timeout }}"{{ if .Values.base.jaeger.enabled }} + - "--jaeger={{ .Values.base.jaeger.agent.name }}:{{ .Values.base.jaeger.agent.port }}"{{ end }} + - "--core-grpc=https://{{ .Release.Name }}-agent-core:50051" + ports: + - containerPort: 8080 + - containerPort: 8081 + env: + - name: RUST_LOG + value: {{ .Values.apis.rest.logLevel }} + {{- if default .Values.base.logSilenceLevel .Values.apis.rest.logSilenceLevel }} + - name: RUST_LOG_SILENCE + value: {{ default .Values.base.logSilenceLevel .Values.apis.rest.logSilenceLevel }} + {{- end }} diff --git a/helm/openebs/charts/mayastor/templates/mayastor/apis/api-rest-service.yaml b/helm/openebs/charts/mayastor/templates/mayastor/apis/api-rest-service.yaml new file mode 100644 index 0000000..37671f0 --- /dev/null +++ b/helm/openebs/charts/mayastor/templates/mayastor/apis/api-rest-service.yaml @@ -0,0 +1,28 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ .Release.Name }}-api-rest + labels: + app: api-rest + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + {{ include "label_prefix" . }}/version: {{ .Chart.Version }} +spec: + type: {{ .Values.apis.rest.service.type }} + selector: + app: api-rest + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + ports: + - port: 8080 + name: https + targetPort: 8080 + protocol: TCP + {{- if eq .Values.apis.rest.service.type "NodePort" }} + nodePort: {{ .Values.apis.rest.service.nodePorts.https }} + {{- end }} + - port: 8081 + name: http + targetPort: 8081 + protocol: TCP + {{- if eq .Values.apis.rest.service.type "NodePort" }} + nodePort: {{ .Values.apis.rest.service.nodePorts.http }} + {{- end }} diff --git a/helm/openebs/charts/mayastor/templates/mayastor/csi/csi-controller-deployment.yaml b/helm/openebs/charts/mayastor/templates/mayastor/csi/csi-controller-deployment.yaml new file mode 100644 index 0000000..1a664f0 --- /dev/null +++ b/helm/openebs/charts/mayastor/templates/mayastor/csi/csi-controller-deployment.yaml @@ -0,0 +1,118 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Release.Name }}-csi-controller + labels: + app: csi-controller + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + {{ include "label_prefix" . }}/version: {{ .Chart.Version }} +spec: + replicas: 1 + selector: + matchLabels: + app: csi-controller + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + template: + metadata: + labels: + app: csi-controller + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + {{ include "label_prefix" . }}/version: {{ .Chart.Version }} + {{ include "label_prefix" . }}/logging: "true" + spec: + hostNetwork: true + serviceAccount: {{ .Release.Name }}-service-account + dnsPolicy: ClusterFirstWithHostNet + imagePullSecrets: + {{- include "base_pull_secrets" . }} + initContainers: + {{- include "jaeger_agent_init_container" . }} + {{- include "rest_agent_init_container" . }} + {{- if $pcName := include "priority_class" (dict "template" . "localPriorityClass" .Values.csi.controller.priorityClassName) }} + priorityClassName: {{ $pcName }} + {{- end }} + {{- if .Values.nodeSelector }} + nodeSelector: {{- toYaml .Values.nodeSelector | nindent 8 }} + {{- end }} + {{- if $tolerations := include "tolerations" (dict "template" . "localTolerations" .Values.csi.controller.tolerations) }} + tolerations: {{ $tolerations }} + {{- end }} + containers: + - name: csi-provisioner + image: "{{ .Values.csi.image.registry }}/{{ .Values.csi.image.repo }}/csi-provisioner:{{ .Values.csi.image.provisionerTag }}" + args: + - "--v=2" + - "--csi-address=$(ADDRESS)" + - "--feature-gates=Topology=true" + - "--strict-topology=false" + - "--default-fstype=ext4" + - "--extra-create-metadata" # This is needed for volume group feature to work + - "--timeout=36s" + - "--worker-threads=10" # 10 for create and 10 for delete + env: + - name: ADDRESS + value: /var/lib/csi/sockets/pluginproxy/csi.sock + imagePullPolicy: {{ .Values.csi.image.pullPolicy }} + volumeMounts: + - name: socket-dir + mountPath: /var/lib/csi/sockets/pluginproxy/ + - name: csi-attacher + image: "{{ .Values.csi.image.registry }}/{{ .Values.csi.image.repo }}/csi-attacher:{{ .Values.csi.image.attacherTag }}" + args: + - "--v=2" + - "--csi-address=$(ADDRESS)" + env: + - name: ADDRESS + value: /var/lib/csi/sockets/pluginproxy/csi.sock + imagePullPolicy: {{ .Values.csi.image.pullPolicy }} + volumeMounts: + - name: socket-dir + mountPath: /var/lib/csi/sockets/pluginproxy/ + - name: csi-snapshotter + image: "{{ .Values.csi.image.registry }}/{{ .Values.csi.image.repo }}/csi-snapshotter:{{ .Values.csi.image.snapshotterTag }}" + args: + - "--v=2" + - "--csi-address=$(ADDRESS)" + env: + - name: ADDRESS + value: /var/lib/csi/sockets/pluginproxy/csi.sock + imagePullPolicy: {{ .Values.csi.image.pullPolicy }} + volumeMounts: + - name: socket-dir + mountPath: /var/lib/csi/sockets/pluginproxy/ + - name: csi-snapshot-controller + args: + - "--v=2" + - "--leader-election=false" # since we are running single container + image: "{{ .Values.csi.image.registry }}/{{ .Values.csi.image.repo }}/snapshot-controller:{{ .Values.csi.image.snapshotControllerTag }}" + imagePullPolicy: {{ .Values.csi.image.pullPolicy }} + - name: csi-controller + resources: + limits: + cpu: {{ .Values.csi.controller.resources.limits.cpu | quote }} + memory: {{ .Values.csi.controller.resources.limits.memory | quote }} + requests: + cpu: {{ .Values.csi.controller.resources.requests.cpu | quote }} + memory: {{ .Values.csi.controller.resources.requests.memory | quote }} + image: "{{ .Values.image.registry }}/{{ .Values.image.repo }}/{{ .Chart.Name }}-csi-controller:{{ default .Values.image.tag .Values.image.repoTags.controlPlane }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + args: + - "--csi-socket=/var/lib/csi/sockets/pluginproxy/csi.sock" + - "--rest-endpoint=http://{{ .Release.Name }}-api-rest:8081"{{ if .Values.base.jaeger.enabled }} + - "--jaeger={{ .Values.base.jaeger.agent.name }}:{{ .Values.base.jaeger.agent.port }}"{{ end }} + {{- range $key, $val := .Values.csi.node.topology.segments }} + - "--node-selector={{ $key }}={{ $val }}" + {{- end }} + env: + - name: RUST_LOG + value: {{ .Values.csi.controller.logLevel }} + {{- if default .Values.base.logSilenceLevel .Values.csi.controller.logSilenceLevel }} + - name: RUST_LOG_SILENCE + value: {{ default .Values.base.logSilenceLevel .Values.csi.controller.logSilenceLevel }} + {{- end }} + volumeMounts: + - name: socket-dir + mountPath: /var/lib/csi/sockets/pluginproxy/ + volumes: + - name: socket-dir + emptyDir: diff --git a/helm/openebs/charts/mayastor/templates/mayastor/csi/csi-node-daemonset.yaml b/helm/openebs/charts/mayastor/templates/mayastor/csi/csi-node-daemonset.yaml new file mode 100644 index 0000000..71e3398 --- /dev/null +++ b/helm/openebs/charts/mayastor/templates/mayastor/csi/csi-node-daemonset.yaml @@ -0,0 +1,156 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: {{ .Release.Name }}-csi-node + labels: + app: csi-node + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + {{ include "label_prefix" . }}/version: {{ .Chart.Version }} + {{- range $key, $val := .Values.csi.node.topology.segments }} + {{ $key }}: {{ $val }} + {{- end }} +spec: + selector: + matchLabels: + app: csi-node + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + updateStrategy: + type: RollingUpdate + rollingUpdate: + maxUnavailable: 1 + minReadySeconds: 10 + template: + metadata: + labels: + app: csi-node + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + {{ include "label_prefix" . }}/version: {{ .Chart.Version }} + {{ include "label_prefix" . }}/logging: "true" + spec: + serviceAccount: {{ .Release.Name }}-service-account + hostNetwork: true + imagePullSecrets: + {{- include "base_pull_secrets" . }} + {{- if $pcName := include "priority_class" (dict "template" . "localPriorityClass" .Values.csi.node.priorityClassName) }} + priorityClassName: {{ $pcName }} + {{- end }} + nodeSelector: + {{- if .Values.nodeSelector }} + {{- toYaml .Values.nodeSelector | nindent 8 }} + {{- end }} + {{- if .Values.csi.node.topology.nodeSelector }} + {{- range $key, $val := .Values.csi.node.topology.segments }} + {{ $key }}: {{ $val }} + {{- end }} + {{- end }} + {{- if $tolerations := include "tolerations" (dict "template" . "localTolerations" .Values.csi.node.tolerations) }} + tolerations: {{ $tolerations }} + {{- end }} + # NOTE: Each container must have mem/cpu limits defined in order to + # belong to Guaranteed QoS class, hence can never get evicted in case of + # pressure unless they exceed those limits. limits and requests must be + # the same. + containers: + - name: csi-node + image: "{{ .Values.image.registry }}/{{ .Values.image.repo }}/{{ .Chart.Name }}-csi-node:{{ default .Values.image.tag .Values.image.repoTags.controlPlane }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + # we need privileged because we mount filesystems and use mknod + securityContext: + privileged: true + env: + - name: RUST_LOG + value: {{ .Values.csi.node.logLevel }} + {{- if default .Values.base.logSilenceLevel .Values.csi.node.logSilenceLevel }} + - name: RUST_LOG_SILENCE + value: {{ default .Values.base.logSilenceLevel .Values.csi.node.logSilenceLevel }} + {{- end }} + - name: MY_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: MY_POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: RUST_BACKTRACE + value: "1" + args: + - "--csi-socket={{ .Values.csi.node.pluginMounthPath }}/{{ .Values.csi.node.socketPath }}" + - "--node-name=$(MY_NODE_NAME)" + - "--grpc-endpoint=$(MY_POD_IP):10199"{{ if .Values.csi.node.nvme.io_timeout }} + - "--nvme-core-io-timeout={{ .Values.csi.node.nvme.io_timeout }}"{{ end }}{{ if .Values.csi.node.nvme.ctrl_loss_tmo }} + - "--nvme-ctrl-loss-tmo={{ .Values.csi.node.nvme.ctrl_loss_tmo }}"{{ end }}{{ if .Values.csi.node.nvme.keep_alive_tmo }} + - "--nvme-keep-alive-tmo={{ .Values.csi.node.nvme.keep_alive_tmo }}"{{ end }} + - "--nvme-nr-io-queues={{ include "coreCount" . }}" + {{- range $key, $val := .Values.csi.node.topology.segments }} + - "--node-selector={{ $key }}={{ $val }}" + {{- end }} + command: + - csi-node + volumeMounts: + - name: device + mountPath: /dev + - name: sys + mountPath: /sys + - name: run-udev + mountPath: /run/udev + - name: plugin-dir + mountPath: {{ .Values.csi.node.pluginMounthPath }} + - name: kubelet-dir + mountPath: {{ .Values.csi.node.kubeletDir }} + mountPropagation: "Bidirectional" + resources: + limits: + cpu: {{ .Values.csi.node.resources.limits.cpu | quote }} + memory: {{ .Values.csi.node.resources.limits.memory | quote }} + requests: + cpu: {{ .Values.csi.node.resources.requests.cpu | quote }} + memory: {{ .Values.csi.node.resources.requests.memory | quote }} + - name: csi-driver-registrar + image: "{{ .Values.csi.image.registry }}/{{ .Values.csi.image.repo }}/csi-node-driver-registrar:{{ .Values.csi.image.registrarTag }}" + imagePullPolicy: {{ .Values.csi.image.pullPolicy }} + args: + - "--csi-address={{ .Values.csi.node.pluginMounthPath }}/{{ .Values.csi.node.socketPath }}" + - "--kubelet-registration-path={{ .Values.csi.node.kubeletDir }}/plugins/io.openebs.mayastor/csi.sock" + volumeMounts: + - name: plugin-dir + mountPath: {{ .Values.csi.node.pluginMounthPath }} + - name: registration-dir + mountPath: /registration + resources: + limits: + cpu: "100m" + memory: "50Mi" + requests: + cpu: "100m" + memory: "50Mi" + # Mayastor node plugin gRPC server + ports: + - containerPort: 10199 + protocol: TCP + name: mayastor-node + volumes: + - name: device + hostPath: + path: /dev + type: Directory + - name: sys + hostPath: + path: /sys + type: Directory + - name: run-udev + hostPath: + path: /run/udev + type: Directory + - name: registration-dir + hostPath: + path: {{ .Values.csi.node.kubeletDir }}/plugins_registry/ + type: Directory + - name: plugin-dir + hostPath: + path: {{ .Values.csi.node.kubeletDir }}/plugins/io.openebs.mayastor/ + type: DirectoryOrCreate + - name: kubelet-dir + hostPath: + path: {{ .Values.csi.node.kubeletDir }} + type: Directory diff --git a/helm/openebs/charts/mayastor/templates/mayastor/io/io-engine-daemonset.yaml b/helm/openebs/charts/mayastor/templates/mayastor/io/io-engine-daemonset.yaml new file mode 100644 index 0000000..e005309 --- /dev/null +++ b/helm/openebs/charts/mayastor/templates/mayastor/io/io-engine-daemonset.yaml @@ -0,0 +1,149 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: {{ .Release.Name }}-io-engine + labels: + app: io-engine + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + {{ include "label_prefix" . }}/version: {{ .Chart.Version }} +spec: + selector: + matchLabels: + app: io-engine + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + updateStrategy: + type: OnDelete + minReadySeconds: 10 + template: + metadata: + labels: + app: io-engine + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + {{ include "label_prefix" . }}/version: {{ .Chart.Version }} + {{ include "label_prefix" . }}/logging: "true" + spec: + imagePullSecrets: + {{- include "base_pull_secrets" . }} + hostNetwork: true + # To resolve services in the namespace + dnsPolicy: ClusterFirstWithHostNet + nodeSelector: {{- .Values.io_engine.nodeSelector | toYaml | nindent 8 }} + {{- if $pcName := include "priority_class" (dict "template" . "localPriorityClass" .Values.io_engine.priorityClassName) }} + priorityClassName: {{ $pcName }} + {{- end }} + {{- if $tolerations := include "tolerations" (dict "template" . "localTolerations" .Values.io_engine.tolerations) }} + tolerations: {{ $tolerations }} + {{- end }} + initContainers: + {{- include "base_init_containers" . }} + containers: + {{- if .Values.base.metrics.enabled }} + - name: metrics-exporter-pool + image: "{{ .Values.image.registry }}/{{ .Values.image.repo }}/{{ .Chart.Name }}-metrics-exporter-pool:{{ default .Values.image.tag .Values.image.repoTags.extensions }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + env: + - name: MY_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: MY_POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + args: + - "-p{{ .Values.base.metrics.pollingInterval }}" + - "--api-versions={{ .Values.io_engine.api }}" + command: + - metrics-exporter-pool + ports: + - containerPort: 9502 + protocol: TCP + name: metrics + {{- end }} + - name: io-engine + image: "{{ .Values.image.registry }}/{{ .Values.image.repo }}/{{ .Chart.Name }}-io-engine:{{ default .Values.image.tag .Values.image.repoTags.dataPlane }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + env: + - name: RUST_LOG + value: {{ .Values.io_engine.logLevel }} + - name: NVME_QPAIR_CONNECT_ASYNC + value: "true" + - name: NVMF_TCP_MAX_QUEUE_DEPTH + value: "32" + - name: MY_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: MY_POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: NEXUS_NVMF_ANA_ENABLE + value: "1" + - name: NEXUS_NVMF_RESV_ENABLE + value: "1" + args: + # The -l argument accepts cpu-list. Indexing starts at zero. + # For example -l 1,2,10-20 means use core 1, 2, 10 to 20. + # Note: Ensure that the CPU resources are updated accordingly. + # If you use 2 CPUs, the CPU: field should also read 2. + - "-g$(MY_POD_IP)" + - "-N$(MY_NODE_NAME)" + - "-Rhttps://{{ .Release.Name }}-agent-core:50051" + - "-y/var/local/io-engine/config.yaml" + - "-l{{ include "cpuFlag" . }}" + - "-p={{ .Release.Name }}-etcd:{{ .Values.etcd.service.port }}"{{ if .Values.io_engine.target.nvmf.ptpl }} + - "--ptpl-dir=/var/local/io-engine/ptpl/"{{ end }} + - "--api-versions={{ .Values.io_engine.api }}"{{ if .Values.io_engine.target.nvmf.iface }} + - "-T={{ .Values.io_engine.target.nvmf.iface }}"{{ end }}{{ if .Values.io_engine.envcontext }} + - "--env-context=--{{ .Values.io_engine.envcontext }}"{{ end }}{{ if .Values.io_engine.reactorFreezeDetection.enabled }} + - "--reactor-freeze-detection"{{ end }} + - "--tgt-crdt={{ .Values.io_engine.target.nvmf.hostCmdRetryDelay.crdt1 }}" + command: + - io-engine + securityContext: + privileged: true + volumeMounts: + - name: device + mountPath: /dev + - name: udev + mountPath: /run/udev + - name: dshm + mountPath: /dev/shm + - name: configlocation + mountPath: /var/local/io-engine/ + - name: hugepage + mountPath: /dev/hugepages + resources: + limits: + cpu: {{ .Values.io_engine.resources.limits.cpu | default (include "coreCount" .) | quote }} + memory: {{ .Values.io_engine.resources.limits.memory | quote }} + hugepages-2Mi: {{ .Values.io_engine.resources.limits.hugepages2Mi | quote }} + requests: + cpu: {{ .Values.io_engine.resources.requests.cpu | default (include "coreCount" .) | quote }} + memory: {{ .Values.io_engine.resources.requests.memory | quote }} + hugepages-2Mi: {{ .Values.io_engine.resources.requests.hugepages2Mi | quote }} + ports: + - containerPort: 10124 + protocol: TCP + name: io-engine + volumes: + - name: device + hostPath: + path: /dev + type: Directory + - name: udev + hostPath: + path: /run/udev + type: Directory + - name: dshm + emptyDir: + medium: Memory + sizeLimit: "1Gi" + - name: hugepage + emptyDir: + medium: HugePages + - name: configlocation + hostPath: + path: /var/local/io-engine/ + type: DirectoryOrCreate diff --git a/helm/openebs/charts/mayastor/templates/mayastor/metrics/metrics-exporter-pool-service.yaml b/helm/openebs/charts/mayastor/templates/mayastor/metrics/metrics-exporter-pool-service.yaml new file mode 100644 index 0000000..cc00248 --- /dev/null +++ b/helm/openebs/charts/mayastor/templates/mayastor/metrics/metrics-exporter-pool-service.yaml @@ -0,0 +1,19 @@ +{{- if .Values.base.metrics.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ .Release.Name }}-metrics-exporter-pool + labels: + app: metrics-exporter-pool + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + {{ include "label_prefix" . }}/version: {{ .Chart.Version }} +spec: + ports: + - name: metrics + port: 9502 + targetPort: 9502 + protocol: TCP + selector: + app: io-engine + {{ include "label_prefix" . }}/release: {{ .Release.Name }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/templates/mayastor/obs/obs-callhome-deployment.yaml b/helm/openebs/charts/mayastor/templates/mayastor/obs/obs-callhome-deployment.yaml new file mode 100644 index 0000000..27cfc7a --- /dev/null +++ b/helm/openebs/charts/mayastor/templates/mayastor/obs/obs-callhome-deployment.yaml @@ -0,0 +1,80 @@ +{{- if .Values.obs.callhome.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Release.Name }}-obs-callhome + labels: + app: obs-callhome + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + {{ include "label_prefix" . }}/version: {{ .Chart.Version }} +spec: + replicas: 1 + selector: + matchLabels: + app: obs-callhome + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + template: + metadata: + labels: + app: obs-callhome + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + {{ include "label_prefix" . }}/version: {{ .Chart.Version }} + {{ include "label_prefix" . }}/logging: "true" + spec: + serviceAccountName: {{ .Release.Name }}-service-account + imagePullSecrets: + {{- include "base_pull_secrets" . }} + {{- if $pcName := include "priority_class" (dict "template" . "localPriorityClass" .Values.obs.callhome.priorityClassName) }} + priorityClassName: {{ $pcName }} + {{- end }} + {{- if .Values.nodeSelector }} + nodeSelector: {{- toYaml .Values.nodeSelector | nindent 8 }} + {{- end }} + {{- if $tolerations := include "tolerations" (dict "template" . "localTolerations" .Values.obs.callhome.tolerations) }} + tolerations: {{ $tolerations }} + {{- end }} + containers: + - name: obs-callhome + image: "{{ .Values.image.registry }}/{{ .Values.image.repo }}/{{ .Chart.Name }}-obs-callhome:{{ default .Values.image.tag .Values.image.repoTags.extensions }}" + args: + - "-e http://{{ .Release.Name }}-api-rest:8081" + - "-n {{ .Release.Namespace }}"{{ if .Values.eventing.enabled }} + - "--aggregator-url=http://{{ .Release.Name }}-obs-callhome-stats:9090/stats"{{ end }} + {{ if .Values.obs.callhome.sendReport }} + - "--send-report" + {{ end }} + env: + - name: RUST_LOG + value: {{ .Values.obs.callhome.logLevel }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + resources: + limits: + cpu: {{ .Values.obs.callhome.resources.limits.cpu | quote }} + memory: {{ .Values.obs.callhome.resources.limits.memory | quote }} + requests: + cpu: {{ .Values.obs.callhome.resources.requests.cpu | quote }} + memory: {{ .Values.obs.callhome.resources.requests.memory | quote }} + {{- if .Values.eventing.enabled }} + - name: obs-callhome-stats + image: "{{ .Values.image.registry }}/{{ .Values.image.repo }}/{{ .Chart.Name }}-obs-callhome-stats:{{ default .Values.image.tag .Values.image.repoTags.extensions }}" + args: + - "--namespace={{ .Release.Namespace }}" + - "--release-name={{ .Release.Name }}" + - "--mbus-url=nats://{{ .Release.Name }}-nats:4222" + ports: + - containerPort: 9090 + protocol: TCP + name: stats + env: + - name: RUST_LOG + value: {{ .Values.obs.stats.logLevel }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + resources: + limits: + cpu: {{ .Values.obs.stats.resources.limits.cpu | quote }} + memory: {{ .Values.obs.stats.resources.limits.memory | quote }} + requests: + cpu: {{ .Values.obs.stats.resources.requests.cpu | quote }} + memory: {{ .Values.obs.stats.resources.requests.memory | quote }} + {{- end }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/templates/mayastor/obs/stats-service.yaml b/helm/openebs/charts/mayastor/templates/mayastor/obs/stats-service.yaml new file mode 100644 index 0000000..8a85a1e --- /dev/null +++ b/helm/openebs/charts/mayastor/templates/mayastor/obs/stats-service.yaml @@ -0,0 +1,29 @@ +{{- if .Values.obs.callhome.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ .Release.Name }}-obs-callhome-stats + labels: + app: obs-callhome + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + {{ include "label_prefix" . }}/version: {{ .Chart.Version }} +spec: + ports: + - port: 9090 + name: https + targetPort: 9090 + protocol: TCP + {{- if eq .Values.obs.stats.service.type "NodePort" }} + nodePort: {{ .Values.obs.stats.service.nodePorts.https }} + {{- end }} + - port: 9091 + name: http + targetPort: 9091 + protocol: TCP + {{- if eq .Values.obs.stats.service.type "NodePort" }} + nodePort: {{ .Values.obs.stats.service.nodePorts.http }} + {{- end }} + selector: + app: obs-callhome + {{ include "label_prefix" . }}/release: {{ .Release.Name }} +{{- end }} diff --git a/helm/openebs/charts/mayastor/templates/mayastor/operators/operator-diskpool-deployment.yaml b/helm/openebs/charts/mayastor/templates/mayastor/operators/operator-diskpool-deployment.yaml new file mode 100644 index 0000000..5dc16a0 --- /dev/null +++ b/helm/openebs/charts/mayastor/templates/mayastor/operators/operator-diskpool-deployment.yaml @@ -0,0 +1,64 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Release.Name }}-operator-diskpool + labels: + app: operator-diskpool + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + {{ include "label_prefix" . }}/version: {{ .Chart.Version }} +spec: + replicas: 1 + selector: + matchLabels: + app: operator-diskpool + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + template: + metadata: + labels: + app: operator-diskpool + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + {{ include "label_prefix" . }}/version: {{ .Chart.Version }} + {{ include "label_prefix" . }}/logging: "true" + spec: + serviceAccount: {{ .Release.Name }}-service-account + imagePullSecrets: + {{- include "base_pull_secrets" . }} + initContainers: + {{- include "base_init_containers" . }} + {{- if $pcName := include "priority_class" (dict "template" . "localPriorityClass" .Values.operators.pool.priorityClassName) }} + priorityClassName: {{ $pcName }} + {{- end }} + {{- if .Values.nodeSelector }} + nodeSelector: {{- toYaml .Values.nodeSelector | nindent 8 }} + {{- end }} + {{- if $tolerations := include "tolerations" (dict "template" . "localTolerations" .Values.operators.pool.tolerations) }} + tolerations: {{ $tolerations }} + {{- end }} + containers: + - name: operator-diskpool + resources: + limits: + cpu: {{ .Values.operators.pool.resources.limits.cpu | quote }} + memory: {{ .Values.operators.pool.resources.limits.memory | quote }} + requests: + cpu: {{ .Values.operators.pool.resources.requests.cpu | quote }} + memory: {{ .Values.operators.pool.resources.requests.memory | quote }} + image: "{{ .Values.image.registry }}/{{ .Values.image.repo }}/{{ .Chart.Name }}-operator-diskpool:{{ default .Values.image.tag .Values.image.repoTags.controlPlane }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + args: + - "-e http://{{ .Release.Name }}-api-rest:8081" + - "-n{{ .Release.Namespace }}" + - "--request-timeout={{ .Values.base.default_req_timeout }}" + - "--interval={{ .Values.base.cache_poll_period }}"{{ if .Values.base.jaeger.enabled }} + - "--jaeger={{ .Values.base.jaeger.agent.name }}:{{ .Values.base.jaeger.agent.port }}"{{ end }} + env: + - name: RUST_LOG + value: {{ .Values.operators.pool.logLevel }} + {{- if default .Values.base.logSilenceLevel .Values.operators.pool.logSilenceLevel }} + - name: RUST_LOG_SILENCE + value: {{ default .Values.base.logSilenceLevel .Values.operators.pool.logSilenceLevel }} + {{- end }} + - name: MY_POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name diff --git a/helm/openebs/charts/mayastor/templates/mayastor/priority-class/priority-class.yaml b/helm/openebs/charts/mayastor/templates/mayastor/priority-class/priority-class.yaml new file mode 100644 index 0000000..22f3909 --- /dev/null +++ b/helm/openebs/charts/mayastor/templates/mayastor/priority-class/priority-class.yaml @@ -0,0 +1,7 @@ +apiVersion: scheduling.k8s.io/v1 +description: Used for critical pods that must run in the cluster, which can be moved to another node if necessary. +kind: PriorityClass +metadata: + name: {{ .Release.Name }}-cluster-critical +preemptionPolicy: PreemptLowerPriority +value: 1000000000 diff --git a/helm/openebs/charts/mayastor/templates/mayastor/rbac/rbac.yaml b/helm/openebs/charts/mayastor/templates/mayastor/rbac/rbac.yaml new file mode 100644 index 0000000..7cbd98b --- /dev/null +++ b/helm/openebs/charts/mayastor/templates/mayastor/rbac/rbac.yaml @@ -0,0 +1,118 @@ +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .Release.Name }}-service-account + namespace: {{ .Release.Namespace }} + labels: + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + {{ include "label_prefix" . }}/version: {{ .Chart.Version }} +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ .Release.Name }}-cluster-role + labels: + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + {{ include "label_prefix" . }}/version: {{ .Chart.Version }} +rules: + # must create mayastor crd if it doesn't exist, replace if exist, + # merge schema to existing CRD. +- apiGroups: ["apiextensions.k8s.io"] + resources: ["customresourcedefinitions"] + verbs: ["create", "get", "update", "list", "patch", "replace"] + # must update stored_version in status to include new schema only. +- apiGroups: ["apiextensions.k8s.io"] + resources: ["customresourcedefinitions/status"] + verbs: ["get", "update", "patch"] + # must read mayastorpools info. This is needed to handle upgrades from v1. +- apiGroups: [ "openebs.io" ] + resources: [ "mayastorpools" ] + verbs: ["get", "list", "patch", "delete", "deletecollection"] + # must read diskpool info +- apiGroups: ["openebs.io"] + resources: ["diskpools"] + verbs: ["get", "list", "watch", "update", "replace", "patch", "create"] + # must update diskpool status +- apiGroups: ["openebs.io"] + resources: ["diskpools/status"] + verbs: ["update", "patch"] + # must read cm info +- apiGroups: [""] + resources: ["configmaps"] + verbs: ["create", "get", "update", "patch"] + # must get deployments info +- apiGroups: ["apps"] + resources: ["deployments"] + verbs: ["get", "list"] + # external provisioner & attacher +- apiGroups: [""] + resources: ["persistentvolumes"] + verbs: ["get", "list", "watch", "update", "create", "delete", "patch"] +- apiGroups: [""] + resources: ["nodes"] + verbs: ["get", "list", "watch"] + + # external provisioner +- apiGroups: [""] + resources: ["persistentvolumeclaims"] + verbs: ["get", "list", "watch", "update"] +- apiGroups: ["storage.k8s.io"] + resources: ["storageclasses"] + verbs: ["get", "list", "watch"] +- apiGroups: [""] + resources: ["events"] + verbs: ["list", "watch", "create", "update", "patch"] + + # external snapshotter and snapshot-controller +- apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotclasses"] + verbs: ["get", "list", "watch"] +- apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotcontents"] + verbs: ["create","get", "list", "watch", "update", "patch", "delete"] +- apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotcontents/status"] + verbs: ["update", "patch"] +- apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshots"] + verbs: ["get", "list", "watch", "update", "patch", "delete"] +- apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshots/status"] + verbs: ["update", "patch"] + +- apiGroups: [""] + resources: ["nodes"] + verbs: ["get", "list", "watch"] + + # external attacher +- apiGroups: ["storage.k8s.io"] + resources: ["volumeattachments"] + verbs: ["get", "list", "watch", "update", "patch"] +- apiGroups: ["storage.k8s.io"] + resources: ["volumeattachments/status"] + verbs: ["patch"] + # CSI nodes must be listed +- apiGroups: ["storage.k8s.io"] + resources: ["csinodes"] + verbs: ["get", "list", "watch"] + # get kube-system namespace to retrieve Uid +- apiGroups: [""] + resources: ["namespaces"] + verbs: ["get"] +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ .Release.Name }}-cluster-role-binding + labels: + {{ include "label_prefix" . }}/release: {{ .Release.Name }} + {{ include "label_prefix" . }}/version: {{ .Chart.Version }} +subjects: +- kind: ServiceAccount + name: {{ .Release.Name }}-service-account + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: {{ .Release.Name }}-cluster-role + apiGroup: rbac.authorization.k8s.io diff --git a/helm/openebs/charts/mayastor/templates/storageclass.yaml b/helm/openebs/charts/mayastor/templates/storageclass.yaml new file mode 100644 index 0000000..398f80a --- /dev/null +++ b/helm/openebs/charts/mayastor/templates/storageclass.yaml @@ -0,0 +1,9 @@ +kind: StorageClass +apiVersion: storage.k8s.io/v1 +metadata: + name: {{ .Release.Name }}-single-replica +parameters: + repl: '1' + protocol: 'nvmf' + ioTimeout: '60' +provisioner: io.openebs.csi-mayastor diff --git a/helm/openebs/charts/mayastor/values.yaml b/helm/openebs/charts/mayastor/values.yaml new file mode 100644 index 0000000..6ff190f --- /dev/null +++ b/helm/openebs/charts/mayastor/values.yaml @@ -0,0 +1,707 @@ +image: + # -- Image registry to pull our product images + registry: docker.io + # -- Image registry's namespace + repo: openebs + # -- Release tag for our images + tag: v2.4.0 + repoTags: + # Note: Below image tag configuration is optional and typically should never be + # used. Setting specific image tags for the different repositories proves useful + # for some integration testing scenarios. Use the 'tag' option above to set + # release/pre-release container image tags. + # The below tag values will be picked for images by default. + # If not specified, 'tag' option provided above will be picked. + controlPlane: "" + dataPlane: "" + extensions: "" + # -- ImagePullPolicy for our images + pullPolicy: IfNotPresent + +# -- Node labels for pod assignment +# ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ +# Note that if multi-arch images support 'kubernetes.io/arch: amd64' +# should be removed and set 'nodeSelector' to empty '{}' as default value. +nodeSelector: + kubernetes.io/arch: amd64 + +# -- Pod scheduling priority. +# Setting this value will apply to all components except the external Chart dependencies. +# If any component has `priorityClassName` set, then this value would be overridden for that component. +# For external components like etcd, jaeger or loki-stack, PriorityClass can only be set at component level. +priorityClassName: "" + +earlyEvictionTolerations: + - effect: NoExecute + key: node.kubernetes.io/unreachable + operator: Exists + tolerationSeconds: 5 + - effect: NoExecute + key: node.kubernetes.io/not-ready + operator: Exists + tolerationSeconds: 5 + +# -- Tolerations to be applied to all components except external Chart dependencies. +# If any component has tolerations set, then it would override this value. +# For external components like etcd, jaeger and loki-stack, tolerations can only be set at component level. +tolerations: [] + +base: + # -- Request timeout for rest & core agents + default_req_timeout: 5s + # -- Cache timeout for core agent & diskpool deployment + cache_poll_period: 30s + # -- Silence specific module components + logSilenceLevel: + initContainers: + enabled: true + containers: + - name: agent-core-grpc-probe + image: busybox:latest + command: ['sh', '-c', 'trap "exit 1" TERM; until nc -vzw 5 {{ .Release.Name }}-agent-core 50051; do date; echo "Waiting for agent-core-grpc services..."; sleep 1; done;'] + - name: etcd-probe + image: busybox:latest + command: ['sh', '-c', 'trap "exit 1" TERM; until nc -vzw 5 {{ .Release.Name }}-etcd {{.Values.etcd.service.port}}; do date; echo "Waiting for etcd..."; sleep 1; done;'] + initHaNodeContainers: + enabled: true + containers: + - name: agent-cluster-grpc-probe + image: busybox:latest + command: ['sh', '-c', 'trap "exit 1" TERM; until nc -vzw 5 {{ .Release.Name }}-agent-core 50052; do date; echo "Waiting for agent-cluster-grpc services..."; sleep 1; done;'] + initCoreContainers: + enabled: true + containers: + - name: etcd-probe + image: busybox:latest + command: ['sh', '-c', 'trap "exit 1" TERM; until nc -vzw 5 {{ .Release.Name }}-etcd {{.Values.etcd.service.port}}; do date; echo "Waiting for etcd..."; sleep 1; done;'] + # docker-secrets required to pull images if the container registry from image.Registry is protected + imagePullSecrets: + # -- Enable imagePullSecrets for pulling our container images + enabled: false + # Name of the imagePullSecret in the installed namespace + secrets: + - name: login + + metrics: + # -- Enable the metrics exporter + enabled: true + # metrics refresh time + # WARNING: Lowering pollingInterval value will affect performance adversely + pollingInterval: "5m" + + jaeger: + # -- Enable jaeger tracing + enabled: false + initContainer: true + agent: + name: jaeger-agent + port: 6831 + initContainer: + - name: jaeger-probe + image: busybox:latest + command: ['sh', '-c', 'trap "exit 1" TERM; until nc -vzw 5 -u {{.Values.base.jaeger.agent.name}} {{.Values.base.jaeger.agent.port}}; do date; echo "Waiting for jaeger..."; sleep 1; done;'] + initRestContainer: + enabled: true + initContainer: + - name: api-rest-probe + image: busybox:latest + command: ['sh', '-c', 'trap "exit 1" TERM; until nc -vzw 5 {{ .Release.Name }}-api-rest 8081; do date; echo "Waiting for REST API endpoint to become available"; sleep 1; done;'] + +operators: + pool: + # -- Log level for diskpool operator service + logLevel: info + resources: + limits: + # -- Cpu limits for diskpool operator + cpu: "100m" + # -- Memory limits for diskpool operator + memory: "32Mi" + requests: + # -- Cpu requests for diskpool operator + cpu: "50m" + # -- Memory requests for diskpool operator + memory: "16Mi" + # -- Set tolerations, overrides global + tolerations: [] + # -- Set PriorityClass, overrides global + priorityClassName: "" + +jaeger-operator: + # Name of jaeger operator + name: "{{ .Release.Name }}" + crd: + # Install jaeger CRDs + install: false + jaeger: + # Install jaeger-operator + create: false + rbac: + # Create a clusterRole for Jaeger + clusterRole: true + tolerations: [] + priorityClassName: "" + +agents: + core: + # -- Log level for the core service + logLevel: info + capacity: + thin: + # -- The allowed pool commitment limit when dealing with thin provisioned volumes. + # Example: If the commitment is 250 and the pool is 10GiB we can overcommit the pool + # up to 25GiB (create 2 10GiB and 1 5GiB volume) but no further. + poolCommitment: "250%" + # -- When creating replicas for an existing volume, each replica pool must have at least + # this much free space percentage of the volume size. + # Example: if this value is 40, the pool has 40GiB free, then the max volume size allowed + # to be created on the pool is 100GiB. + volumeCommitment: "40%" + # -- Same as the `volumeCommitment` argument, but applicable only when creating replicas + # for a new volume. + volumeCommitmentInitial: "40%" + # -- When creating snapshots for an existing volume, each replica pool must have at least + # this much free space percentage of the volume size. + # Example: if this value is 40, the pool has 40GiB free, then the max volume size allowed + # to be snapped on the pool is 100GiB. + snapshotCommitment: "40%" + resources: + limits: + # -- Cpu limits for core agents + cpu: "1000m" + # -- Memory limits for core agents + memory: "128Mi" + requests: + # -- Cpu requests for core agents + cpu: "500m" + # -- Memory requests for core agents + memory: "32Mi" + # -- If a faulted replica comes back online within this time period then it will be + # rebuilt using the partial rebuild capability (using a log of missed IO), hence a bit + # faster depending on the log size. Otherwise, the replica will be fully rebuilt. + # A blank value "" means internally derived value will be used. + partialRebuildWaitPeriod: "" + # -- Set tolerations, overrides global + tolerations: [] + # -- Set PriorityClass, overrides global. + # If both local and global are not set, the final deployment manifest has a mayastor custom critical priority class assigned to the pod by default. + # Refer the `templates/_helpers.tpl` and `templates/mayastor/agents/core/agent-core-deployment.yaml` for more details. + priorityClassName: "" + ha: + enabled: true + node: + # -- Log level for the ha node service + logLevel: info + resources: + limits: + # -- Cpu limits for ha node agent + cpu: "100m" + # -- Memory limits for ha node agent + memory: "64Mi" + requests: + # -- Cpu requests for ha node agent + cpu: "100m" + # -- Memory requests for ha node agent + memory: "64Mi" + # -- Set tolerations, overrides global + tolerations: [] + # -- Set PriorityClass, overrides global + priorityClassName: "" + cluster: + # -- Log level for the ha cluster service + logLevel: info + resources: + limits: + # -- Cpu limits for ha cluster agent + cpu: "100m" + # -- Memory limits for ha cluster agent + memory: "64Mi" + requests: + # -- Cpu requests for ha cluster agent + cpu: "100m" + # -- Memory requests for ha cluster agent + memory: "16Mi" + +apis: + rest: + # -- Log level for the rest service + logLevel: info + # -- Number of replicas of rest + replicaCount: 1 + resources: + limits: + # -- Cpu limits for rest + cpu: "100m" + # -- Memory limits for rest + memory: "64Mi" + requests: + # -- Cpu requests for rest + cpu: "50m" + # -- Memory requests for rest + memory: "32Mi" + # Rest service parameters define how the rest service is exposed + service: + # -- Rest K8s service type + type: ClusterIP + # Ports from where rest endpoints are accessible from outside the cluster, only valid if type is NodePort + nodePorts: + # NodePort associated with http port + http: 30011 + # NodePort associated with https port + https: 30010 + # -- Set tolerations, overrides global + tolerations: [] + # -- Set PriorityClass, overrides global. + # If both local and global are not set, the final deployment manifest has a mayastor custom critical priority class assigned to the pod by default. + # Refer the `templates/_helpers.tpl` and `templates/mayastor/apis/rest/api-rest-deployment.yaml` for more details. + priorityClassName: "" + +csi: + image: + # -- Image registry to pull all CSI Sidecar images + registry: registry.k8s.io + # -- Image registry's namespace + repo: sig-storage + # -- imagePullPolicy for all CSI Sidecar images + pullPolicy: IfNotPresent + # -- csi-provisioner image release tag + provisionerTag: v3.5.0 + # -- csi-attacher image release tag + attacherTag: v4.3.0 + # -- csi-snapshotter image release tag + snapshotterTag: v6.2.1 + # -- csi-snapshot-controller image release tag + snapshotControllerTag: v6.2.1 + # -- csi-node-driver-registrar image release tag + registrarTag: v2.8.0 + + controller: + # -- Log level for the csi controller + logLevel: info + resources: + limits: + # -- Cpu limits for csi controller + cpu: "32m" + # -- Memory limits for csi controller + memory: "128Mi" + requests: + # -- Cpu requests for csi controller + cpu: "16m" + # -- Memory requests for csi controller + memory: "64Mi" + # -- Set tolerations, overrides global + tolerations: [] + # -- Set PriorityClass, overrides global + priorityClassName: "" + node: + logLevel: info + topology: + segments: + openebs.io/csi-node: mayastor + # -- Add topology segments to the csi-node daemonset node selector + nodeSelector: false + resources: + limits: + # -- Cpu limits for csi node plugin + cpu: "100m" + # -- Memory limits for csi node plugin + memory: "128Mi" + requests: + # -- Cpu requests for csi node plugin + cpu: "100m" + # -- Memory requests for csi node plugin + memory: "64Mi" + nvme: + # -- The nvme_core module io timeout in seconds + io_timeout: "30" + # -- The ctrl_loss_tmo (controller loss timeout) in seconds + ctrl_loss_tmo: "1980" + # Kato (keep alive timeout) in seconds + keep_alive_tmo: "" + # -- The kubeletDir directory for the csi-node plugin + kubeletDir: /var/lib/kubelet + pluginMounthPath: /csi + socketPath: csi.sock + # -- Set tolerations, overrides global + tolerations: [] + # -- Set PriorityClass, overrides global + priorityClassName: "" + +io_engine: + # -- Log level for the io-engine service + logLevel: info + api: "v1" + target: + nvmf: + # -- NVMF target interface (ip, mac, name or subnet) + iface: "" + # -- Reservations Persist Through Power Loss State + ptpl: true + # NVMF target Command Retry Delay for volume target initiators + hostCmdRetryDelay: + # A command retry delay in seconds. A value of 0 means no delay, host may retry immediately + crdt1: 30 + + # -- Pass additional arguments to the Environment Abstraction Layer. + # Example: --set {product}.envcontext=iova-mode=pa + envcontext: "" + reactorFreezeDetection: + enabled: false + # -- The number of cores that each io-engine instance will bind to. + cpuCount: "2" + # -- If not empty, overrides the cpuCount and explicitly sets the list of cores. + # Example: --set='io_engine.coreList={30,31}' + coreList: [] + # -- Node selectors to designate storage nodes for diskpool creation + # Note that if multi-arch images support 'kubernetes.io/arch: amd64' + # should be removed. + nodeSelector: + openebs.io/engine: mayastor + kubernetes.io/arch: amd64 + resources: + limits: + # -- Cpu limits for the io-engine + cpu: "" + # -- Memory limits for the io-engine + memory: "1Gi" + # -- Hugepage size available on the nodes + hugepages2Mi: "2Gi" + requests: + # -- Cpu requests for the io-engine + cpu: "" + # -- Memory requests for the io-engine + memory: "1Gi" + # -- Hugepage size available on the nodes + hugepages2Mi: "2Gi" + # -- Set tolerations, overrides global + tolerations: [] + # -- Set PriorityClass, overrides global + priorityClassName: "" + +etcd: + # Configuration for etcd's localpv hostpath storage class. + localpvScConfig: + # Name of etcd's localpv hostpath storage class. + name: "mayastor-etcd-localpv" + # -- Host path where local etcd data is stored in. + basePath: "/var/local/localpv-hostpath/{{ .Release.Name }}/etcd" + # -- ReclaimPolicy of etcd's localpv hostpath storage class. + reclaimPolicy: Delete + # -- VolumeBindingMode of etcd's localpv hostpath storage class. + volumeBindingMode: WaitForFirstConsumer + # Pod labels; okay to remove the openebs logging label if required + podLabels: + app: etcd + openebs.io/logging: "true" + # -- Number of replicas of etcd + replicaCount: 3 + # Kubernetes Cluster Domain + clusterDomain: cluster.local + # TLS authentication for client-to-server communications + # ref: https://etcd.io/docs/current/op-guide/security/ + client: + secureTransport: false + # TLS authentication for server-to-server communications + # ref: https://etcd.io/docs/current/op-guide/security/ + peer: + secureTransport: false + # Enable persistence using Persistent Volume Claims + persistence: + # -- If true, use a Persistent Volume Claim. If false, use emptyDir. + enabled: true + # -- Will define which storageClass to use in etcd's StatefulSets. Options: + #

- `"manual"` - Will provision a hostpath PV on the same node.
+ # - `""` (empty) - Will use the default StorageClass on the cluster.

+ storageClass: "mayastor-etcd-localpv" + # -- Volume size + size: 2Gi + # -- PVC's reclaimPolicy + reclaimPolicy: "Delete" + # -- Use a PreStop hook to remove the etcd members from the etcd cluster on container termination + # Ignored if lifecycleHooks is set or replicaCount=1 + removeMemberOnContainerTermination: false + + # -- AutoCompaction + # Since etcd keeps an exact history of its keyspace, this history should be + # periodically compacted to avoid performance degradation + # and eventual storage space exhaustion. + # Auto compaction mode. Valid values: "periodic", "revision". + # - 'periodic' for duration based retention, defaulting to hours if no time unit is provided (e.g. 5m). + # - 'revision' for revision number based retention. + autoCompactionMode: revision + # -- Auto compaction retention length. 0 means disable auto compaction. + autoCompactionRetention: 100 + extraEnvVars: + # -- Raise alarms when backend size exceeds the given quota. + - name: ETCD_QUOTA_BACKEND_BYTES + value: "8589934592" + + auth: + rbac: + create: false + enabled: false + allowNoneAuthentication: true + # Init containers parameters: + # volumePermissions: Change the owner and group of the persistent volume mountpoint to runAsUser:fsGroup values from the securityContext section. + # + volumePermissions: + # chown the mounted volume; this is required if a statically provisioned hostpath volume is used + enabled: true + # extra debug information on logs + debug: false + initialClusterState: "new" + + # -- Pod anti-affinity preset + # Ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity + podAntiAffinityPreset: "hard" + ## -- nodeSelector [object] Node labels for pod assignment + ## Ref: https://kubernetes.io/docs/user-guide/node-selection/ + nodeSelector: {} + + # etcd service parameters defines how the etcd service is exposed + service: + # K8s service type + type: ClusterIP + + # etcd client port + port: 2379 + + # Specify the nodePort(s) value(s) for the LoadBalancer and NodePort service types. + # ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + # + nodePorts: + # Port from where etcd endpoints are accessible from outside cluster + clientPort: 31379 + peerPort: "" + tolerations: [] + priorityClassName: "" + +loki-stack: + # -- Enable loki log collection for our components + enabled: true + # Configuration for loki's localpv hostpath storage class. + localpvScConfig: + # Name of loki's localpv hostpath storage class. + name: "mayastor-loki-localpv" + # -- Host path where local etcd data is stored in. + basePath: "/var/local/localpv-hostpath/{{ .Release.Name }}/loki" + # -- ReclaimPolicy of loki's localpv hostpath storage class. + reclaimPolicy: Delete + # -- VolumeBindingMode of loki's localpv hostpath storage class. + volumeBindingMode: WaitForFirstConsumer + loki: + rbac: + # -- Create rbac roles for loki + create: true + pspEnabled: false + # -- Enable loki installation as part of loki-stack + enabled: true + # Install loki with persistence storage + persistence: + # -- Enable persistence storage for the logs + enabled: true + # -- StorageClass for Loki's centralised log storage. Options: + #

- `"manual"` - Will provision a hostpath PV on the same node.
+ # - `""` (empty) - Will use the default StorageClass on the cluster.

+ storageClassName: "mayastor-loki-localpv" + # -- PVC's ReclaimPolicy, can be Delete or Retain + reclaimPolicy: "Delete" + # -- Size of Loki's persistence storage + size: 10Gi + # loki process run & file permissions, required if sc=manual + securityContext: + fsGroup: 1001 + runAsGroup: 1001 + runAsNonRoot: false + runAsUser: 1001 + # initContainers to chown the static hostpath PV by 1001 user + initContainers: + - command: ["/bin/bash", "-ec", "chown -R 1001:1001 /data"] + image: docker.io/bitnami/bitnami-shell:10 + imagePullPolicy: IfNotPresent + name: volume-permissions + securityContext: + runAsUser: 0 + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /data + name: storage + config: + # Compactor is a BoltDB(loki term) Shipper specific service that reduces the index + # size by deduping the index and merging all the files to a single file per table. + # Ref: https://grafana.com/docs/loki/latest/operations/storage/retention/ + compactor: + # Dictates how often compaction and/or retention is applied. If the + # Compactor falls behind, compaction and/or retention occur as soon as possible. + compaction_interval: 20m + + # If not enabled compactor will only compact table but they will not get + # deleted + retention_enabled: true + + # The delay after which the compactor will delete marked chunks + retention_delete_delay: 1h + + # Specifies the maximum quantity of goroutine workers instantiated to + # delete chunks + retention_delete_worker_count: 50 + + # Rentention period of logs is configured within the limits_config section + limits_config: + # configuring retention period for logs + retention_period: 168h + + # Loki service parameters defines how the Loki service is exposed + service: + # K8s service type + type: ClusterIP + port: 3100 + # Port where REST endpoints of Loki are accessible from outside cluster + nodePort: 31001 + tolerations: [] + priorityClassName: "" + + # promtail configuration + promtail: + rbac: + # create rbac roles for promtail + create: true + pspEnabled: false + # -- Enables promtail for scraping logs from nodes + enabled: true + # -- Disallow promtail from running on the master node + tolerations: [] + priorityClassName: "" + config: + # -- The Loki address to post logs to + lokiAddress: http://{{ .Release.Name }}-loki:3100/loki/api/v1/push + snippets: + # Promtail will export logs to loki only based on based on below + # configuration, below scrape config will export only our services + # which are labeled with openebs.io/logging=true + scrapeConfigs: | + - job_name: {{ .Release.Name }}-pods-name + pipeline_stages: + - docker: {} + kubernetes_sd_configs: + - role: pod + relabel_configs: + - source_labels: + - __meta_kubernetes_pod_node_name + target_label: hostname + action: replace + - action: labelmap + regex: __meta_kubernetes_pod_label_(.+) + - action: keep + source_labels: + - __meta_kubernetes_pod_label_openebs_io_logging + regex: true + target_label: {{ .Release.Name }}_component + - action: replace + replacement: $1 + separator: / + source_labels: + - __meta_kubernetes_namespace + target_label: job + - action: replace + source_labels: + - __meta_kubernetes_pod_name + target_label: pod + - action: replace + source_labels: + - __meta_kubernetes_pod_container_name + target_label: container + - replacement: /var/log/pods/*$1/*.log + separator: / + source_labels: + - __meta_kubernetes_pod_uid + - __meta_kubernetes_pod_container_name + target_label: __path__ + +# Eventing which enables or disables eventing-related components. +eventing: + enabled: true + +# Configuration for the nats message-bus. This is an eventing component, and is enabled when +# 'eventing.enabled' is set to 'true'. +nats: + nats: + image: + pullPolicy: IfNotPresent + # Defaults to docker.io + registry: "" + jetstream: + enabled: true + memStorage: + enabled: true + # Size of nats message is around 0.3 KB, so it can store around 10K messages. + size: "5Mi" + fileStorage: + enabled: false + cluster: + enabled: true + replicas: 3 + # The nats box can be installed for debugging, by default its enabled. + natsbox: + enabled: false + + +obs: + callhome: + # -- Enable callhome + enabled: true + # -- Log level for callhome + logLevel: "info" + sendReport: true + resources: + limits: + # -- Cpu limits for callhome + cpu: "100m" + # -- Memory limits for callhome + memory: "32Mi" + requests: + # -- Cpu requests for callhome + cpu: "50m" + # -- Memory requests for callhome + memory: "16Mi" + # -- Set tolerations, overrides global + tolerations: [] + # -- Set PriorityClass, overrides global + priorityClassName: "" + # Eventing component enabled/disabled based on obs.callhome.enabled value + stats: + # -- Log level for stats + logLevel: "info" + resources: + limits: + # -- Cpu limits for stats + cpu: "100m" + # -- Memory limits for stats + memory: "32Mi" + requests: + # -- Cpu requests for stats + cpu: "50m" + # -- Memory requests for stats + memory: "16Mi" + service: + # -- Rest K8s service type + type: ClusterIP + # Ports from where rest endpoints are accessible from outside the cluster, only valid if type is NodePort + nodePorts: + # NodePort associated with http port + http: 90011 + # NodePort associated with https port + https: 90010 + +localpv-provisioner: + # -- Enables the openebs dynamic-localpv provisioner. If disabled, modify etcd and loki-stack storage class accordingly. + enabled: true + # Enable/disable the openebs NDM sub-chart. It's recommended to keep this disabled. + openebsNDM: + enabled: false + # Enable/disable the creation of the openebs-device StorageClass. It's recommended to keep this disabled. + deviceClass: + enabled: false + hostpathClass: + enabled: false diff --git a/helm/openebs/charts/nfs-provisioner/Chart.yaml b/helm/openebs/charts/nfs-provisioner/Chart.yaml new file mode 100644 index 0000000..a0ffe88 --- /dev/null +++ b/helm/openebs/charts/nfs-provisioner/Chart.yaml @@ -0,0 +1,25 @@ +apiVersion: v2 +appVersion: 0.10.0 +description: Helm chart for OpenEBS Dynamic NFS PV. For instructions to install OpenEBS + Dynamic NFS PV using helm chart, refer to https://openebs.github.io/dynamic-nfs-provisioner. +home: http://www.openebs.io/ +icon: https://raw.githubusercontent.com/cncf/artwork/master/projects/openebs/icon/color/openebs-icon-color.png +keywords: +- storage +- nfs +- dynamic-nfs-pv +- kubernetes +maintainers: +- email: kiran.mova@mayadata.io + name: kmova +- email: mayank.patel@mayadata.io + name: mynktl +- email: rahulkrishnanfs@gmail.com + name: rahulkrishnanra +- email: sai.chaithanya@mayadata.io + name: mittachaitu +name: nfs-provisioner +sources: +- https://github.com/openebs/dynamic-nfs-provisioner +type: application +version: 0.10.0 diff --git a/helm/openebs/charts/nfs-provisioner/README.md b/helm/openebs/charts/nfs-provisioner/README.md new file mode 100644 index 0000000..6ef3117 --- /dev/null +++ b/helm/openebs/charts/nfs-provisioner/README.md @@ -0,0 +1,156 @@ +# OpenEBS NFS Provisioner + +[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) + +A Helm chart for openebs dynamic nfs provisioner. This chart bootstraps OpenEBS Dynamic NFS Provisioner deployment on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. + + +**Homepage:** + +## Maintainers + +| Name | Email | Url | +| ---- | ------ | --- | +| kmova | kiran.mova@mayadata.io | | +| mynktl | mayank.patel@mayadata.io | | +| rahulkrishnanra | rahulkrishnanfs@gmail.com | | +| mittachaitu | sai.chaithanya@mayadata.io | | + + +## Get Repo Info + +```console +helm repo add openebs-nfs https://openebs.github.io/dynamic-nfs-provisioner +helm repo update +``` + +_See [helm repo](https://helm.sh/docs/helm/helm_repo/) for command documentation._ + +## Install Chart + +Run the following command to install the OpenEBS Dynamic NFS Provisioner helm chart using the default StorageClass as the Backend StorageClass: + +```console +# Helm +helm install [RELEASE_NAME] openebs-nfs/nfs-provisioner --namespace [NAMESPACE] --create-namespace +``` + +The chart requires a StorageClass to provision the backend volume for the NFS share. You can use the `--set-string nfsStorageClass.backendStorageClass=` flag in the `helm install` command to specify the Backend StorageClass. If a StorageClass is not specified, the default StorageClass is used. + +Use the command below to get the name of the default StorageClasses in your cluster: + +```console +kubectl get sc -o=jsonpath='{range .items[?(@.metadata.annotations.storageclass\.kubernetes\.io/is-default-class=="true")]}{@.metadata.name}{"\n"}{end}' +``` + +Sample command to install the OpenEBS Dynamic NFS Provisioner helm chart using the default StorageClass as BackendStorageClass: + +```console +helm install openebs-nfs openebs-nfs/nfs-provisioner --namespace openebs --create-namespace +``` + +If you do not have an available StorageClass, you can install the [OpenEBS Dynamic LocalPV Provisioner helm chart](https://openebs.github.io/dynamic-localpv-provisioner) and use the 'openebs-hostpath' StorageClass as Backend Storage Class. Sample commands: + +```console +# Add openebs-localpv repo +helm repo add openebs-localpv https://openebs.github.io/dynamic-localpv-provisioner +helm repo update + +# Install localpv-provisioner +helm install openebs-localpv openebs-localpv/localpv-provisioner -n openebs --create-namespace \ + --set openebsNDM.enabled=false \ + --set deviceClass.enabled=false + +# Install nfs-provisioner +helm install openebs-nfs openebs-nfs/nfs-provisioner -n openebs \ + --set-string nfsStorageClass.backendStorageClass="openebs-hostpath" +``` + +Please visit this [link](https://helm.sh/docs/) for helm 3 installation instructions. + +_See [configuration](#configuration) below._ + +_See [helm install](https://helm.sh/docs/helm/helm_install/) for command documentation._ + + +## Uninstall Chart + +```console +# Helm +helm uninstall [RELEASE_NAME] --namespace [NAMESPACE] +``` + +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._ + +## Upgrading Chart + +```console +# Helm +helm upgrade [RELEASE_NAME] [CHART] --install --namespace [NAMESPACE] +``` + + +## Configuration + +The following table lists the configurable parameters of the OpenEBS Dynamic NFS Provisioner chart and their default values. You can modify different parameters by specifying the desired value in the `helm install` command by using the `--set` and/or the `--set-string` flag(s). + +In the following sample command we modify `nfsStorageClass.backendStorageClass` to specify the StorageClass to be used to provision the backend volume used for the NFS share. We also use `nfsStorageClass.isDefaultClass` to set an annotation such that the 'openebs-kernel-nfs' StorageClass is used as the default StorageClass for the cluster. + +```console +helm install openebs-nfs openebs-nfs/nfs-provisioner --namespace openebs --create-namespace \ + --set-string nfsStorageClass.backendStorageClass="openebs-hostpath" \ + --set nfsStorageClass.isDefaultClass=true +``` + +| Parameter | Description | Default | +| ------------------------------------- | --------------------------------------------- |-----------------------------| +| `analytics.enabled` | Enable sending stats to Google Analytics | `true` | +| `fullnameOverride` | Set custom Full Name for resources. Defaults to ( Release-name + `nfsProvisioner.name` ) | `""` | +| `imagePullSecrets` | Provides image pull secret | `""` | +| `nameOverride` | Set custom name for resources. Defaults to `nfsProvisioner.name` | `""` | +| `nfsProvisioner.affinity` | NFS Provisioner pod affinity | `{}` | +| `nfsProvisioner.enabled` | Enable NFS Provisioner | `true` | +| `nfsProvisioner.enableLeaderElection` | Enable leader election | `true` | +| `nfsProvisioner.healthCheck.initialDelaySeconds` | Delay before liveness probe is initiated | `30` | +| `nfsProvisioner.healthCheck.periodSeconds` | How often to perform the liveness probe | `60` | +| `nfsProvisioner.image.registry` | Registry for NFS Provisioner image | `""` | +| `nfsProvisioner.image.repository` | Image repository for NFS Provisioner | `openebs/provisioner-nfs` | +| `nfsProvisioner.image.tag` | Image tag for NFS Provisioner | `0.10.0` | +| `nfsProvisioner.image.pullPolicy` | Image pull policy for NFS Provisioner image | `IfNotPresent` | +| `nfsProvisioner.annotations` | Annotations for NFS Provisioner metadata | `""` | +| `nfsProvisioner.nodeSelector` | Nodeselector for NFS Provisioner pod | `""` | +| `nfsProvisioner.nfsServerAlpineImage.registry` | Registry for nfs-server-alpine | `""` | +| `nfsProvisioner.nfsServerAlpineImage.repository` | Image repository for nfs-server-alpine | `openebs/nfs-server-alpine` | +| `nfsProvisioner.nfsServerAlpineImage.tag` | Image tag for nfs-server-alpine | `0.10.0` | +| `nfsProvisioner.resources` | Resource request and limit for the container | `true` | +| `nfsProvisioner.securityContext` | Security context for container | `""` | +| `nfsProvisioner.tolerations` | NFS Provisioner pod toleration values | `""` | +| `nfsProvisioner.nfsServerNamespace` | NFS server namespace | `"openebs"` | +| `nfsProvisioner.nfsServerNodeAffinity` | NFS Server node affinity rules | `""` | +| `nfsProvisioner.nfsBackendPvcTimeout` | Timeout for backend PVC binding in seconds | `"60"` | +| `nfsProvisioner.nfsHookConfigMap` | Existing Configmap name to load hook configuration | `""` | +| `nfsStorageClass.backendStorageClass` | StorageClass to be used to provision the backend volume. If not specified, the default StorageClass is used. | `""` | +| `nfsStorageClass.isDefaultClass` | Make 'openebs-kernel-nfs' the default StorageClass | `"false"` | +| `nfsStorageClass.reclaimPolicy` | ReclaimPolicy for NFS PVs | `"Delete"` | +| `nfsStorageClass.leaseTime` | Renewal period(in seconds) for NFS client state | `90` | +| `nfsStorageClass.graceTime` | Recovery period(in seconds) to reclaim locks for NFS client | `90` | +| `nfsStorageClass.nfsServerResources` | Resource requests and limits of NFS Server | `""` | +| `nfsStorageClass.filePermissions.UID` | Set user owner of the shared directory | `""` | +| `nfsStorageClass.filePermissions.GID` | Set group owner of the shared directory | `""` | +| `nfsStorageClass.filePermissions.mode` | Set file mode of the shared directory | `""` | +| `rbac.create` | Enable RBAC Resources | `true` | +| `rbac.pspEnabled` | Create pod security policy resources | `false` | +| `nfsServer.imagePullSecret` | Image pull secret name to be used by NFS Server pods | `""` | + + +Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. + +Alternatively, a YAML file that specifies the values for the parameters can be provided while installing the chart. For example, + +```console +helm install -f values.yaml ----namespace openebs openebs-nfs/nfs-provisioner --create-namespace +``` + +> **Tip**: You can use the default [values.yaml](values.yaml) diff --git a/helm/openebs/charts/nfs-provisioner/templates/NOTES.txt b/helm/openebs/charts/nfs-provisioner/templates/NOTES.txt new file mode 100644 index 0000000..93b5984 --- /dev/null +++ b/helm/openebs/charts/nfs-provisioner/templates/NOTES.txt @@ -0,0 +1,9 @@ +Thank you for installing {{ .Chart.Name }} 😀 + +Your release is named {{ .Release.Name }} and it's installed to namespace: {{ .Release.Namespace }}. + +The OpenEBS NFSPV Provisioner has been installed check its status by running: +$ kubectl get pods -n {{ .Release.Namespace }} + +For more information, visit our Slack at https://openebs.io/community or view +the documentation online at https://github.com/openebs/dynamic-nfs-provisioner/. diff --git a/helm/openebs/charts/nfs-provisioner/templates/_helpers.tpl b/helm/openebs/charts/nfs-provisioner/templates/_helpers.tpl new file mode 100644 index 0000000..9df575f --- /dev/null +++ b/helm/openebs/charts/nfs-provisioner/templates/_helpers.tpl @@ -0,0 +1,77 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "nfsProvisioner.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 "nfsProvisioner.fullname" -}} +{{- if .Values.fullnameOverride -}} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Create the name of the service account to use +*/}} +{{- define "nfsProvisioner.serviceAccountName" -}} +{{- if .Values.serviceAccount.create -}} + {{ default (include "nfsProvisioner.fullname" .) .Values.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "nfsProvisioner.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Meta labels +*/}} +{{- define "nfsProvisioner.common.metaLabels" -}} +chart: {{ include "nfsProvisioner.chart" . }} +heritage: {{ .Release.Service }} +openebs.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} + +{{/* +Selector Labels +*/}} +{{- define "nfsProvisioner.selectorLabels" -}} +app: {{ include "nfsProvisioner.name" . }} +release: {{ .Release.Name }} +component: {{ .Values.nfsProvisioner.name }} +{{- end }} + +{{/* +Component labels +*/}} +{{- define "nfsProvisioner.componentLabels" -}} +openebs.io/component-name: openebs-{{ .Values.nfsProvisioner.name }} +{{- end -}} + +{{/* +Common labels +*/}} +{{- define "nfsProvisioner.labels" -}} +{{ include "nfsProvisioner.common.metaLabels" . }} +{{ include "nfsProvisioner.selectorLabels" . }} +{{ include "nfsProvisioner.componentLabels" . }} +{{- end -}} diff --git a/helm/openebs/charts/nfs-provisioner/templates/clusterrole.yaml b/helm/openebs/charts/nfs-provisioner/templates/clusterrole.yaml new file mode 100644 index 0000000..a4accbc --- /dev/null +++ b/helm/openebs/charts/nfs-provisioner/templates/clusterrole.yaml @@ -0,0 +1,58 @@ +# Define Role that allows operations on K8s pods/deployments +{{- if .Values.rbac.create }} +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ include "nfsProvisioner.fullname" . }} + {{- with .Values.nfsProvisioner.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "nfsProvisioner.labels" . | nindent 4 }} +rules: + - apiGroups: ["*"] + resources: ["nodes", "nodes/proxy"] + verbs: ["*"] + - apiGroups: ["*"] + resources: ["namespaces", "services", "pods", "pods/exec", "deployments", "deployments/finalizers", "replicationcontrollers", "replicasets", "events", "endpoints", "configmaps", "secrets", "jobs", "cronjobs"] + verbs: ["*"] + - apiGroups: ["*"] + resources: ["statefulsets", "daemonsets"] + verbs: ["*"] + - apiGroups: ["*"] + resources: ["resourcequotas", "limitranges"] + verbs: ["list", "watch"] + - apiGroups: ["*"] + resources: ["ingresses", "horizontalpodautoscalers", "verticalpodautoscalers", "poddisruptionbudgets", "certificatesigningrequests"] + verbs: ["list", "watch"] + - apiGroups: ["*"] + resources: ["storageclasses", "persistentvolumeclaims", "persistentvolumes"] + verbs: ["*"] + - apiGroups: ["apiextensions.k8s.io"] + resources: ["customresourcedefinitions"] + verbs: [ "get", "list", "create", "update", "delete", "patch"] + - apiGroups: ["openebs.io"] + resources: [ "*"] + verbs: ["*"] + - nonResourceURLs: ["/metrics"] + verbs: ["get"] + +{{- if .Values.rbac.pspEnabled }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "nfsProvisioner.fullname" . }}-psp + {{- with .Values.nfsProvisioner.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "nfsProvisioner.labels" . | nindent 4 }} +rules: + - apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ include "nfsProvisioner.fullname" . }}-psp +{{- end }} +{{- end }} diff --git a/helm/openebs/charts/nfs-provisioner/templates/clusterrolebinding.yaml b/helm/openebs/charts/nfs-provisioner/templates/clusterrolebinding.yaml new file mode 100644 index 0000000..caca823 --- /dev/null +++ b/helm/openebs/charts/nfs-provisioner/templates/clusterrolebinding.yaml @@ -0,0 +1,43 @@ +--- +# Bind the Service Account with the Role Privileges. +{{- if .Values.rbac.create }} +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ include "nfsProvisioner.fullname" . }} + {{- with .Values.nfsProvisioner.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "nfsProvisioner.labels" . | nindent 4 }} +roleRef: + kind: ClusterRole + name: {{ include "nfsProvisioner.fullname" . }} + apiGroup: rbac.authorization.k8s.io +subjects: + - kind: ServiceAccount + name: {{ include "nfsProvisioner.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} + +{{- if .Values.rbac.pspEnabled }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "nfsProvisioner.fullname" . }}-psp + {{- with .Values.nfsProvisioner.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "nfsProvisioner.labels" . | nindent 4 }} +roleRef: + kind: ClusterRole + name: {{ include "nfsProvisioner.fullname" . }}-psp + apiGroup: rbac.authorization.k8s.io +subjects: + # Authorize specific service accounts: + - kind: ServiceAccount + name: {{ include "nfsProvisioner.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +{{- end }} +{{- end }} diff --git a/helm/openebs/charts/nfs-provisioner/templates/deployment.yaml b/helm/openebs/charts/nfs-provisioner/templates/deployment.yaml new file mode 100644 index 0000000..c2a00a1 --- /dev/null +++ b/helm/openebs/charts/nfs-provisioner/templates/deployment.yaml @@ -0,0 +1,149 @@ +{{- if .Values.nfsProvisioner.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "nfsProvisioner.fullname" . }} + namespace: {{ .Release.Namespace }} + {{- if .Values.nfsProvisioner.annotations }} + annotations: {{- with .Values.nfsProvisioner.annotations }} + {{ toYaml . | nindent 4 }} + {{- end }} + {{- end }} + labels: + {{- include "nfsProvisioner.labels" . | nindent 4 }} +spec: + selector: + matchLabels: + {{- include "nfsProvisioner.selectorLabels" . | nindent 8 }} + replicas: 1 + strategy: + type: Recreate + rollingUpdate: null + template: + metadata: + labels: + {{- include "nfsProvisioner.labels" . | nindent 8 }} + {{- with .Values.nfsProvisioner.podLabels -}} + {{ toYaml . | nindent 8 }} + {{- end }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "nfsProvisioner.serviceAccountName" . }} + {{- if .Values.podSecurityContext }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + {{- end }} + containers: + - name: {{ include "nfsProvisioner.fullname" . }} + imagePullPolicy: {{ .Values.nfsProvisioner.image.pullPolicy }} + image: "{{ .Values.nfsProvisioner.image.registry }}{{ .Values.nfsProvisioner.image.repository }}:{{ default .Chart.AppVersion .Values.nfsProvisioner.image.tag }}" + {{- if .Values.nfsProvisioner.resources }} + resources: + {{- toYaml .Values.nfsProvisioner.resources | nindent 12 }} + {{ end }} + env: + # OPENEBS_IO_K8S_MASTER enables openebs provisioner to connect to K8s + # based on this address. This is ignored if empty. + # This is supported for openebs provisioner version 0.5.2 onwards + #- name: OPENEBS_IO_K8S_MASTER + # value: "http://10.128.0.12:8080" + # OPENEBS_IO_KUBE_CONFIG enables openebs provisioner to connect to K8s + # based on this config. This is ignored if empty. + # This is supported for openebs provisioner version 0.5.2 onwards + #- name: OPENEBS_IO_KUBE_CONFIG + # value: "/home/ubuntu/.kube/config" + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: OPENEBS_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + # OPENEBS_SERVICE_ACCOUNT provides the service account of this pod as + # environment variable + - name: OPENEBS_SERVICE_ACCOUNT + valueFrom: + fieldRef: + fieldPath: spec.serviceAccountName + - name: OPENEBS_IO_ENABLE_ANALYTICS + value: "{{ .Values.analytics.enabled }}" + - name: OPENEBS_IO_NFS_SERVER_USE_CLUSTERIP + value: "{{ .Values.nfsServer.useClusterIP }}" + - name: OPENEBS_IO_INSTALLER_TYPE + value: "nfs-helm" + # OPENEBS_IO_NFS_SERVER_IMG defines the nfs-server-alpine image name to be used + # while creating nfs volume + - name: OPENEBS_IO_NFS_SERVER_IMG + value: "{{ .Values.nfsProvisioner.nfsServerAlpineImage.registry }}{{ .Values.nfsProvisioner.nfsServerAlpineImage.repository }}:{{ default .Chart.AppVersion .Values.nfsProvisioner.nfsServerAlpineImage.tag }}" + # LEADER_ELECTION_ENABLED is used to enable/disable leader election. By default + # leader election is enabled. + - name: LEADER_ELECTION_ENABLED + value: "{{ .Values.nfsProvisioner.enableLeaderElection }}" + {{- if .Values.nfsProvisioner.nfsServerNamespace }} + - name: OPENEBS_IO_NFS_SERVER_NS + value: {{ .Values.nfsProvisioner.nfsServerNamespace }} + {{- end }} + {{- if .Values.nfsServer.imagePullSecret }} + - name: OPENEBS_IO_NFS_SERVER_IMAGE_PULL_SECRET + value: {{ .Values.nfsServer.imagePullSecret }} + {{- end }} + # OPENEBS_IO_NFS_SERVER_NODE_AFFINITY defines the node affinity rules to place NFS Server + # instance. It accepts affinity rules in multiple ways: + # - If NFS Server needs to be placed on storage nodes as well as only in + # zone-1 & zone-2 then value can be: + # value: "kubernetes.io/zone:[zone-1,zone-2],kubernetes.io/storage-node". + # - If NFS Server needs to be placed only on storage nodes & nfs nodes then + # value can be: + # value: "kubernetes.io/storage-node,kubernetes.io/nfs-node" + {{- if .Values.nfsProvisioner.nfsServerNodeAffinity }} + - name: OPENEBS_IO_NFS_SERVER_NODE_AFFINITY + value: "{{ .Values.nfsProvisioner.nfsServerNodeAffinity }}" + {{- end }} + {{- if .Values.nfsProvisioner.nfsBackendPvcTimeout }} + - name: OPENEBS_IO_NFS_SERVER_BACKEND_PVC_TIMEOUT + value: "{{ .Values.nfsProvisioner.nfsBackendPvcTimeout }}" + {{- end }} + # Process name used for matching is limited to the 15 characters + # present in the pgrep output. + # So fullname can't be used here with pgrep (>15 chars).A regular expression + # that matches the entire command name has to specified. + # Anchor `^` : matches any string that starts with `provisioner-nfs` + # `.*`: matches any string that has `provisioner-loc` followed by zero or more char + livenessProbe: + exec: + command: + - sh + - -c + - test `pgrep "^provisioner-nfs.*"` = 1 + initialDelaySeconds: {{ .Values.nfsProvisioner.healthCheck.initialDelaySeconds }} + periodSeconds: {{ .Values.nfsProvisioner.healthCheck.periodSeconds }} + volumeMounts: + # Mounting hook-config volume into nfs-provisioner config directory + {{- if .Values.nfsProvisioner.nfsHookConfigMap }} + - name: hook-config + mountPath: /etc/nfs-provisioner + {{- end }} + volumes: + # hook-config volume uses ConfigMap 'hook-config' to load hook configuration + {{- if .Values.nfsProvisioner.nfsHookConfigMap }} + - name: hook-config + configMap: + name: {{ .Values.nfsProvisioner.nfsHookConfigMap }} + {{- end }} +{{- if .Values.nfsProvisioner.nodeSelector }} + nodeSelector: +{{ toYaml .Values.nfsProvisioner.nodeSelector | indent 8 }} +{{- end }} +{{- if .Values.nfsProvisioner.tolerations }} + tolerations: +{{ toYaml .Values.nfsProvisioner.tolerations | indent 8 }} +{{- end }} +{{- if .Values.nfsProvisioner.affinity }} + affinity: +{{ toYaml .Values.nfsProvisioner.affinity | indent 8 }} +{{- end }} +{{- end }} diff --git a/helm/openebs/charts/nfs-provisioner/templates/kernel-nfs-storageclass.yaml b/helm/openebs/charts/nfs-provisioner/templates/kernel-nfs-storageclass.yaml new file mode 100644 index 0000000..da77f52 --- /dev/null +++ b/helm/openebs/charts/nfs-provisioner/templates/kernel-nfs-storageclass.yaml @@ -0,0 +1,57 @@ +--- +# Storage classes for OpenEBS NFS Dynamic PV +apiVersion: storage.k8s.io/v1 +kind: StorageClass +metadata: + name: {{ .Values.nfsStorageClass.name }} + annotations: + openebs.io/cas-type: nfsrwx + cas.openebs.io/config: | + - name: NFSServerType + value: {{ .Values.nfsStorageClass.nfsServerType }} +{{- if .Values.nfsStorageClass.backendStorageClass }} + - name: BackendStorageClass + value: {{ .Values.nfsStorageClass.backendStorageClass }} +{{- end }} +{{- if .Values.nfsStorageClass.customServerConfig }} + - name: CustomServerConfig + value: {{ .Values.nfsStorageClass.customServerConfig }} +{{- end }} +{{- if .Values.nfsStorageClass.leaseTime }} + - name: LeaseTime + value: {{ .Values.nfsStorageClass.leaseTime }} +{{- end }} +{{- if .Values.nfsStorageClass.graceTime }} + - name: GraceTime + value: {{ .Values.nfsStorageClass.graceTime }} +{{- end }} +{{- if .Values.nfsStorageClass.nfsServerResources }} +{{- if .Values.nfsStorageClass.nfsServerResources.requests }} + - name: NFSServerResourceRequests + value: |- +{{ toYaml .Values.nfsStorageClass.nfsServerResources.requests | indent 10 }} +{{- end }} +{{- if .Values.nfsStorageClass.nfsServerResources.limits }} + - name: NFSServerResourceLimits + value: |- +{{ toYaml .Values.nfsStorageClass.nfsServerResources.limits | indent 10 }} +{{- end }} +{{- end }} +{{- if .Values.nfsStorageClass.filePermissions }} + - name: FilePermissions + data: +{{- if .Values.nfsStorageClass.filePermissions.UID }} + UID: {{ .Values.nfsStorageClass.filePermissions.UID | quote }} +{{- end }} +{{- if .Values.nfsStorageClass.filePermissions.GID }} + GID: {{ .Values.nfsStorageClass.filePermissions.GID | quote }} +{{- end }} +{{- if .Values.nfsStorageClass.filePermissions.mode }} + mode: {{ .Values.nfsStorageClass.filePermissions.mode | quote }} +{{- end }} +{{- end }} +{{- if .Values.nfsStorageClass.isDefaultClass }} + storageclass.kubernetes.io/is-default-class: "true" +{{- end }} +provisioner: openebs.io/nfsrwx +reclaimPolicy: {{ .Values.nfsStorageClass.reclaimPolicy }} diff --git a/helm/openebs/charts/nfs-provisioner/templates/psp.yaml b/helm/openebs/charts/nfs-provisioner/templates/psp.yaml new file mode 100644 index 0000000..f17e37f --- /dev/null +++ b/helm/openebs/charts/nfs-provisioner/templates/psp.yaml @@ -0,0 +1,31 @@ +{{- if .Values.rbac.pspEnabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "nfsProvisioner.fullname" . }}-psp + {{- with .Values.nfsProvisioner.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "nfsProvisioner.labels" . | nindent 4 }} +spec: + privileged: {{ .Values.nfsProvisioner.privileged }} + allowPrivilegeEscalation: true + allowedCapabilities: ['*'] + volumes: ['*'] + hostNetwork: true + hostPorts: + - min: 0 + max: 65535 + hostIPC: true + hostPID: true + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'RunAsAny' + fsGroup: + rule: 'RunAsAny' + {{- end }} + diff --git a/helm/openebs/charts/nfs-provisioner/templates/serviceaccount.yaml b/helm/openebs/charts/nfs-provisioner/templates/serviceaccount.yaml new file mode 100644 index 0000000..45079bf --- /dev/null +++ b/helm/openebs/charts/nfs-provisioner/templates/serviceaccount.yaml @@ -0,0 +1,10 @@ +# Create Service Account for nfs-provisioner. +{{- if .Values.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "nfsProvisioner.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "nfsProvisioner.labels" . | nindent 4 }} +{{- end }} diff --git a/helm/openebs/charts/nfs-provisioner/values.yaml b/helm/openebs/charts/nfs-provisioner/values.yaml new file mode 100644 index 0000000..7d1f226 --- /dev/null +++ b/helm/openebs/charts/nfs-provisioner/values.yaml @@ -0,0 +1,142 @@ +# Default values for nfspv-provisioner. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +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: + +rbac: + # rbac.create: `true` if rbac resources should be created + create: true + # rbac.pspEnabled: `true` if PodSecurityPolicy resources should be created + pspEnabled: false + +podSecurityContext: {} +# fsGroup: 2000 + +imagePullSecrets: +# - name: image-pull-secret + +fullnameOverride: "" +nameOverride: "" + +nfsProvisioner: + name: nfs-provisioner + enabled: true + annotations: {} + podLabels: + name: openebs-nfs-provisioner + image: + # Make sure that registry name end with a '/'. + # For example : quay.io/ is a correct value here and quay.io is incorrect + registry: + repository: openebs/provisioner-nfs + tag: + pullPolicy: IfNotPresent + enableLeaderElection: "true" + # Specify image name of nfs-server-alpine used for creating nfs server deployment + # If not mentioned, default value openebs/nfs-server-alpine:tag will be used where + # the tag will be the same as a provisioner-nfs image tag + nfsServerAlpineImage: + registry: + repository: openebs/nfs-server-alpine + tag: + 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:'. + # ## Normal cases CPU and memory usage are around ~10 millicores and + # ## memory usage is around ~16Mb(after provisioing 70 volumes) + # requests: + # cpu: 50m + # memory: 50M + # ## During provisioning(large no.of pvcs at a time) time CPU and memory usage + # ## are around ~67 millicores(6.7% of cpu) and memory usage is around ~34Mb + # limits: + # cpu: 200m + # memory: 200Mi + # If set to false, containers created by the nfs provisioner will run without extra privileges. + privileged: true + nodeSelector: {} + tolerations: [] + affinity: {} + healthCheck: + initialDelaySeconds: 30 + periodSeconds: 60 + # namespace in which nfs server objects should be created + # By default, nfs provisioner will create these resources in nfs provisioner's namespace + # nfsServerNamespace: openebs + # + # nfsServerNodeAffinity defines the node affinity rules to place NFS Server + # instance. It accepts affinity rules in multiple ways: + # - If NFS Server needs to be placed on storage nodes as well as only in + # zone-1 & zone-2 then value can be: "kubernetes.io/zone:[zone-1,zone-2],kubernetes.io/storage-node". + # - If NFS Server needs to be placed only on storage nodes & nfs nodes then + # value can be: "kubernetes.io/storage-node,kubernetes.io/nfs-node" + # nfsServerNodeAffinity: "kubernetes.io/storage-node,kubernetes.io/nfs-node" + # + # nfsHookConfigMap represent the ConfigMap name to be used for hook configuration. + # By default, nfsHookConfigMap is set to empty. + # If nfsHookConfigMap is set then chart will mount the configmap using volume, named `hook-config` + nfsHookConfigMap: "" + +nfsStorageClass: + name: openebs-kernel-nfs + reclaimPolicy: Delete + nfsServerType: kernel + isDefaultClass: false + backendStorageClass: "" + # The customServerConfig key passes a custom /etc/exports configuration to + # the NFS servers created using this StorageClass. + # The configuration settings are not validated, and can lead to security + # vulnerability. + # USING THIS IS NOT RECOMMENDED + customServerConfig: "" + # leaseTime defines the renewal period(in seconds) for client state + leaseTime: + # graceTime defines the recovery period(in seconds) to reclaim locks + # setting graceTime and leaseTime lower will reduce the io pause time during nfs server restart + graceTime: + # filePermissions defines the file ownership and mode specifications + # for the NFS server's shared filesystem volume. + # File permission changes are applied recursively if the root of the + # volume's filesystem does not match the specified value. + # For more information: https://github.com/openebs/dynamic-nfs-provisioner/blob/develop/docs/tutorial/file-permissions.md + filePermissions: {} + # The UID value is used to set the user-owner of NFS shared directory. Only valid + # UIDs are accepted. + # The ownership change is carried out recursively down the directory tree. + # UID: "" + # The GID value is used to set the group-owner of NFS shared directory. Only valid + # GIDs are accepted. + # The ownership change is carried out recursively down the directory tree. + # GID: "" + # The mode value is used to set the file mode of NFS shared directory. Both octals (e.g. 0744) + # and incremental/decremental (e.g. "u+r", "o+rw") values are accepted. + # The file mode change is carried out recursively down the directory tree. + # mode: "" + + # nfsServerResources defines the NFS server resource requests and limits + # Usually, below request and limits are good enough for NFS Server to work + # seamlessly(IOs will be taken care by kerner space process i.e nfsd). + nfsServerResources: {} + # requests: + # memory: 50Mi + # cpu: 50m + # limits: + # memory: 100Mi + # cpu: 100m + +nfsServer: + useClusterIP: "true" + imagePullSecret: "" + +analytics: + enabled: "true" diff --git a/helm/openebs/charts/openebs-ndm/Chart.yaml b/helm/openebs/charts/openebs-ndm/Chart.yaml new file mode 100644 index 0000000..53484cd --- /dev/null +++ b/helm/openebs/charts/openebs-ndm/Chart.yaml @@ -0,0 +1,23 @@ +apiVersion: v2 +appVersion: 2.1.0 +description: Helm chart for OpenEBS Node Disk Manager - a Kubernetes native storage + device management solution. For instructions on how to install, refer to https://openebs.github.io/node-disk-manager/. +home: http://www.openebs.io/ +icon: https://raw.githubusercontent.com/cncf/artwork/master/projects/openebs/icon/color/openebs-icon-color.png +keywords: +- cloud-native-storage +- block-storage +- ndm +- disk-inventory +- storage +maintainers: +- email: akhil.mohan@mayadata.io + name: akhilerm +- email: michaelfornaro@gmail.com + name: xUnholy +- email: prateek.pandey@mayadata.io + name: prateekpandey14 +name: openebs-ndm +sources: +- https://github.com/openebs/node-disk-manager +version: 2.1.0 diff --git a/helm/openebs/charts/openebs-ndm/README.md b/helm/openebs/charts/openebs-ndm/README.md new file mode 100644 index 0000000..399a687 --- /dev/null +++ b/helm/openebs/charts/openebs-ndm/README.md @@ -0,0 +1,93 @@ +## Introduction + +This chart bootstraps OpenEBS NDM deployment on a [Kubernetes](http://kubernetes.io) cluster using the +[Helm](https://helm.sh) package manager. + +## Installation + +You can run OpenEBS NDM on any Kubernetes 1.17+ cluster in a matter of seconds. + +Please visit the [link](https://openebs.github.io/node-disk-manager/) for install instructions via helm3. + +## Configuration + +The following table lists the configurable parameters of the OpenEBS NDM chart and their default values. + +| Parameter | Description | Default | +|-------------------------------------------------------------|-------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------| +| `imagePullSecrets` | Provides image pull secrect | `""` | +| `ndm.enabled` | Enable Node Disk Manager | `true` | +| `ndm.image.registry` | Registry for Node Disk Manager image | `""` | +| `ndm.image.repository` | Image repository for Node Disk Manager | `openebs/node-disk-manager` | +| `ndm.image.pullPolicy` | Image pull policy for Node Disk Manager | `IfNotPresent` | +| `ndm.image.tag` | Image tag for Node Disk Manager | `2.1.0` | +| `ndm.sparse.path` | Directory where Sparse files are created | `/var/openebs/sparse` | +| `ndm.sparse.size` | Size of the sparse file in bytes | `10737418240` | +| `ndm.sparse.count` | Number of sparse files to be created | `0` | +| `ndm.updateStrategy.type` | Update strategy for NDM daemonset | `RollingUpdate` | +| `ndm.annotations` | Annotations for NDM daemonset metadata | `""` | +| `ndm.podAnnotations` | Annotations for NDM daemonset's pods metadata | `""` | +| `ndm.resources` | Resource and request and limit for containers | `""` | +| `ndm.podLabels` | Appends labels to the pods | `""` | +| `ndm.nodeSelector` | Nodeselector for daemonset pods | `""` | +| `ndm.tolerations` | NDM daemonset's pod toleration values | `""` | +| `ndm.securityContext` | Seurity context for container | `""` | +| `ndm.filters.enableOsDiskExcludeFilter` | Enable filters of OS disk exclude | `true` | +| `ndm.filters.osDiskExcludePaths` | Paths/Mountpoints to be excluded by OS Disk Filter | `/,/etc/hosts,/boot` | +| `ndm.filters.enableVendorFilter` | Enable filters of vendors | `true` | +| `ndm.filters.excludeVendors` | Exclude devices with specified vendor | `CLOUDBYT,OpenEBS` | +| `ndm.filters.enablePathFilter` | Enable filters of paths | `true` | +| `ndm.filters.includePaths` | Include devices with specified path patterns | `""` | +| `ndm.filters.excludePaths` | Exclude devices with specified path patterns | `loop,fd0,sr0,/dev/ram,/dev/dm-,/dev/md,/dev/rbd,/dev/zd` | +| `ndm.probes.enableSeachest` | Enable Seachest probe for NDM | `false` | +| `ndm.probes.enableUdevProbe` | Enable Udev probe for NDM | `true` | +| `ndm.probes.enableSmartProbe` | Enable Smart probe for NDM | `true` | +| `ndm.metaConfig.nodeLabelPattern` | Config for adding node labels as BD labels | `kubernetes.io*,beta.kubernetes.io*` | +| `ndm.metaConfig.deviceLabelTypes` | Config for adding device attributes as BD labels | `.spec.details.vendor,.spec.details.model,.spec.details.driveType,.spec.filesystem.fsType` | +| `ndmOperator.enabled` | Enable NDM Operator | `true` | +| `ndmOperator.replica` | Pod replica count for NDM operator | `1` | +| `ndmOperator.upgradeStrategy` | Update strategy NDM operator | `"Recreate"` | +| `ndmOperator.image.registry` | Registry for NDM operator image | `""` | +| `ndmOperator.image.repository` | Image repository for NDM operator | `openebs/node-disk-operator` | +| `ndmOperator.image.pullPolicy` | Image pull policy for NDM operator | `IfNotPresent` | +| `ndmOperator.image.tag` | Image tag for NDM operator | `2.1.0` | +| `ndmOperator.annotations` | Annotations for NDM operator metadata | `""` | +| `ndmOperator.podAnnotations` | Annotations for NDM operator's pods metadata | `""` | +| `ndmOperator.resources` | Resource and request and limit for containers | `""` | +| `ndmOperator.podLabels` | Appends labels to the pods | `""` | +| `ndmOperator.nodeSelector` | Nodeselector for operator pods | `""` | +| `ndmOperator.tolerations` | NDM operator's pod toleration values | `""` | +| `ndmOperator.securityContext` | Security context for container | `""` | +| `ndmExporter.enabled` | Enable NDM Exporters | `false` | +| `ndmExporter.image.registry` | Registry for NDM Exporters image | `""` | +| `ndmExporter.repository` | Image repository for NDM Exporters | `openebs/node-disk-exporter` | +| `ndmExporter.pullPolicy` | Image pull policy for NDM Exporters | `IfNotPresent` | +| `ndmExporter.tag` | Image tag for NDM Exporters | `2.1.0` | +| `ndmExporter.nodeExporter.metricsPort` | The TCP port number used for exposing NDM node exporter metrics | `9101` | +| `ndmExporter.nodeExporter.nodeExporter.nodeSelector` | Node selector for NDM node exporter pods | `9101` | +| `ndmExporter.nodeExporter.nodeExporter.tolerations` | NDM node exporter toleration values | `9101` | +| `ndmExporter.clusterExporter.metricsPort` | The TCP port number used for exposing NDM cluster exporter metrics | `9100` | +| `ndmExporter.clusterExporter.clusterExpoerter.nodeSelector` | Node selector for NDM cluster exporter pod | `9100` | +| `ndmExporter.clusterExporter.clusterExpoerter.tolerations` | NDM cluster exporter toleraion values | `9100` | +| `featureGates.APIService.enabled` | Enable the gRPC API service of NDM | `false` | +| `featureGates.UseOSDisk.enabled` | Enable feature-gate to use free space on OS disk | `false` | +| `featureGates.ChangeDetection.enabled` | Enable feature-gate to detect mountpoint/filesystem/size changes | `false` | +| `featureGates.PartitionTableUUID.enabled` | Enable feature-gate to use partition table UUID instead of creating partition | `true` | +| `helperPod.image.registry` | Registry for helper image | `""` | +| `helperPod.image.repository` | Image for helper pod | `openebs/linux-utils` | +| `helperPod.image.pullPolicy` | Pull policy for helper pod | `IfNotPresent` | +| `helperPod.image.tag` | Image tag for helper image | `3.4.0` | +| `varDirectoryPath.baseDir` | Directory to store debug info and so forth | `/var/openebs` | +| `serviceAccount.create` | Create a service account or not | `true` | +| `serviceAccount.name` | Name for the service account | `true` | + + +Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. + +Alternatively, a YAML file that specifies the values for the parameters can be provided while installing the chart. For example, + +```bash +helm install -f values.yaml ndm/openebs-ndm +``` + +> **Tip**: You can use the default [values.yaml](values.yaml) diff --git a/helm/openebs/charts/openebs-ndm/crds/blockdevice.yaml b/helm/openebs/charts/openebs-ndm/crds/blockdevice.yaml new file mode 100644 index 0000000..95f4070 --- /dev/null +++ b/helm/openebs/charts/openebs-ndm/crds/blockdevice.yaml @@ -0,0 +1,241 @@ + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.5.0 + creationTimestamp: null + name: blockdevices.openebs.io +spec: + group: openebs.io + names: + kind: BlockDevice + listKind: BlockDeviceList + plural: blockdevices + shortNames: + - bd + singular: blockdevice + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.nodeAttributes.nodeName + name: NodeName + type: string + - jsonPath: .spec.path + name: Path + priority: 1 + type: string + - jsonPath: .spec.filesystem.fsType + name: FSType + priority: 1 + type: string + - jsonPath: .spec.capacity.storage + name: Size + type: string + - jsonPath: .status.claimState + name: ClaimState + type: string + - jsonPath: .status.state + name: Status + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: BlockDevice is the Schema for the blockdevices 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: DeviceSpec defines the properties and runtime status of a BlockDevice + properties: + aggregateDevice: + description: AggregateDevice was intended to store the hierarchical information in cases of LVM. However this is currently not implemented and may need to be re-looked into for better design. To be deprecated + type: string + capacity: + description: Capacity + properties: + logicalSectorSize: + description: LogicalSectorSize is blockdevice logical-sector size in bytes + format: int32 + type: integer + physicalSectorSize: + description: PhysicalSectorSize is blockdevice physical-Sector size in bytes + format: int32 + type: integer + storage: + description: Storage is the blockdevice capacity in bytes + format: int64 + type: integer + required: + - storage + type: object + claimRef: + description: ClaimRef is the reference to the BDC which has claimed this BD + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: 'If referring to a piece of an object instead of an entire object, this string should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. For example, if the object reference is to a container within a pod, this would take on a value like: "spec.containers{name}" (where "name" refers to the name of the container that triggered the event) or if no container name is specified "spec.containers[2]" (container with index 2 in this pod). This syntax is chosen only to have some well-defined way of referencing a part of an object. TODO: this design is not final and this field is subject to change in the future.' + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: 'Specific resourceVersion to which this reference is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + details: + description: Details contain static attributes of BD like model,serial, and so forth + properties: + compliance: + description: Compliance is standards/specifications version implemented by device firmware such as SPC-1, SPC-2, etc + type: string + deviceType: + description: DeviceType represents the type of device like sparse, disk, partition, lvm, crypt + enum: + - disk + - partition + - sparse + - loop + - lvm + - crypt + - dm + - mpath + type: string + driveType: + description: DriveType is the type of backing drive, HDD/SSD + enum: + - HDD + - SSD + - Unknown + - "" + type: string + firmwareRevision: + description: FirmwareRevision is the disk firmware revision + type: string + hardwareSectorSize: + description: HardwareSectorSize is the hardware sector size in bytes + format: int32 + type: integer + logicalBlockSize: + description: LogicalBlockSize is the logical block size in bytes reported by /sys/class/block/sda/queue/logical_block_size + format: int32 + type: integer + model: + description: Model is model of disk + type: string + physicalBlockSize: + description: PhysicalBlockSize is the physical block size in bytes reported by /sys/class/block/sda/queue/physical_block_size + format: int32 + type: integer + serial: + description: Serial is serial number of disk + type: string + vendor: + description: Vendor is vendor of disk + type: string + type: object + devlinks: + description: DevLinks contains soft links of a block device like /dev/by-id/... /dev/by-uuid/... + items: + description: DeviceDevLink holds the mapping between type and links like by-id type or by-path type link + properties: + kind: + description: Kind is the type of link like by-id or by-path. + enum: + - by-id + - by-path + type: string + links: + description: Links are the soft links + items: + type: string + type: array + type: object + type: array + filesystem: + description: FileSystem contains mountpoint and filesystem type + properties: + fsType: + description: Type represents the FileSystem type of the block device + type: string + mountPoint: + description: MountPoint represents the mountpoint of the block device. + type: string + type: object + nodeAttributes: + description: NodeAttributes has the details of the node on which BD is attached + properties: + nodeName: + description: NodeName is the name of the Kubernetes node resource on which the device is attached + type: string + type: object + parentDevice: + description: "ParentDevice was intended to store the UUID of the parent Block Device as is the case for partitioned block devices. \n For example: /dev/sda is the parent for /dev/sda1 To be deprecated" + type: string + partitioned: + description: Partitioned represents if BlockDevice has partitions or not (Yes/No) Currently always default to No. To be deprecated + enum: + - "Yes" + - "No" + type: string + path: + description: Path contain devpath (e.g. /dev/sdb) + type: string + required: + - capacity + - devlinks + - nodeAttributes + - path + type: object + status: + description: DeviceStatus defines the observed state of BlockDevice + properties: + claimState: + description: ClaimState represents the claim state of the block device + enum: + - Claimed + - Unclaimed + - Released + type: string + state: + description: State is the current state of the blockdevice (Active/Inactive/Unknown) + enum: + - Active + - Inactive + - Unknown + type: string + required: + - claimState + - state + type: object + type: object + served: true + storage: true + subresources: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/helm/openebs/charts/openebs-ndm/crds/blockdeviceclaim.yaml b/helm/openebs/charts/openebs-ndm/crds/blockdeviceclaim.yaml new file mode 100644 index 0000000..81b9a35 --- /dev/null +++ b/helm/openebs/charts/openebs-ndm/crds/blockdeviceclaim.yaml @@ -0,0 +1,144 @@ + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.5.0 + creationTimestamp: null + name: blockdeviceclaims.openebs.io +spec: + group: openebs.io + names: + kind: BlockDeviceClaim + listKind: BlockDeviceClaimList + plural: blockdeviceclaims + shortNames: + - bdc + singular: blockdeviceclaim + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.blockDeviceName + name: BlockDeviceName + type: string + - jsonPath: .status.phase + name: Phase + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: BlockDeviceClaim is the Schema for the blockdeviceclaims 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: DeviceClaimSpec defines the request details for a BlockDevice + properties: + blockDeviceName: + description: BlockDeviceName is the reference to the block-device backing this claim + type: string + blockDeviceNodeAttributes: + description: BlockDeviceNodeAttributes is the attributes on the node from which a BD should be selected for this claim. It can include nodename, failure domain etc. + properties: + hostName: + description: HostName represents the hostname of the Kubernetes node resource where the BD should be present + type: string + nodeName: + description: NodeName represents the name of the Kubernetes node resource where the BD should be present + type: string + type: object + deviceClaimDetails: + description: Details of the device to be claimed + properties: + allowPartition: + description: AllowPartition represents whether to claim a full block device or a device that is a partition + type: boolean + blockVolumeMode: + description: 'BlockVolumeMode represents whether to claim a device in Block mode or Filesystem mode. These are use cases of BlockVolumeMode: 1) Not specified: VolumeMode check will not be effective 2) VolumeModeBlock: BD should not have any filesystem or mountpoint 3) VolumeModeFileSystem: BD should have a filesystem and mountpoint. If DeviceFormat is specified then the format should match with the FSType in BD' + type: string + formatType: + description: Format of the device required, eg:ext4, xfs + type: string + type: object + deviceType: + description: DeviceType represents the type of drive like SSD, HDD etc., + nullable: true + type: string + hostName: + description: Node name from where blockdevice has to be claimed. To be deprecated. Use NodeAttributes.HostName instead + type: string + resources: + description: Resources will help with placing claims on Capacity, IOPS + properties: + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum resources required. eg: if storage resource of 10G is requested minimum capacity of 10G should be available TODO for validating' + type: object + required: + - requests + type: object + selector: + description: Selector is used to find block devices to be considered for claiming + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + type: object + status: + description: DeviceClaimStatus defines the observed state of BlockDeviceClaim + properties: + phase: + description: Phase represents the current phase of the claim + type: string + required: + - phase + type: object + type: object + served: true + storage: true + subresources: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/helm/openebs/charts/openebs-ndm/templates/NOTES.txt b/helm/openebs/charts/openebs-ndm/templates/NOTES.txt new file mode 100644 index 0000000..3c84551 --- /dev/null +++ b/helm/openebs/charts/openebs-ndm/templates/NOTES.txt @@ -0,0 +1,8 @@ +The OpenEBS Node Disk Manager has been installed. Check its status by running: +$ kubectl get pods -n {{ .Release.Namespace }} + +Use `kubectl get bd -n {{ .Release.Namespace }} ` to see the list of +blockdevices attached to the Kubernetes cluster nodes. + +For more information, visit our Slack at https://openebs.io/community or view +the documentation online at http://docs.openebs.io/. diff --git a/helm/openebs/charts/openebs-ndm/templates/_helpers.tpl b/helm/openebs/charts/openebs-ndm/templates/_helpers.tpl new file mode 100644 index 0000000..c975510 --- /dev/null +++ b/helm/openebs/charts/openebs-ndm/templates/_helpers.tpl @@ -0,0 +1,242 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +This name is used for ndm daemonset +*/}} +{{- define "openebs-ndm.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "openebs-ndm.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified ndm daemonset 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 "openebs-ndm.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains .Release.Name $name }} +{{- $name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{- define "openebs-ndm.operator.name" -}} +{{- $ndmName := default .Chart.Name .Values.ndmOperator.nameOverride | trunc 63 | trimSuffix "-" }} +{{- $componentName := .Values.ndmOperator.name | trunc 63 | trimSuffix "-" }} +{{- printf "%s-%s" $ndmName $componentName | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified ndm operator 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 "openebs-ndm.operator.fullname" -}} +{{- if .Values.ndmOperator.fullnameOverride }} +{{- .Values.ndmOperator.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $ndmOperatorName := include "openebs-ndm.operator.name" .}} + +{{- $name := default $ndmOperatorName .Values.ndmOperator.nameOverride }} +{{- if contains .Release.Name $name }} +{{- $name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{- define "openebs-ndm.cluster-exporter.name" -}} +{{- $ndmName := default .Chart.Name .Values.ndmExporter.clusterExporter.nameOverride | trunc 63 | trimSuffix "-" }} +{{- $componentName := .Values.ndmExporter.clusterExporter.name | trunc 63 | trimSuffix "-" }} +{{- printf "%s-%s" $ndmName $componentName | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified ndm cluster exporter 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 "openebs-ndm.cluster-exporter.fullname" -}} +{{- if .Values.ndmExporter.clusterExporter.fullnameOverride }} +{{- .Values.ndmExporter.clusterExporter.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $ndmClusterExporterName := include "openebs-ndm.cluster-exporter.name" .}} + +{{- $name := default $ndmClusterExporterName .Values.ndmExporter.clusterExporter.nameOverride }} +{{- if contains .Release.Name $name }} +{{- $name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{- define "openebs-ndm.exporter.name" -}} +{{- $ndmName := .Chart.Name | trunc 63 | trimSuffix "-" }} +{{- $componentName := "exporter" | trunc 63 | trimSuffix "-" }} +{{- printf "%s-%s" $ndmName $componentName | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{- define "openebs-ndm.node-exporter.name" -}} +{{- $ndmName := default .Chart.Name .Values.ndmExporter.nodeExporter.nameOverride | trunc 63 | trimSuffix "-" }} +{{- $componentName := .Values.ndmExporter.nodeExporter.name | trunc 63 | trimSuffix "-" }} +{{- printf "%s-%s" $ndmName $componentName | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified ndm node exporter 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 "openebs-ndm.node-exporter.fullname" -}} +{{- if .Values.ndmExporter.nodeExporter.fullnameOverride }} +{{- .Values.ndmExporter.nodeExporter.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $ndmNodeExporterName := include "openebs-ndm.node-exporter.name" .}} + +{{- $name := default $ndmNodeExporterName .Values.ndmExporter.nodeExporter.nameOverride }} +{{- if contains .Release.Name $name }} +{{- $name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "openebs-ndm.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "openebs-ndm.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} + +{{/* +Define meta labels for ndm components +*/}} +{{- define "openebs-ndm.common.metaLabels" -}} +chart: {{ template "openebs-ndm.chart" . }} +heritage: {{ .Release.Service }} +openebs.io/version: {{ .Values.release.version | quote }} +{{- end -}} + + +{{/* +Create match labels for ndm daemonset component +*/}} +{{- define "openebs-ndm.matchLabels" -}} +app: {{ template "openebs-ndm.name" . }} +release: {{ .Release.Name }} +component: {{ .Values.ndm.componentName | quote }} +{{- end -}} + +{{/* +Create component labels for ndm daemonset component +*/}} +{{- define "openebs-ndm.componentLabels" -}} +openebs.io/component-name: {{ .Values.ndm.componentName | quote }} +{{- end -}} + + +{{/* +Create labels for ndm daemonset component +*/}} +{{- define "openebs-ndm.labels" -}} +{{ include "openebs-ndm.common.metaLabels" . }} +{{ include "openebs-ndm.matchLabels" . }} +{{ include "openebs-ndm.componentLabels" . }} +{{- end -}} + +{{/* +Create match labels for ndm operator deployment +*/}} +{{- define "openebs-ndm.operator.matchLabels" -}} +app: {{ template "openebs-ndm.operator.name" . }} +release: {{ .Release.Name }} +component: {{ default (include "openebs-ndm.operator.name" .) .Values.ndmOperator.componentName }} +{{- end -}} + +{{/* +Create component labels for ndm operator component +*/}} +{{- define "openebs-ndm.operator.componentLabels" -}} +openebs.io/component-name: {{ default (include "openebs-ndm.operator.name" .) .Values.ndmOperator.componentName }} +{{- end -}} + + +{{/* +Create labels for ndm operator component +*/}} +{{- define "openebs-ndm.operator.labels" -}} +{{ include "openebs-ndm.common.metaLabels" . }} +{{ include "openebs-ndm.operator.matchLabels" . }} +{{ include "openebs-ndm.operator.componentLabels" . }} +{{- end -}} + +{{/* +Create match labels for ndm cluster exporter deployment +*/}} +{{- define "openebs-ndm.cluster-exporter.matchLabels" -}} +app: {{ template "openebs-ndm.exporter.name" . }} +release: {{ .Release.Name }} +component: {{ default (include "openebs-ndm.cluster-exporter.name" .) .Values.ndmExporter.clusterExporter.componentName }} +{{- end -}} + +{{/* +Create component labels for ndm cluster exporter component +*/}} +{{- define "openebs-ndm.cluster-exporter.componentLabels" -}} +openebs.io/component-name: {{ default (include "openebs-ndm.cluster-exporter.name" .) .Values.ndmExporter.clusterExporter.componentName }} +{{- end -}} + + +{{/* +Create labels for ndm cluster exporter component +*/}} +{{- define "openebs-ndm.cluster-exporter.labels" -}} +{{ include "openebs-ndm.common.metaLabels" . }} +{{ include "openebs-ndm.cluster-exporter.matchLabels" . }} +{{ include "openebs-ndm.cluster-exporter.componentLabels" . }} +{{- end -}} + +{{/* +Create match labels for ndm node exporter deployment +*/}} +{{- define "openebs-ndm.node-exporter.matchLabels" -}} +app: {{ template "openebs-ndm.exporter.name" . }} +release: {{ .Release.Name }} +component: {{ default (include "openebs-ndm.node-exporter.name" .) .Values.ndmExporter.nodeExporter.componentName }} +{{- end -}} + +{{/* +Create component labels for ndm node exporter component +*/}} +{{- define "openebs-ndm.node-exporter.componentLabels" -}} +openebs.io/component-name: {{ default (include "openebs-ndm.node-exporter.name" .) .Values.ndmExporter.nodeExporter.componentName }} +{{- end -}} + + +{{/* +Create labels for ndm cluster node component +*/}} +{{- define "openebs-ndm.node-exporter.labels" -}} +{{ include "openebs-ndm.common.metaLabels" . }} +{{ include "openebs-ndm.node-exporter.matchLabels" . }} +{{ include "openebs-ndm.node-exporter.componentLabels" . }} +{{- end -}} diff --git a/helm/openebs/charts/openebs-ndm/templates/cluster-exporter-service.yaml b/helm/openebs/charts/openebs-ndm/templates/cluster-exporter-service.yaml new file mode 100644 index 0000000..719f6b4 --- /dev/null +++ b/helm/openebs/charts/openebs-ndm/templates/cluster-exporter-service.yaml @@ -0,0 +1,18 @@ +{{- if and .Values.ndmExporter.enabled .Values.ndmExporter.clusterExporter.metricsPort }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "openebs-ndm.cluster-exporter.fullname" . }}-service + labels: + {{- include "openebs-ndm.cluster-exporter.labels" . | nindent 4 }} +spec: + clusterIP: None + ports: + - name: metrics + port: {{ .Values.ndmExporter.clusterExporter.metricsPort }} + targetPort: {{ .Values.ndmExporter.clusterExporter.metricsPort }} + selector: + {{- with .Values.ndmExporter.clusterExporter.podLabels }} + {{ toYaml . }} + {{- end }} + {{- end }} diff --git a/helm/openebs/charts/openebs-ndm/templates/cluster-exporter.yaml b/helm/openebs/charts/openebs-ndm/templates/cluster-exporter.yaml new file mode 100644 index 0000000..af8b1e6 --- /dev/null +++ b/helm/openebs/charts/openebs-ndm/templates/cluster-exporter.yaml @@ -0,0 +1,60 @@ +{{- if .Values.ndmExporter.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "openebs-ndm.cluster-exporter.fullname" . }} + labels: + {{- include "openebs-ndm.cluster-exporter.labels" . | nindent 4 }} +spec: + replicas: 1 + strategy: + type: Recreate + selector: + matchLabels: + {{- include "openebs-ndm.cluster-exporter.matchLabels" . | nindent 6 }} + template: + metadata: + labels: + {{- include "openebs-ndm.cluster-exporter.labels" . | nindent 8 }} + {{- with .Values.ndmExporter.clusterExporter.podLabels }} + {{ toYaml . }} + {{- end }} + spec: + serviceAccountName: {{ template "openebs-ndm.serviceAccountName" . }} + containers: + - name: {{ template "openebs-ndm.cluster-exporter.fullname" . }} + image: "{{ .Values.ndmExporter.image.registry }}{{ .Values.ndmExporter.image.repository }}:{{ .Values.ndmExporter.image.tag }}" + command: + - /usr/local/bin/exporter + args: + - "start" + - "--mode=cluster" + - "--port=$(METRICS_LISTEN_PORT)" + - "--metrics=/metrics" + ports: + - containerPort: {{ .Values.ndmExporter.clusterExporter.metricsPort }} + protocol: TCP + name: metrics + imagePullPolicy: {{ .Values.ndmExporter.image.pullPolicy }} + env: + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + {{- if .Values.ndmExporter.clusterExporter.metricsPort }} + - name: METRICS_LISTEN_PORT + value: :{{ .Values.ndmExporter.clusterExporter.metricsPort }} + {{- end }} +{{- if .Values.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | indent 8 }} +{{- end }} +{{- if .Values.ndmExporter.clusterExporter.nodeSelector }} + nodeSelector: +{{ toYaml .Values.ndmExporter.clusterExporter.nodeSelector | indent 8 }} +{{- end }} +{{- if .Values.ndmExporter.clusterExporter.tolerations }} + tolerations: +{{ toYaml .Values.ndmExporter.clusterExporter.tolerations | indent 8 }} +{{- end }} +{{- end }} diff --git a/helm/openebs/charts/openebs-ndm/templates/configmap.yaml b/helm/openebs/charts/openebs-ndm/templates/configmap.yaml new file mode 100644 index 0000000..99b814d --- /dev/null +++ b/helm/openebs/charts/openebs-ndm/templates/configmap.yaml @@ -0,0 +1,45 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "openebs-ndm.fullname" . }}-config +data: + # node-disk-manager-config contains config of available probes and filters. + # Probes and Filters will initialize with default values if config for that + # filter or probe are not present in configmap + + # udev-probe is default or primary probe it should be enabled to run ndm + # filterconfigs contains configs of filters. To provide a group of include + # and exclude values add it as , separated string + node-disk-manager.config: | + probeconfigs: + - key: udev-probe + name: udev probe + state: {{ .Values.ndm.probes.enableUdevProbe }} + - key: seachest-probe + name: seachest probe + state: {{ .Values.ndm.probes.enableSeachest }} + - key: smart-probe + name: smart probe + state: {{ .Values.ndm.probes.enableSmartProbe }} + filterconfigs: + - key: os-disk-exclude-filter + name: os disk exclude filter + state: {{ .Values.ndm.filters.enableOsDiskExcludeFilter }} + exclude: "{{ .Values.ndm.filters.osDiskExcludePaths }}" + - key: vendor-filter + name: vendor filter + state: {{ .Values.ndm.filters.enableVendorFilter }} + include: "" + exclude: "{{ .Values.ndm.filters.excludeVendors }}" + - key: path-filter + name: path filter + state: {{ .Values.ndm.filters.enablePathFilter }} + include: "{{ .Values.ndm.filters.includePaths }}" + exclude: "{{ .Values.ndm.filters.excludePaths }}" + metaconfigs: + - key: node-labels + name: node labels + pattern: "{{ .Values.ndm.metaConfig.nodeLabelPattern }}" + - key: device-labels + name: device labels + type: "{{ .Values.ndm.metaConfig.deviceLabelTypes }}" diff --git a/helm/openebs/charts/openebs-ndm/templates/daemonset.yaml b/helm/openebs/charts/openebs-ndm/templates/daemonset.yaml new file mode 100644 index 0000000..715db87 --- /dev/null +++ b/helm/openebs/charts/openebs-ndm/templates/daemonset.yaml @@ -0,0 +1,179 @@ +{{- if .Values.ndm.enabled }} +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: {{ template "openebs-ndm.fullname" . }} + {{- with .Values.ndm.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "openebs-ndm.labels" . | nindent 4 }} +spec: + updateStrategy: +{{ toYaml .Values.ndm.updateStrategy | indent 4 }} + selector: + matchLabels: + {{- include "openebs-ndm.matchLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.ndm.podAnnotations }} + annotations: {{ toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "openebs-ndm.labels" . | nindent 8 }} + {{- with .Values.ndm.podLabels}} + {{ toYaml . }} + {{- end}} + spec: + serviceAccountName: {{ template "openebs-ndm.serviceAccountName" . }} +{{- if .Values.featureGates.enabled }} +{{- if .Values.featureGates.APIService.enabled }} + hostPID: true +{{- end}} +{{- end}} + containers: + - name: {{ template "openebs-ndm.name" . }} + image: "{{ .Values.ndm.image.registry }}{{ .Values.ndm.image.repository }}:{{ .Values.ndm.image.tag }}" + args: + - -v=4 +{{- if .Values.featureGates.enabled }} +{{- if .Values.featureGates.GPTBasedUUID.enabled }} + - --feature-gates={{ .Values.featureGates.GPTBasedUUID.featureGateFlag }} +{{- end}} +{{- if .Values.featureGates.APIService.enabled }} + - --feature-gates={{ .Values.featureGates.APIService.featureGateFlag }} + - --api-service-address={{ .Values.featureGates.APIService.address }} +{{- end}} +{{- if .Values.featureGates.UseOSDisk.enabled }} + - --feature-gates={{ .Values.featureGates.UseOSDisk.featureGateFlag }} +{{- end}} +{{- if .Values.featureGates.ChangeDetection.enabled }} + - --feature-gates={{ .Values.featureGates.ChangeDetection.featureGateFlag }} +{{- end}} +{{- if .Values.featureGates.PartitionTableUUID.enabled }} + - --feature-gates={{ .Values.featureGates.PartitionTableUUID.featureGateFlag }} +{{- end}} +{{- end}} + imagePullPolicy: {{ .Values.ndm.image.pullPolicy }} + resources: +{{ toYaml .Values.ndm.resources | indent 12 }} + securityContext: + privileged: true + env: + # namespace in which NDM is installed will be passed to NDM Daemonset + # as environment variable + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + # pass hostname as env variable using downward API to the NDM container + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName +{{- if .Values.ndm.sparse }} +{{- if .Values.ndm.sparse.path }} + # specify the directory where the sparse files need to be created. + # if not specified, then sparse files will not be created. + - name: SPARSE_FILE_DIR + value: "{{ .Values.ndm.sparse.path }}" +{{- end }} +{{- if .Values.ndm.sparse.size }} + # Size(bytes) of the sparse file to be created. + - name: SPARSE_FILE_SIZE + value: "{{ .Values.ndm.sparse.size }}" +{{- end }} +{{- if .Values.ndm.sparse.count }} + # Specify the number of sparse files to be created + - name: SPARSE_FILE_COUNT + value: "{{ .Values.ndm.sparse.count }}" +{{- end }} +{{- end }} + # Process name used for matching is limited to the 15 characters + # present in the pgrep output. + # So fullname can be used here with pgrep (cmd is < 15 chars). + livenessProbe: + exec: + command: + - pgrep + - "ndm" + initialDelaySeconds: {{ .Values.ndm.healthCheck.initialDelaySeconds }} + periodSeconds: {{ .Values.ndm.healthCheck.periodSeconds }} + volumeMounts: + - name: config + mountPath: /host/node-disk-manager.config + subPath: node-disk-manager.config + readOnly: true + - name: udev + mountPath: /run/udev + - name: procmount + mountPath: /host/proc + readOnly: true + - name: devmount + mountPath: /dev + - name: basepath + mountPath: /var/openebs/ndm +{{- if .Values.ndm.sparse }} +{{- if .Values.ndm.sparse.path }} + - name: sparsepath + mountPath: {{ .Values.ndm.sparse.path }} +{{- end }} +{{- end }} + volumes: + - name: config + configMap: + name: {{ include "openebs-ndm.fullname" . }}-config + - name: udev + hostPath: + path: /run/udev + type: Directory + # mount /proc (to access mount file of process 1 of host) inside container + # to read mount-point of disks and partitions + - name: procmount + hostPath: + path: /proc + type: Directory + - name: devmount + # the /dev directory is mounted so that we have access to the devices that + # are connected at runtime of the pod. + hostPath: + path: /dev + type: Directory + - name: basepath + hostPath: + path: "{{ .Values.varDirectoryPath.baseDir }}/ndm" + type: DirectoryOrCreate +{{- if .Values.ndm.sparse }} +{{- if .Values.ndm.sparse.path }} + - name: sparsepath + hostPath: + path: {{ .Values.ndm.sparse.path }} +{{- end }} +{{- end }} + # By default the node-disk-manager will be run on all kubernetes nodes + # If you would like to limit this to only some nodes, say the nodes + # that have storage attached, you could label those node and use + # nodeSelector. + # + # e.g. label the storage nodes with - "openebs.io/nodegroup"="storage-node" + # kubectl label node "openebs.io/nodegroup"="storage-node" + #nodeSelector: + # "openebs.io/nodegroup": "storage-node" +{{- if .Values.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | indent 8 }} +{{- end }} +{{- if .Values.ndm.nodeSelector }} + nodeSelector: +{{ toYaml .Values.ndm.nodeSelector | indent 8 }} +{{- end }} +{{- if .Values.ndm.tolerations }} + tolerations: +{{ toYaml .Values.ndm.tolerations | indent 8 }} +{{- end }} +{{- if .Values.ndm.securityContext }} + securityContext: +{{ toYaml .Values.ndm.securityContext | indent 8 }} +{{- end }} + hostNetwork: true +{{- end }} diff --git a/helm/openebs/charts/openebs-ndm/templates/deployment.yaml b/helm/openebs/charts/openebs-ndm/templates/deployment.yaml new file mode 100644 index 0000000..213a861 --- /dev/null +++ b/helm/openebs/charts/openebs-ndm/templates/deployment.yaml @@ -0,0 +1,87 @@ +{{- if .Values.ndmOperator.enabled }} +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "openebs-ndm.operator.fullname" . }} + {{- with .Values.ndmOperator.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "openebs-ndm.operator.labels" . | nindent 4 }} +spec: + replicas: {{ .Values.ndmOperator.replicas }} + strategy: + type: "Recreate" + rollingUpdate: null + selector: + matchLabels: + {{- include "openebs-ndm.operator.matchLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.ndmOperator.podAnnotations }} + annotations: {{ toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "openebs-ndm.operator.labels" . | nindent 8 }} + {{- with .Values.ndmOperator.podLabels}} + {{ toYaml . }} + {{- end}} + spec: + serviceAccountName: {{ template "openebs-ndm.serviceAccountName" . }} + containers: + - name: {{ template "openebs-ndm.operator.fullname" . }} + image: "{{ .Values.ndmOperator.image.registry }}{{ .Values.ndmOperator.image.repository }}:{{ .Values.ndmOperator.image.tag }}" + imagePullPolicy: {{ .Values.ndmOperator.image.pullPolicy }} + resources: +{{ toYaml .Values.ndmOperator.resources | indent 12 }} + livenessProbe: + httpGet: + path: /healthz + port: 8585 + initialDelaySeconds: {{ .Values.ndmOperator.healthCheck.initialDelaySeconds }} + periodSeconds: {{ .Values.ndmOperator.healthCheck.periodSeconds }} + readinessProbe: + httpGet: + path: /readyz + port: 8585 + initialDelaySeconds: {{ .Values.ndmOperator.readinessCheck.initialDelaySeconds }} + periodSeconds: {{ .Values.ndmOperator.readinessCheck.periodSeconds }} + env: + - name: WATCH_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: SERVICE_ACCOUNT + valueFrom: + fieldRef: + fieldPath: spec.serviceAccountName + - name: OPERATOR_NAME + value: "node-disk-operator" + - name: CLEANUP_JOB_IMAGE + value: "{{ .Values.helperPod.image.registry }}{{ .Values.helperPod.image.repository }}:{{ .Values.helperPod.image.tag }}" +{{- if .Values.imagePullSecrets }} + - name: OPENEBS_IO_IMAGE_PULL_SECRETS + value: "{{- range $index, $secret := .Values.imagePullSecrets}}{{if $index}},{{end}}{{ $secret.name }}{{- end}}" +{{- end }} +{{- if .Values.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | indent 8 }} +{{- end }} +{{- if .Values.ndmOperator.nodeSelector }} + nodeSelector: +{{ toYaml .Values.ndmOperator.nodeSelector | indent 8 }} +{{- end }} +{{- if .Values.ndmOperator.securityContext }} + securityContext: +{{ toYaml .Values.ndmOperator.securityContext | indent 8 }} +{{- end }} +{{- if .Values.ndmOperator.tolerations }} + tolerations: +{{ toYaml .Values.ndmOperator.tolerations | indent 8 }} +{{- end }} +{{- end }} diff --git a/helm/openebs/charts/openebs-ndm/templates/node-exporter-service.yaml b/helm/openebs/charts/openebs-ndm/templates/node-exporter-service.yaml new file mode 100644 index 0000000..026b77d --- /dev/null +++ b/helm/openebs/charts/openebs-ndm/templates/node-exporter-service.yaml @@ -0,0 +1,18 @@ +{{- if and .Values.ndmExporter.enabled .Values.ndmExporter.nodeExporter.metricsPort }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "openebs-ndm.node-exporter.fullname" . }}-service + labels: + {{- include "openebs-ndm.node-exporter.labels" . | nindent 4 }} +spec: + clusterIP: None + ports: + - name: metrics + port: {{ .Values.ndmExporter.nodeExporter.metricsPort }} + targetPort: {{ .Values.ndmExporter.nodeExporter.metricsPort }} + selector: + {{- with .Values.ndmExporter.nodeExporter.podLabels }} + {{ toYaml . }} + {{- end }} + {{- end }} diff --git a/helm/openebs/charts/openebs-ndm/templates/node-exporter.yaml b/helm/openebs/charts/openebs-ndm/templates/node-exporter.yaml new file mode 100644 index 0000000..cd5f635 --- /dev/null +++ b/helm/openebs/charts/openebs-ndm/templates/node-exporter.yaml @@ -0,0 +1,62 @@ +{{- if .Values.ndmExporter.enabled }} +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: {{ template "openebs-ndm.node-exporter.fullname" . }} + labels: + {{- include "openebs-ndm.node-exporter.labels" . | nindent 4 }} +spec: + updateStrategy: + type: RollingUpdate + selector: + matchLabels: + {{- include "openebs-ndm.node-exporter.matchLabels" . | nindent 6 }} + template: + metadata: + labels: + {{- include "openebs-ndm.node-exporter.labels" . | nindent 8 }} + {{- with .Values.ndmExporter.nodeExporter.podLabels }} + {{ toYaml . }} + {{- end }} + spec: + serviceAccountName: {{ template "openebs-ndm.serviceAccountName" . }} + containers: + - name: {{ template "openebs-ndm.node-exporter.fullname" . }} + image: "{{ .Values.ndmExporter.image.registry }}{{ .Values.ndmExporter.image.repository }}:{{ .Values.ndmExporter.image.tag }}" + command: + - /usr/local/bin/exporter + args: + - "start" + - "--mode=node" + - "--port=$(METRICS_LISTEN_PORT)" + - "--metrics=/metrics" + ports: + - containerPort: {{ .Values.ndmExporter.nodeExporter.metricsPort }} + protocol: TCP + name: metrics + imagePullPolicy: {{ .Values.ndmExporter.image.pullPolicy }} + securityContext: + privileged: true + env: + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + {{- if .Values.ndmExporter.nodeExporter.metricsPort }} + - name: METRICS_LISTEN_PORT + value: :{{ .Values.ndmExporter.nodeExporter.metricsPort }} + {{- end }} +{{- if .Values.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | indent 8 }} +{{- end }} +{{- if .Values.ndmExporter.nodeExporter.nodeSelector }} + nodeSelector: +{{ toYaml .Values.ndmExporter.nodeExporter.nodeSelector | indent 8 }} +{{- end }} +{{- if .Values.ndmExporter.nodeExporter.tolerations }} + tolerations: +{{ toYaml .Values.ndmExporter.nodeExporter.tolerations | indent 8 }} +{{- end }} +{{- end }} + diff --git a/helm/openebs/charts/openebs-ndm/templates/rbac.yaml b/helm/openebs/charts/openebs-ndm/templates/rbac.yaml new file mode 100644 index 0000000..8e81c49 --- /dev/null +++ b/helm/openebs/charts/openebs-ndm/templates/rbac.yaml @@ -0,0 +1,44 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "openebs-ndm.serviceAccountName" . }} +{{- end }} +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ include "openebs-ndm.fullname" . }} +rules: + - apiGroups: ["*"] + resources: ["nodes", "pods", "events", "configmaps", "jobs"] + verbs: + - '*' + - apiGroups: ["apiextensions.k8s.io"] + resources: ["customresourcedefinitions"] + verbs: + - '*' + - apiGroups: + - openebs.io + resources: + - blockdevices + - blockdeviceclaims + verbs: + - '*' +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ include "openebs-ndm.fullname" . }} +subjects: + - kind: ServiceAccount + name: {{ include "openebs-ndm.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} + - kind: User + name: system:serviceaccount:default:default + apiGroup: rbac.authorization.k8s.io +roleRef: + kind: ClusterRole + name: {{ include "openebs-ndm.fullname" . }} + apiGroup: rbac.authorization.k8s.io +--- diff --git a/helm/openebs/charts/openebs-ndm/values.yaml b/helm/openebs/charts/openebs-ndm/values.yaml new file mode 100644 index 0000000..2548606 --- /dev/null +++ b/helm/openebs/charts/openebs-ndm/values.yaml @@ -0,0 +1,156 @@ +# Default values for ndm. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. +release: + version: "2.1.0" + +imagePullSecrets: +# - name: "image-pull-secret" + +ndm: + componentName: ndm + enabled: true + image: + # Make sure that registry name end with a '/'. + # For example : quay.io/ is a correct value here and quay.io is incorrect + registry: + repository: openebs/node-disk-manager + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: 2.1.0 + sparse: + path: "/var/openebs/sparse" + size: "10737418240" + count: "0" + updateStrategy: + type: RollingUpdate + annotations: {} + podAnnotations: {} + resources: {} + # limits: + # cpu: 10m + # memory: 32Mi + # requests: + # cpu: 10m + # memory: 32Mi + ## Labels to be added to ndm daemonset pods + podLabels: + name: openebs-ndm + nodeSelector: {} + tolerations: [] + securityContext: {} + filters: + enableOsDiskExcludeFilter: true + osDiskExcludePaths: "/,/etc/hosts,/boot" + enableVendorFilter: true + excludeVendors: "CLOUDBYT,OpenEBS" + enablePathFilter: true + includePaths: "" + excludePaths: "loop,fd0,sr0,/dev/ram,/dev/dm-,/dev/md,/dev/rbd,/dev/zd" + probes: + enableSeachest: false + enableUdevProbe: true + enableSmartProbe: true + metaConfig: + nodeLabelPattern: "" + deviceLabelTypes: "" + healthCheck: + initialDelaySeconds: 30 + periodSeconds: 60 + +ndmOperator: + name: operator + enabled: true + image: + registry: + repository: openebs/node-disk-operator + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: 2.1.0 + podLabels: + name: openebs-ndm-operator + annotations: {} + podAnnotations: {} + nodeSelector: {} + resources: {} + securityContext: {} + tolerations: [] + healthCheck: + initialDelaySeconds: 15 + periodSeconds: 20 + readinessCheck: + initialDelaySeconds: 5 + periodSeconds: 10 + replicas: 1 + upgradeStrategy: Recreate + +ndmExporter: + enabled: false + image: + registry: + repository: openebs/node-disk-exporter + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: 2.1.0 + nodeExporter: + name: node-exporter + podLabels: + name: openebs-ndm-node-exporter + # The TCP port number used for exposing ndm-node-exporter metrics. + # If not set, service will not be created to expose metrics endpoint to serviceMonitor + # and listen-port flag will not be set and container port will be empty. + metricsPort: 9101 + nodeSelector: {} + tolerations: [] + clusterExporter: + name: cluster-exporter + podLabels: + name: openebs-ndm-cluster-exporter + # The TCP port number used for exposing ndm-cluster-exporter metrics. + # If not set, service will not be created to expose metrics endpoint to serviceMonitor + # and listen-port flag will not be set and container port will be empty. + metricsPort: 9100 + nodeSelector: {} + tolerations: [] + +helperPod: + image: + registry: "" + repository: openebs/linux-utils + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: 3.4.0 + +crd: + enableInstall: false + +featureGates: + enabled: true + GPTBasedUUID: + enabled: true + featureGateFlag: "GPTBasedUUID" + APIService: + enabled: false + featureGateFlag: "APIService" + address: "0.0.0.0:9115" + UseOSDisk: + enabled: false + featureGateFlag: "UseOSDisk" + ChangeDetection: + enabled: false + featureGateFlag: "ChangeDetection" + PartitionTableUUID: + enabled: false + featureGateFlag: "PartitionTableUUID" + +# Directory used by the OpenEBS to store debug information and so forth +# that are generated in the course of running OpenEBS containers. +varDirectoryPath: + baseDir: "/var/openebs" + +serviceAccount: + # Specifies whether a service account should be created + create: true + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: openebs-ndm diff --git a/helm/openebs/charts/zfs-localpv/.helmignore b/helm/openebs/charts/zfs-localpv/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/helm/openebs/charts/zfs-localpv/.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/helm/openebs/charts/zfs-localpv/Chart.yaml b/helm/openebs/charts/zfs-localpv/Chart.yaml new file mode 100644 index 0000000..c3e843d --- /dev/null +++ b/helm/openebs/charts/zfs-localpv/Chart.yaml @@ -0,0 +1,24 @@ +apiVersion: v2 +appVersion: 2.3.0 +description: Helm chart for CSI Driver for dynamic provisioning of ZFS Persistent + Local Volumes. For instructions on how to use this helm chart, see - https://openebs.github.io/zfs-localpv/ +home: https://openebs.io/ +icon: https://raw.githubusercontent.com/cncf/artwork/master/projects/openebs/icon/color/openebs-icon-color.png +keywords: +- cloud-native-storage +- block-storage +- filesystem +- ZFS +- Local Persistent Volumes +- storage +maintainers: +- email: michaelfornaro@gmail.com + name: xUnholy +- email: prateek.pandey@mayadata.io + name: prateekpandey14 +- email: pawan@mayadata.io + name: pawanpraka1 +name: zfs-localpv +sources: +- https://github.com/openebs/zfs-localpv +version: 2.3.1 diff --git a/helm/openebs/charts/zfs-localpv/README.md b/helm/openebs/charts/zfs-localpv/README.md new file mode 100644 index 0000000..d30f550 --- /dev/null +++ b/helm/openebs/charts/zfs-localpv/README.md @@ -0,0 +1,137 @@ + +# OpenEBS LocalPV Provisioner + +[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) +![Chart Lint and Test](https://github.com/openebs/zfs-localpv/workflows/Chart%20Lint%20and%20Test/badge.svg) +![Release Charts](https://github.com/openebs/zfs-localpv/workflows/Release%20Charts/badge.svg?branch=develop) + +A Helm chart for openebs zfs localpv provisioner. This chart bootstraps OpenEBS ZFS LocalPV provisioner deployment on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. + + +**Homepage:** + +## Maintainers + +| Name | Email | Url | +| ---- | ------ | --- | +| pawanpraka1 | pawan@mayadata.io | | +| xUnholy | michaelfornaro@gmail.com | | +| prateekpandey14 | prateek.pandey@mayadata.io | | + + +## Get Repo Info + +```console +helm repo add openebs-zfslocalpv https://openebs.github.io/zfs-localpv +helm repo update +``` + +_See [helm repo](https://helm.sh/docs/helm/helm_repo/) for command documentation._ + +## Install Chart + +Please visit the [link](https://openebs.github.io/zfs-localpv/) for install instructions via helm3. + +```console +# Helm +$ helm install [RELEASE_NAME] openebs-zfslocalpv/zfs-localpv +``` + +**Note:** If moving from the operator to helm +- Make sure the namespace provided in the helm install command is same as `OPENEBS_NAMESPACE` (by default it is `openebs`) env in the controller statefulset. +- Before installing, clean up the stale statefulset and daemonset from `kube-system` namespace using the below commands +```sh +kubectl delete sts openebs-zfs-controller -n kube-system +kubectl delete ds openebs-zfs-node -n kube-system +``` + + +_See [configuration](#configuration) below._ + +_See [helm install](https://helm.sh/docs/helm/helm_install/) for command documentation._ + +## Uninstall Chart + +```console +# Helm +$ helm uninstall [RELEASE_NAME] +``` + +This removes all the Kubernetes components associated with the chart and deletes the release. + +_See [helm uninstall](https://helm.sh/docs/helm/helm_uninstall/) for command documentation._ + +## Upgrading Chart + +```console +# Helm +$ helm upgrade [RELEASE_NAME] [CHART] --install +``` + +## Configuration + +The following table lists the configurable parameters of the OpenEBS ZFS Localpv chart and their default values. + +| Parameter| Description| Default| +| -| -| -| +| `imagePullSecrets`| Provides image pull secrect| `""`| +| `zfsPlugin.image.registry`| Registry for openebs-zfs-plugin image| `""`| +| `zfsPlugin.image.repository`| Image repository for openebs-zfs-plugin| `openebs/zfs-driver`| +| `zfsPlugin.image.pullPolicy`| Image pull policy for openebs-zfs-plugin| `IfNotPresent`| +| `zfsPlugin.image.tag`| Image tag for openebs-zfs-plugin| `2.3.0`| +| `zfsNode.allowedTopologyKeys`| Custom topology keys required for provisioning| `"kubernetes.io/hostname,"`| +| `zfsNode.driverRegistrar.image.registry`| Registry for csi-node-driver-registrar image| `registry.k8s.io/`| +| `zfsNode.driverRegistrar.image.repository`| Image repository for csi-node-driver-registrar| `sig-storage/csi-node-driver-registrar`| +| `zfsNode.driverRegistrar.image.pullPolicy`| Image pull policy for csi-node-driver-registrar| `IfNotPresent`| +| `zfsNode.driverRegistrar.image.tag`| Image tag for csi-node-driver-registrar| `v2.8.0`| +| `zfsNode.updateStrategy.type`| Update strategy for zfsnode daemonset | `RollingUpdate` | +| `zfsNode.kubeletDir`| Kubelet mount point for zfsnode daemonset| `"/var/lib/kubelet/"` | +| `zfsNode.annotations` | Annotations for zfsnode daemonset metadata| `""`| +| `zfsNode.podAnnotations`| Annotations for zfsnode daemonset's pods metadata | `""`| +| `zfsNode.resources`| Resource and request and limit for zfsnode daemonset containers | `""`| +| `zfsNode.labels`| Labels for zfsnode daemonset metadata | `""`| +| `zfsNode.podLabels`| Appends labels to the zfsnode daemonset pods| `""`| +| `zfsNode.nodeSelector`| Nodeselector for zfsnode daemonset pods| `""`| +| `zfsNode.tolerations` | zfsnode daemonset's pod toleration values | `""`| +| `zfsNode.securityContext` | Seurity context for zfsnode daemonset container | `""`| +| `zfsController.resizer.image.registry`| Registry for csi-resizer image| `registry.k8s.io/`| +| `zfsController.resizer.image.repository`| Image repository for csi-resizer| `sig-storage/csi-resizer`| +| `zfsController.resizer.image.pullPolicy`| Image pull policy for csi-resizer| `IfNotPresent`| +| `zfsController.resizer.image.tag`| Image tag for csi-resizer| `v1.8.0`| +| `zfsController.snapshotter.image.registry`| Registry for csi-snapshotter image| `registry.k8s.io/`| +| `zfsController.snapshotter.image.repository`| Image repository for csi-snapshotter| `sig-storage/csi-snapshotter`| +| `zfsController.snapshotter.image.pullPolicy`| Image pull policy for csi-snapshotter| `IfNotPresent`| +| `zfsController.snapshotter.image.tag`| Image tag for csi-snapshotter| `v6.2.2`| +| `zfsController.snapshotController.image.registry`| Registry for snapshot-controller image| `registry.k8s.io/`| +| `zfsController.snapshotController.image.repository`| Image repository for snapshot-controller| `sig-storage/snapshot-controller`| +| `zfsController.snapshotController.image.pullPolicy`| Image pull policy for snapshot-controller| `IfNotPresent`| +| `zfsController.snapshotController.image.tag`| Image tag for snapshot-controller| `v6.2.2`| +| `zfsController.provisioner.image.registry`| Registry for csi-provisioner image| `registry.k8s.io/`| +| `zfsController.provisioner.image.repository`| Image repository for csi-provisioner| `sig-storage/csi-provisioner`| +| `zfsController.provisioner.image.pullPolicy`| Image pull policy for csi-provisioner| `IfNotPresent`| +| `zfsController.provisioner.image.tag`| Image tag for csi-provisioner| `v3.5.0`| +| `zfsController.updateStrategy.type`| Update strategy for zfs localpv controller statefulset | `RollingUpdate` | +| `zfsController.annotations` | Annotations for zfs localpv controller statefulset metadata| `""`| +| `zfsController.podAnnotations`| Annotations for zfs localpv controller statefulset's pods metadata | `""`| +| `zfsController.resources`| Resource and request and limit for zfs localpv controller statefulset containers | `""`| +| `zfsController.labels`| Labels for zfs localpv controller statefulset metadata | `""`| +| `zfsController.podLabels`| Appends labels to the zfs localpv controller statefulset pods| `""`| +| `zfsController.nodeSelector`| Nodeselector for zfs localpv controller statefulset pods| `""`| +| `zfsController.tolerations` | zfs localpv controller statefulset's pod toleration values | `""`| +| `zfsController.securityContext` | Seurity context for zfs localpv controller statefulset container | `""`| +| `rbac.pspEnabled` | Enable PodSecurityPolicy | `false` | +| `serviceAccount.zfsNode.create` | Create a service account for zfsnode or not| `true`| +| `serviceAccount.zfsNode.name` | Name for the zfsnode service account| `openebs-zfs-node-sa`| +| `serviceAccount.zfsController.create` | Create a service account for zfs localpv controller or not| `true`| +| `serviceAccount.zfsController.name` | Name for the zfs localpv controller service account| `openebs-zfs-controller-sa`| +| `analytics.enabled` | Enable or Disable google analytics for the controller| `true`| + +Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. + +Alternatively, a YAML file that specifies the values for the parameters can be provided while installing the chart. For example, + +```bash +helm install -f values.yaml openebs/zfs-localpv +``` + +> **Tip**: You can use the default [values.yaml](values.yaml) diff --git a/helm/openebs/charts/zfs-localpv/crds/volumesnapshotclasses.yaml b/helm/openebs/charts/zfs-localpv/crds/volumesnapshotclasses.yaml new file mode 100644 index 0000000..3500b8b --- /dev/null +++ b/helm/openebs/charts/zfs-localpv/crds/volumesnapshotclasses.yaml @@ -0,0 +1,134 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.11.3 + api-approved.kubernetes.io: "https://github.com/kubernetes-csi/external-snapshotter/pull/814" + creationTimestamp: null + name: volumesnapshotclasses.snapshot.storage.k8s.io +spec: + group: snapshot.storage.k8s.io + names: + kind: VolumeSnapshotClass + listKind: VolumeSnapshotClassList + plural: volumesnapshotclasses + shortNames: + - vsclass + - vsclasses + singular: volumesnapshotclass + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .driver + name: Driver + type: string + - description: Determines whether a VolumeSnapshotContent created through the + VolumeSnapshotClass should be deleted when its bound VolumeSnapshot is deleted. + jsonPath: .deletionPolicy + name: DeletionPolicy + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: VolumeSnapshotClass specifies parameters that a underlying storage + system uses when creating a volume snapshot. A specific VolumeSnapshotClass + is used by specifying its name in a VolumeSnapshot object. VolumeSnapshotClasses + are non-namespaced + 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 + deletionPolicy: + description: deletionPolicy determines whether a VolumeSnapshotContent + created through the VolumeSnapshotClass should be deleted when its bound + VolumeSnapshot is deleted. Supported values are "Retain" and "Delete". + "Retain" means that the VolumeSnapshotContent and its physical snapshot + on underlying storage system are kept. "Delete" means that the VolumeSnapshotContent + and its physical snapshot on underlying storage system are deleted. + Required. + enum: + - Delete + - Retain + type: string + driver: + description: driver is the name of the storage driver that handles this + VolumeSnapshotClass. Required. + 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 + parameters: + additionalProperties: + type: string + description: parameters is a key-value map with storage driver specific + parameters for creating snapshots. These values are opaque to Kubernetes. + type: object + required: + - deletionPolicy + - driver + type: object + served: true + storage: true + subresources: {} + - additionalPrinterColumns: + - jsonPath: .driver + name: Driver + type: string + - description: Determines whether a VolumeSnapshotContent created through the VolumeSnapshotClass should be deleted when its bound VolumeSnapshot is deleted. + jsonPath: .deletionPolicy + name: DeletionPolicy + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + # This indicates the v1beta1 version of the custom resource is deprecated. + # API requests to this version receive a warning in the server response. + deprecated: true + # This overrides the default warning returned to clients making v1beta1 API requests. + deprecationWarning: "snapshot.storage.k8s.io/v1beta1 VolumeSnapshotClass is deprecated; use snapshot.storage.k8s.io/v1 VolumeSnapshotClass" + schema: + openAPIV3Schema: + description: VolumeSnapshotClass specifies parameters that a underlying storage system uses when creating a volume snapshot. A specific VolumeSnapshotClass is used by specifying its name in a VolumeSnapshot object. VolumeSnapshotClasses are non-namespaced + 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 + deletionPolicy: + description: deletionPolicy determines whether a VolumeSnapshotContent created through the VolumeSnapshotClass should be deleted when its bound VolumeSnapshot is deleted. Supported values are "Retain" and "Delete". "Retain" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are kept. "Delete" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are deleted. Required. + enum: + - Delete + - Retain + type: string + driver: + description: driver is the name of the storage driver that handles this VolumeSnapshotClass. Required. + 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 + parameters: + additionalProperties: + type: string + description: parameters is a key-value map with storage driver specific parameters for creating snapshots. These values are opaque to Kubernetes. + type: object + required: + - deletionPolicy + - driver + type: object + served: false + storage: false + subresources: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] \ No newline at end of file diff --git a/helm/openebs/charts/zfs-localpv/crds/volumesnapshotcontents.yaml b/helm/openebs/charts/zfs-localpv/crds/volumesnapshotcontents.yaml new file mode 100644 index 0000000..f694590 --- /dev/null +++ b/helm/openebs/charts/zfs-localpv/crds/volumesnapshotcontents.yaml @@ -0,0 +1,401 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.11.3 + api-approved.kubernetes.io: "https://github.com/kubernetes-csi/external-snapshotter/pull/814" + creationTimestamp: null + name: volumesnapshotcontents.snapshot.storage.k8s.io +spec: + group: snapshot.storage.k8s.io + names: + kind: VolumeSnapshotContent + listKind: VolumeSnapshotContentList + plural: volumesnapshotcontents + shortNames: + - vsc + - vscs + singular: volumesnapshotcontent + scope: Cluster + versions: + - additionalPrinterColumns: + - description: Indicates if the snapshot is ready to be used to restore a volume. + jsonPath: .status.readyToUse + name: ReadyToUse + type: boolean + - description: Represents the complete size of the snapshot in bytes + jsonPath: .status.restoreSize + name: RestoreSize + type: integer + - description: Determines whether this VolumeSnapshotContent and its physical + snapshot on the underlying storage system should be deleted when its bound + VolumeSnapshot is deleted. + jsonPath: .spec.deletionPolicy + name: DeletionPolicy + type: string + - description: Name of the CSI driver used to create the physical snapshot on + the underlying storage system. + jsonPath: .spec.driver + name: Driver + type: string + - description: Name of the VolumeSnapshotClass to which this snapshot belongs. + jsonPath: .spec.volumeSnapshotClassName + name: VolumeSnapshotClass + type: string + - description: Name of the VolumeSnapshot object to which this VolumeSnapshotContent + object is bound. + jsonPath: .spec.volumeSnapshotRef.name + name: VolumeSnapshot + type: string + - description: Namespace of the VolumeSnapshot object to which this VolumeSnapshotContent object is bound. + jsonPath: .spec.volumeSnapshotRef.namespace + name: VolumeSnapshotNamespace + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: VolumeSnapshotContent represents the actual "on-disk" snapshot + object in the underlying storage system + 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 + spec: + description: spec defines properties of a VolumeSnapshotContent created + by the underlying storage system. Required. + properties: + deletionPolicy: + description: deletionPolicy determines whether this VolumeSnapshotContent + and its physical snapshot on the underlying storage system should + be deleted when its bound VolumeSnapshot is deleted. Supported values + are "Retain" and "Delete". "Retain" means that the VolumeSnapshotContent + and its physical snapshot on underlying storage system are kept. + "Delete" means that the VolumeSnapshotContent and its physical snapshot + on underlying storage system are deleted. For dynamically provisioned + snapshots, this field will automatically be filled in by the CSI + snapshotter sidecar with the "DeletionPolicy" field defined in the + corresponding VolumeSnapshotClass. For pre-existing snapshots, users + MUST specify this field when creating the VolumeSnapshotContent + object. Required. + enum: + - Delete + - Retain + type: string + driver: + description: driver is the name of the CSI driver used to create the + physical snapshot on the underlying storage system. This MUST be + the same as the name returned by the CSI GetPluginName() call for + that driver. Required. + type: string + source: + description: source specifies whether the snapshot is (or should be) + dynamically provisioned or already exists, and just requires a Kubernetes + object representation. This field is immutable after creation. Required. + properties: + snapshotHandle: + description: snapshotHandle specifies the CSI "snapshot_id" of + a pre-existing snapshot on the underlying storage system for + which a Kubernetes object representation was (or should be) + created. This field is immutable. + type: string + volumeHandle: + description: volumeHandle specifies the CSI "volume_id" of the + volume from which a snapshot should be dynamically taken from. + This field is immutable. + type: string + type: object + oneOf: + - required: ["snapshotHandle"] + - required: ["volumeHandle"] + sourceVolumeMode: + description: SourceVolumeMode is the mode of the volume whose snapshot + is taken. Can be either “Filesystem” or “Block”. If not specified, + it indicates the source volume's mode is unknown. This field is + immutable. This field is an alpha field. + type: string + volumeSnapshotClassName: + description: name of the VolumeSnapshotClass from which this snapshot + was (or will be) created. Note that after provisioning, the VolumeSnapshotClass + may be deleted or recreated with different set of values, and as + such, should not be referenced post-snapshot creation. + type: string + volumeSnapshotRef: + description: volumeSnapshotRef specifies the VolumeSnapshot object + to which this VolumeSnapshotContent object is bound. VolumeSnapshot.Spec.VolumeSnapshotContentName + field must reference to this VolumeSnapshotContent's name for the + bidirectional binding to be valid. For a pre-existing VolumeSnapshotContent + object, name and namespace of the VolumeSnapshot object MUST be + provided for binding to happen. This field is immutable after creation. + Required. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: 'If referring to a piece of an object instead of + an entire object, this string should contain a valid JSON/Go + field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within + a pod, this would take on a value like: "spec.containers{name}" + (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" + (container with index 2 in this pod). This syntax is chosen + only to have some well-defined way of referencing a part of + an object. TODO: this design is not final and this field is + subject to change in the future.' + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: 'Specific resourceVersion to which this reference + is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + x-kubernetes-map-type: atomic + required: + - deletionPolicy + - driver + - source + - volumeSnapshotRef + type: object + status: + description: status represents the current information of a snapshot. + properties: + creationTime: + description: creationTime is the timestamp when the point-in-time + snapshot is taken by the underlying storage system. In dynamic snapshot + creation case, this field will be filled in by the CSI snapshotter + sidecar with the "creation_time" value returned from CSI "CreateSnapshot" + gRPC call. For a pre-existing snapshot, this field will be filled + with the "creation_time" value returned from the CSI "ListSnapshots" + gRPC call if the driver supports it. If not specified, it indicates + the creation time is unknown. The format of this field is a Unix + nanoseconds time encoded as an int64. On Unix, the command `date + +%s%N` returns the current time in nanoseconds since 1970-01-01 + 00:00:00 UTC. + format: int64 + type: integer + error: + description: error is the last observed error during snapshot creation, + if any. Upon success after retry, this error field will be cleared. + properties: + message: + description: 'message is a string detailing the encountered error + during snapshot creation if specified. NOTE: message may be + logged, and it should not contain sensitive information.' + type: string + time: + description: time is the timestamp when the error was encountered. + format: date-time + type: string + type: object + readyToUse: + description: readyToUse indicates if a snapshot is ready to be used + to restore a volume. In dynamic snapshot creation case, this field + will be filled in by the CSI snapshotter sidecar with the "ready_to_use" + value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing + snapshot, this field will be filled with the "ready_to_use" value + returned from the CSI "ListSnapshots" gRPC call if the driver supports + it, otherwise, this field will be set to "True". If not specified, + it means the readiness of a snapshot is unknown. + type: boolean + restoreSize: + description: restoreSize represents the complete size of the snapshot + in bytes. In dynamic snapshot creation case, this field will be + filled in by the CSI snapshotter sidecar with the "size_bytes" value + returned from CSI "CreateSnapshot" gRPC call. For a pre-existing + snapshot, this field will be filled with the "size_bytes" value + returned from the CSI "ListSnapshots" gRPC call if the driver supports + it. When restoring a volume from this snapshot, the size of the + volume MUST NOT be smaller than the restoreSize if it is specified, + otherwise the restoration will fail. If not specified, it indicates + that the size is unknown. + format: int64 + minimum: 0 + type: integer + snapshotHandle: + description: snapshotHandle is the CSI "snapshot_id" of a snapshot + on the underlying storage system. If not specified, it indicates + that dynamic snapshot creation has either failed or it is still + in progress. + type: string + volumeGroupSnapshotContentName: + description: VolumeGroupSnapshotContentName is the name of the VolumeGroupSnapshotContent + of which this VolumeSnapshotContent is a part of. + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} + - additionalPrinterColumns: + - description: Indicates if the snapshot is ready to be used to restore a volume. + jsonPath: .status.readyToUse + name: ReadyToUse + type: boolean + - description: Represents the complete size of the snapshot in bytes + jsonPath: .status.restoreSize + name: RestoreSize + type: integer + - description: Determines whether this VolumeSnapshotContent and its physical snapshot on the underlying storage system should be deleted when its bound VolumeSnapshot is deleted. + jsonPath: .spec.deletionPolicy + name: DeletionPolicy + type: string + - description: Name of the CSI driver used to create the physical snapshot on the underlying storage system. + jsonPath: .spec.driver + name: Driver + type: string + - description: Name of the VolumeSnapshotClass to which this snapshot belongs. + jsonPath: .spec.volumeSnapshotClassName + name: VolumeSnapshotClass + type: string + - description: Name of the VolumeSnapshot object to which this VolumeSnapshotContent object is bound. + jsonPath: .spec.volumeSnapshotRef.name + name: VolumeSnapshot + type: string + - description: Namespace of the VolumeSnapshot object to which this VolumeSnapshotContent object is bound. + jsonPath: .spec.volumeSnapshotRef.namespace + name: VolumeSnapshotNamespace + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + # This indicates the v1beta1 version of the custom resource is deprecated. + # API requests to this version receive a warning in the server response. + deprecated: true + # This overrides the default warning returned to clients making v1beta1 API requests. + deprecationWarning: "snapshot.storage.k8s.io/v1beta1 VolumeSnapshotContent is deprecated; use snapshot.storage.k8s.io/v1 VolumeSnapshotContent" + schema: + openAPIV3Schema: + description: VolumeSnapshotContent represents the actual "on-disk" snapshot object in the underlying storage system + 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 + spec: + description: spec defines properties of a VolumeSnapshotContent created by the underlying storage system. Required. + properties: + deletionPolicy: + description: deletionPolicy determines whether this VolumeSnapshotContent and its physical snapshot on the underlying storage system should be deleted when its bound VolumeSnapshot is deleted. Supported values are "Retain" and "Delete". "Retain" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are kept. "Delete" means that the VolumeSnapshotContent and its physical snapshot on underlying storage system are deleted. For dynamically provisioned snapshots, this field will automatically be filled in by the CSI snapshotter sidecar with the "DeletionPolicy" field defined in the corresponding VolumeSnapshotClass. For pre-existing snapshots, users MUST specify this field when creating the VolumeSnapshotContent object. Required. + enum: + - Delete + - Retain + type: string + driver: + description: driver is the name of the CSI driver used to create the physical snapshot on the underlying storage system. This MUST be the same as the name returned by the CSI GetPluginName() call for that driver. Required. + type: string + source: + description: source specifies whether the snapshot is (or should be) dynamically provisioned or already exists, and just requires a Kubernetes object representation. This field is immutable after creation. Required. + properties: + snapshotHandle: + description: snapshotHandle specifies the CSI "snapshot_id" of a pre-existing snapshot on the underlying storage system for which a Kubernetes object representation was (or should be) created. This field is immutable. + type: string + volumeHandle: + description: volumeHandle specifies the CSI "volume_id" of the volume from which a snapshot should be dynamically taken from. This field is immutable. + type: string + type: object + volumeSnapshotClassName: + description: name of the VolumeSnapshotClass from which this snapshot was (or will be) created. Note that after provisioning, the VolumeSnapshotClass may be deleted or recreated with different set of values, and as such, should not be referenced post-snapshot creation. + type: string + volumeSnapshotRef: + description: volumeSnapshotRef specifies the VolumeSnapshot object to which this VolumeSnapshotContent object is bound. VolumeSnapshot.Spec.VolumeSnapshotContentName field must reference to this VolumeSnapshotContent's name for the bidirectional binding to be valid. For a pre-existing VolumeSnapshotContent object, name and namespace of the VolumeSnapshot object MUST be provided for binding to happen. This field is immutable after creation. Required. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: 'If referring to a piece of an object instead of an entire object, this string should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. For example, if the object reference is to a container within a pod, this would take on a value like: "spec.containers{name}" (where "name" refers to the name of the container that triggered the event) or if no container name is specified "spec.containers[2]" (container with index 2 in this pod). This syntax is chosen only to have some well-defined way of referencing a part of an object. TODO: this design is not final and this field is subject to change in the future.' + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: 'Specific resourceVersion to which this reference is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + required: + - deletionPolicy + - driver + - source + - volumeSnapshotRef + type: object + status: + description: status represents the current information of a snapshot. + properties: + creationTime: + description: creationTime is the timestamp when the point-in-time snapshot is taken by the underlying storage system. In dynamic snapshot creation case, this field will be filled in by the CSI snapshotter sidecar with the "creation_time" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "creation_time" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. If not specified, it indicates the creation time is unknown. The format of this field is a Unix nanoseconds time encoded as an int64. On Unix, the command `date +%s%N` returns the current time in nanoseconds since 1970-01-01 00:00:00 UTC. + format: int64 + type: integer + error: + description: error is the last observed error during snapshot creation, if any. Upon success after retry, this error field will be cleared. + properties: + message: + description: 'message is a string detailing the encountered error during snapshot creation if specified. NOTE: message may be logged, and it should not contain sensitive information.' + type: string + time: + description: time is the timestamp when the error was encountered. + format: date-time + type: string + type: object + readyToUse: + description: readyToUse indicates if a snapshot is ready to be used to restore a volume. In dynamic snapshot creation case, this field will be filled in by the CSI snapshotter sidecar with the "ready_to_use" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "ready_to_use" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it, otherwise, this field will be set to "True". If not specified, it means the readiness of a snapshot is unknown. + type: boolean + restoreSize: + description: restoreSize represents the complete size of the snapshot in bytes. In dynamic snapshot creation case, this field will be filled in by the CSI snapshotter sidecar with the "size_bytes" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "size_bytes" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. When restoring a volume from this snapshot, the size of the volume MUST NOT be smaller than the restoreSize if it is specified, otherwise the restoration will fail. If not specified, it indicates that the size is unknown. + format: int64 + minimum: 0 + type: integer + snapshotHandle: + description: snapshotHandle is the CSI "snapshot_id" of a snapshot on the underlying storage system. If not specified, it indicates that dynamic snapshot creation has either failed or it is still in progress. + type: string + type: object + required: + - spec + type: object + served: false + storage: false + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] \ No newline at end of file diff --git a/helm/openebs/charts/zfs-localpv/crds/volumesnapshots.yaml b/helm/openebs/charts/zfs-localpv/crds/volumesnapshots.yaml new file mode 100644 index 0000000..bf534c4 --- /dev/null +++ b/helm/openebs/charts/zfs-localpv/crds/volumesnapshots.yaml @@ -0,0 +1,312 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.11.3 + api-approved.kubernetes.io: "https://github.com/kubernetes-csi/external-snapshotter/pull/814" + creationTimestamp: null + name: volumesnapshots.snapshot.storage.k8s.io +spec: + group: snapshot.storage.k8s.io + names: + kind: VolumeSnapshot + listKind: VolumeSnapshotList + plural: volumesnapshots + shortNames: + - vs + singular: volumesnapshot + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Indicates if the snapshot is ready to be used to restore a volume. + jsonPath: .status.readyToUse + name: ReadyToUse + type: boolean + - description: If a new snapshot needs to be created, this contains the name of + the source PVC from which this snapshot was (or will be) created. + jsonPath: .spec.source.persistentVolumeClaimName + name: SourcePVC + type: string + - description: If a snapshot already exists, this contains the name of the existing + VolumeSnapshotContent object representing the existing snapshot. + jsonPath: .spec.source.volumeSnapshotContentName + name: SourceSnapshotContent + type: string + - description: Represents the minimum size of volume required to rehydrate from + this snapshot. + jsonPath: .status.restoreSize + name: RestoreSize + type: string + - description: The name of the VolumeSnapshotClass requested by the VolumeSnapshot. + jsonPath: .spec.volumeSnapshotClassName + name: SnapshotClass + type: string + - description: Name of the VolumeSnapshotContent object to which the VolumeSnapshot + object intends to bind to. Please note that verification of binding actually + requires checking both VolumeSnapshot and VolumeSnapshotContent to ensure + both are pointing at each other. Binding MUST be verified prior to usage of + this object. + jsonPath: .status.boundVolumeSnapshotContentName + name: SnapshotContent + type: string + - description: Timestamp when the point-in-time snapshot was taken by the underlying + storage system. + jsonPath: .status.creationTime + name: CreationTime + type: date + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: VolumeSnapshot is a user's request for either creating a point-in-time + snapshot of a persistent volume, or binding to a pre-existing snapshot. + 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 + spec: + description: 'spec defines the desired characteristics of a snapshot requested + by a user. More info: https://kubernetes.io/docs/concepts/storage/volume-snapshots#volumesnapshots + Required.' + properties: + source: + description: source specifies where a snapshot will be created from. + This field is immutable after creation. Required. + properties: + persistentVolumeClaimName: + description: persistentVolumeClaimName specifies the name of the + PersistentVolumeClaim object representing the volume from which + a snapshot should be created. This PVC is assumed to be in the + same namespace as the VolumeSnapshot object. This field should + be set if the snapshot does not exists, and needs to be created. + This field is immutable. + type: string + volumeSnapshotContentName: + description: volumeSnapshotContentName specifies the name of a + pre-existing VolumeSnapshotContent object representing an existing + volume snapshot. This field should be set if the snapshot already + exists and only needs a representation in Kubernetes. This field + is immutable. + type: string + type: object + oneOf: + - required: ["persistentVolumeClaimName"] + - required: ["volumeSnapshotContentName"] + volumeSnapshotClassName: + description: 'VolumeSnapshotClassName is the name of the VolumeSnapshotClass + requested by the VolumeSnapshot. VolumeSnapshotClassName may be + left nil to indicate that the default SnapshotClass should be used. + A given cluster may have multiple default Volume SnapshotClasses: + one default per CSI Driver. If a VolumeSnapshot does not specify + a SnapshotClass, VolumeSnapshotSource will be checked to figure + out what the associated CSI Driver is, and the default VolumeSnapshotClass + associated with that CSI Driver will be used. If more than one VolumeSnapshotClass + exist for a given CSI Driver and more than one have been marked + as default, CreateSnapshot will fail and generate an event. Empty + string is not allowed for this field.' + type: string + required: + - source + type: object + status: + description: status represents the current information of a snapshot. + Consumers must verify binding between VolumeSnapshot and VolumeSnapshotContent + objects is successful (by validating that both VolumeSnapshot and VolumeSnapshotContent + point at each other) before using this object. + properties: + boundVolumeSnapshotContentName: + description: 'boundVolumeSnapshotContentName is the name of the VolumeSnapshotContent + object to which this VolumeSnapshot object intends to bind to. If + not specified, it indicates that the VolumeSnapshot object has not + been successfully bound to a VolumeSnapshotContent object yet. NOTE: + To avoid possible security issues, consumers must verify binding + between VolumeSnapshot and VolumeSnapshotContent objects is successful + (by validating that both VolumeSnapshot and VolumeSnapshotContent + point at each other) before using this object.' + type: string + creationTime: + description: creationTime is the timestamp when the point-in-time + snapshot is taken by the underlying storage system. In dynamic snapshot + creation case, this field will be filled in by the snapshot controller + with the "creation_time" value returned from CSI "CreateSnapshot" + gRPC call. For a pre-existing snapshot, this field will be filled + with the "creation_time" value returned from the CSI "ListSnapshots" + gRPC call if the driver supports it. If not specified, it may indicate + that the creation time of the snapshot is unknown. + format: date-time + type: string + error: + description: error is the last observed error during snapshot creation, + if any. This field could be helpful to upper level controllers(i.e., + application controller) to decide whether they should continue on + waiting for the snapshot to be created based on the type of error + reported. The snapshot controller will keep retrying when an error + occurs during the snapshot creation. Upon success, this error field + will be cleared. + properties: + message: + description: 'message is a string detailing the encountered error + during snapshot creation if specified. NOTE: message may be + logged, and it should not contain sensitive information.' + type: string + time: + description: time is the timestamp when the error was encountered. + format: date-time + type: string + type: object + readyToUse: + description: readyToUse indicates if the snapshot is ready to be used + to restore a volume. In dynamic snapshot creation case, this field + will be filled in by the snapshot controller with the "ready_to_use" + value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing + snapshot, this field will be filled with the "ready_to_use" value + returned from the CSI "ListSnapshots" gRPC call if the driver supports + it, otherwise, this field will be set to "True". If not specified, + it means the readiness of a snapshot is unknown. + type: boolean + restoreSize: + type: string + description: restoreSize represents the minimum size of volume required + to create a volume from this snapshot. In dynamic snapshot creation + case, this field will be filled in by the snapshot controller with + the "size_bytes" value returned from CSI "CreateSnapshot" gRPC call. + For a pre-existing snapshot, this field will be filled with the + "size_bytes" value returned from the CSI "ListSnapshots" gRPC call + if the driver supports it. When restoring a volume from this snapshot, + the size of the volume MUST NOT be smaller than the restoreSize + if it is specified, otherwise the restoration will fail. If not + specified, it indicates that the size is unknown. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + volumeGroupSnapshotName: + description: VolumeGroupSnapshotName is the name of the VolumeGroupSnapshot + of which this VolumeSnapshot is a part of. + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} + - additionalPrinterColumns: + - description: Indicates if the snapshot is ready to be used to restore a volume. + jsonPath: .status.readyToUse + name: ReadyToUse + type: boolean + - description: If a new snapshot needs to be created, this contains the name of the source PVC from which this snapshot was (or will be) created. + jsonPath: .spec.source.persistentVolumeClaimName + name: SourcePVC + type: string + - description: If a snapshot already exists, this contains the name of the existing VolumeSnapshotContent object representing the existing snapshot. + jsonPath: .spec.source.volumeSnapshotContentName + name: SourceSnapshotContent + type: string + - description: Represents the minimum size of volume required to rehydrate from this snapshot. + jsonPath: .status.restoreSize + name: RestoreSize + type: string + - description: The name of the VolumeSnapshotClass requested by the VolumeSnapshot. + jsonPath: .spec.volumeSnapshotClassName + name: SnapshotClass + type: string + - description: Name of the VolumeSnapshotContent object to which the VolumeSnapshot object intends to bind to. Please note that verification of binding actually requires checking both VolumeSnapshot and VolumeSnapshotContent to ensure both are pointing at each other. Binding MUST be verified prior to usage of this object. + jsonPath: .status.boundVolumeSnapshotContentName + name: SnapshotContent + type: string + - description: Timestamp when the point-in-time snapshot was taken by the underlying storage system. + jsonPath: .status.creationTime + name: CreationTime + type: date + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + # This indicates the v1beta1 version of the custom resource is deprecated. + # API requests to this version receive a warning in the server response. + deprecated: true + # This overrides the default warning returned to clients making v1beta1 API requests. + deprecationWarning: "snapshot.storage.k8s.io/v1beta1 VolumeSnapshot is deprecated; use snapshot.storage.k8s.io/v1 VolumeSnapshot" + schema: + openAPIV3Schema: + description: VolumeSnapshot is a user's request for either creating a point-in-time snapshot of a persistent volume, or binding to a pre-existing snapshot. + 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 + spec: + description: 'spec defines the desired characteristics of a snapshot requested by a user. More info: https://kubernetes.io/docs/concepts/storage/volume-snapshots#volumesnapshots Required.' + properties: + source: + description: source specifies where a snapshot will be created from. This field is immutable after creation. Required. + properties: + persistentVolumeClaimName: + description: persistentVolumeClaimName specifies the name of the PersistentVolumeClaim object representing the volume from which a snapshot should be created. This PVC is assumed to be in the same namespace as the VolumeSnapshot object. This field should be set if the snapshot does not exists, and needs to be created. This field is immutable. + type: string + volumeSnapshotContentName: + description: volumeSnapshotContentName specifies the name of a pre-existing VolumeSnapshotContent object representing an existing volume snapshot. This field should be set if the snapshot already exists and only needs a representation in Kubernetes. This field is immutable. + type: string + type: object + volumeSnapshotClassName: + description: 'VolumeSnapshotClassName is the name of the VolumeSnapshotClass requested by the VolumeSnapshot. VolumeSnapshotClassName may be left nil to indicate that the default SnapshotClass should be used. A given cluster may have multiple default Volume SnapshotClasses: one default per CSI Driver. If a VolumeSnapshot does not specify a SnapshotClass, VolumeSnapshotSource will be checked to figure out what the associated CSI Driver is, and the default VolumeSnapshotClass associated with that CSI Driver will be used. If more than one VolumeSnapshotClass exist for a given CSI Driver and more than one have been marked as default, CreateSnapshot will fail and generate an event. Empty string is not allowed for this field.' + type: string + required: + - source + type: object + status: + description: status represents the current information of a snapshot. Consumers must verify binding between VolumeSnapshot and VolumeSnapshotContent objects is successful (by validating that both VolumeSnapshot and VolumeSnapshotContent point at each other) before using this object. + properties: + boundVolumeSnapshotContentName: + description: 'boundVolumeSnapshotContentName is the name of the VolumeSnapshotContent object to which this VolumeSnapshot object intends to bind to. If not specified, it indicates that the VolumeSnapshot object has not been successfully bound to a VolumeSnapshotContent object yet. NOTE: To avoid possible security issues, consumers must verify binding between VolumeSnapshot and VolumeSnapshotContent objects is successful (by validating that both VolumeSnapshot and VolumeSnapshotContent point at each other) before using this object.' + type: string + creationTime: + description: creationTime is the timestamp when the point-in-time snapshot is taken by the underlying storage system. In dynamic snapshot creation case, this field will be filled in by the snapshot controller with the "creation_time" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "creation_time" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. If not specified, it may indicate that the creation time of the snapshot is unknown. + format: date-time + type: string + error: + description: error is the last observed error during snapshot creation, if any. This field could be helpful to upper level controllers(i.e., application controller) to decide whether they should continue on waiting for the snapshot to be created based on the type of error reported. The snapshot controller will keep retrying when an error occurs during the snapshot creation. Upon success, this error field will be cleared. + properties: + message: + description: 'message is a string detailing the encountered error during snapshot creation if specified. NOTE: message may be logged, and it should not contain sensitive information.' + type: string + time: + description: time is the timestamp when the error was encountered. + format: date-time + type: string + type: object + readyToUse: + description: readyToUse indicates if the snapshot is ready to be used to restore a volume. In dynamic snapshot creation case, this field will be filled in by the snapshot controller with the "ready_to_use" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "ready_to_use" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it, otherwise, this field will be set to "True". If not specified, it means the readiness of a snapshot is unknown. + type: boolean + restoreSize: + type: string + description: restoreSize represents the minimum size of volume required to create a volume from this snapshot. In dynamic snapshot creation case, this field will be filled in by the snapshot controller with the "size_bytes" value returned from CSI "CreateSnapshot" gRPC call. For a pre-existing snapshot, this field will be filled with the "size_bytes" value returned from the CSI "ListSnapshots" gRPC call if the driver supports it. When restoring a volume from this snapshot, the size of the volume MUST NOT be smaller than the restoreSize if it is specified, otherwise the restoration will fail. If not specified, it indicates that the size is unknown. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + required: + - spec + type: object + served: false + storage: false + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] \ No newline at end of file diff --git a/helm/openebs/charts/zfs-localpv/crds/zfsbackup.yaml b/helm/openebs/charts/zfs-localpv/crds/zfsbackup.yaml new file mode 100644 index 0000000..492e5d4 --- /dev/null +++ b/helm/openebs/charts/zfs-localpv/crds/zfsbackup.yaml @@ -0,0 +1,116 @@ + + +############################################## +########### ############ +########### ZFSBackup CRD ############ +########### ############ +############################################## + +# ZFSBackups CRD is autogenerated via `make manifests` command. +# Do the modification in the code and run the `make manifests` command +# to generate the CRD definition + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.0 + creationTimestamp: null + name: zfsbackups.zfs.openebs.io +spec: + group: zfs.openebs.io + names: + kind: ZFSBackup + listKind: ZFSBackupList + plural: zfsbackups + shortNames: + - zb + singular: zfsbackup + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Previous snapshot for backup + jsonPath: .spec.prevSnapName + name: PrevSnap + type: string + - description: Backup status + jsonPath: .status + name: Status + type: string + - description: Age of the volume + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: ZFSBackup describes a zfs backup resource created as a custom + resource + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: ZFSBackupSpec is the spec for a ZFSBackup resource + properties: + backupDest: + description: BackupDest is the remote address for backup transfer + minLength: 1 + pattern: ^([0-9]+.[0-9]+.[0-9]+.[0-9]+:[0-9]+)$ + type: string + ownerNodeID: + description: OwnerNodeID is a name of the nodes where the source volume + is + minLength: 1 + type: string + prevSnapName: + description: PrevSnapName is the last completed-backup's snapshot + name + type: string + snapName: + description: SnapName is the snapshot name for backup + minLength: 1 + type: string + volumeName: + description: VolumeName is a name of the volume for which this backup + is destined + minLength: 1 + type: string + required: + - backupDest + - ownerNodeID + - volumeName + type: object + status: + description: ZFSBackupStatus is to hold status of backup + enum: + - Init + - Done + - Failed + - Pending + - InProgress + - Invalid + type: string + required: + - spec + - status + type: object + served: true + storage: true + subresources: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/helm/openebs/charts/zfs-localpv/crds/zfsnode.yaml b/helm/openebs/charts/zfs-localpv/crds/zfsnode.yaml new file mode 100644 index 0000000..db0540d --- /dev/null +++ b/helm/openebs/charts/zfs-localpv/crds/zfsnode.yaml @@ -0,0 +1,87 @@ + +############################################## +########### ############ +########### ZFSNode CRD ############ +########### ############ +############################################## + +# ZFSNode CRD is autogenerated via `make manifests` command. +# Do the modification in the code and run the `make manifests` command +# to generate the CRD definition + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.0 + creationTimestamp: null + name: zfsnodes.zfs.openebs.io +spec: + group: zfs.openebs.io + names: + kind: ZFSNode + listKind: ZFSNodeList + plural: zfsnodes + shortNames: + - zfsnode + singular: zfsnode + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + description: ZFSNode records information about all zfs pools available in + a node. In general, the openebs node-agent creates the ZFSNode object & + periodically synchronizing the zfs pools available in the node. ZFSNode + has an owner reference pointing to the corresponding node object. + 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 + pools: + items: + description: Pool specifies attributes of a given zfs pool that exists + on the node. + properties: + free: + anyOf: + - type: integer + - type: string + description: Free specifies the available capacity of zfs pool. + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + name: + description: Name of the zfs pool. + minLength: 1 + type: string + uuid: + description: UUID denotes a unique identity of a zfs pool. + minLength: 1 + type: string + required: + - free + - name + - uuid + type: object + type: array + required: + - pools + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/helm/openebs/charts/zfs-localpv/crds/zfsrestore.yaml b/helm/openebs/charts/zfs-localpv/crds/zfsrestore.yaml new file mode 100644 index 0000000..ffffb71 --- /dev/null +++ b/helm/openebs/charts/zfs-localpv/crds/zfsrestore.yaml @@ -0,0 +1,238 @@ + + +############################################## +########### ############ +########### ZFSRestore CRD ############ +########### ############ +############################################## + +# ZFSRestores CRD is autogenerated via `make manifests` command. +# Do the modification in the code and run the `make manifests` command +# to generate the CRD definition + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.0 + creationTimestamp: null + name: zfsrestores.zfs.openebs.io +spec: + group: zfs.openebs.io + names: + kind: ZFSRestore + listKind: ZFSRestoreList + plural: zfsrestores + singular: zfsrestore + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + description: ZFSRestore describes a cstor restore resource created as a custom + resource + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: ZFSRestoreSpec is the spec for a ZFSRestore resource + properties: + ownerNodeID: + description: owner node name where restore volume is present + minLength: 1 + type: string + restoreSrc: + description: it can be ip:port in case of restore from remote or volumeName + in case of local restore + minLength: 1 + pattern: ^([0-9]+.[0-9]+.[0-9]+.[0-9]+:[0-9]+)$ + type: string + volumeName: + description: volume name to where restore has to be performed + minLength: 1 + type: string + required: + - ownerNodeID + - restoreSrc + - volumeName + type: object + status: + description: ZFSRestoreStatus is to hold result of action. + enum: + - Init + - Done + - Failed + - Pending + - InProgress + - Invalid + type: string + volSpec: + description: VolumeInfo defines ZFS volume parameters for all modes in + which ZFS volumes can be created like - ZFS volume with filesystem, + ZFS Volume exposed as zfs or ZFS volume exposed as raw block device. + Some of the parameters can be only set during creation time (as specified + in the details of the parameter), and a few are editable. In case of + Cloned volumes, the parameters are assigned the same values as the source + volume. + properties: + capacity: + description: Capacity of the volume + minLength: 1 + type: string + compression: + description: 'Compression specifies the block-level compression algorithm + to be applied to the ZFS Volume. The value "on" indicates ZFS to + use the default compression algorithm. The default compression algorithm + used by ZFS will be either lzjb or, if the lz4_compress feature + is enabled, lz4. Compression property can be edited after the volume + has been created. The change will only be applied to the newly-written + data. For instance, if the Volume was created with "off" and the + next day the compression was modified to "on", the data written + prior to setting "on" will not be compressed. Default Value: off.' + pattern: ^(on|off|lzjb|zstd|zstd-[1-9]|zstd-1[0-9]|gzip|gzip-[1-9]|zle|lz4)$ + type: string + dedup: + description: 'Deduplication is the process for removing redundant + data at the block level, reducing the total amount of data stored. + If a file system has the dedup property enabled, duplicate data + blocks are removed synchronously. The result is that only unique + data is stored and common components are shared among files. Deduplication + can consume significant processing power (CPU) and memory as well + as generate additional disk IO. Before creating a pool with deduplication + enabled, ensure that you have planned your hardware requirements + appropriately and implemented appropriate recovery practices, such + as regular backups. As an alternative to deduplication consider + using compression=lz4, as a less resource-intensive alternative. + should be enabled on the zvol. Dedup property can be edited after + the volume has been created. Default Value: off.' + enum: + - "on" + - "off" + type: string + encryption: + description: 'Enabling the encryption feature allows for the creation + of encrypted filesystems and volumes. ZFS will encrypt file and + zvol data, file attributes, ACLs, permission bits, directory listings, + FUID mappings, and userused / groupused data. ZFS will not encrypt + metadata related to the pool structure, including dataset and snapshot + names, dataset hierarchy, properties, file size, file holes, and + deduplication tables (though the deduplicated data itself is encrypted). + Default Value: off.' + pattern: ^(on|off|aes-128-[c,g]cm|aes-192-[c,g]cm|aes-256-[c,g]cm)$ + type: string + fsType: + description: 'FsType specifies filesystem type for the zfs volume/dataset. + If FsType is provided as "zfs", then the driver will create a ZFS + dataset, formatting is not required as underlying filesystem is + ZFS anyway. If FsType is ext2, ext3, ext4 or xfs, then the driver + will create a ZVOL and format the volume accordingly. FsType can + not be modified once volume has been provisioned. Default Value: + ext4.' + type: string + keyformat: + description: KeyFormat specifies format of the encryption key The + supported KeyFormats are passphrase, raw, hex. + enum: + - passphrase + - raw + - hex + type: string + keylocation: + description: KeyLocation is the location of key for the encryption + type: string + ownerNodeID: + description: OwnerNodeID is the Node ID where the ZPOOL is running + which is where the volume has been provisioned. OwnerNodeID can + not be edited after the volume has been provisioned. + minLength: 1 + type: string + poolName: + description: poolName specifies the name of the pool where the volume + has been created. PoolName can not be edited after the volume has + been provisioned. + minLength: 1 + type: string + recordsize: + description: 'Specifies a suggested block size for files in the file + system. The size specified must be a power of two greater than or + equal to 512 and less than or equal to 128 Kbytes. RecordSize property + can be edited after the volume has been created. Changing the file + system''s recordsize affects only files created afterward; existing + files are unaffected. Default Value: 128k.' + minLength: 1 + type: string + shared: + description: Shared specifies whether the volume can be shared among + multiple pods. If it is not set to "yes", then the ZFS-LocalPV Driver + will not allow the volumes to be mounted by more than one pods. + enum: + - "yes" + - "no" + type: string + snapname: + description: SnapName specifies the name of the snapshot where the + volume has been cloned from. Snapname can not be edited after the + volume has been provisioned. + type: string + thinProvision: + description: 'ThinProvision describes whether space reservation for + the source volume is required or not. The value "yes" indicates + that volume should be thin provisioned and "no" means thick provisioning + of the volume. If thinProvision is set to "yes" then volume can + be provisioned even if the ZPOOL does not have the enough capacity. + If thinProvision is set to "no" then volume can be provisioned only + if the ZPOOL has enough capacity and capacity required by volume + can be reserved. ThinProvision can not be modified once volume has + been provisioned. Default Value: no.' + enum: + - "yes" + - "no" + type: string + volblocksize: + description: 'VolBlockSize specifies the block size for the zvol. + The volsize can only be set to a multiple of volblocksize, and cannot + be zero. VolBlockSize can not be edited after the volume has been + provisioned. Default Value: 8k.' + minLength: 1 + type: string + volumeType: + description: volumeType determines whether the volume is of type "DATASET" + or "ZVOL". If fstype provided in the storageclass is "zfs", a volume + of type dataset will be created. If "ext4", "ext3", "ext2" or "xfs" + is mentioned as fstype in the storageclass, then a volume of type + zvol will be created, which will be further formatted as the fstype + provided in the storageclass. VolumeType can not be modified once + volume has been provisioned. + enum: + - ZVOL + - DATASET + type: string + required: + - capacity + - ownerNodeID + - poolName + - volumeType + type: object + required: + - spec + - status + type: object + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/helm/openebs/charts/zfs-localpv/crds/zfssnapshot.yaml b/helm/openebs/charts/zfs-localpv/crds/zfssnapshot.yaml new file mode 100644 index 0000000..fb6a9af --- /dev/null +++ b/helm/openebs/charts/zfs-localpv/crds/zfssnapshot.yaml @@ -0,0 +1,383 @@ + + +############################################## +########### ############ +########### ZFSSnapshot CRD ############ +########### ############ +############################################## + +# ZFSSnapshot CRD is autogenerated via `make manifests` command. +# Do the modification in the code and run the `make manifests` command +# to generate the CRD definition + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.0 + creationTimestamp: null + name: zfssnapshots.zfs.openebs.io +spec: + group: zfs.openebs.io + names: + kind: ZFSSnapshot + listKind: ZFSSnapshotList + plural: zfssnapshots + shortNames: + - zfssnap + singular: zfssnapshot + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + description: ZFSSnapshot represents a ZFS Snapshot of the zfsvolume + 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: VolumeInfo defines ZFS volume parameters for all modes in + which ZFS volumes can be created like - ZFS volume with filesystem, + ZFS Volume exposed as zfs or ZFS volume exposed as raw block device. + Some of the parameters can be only set during creation time (as specified + in the details of the parameter), and a few are editable. In case of + Cloned volumes, the parameters are assigned the same values as the source + volume. + properties: + capacity: + description: Capacity of the volume + minLength: 1 + type: string + compression: + description: 'Compression specifies the block-level compression algorithm + to be applied to the ZFS Volume. The value "on" indicates ZFS to + use the default compression algorithm. The default compression algorithm + used by ZFS will be either lzjb or, if the lz4_compress feature + is enabled, lz4. Compression property can be edited after the volume + has been created. The change will only be applied to the newly-written + data. For instance, if the Volume was created with "off" and the + next day the compression was modified to "on", the data written + prior to setting "on" will not be compressed. Default Value: off.' + pattern: ^(on|off|lzjb|zstd|zstd-[1-9]|zstd-1[0-9]|gzip|gzip-[1-9]|zle|lz4)$ + type: string + dedup: + description: 'Deduplication is the process for removing redundant + data at the block level, reducing the total amount of data stored. + If a file system has the dedup property enabled, duplicate data + blocks are removed synchronously. The result is that only unique + data is stored and common components are shared among files. Deduplication + can consume significant processing power (CPU) and memory as well + as generate additional disk IO. Before creating a pool with deduplication + enabled, ensure that you have planned your hardware requirements + appropriately and implemented appropriate recovery practices, such + as regular backups. As an alternative to deduplication consider + using compression=lz4, as a less resource-intensive alternative. + should be enabled on the zvol. Dedup property can be edited after + the volume has been created. Default Value: off.' + enum: + - "on" + - "off" + type: string + encryption: + description: 'Enabling the encryption feature allows for the creation + of encrypted filesystems and volumes. ZFS will encrypt file and + zvol data, file attributes, ACLs, permission bits, directory listings, + FUID mappings, and userused / groupused data. ZFS will not encrypt + metadata related to the pool structure, including dataset and snapshot + names, dataset hierarchy, properties, file size, file holes, and + deduplication tables (though the deduplicated data itself is encrypted). + Default Value: off.' + pattern: ^(on|off|aes-128-[c,g]cm|aes-192-[c,g]cm|aes-256-[c,g]cm)$ + type: string + fsType: + description: 'FsType specifies filesystem type for the zfs volume/dataset. + If FsType is provided as "zfs", then the driver will create a ZFS + dataset, formatting is not required as underlying filesystem is + ZFS anyway. If FsType is ext2, ext3, ext4 or xfs, then the driver + will create a ZVOL and format the volume accordingly. FsType can + not be modified once volume has been provisioned. Default Value: + ext4.' + type: string + keyformat: + description: KeyFormat specifies format of the encryption key The + supported KeyFormats are passphrase, raw, hex. + enum: + - passphrase + - raw + - hex + type: string + keylocation: + description: KeyLocation is the location of key for the encryption + type: string + ownerNodeID: + description: OwnerNodeID is the Node ID where the ZPOOL is running + which is where the volume has been provisioned. OwnerNodeID can + not be edited after the volume has been provisioned. + minLength: 1 + type: string + poolName: + description: poolName specifies the name of the pool where the volume + has been created. PoolName can not be edited after the volume has + been provisioned. + minLength: 1 + type: string + recordsize: + description: 'Specifies a suggested block size for files in the file + system. The size specified must be a power of two greater than or + equal to 512 and less than or equal to 128 Kbytes. RecordSize property + can be edited after the volume has been created. Changing the file + system''s recordsize affects only files created afterward; existing + files are unaffected. Default Value: 128k.' + minLength: 1 + type: string + shared: + description: Shared specifies whether the volume can be shared among + multiple pods. If it is not set to "yes", then the ZFS-LocalPV Driver + will not allow the volumes to be mounted by more than one pods. + enum: + - "yes" + - "no" + type: string + snapname: + description: SnapName specifies the name of the snapshot where the + volume has been cloned from. Snapname can not be edited after the + volume has been provisioned. + type: string + thinProvision: + description: 'ThinProvision describes whether space reservation for + the source volume is required or not. The value "yes" indicates + that volume should be thin provisioned and "no" means thick provisioning + of the volume. If thinProvision is set to "yes" then volume can + be provisioned even if the ZPOOL does not have the enough capacity. + If thinProvision is set to "no" then volume can be provisioned only + if the ZPOOL has enough capacity and capacity required by volume + can be reserved. ThinProvision can not be modified once volume has + been provisioned. Default Value: no.' + enum: + - "yes" + - "no" + type: string + volblocksize: + description: 'VolBlockSize specifies the block size for the zvol. + The volsize can only be set to a multiple of volblocksize, and cannot + be zero. VolBlockSize can not be edited after the volume has been + provisioned. Default Value: 8k.' + minLength: 1 + type: string + volumeType: + description: volumeType determines whether the volume is of type "DATASET" + or "ZVOL". If fstype provided in the storageclass is "zfs", a volume + of type dataset will be created. If "ext4", "ext3", "ext2" or "xfs" + is mentioned as fstype in the storageclass, then a volume of type + zvol will be created, which will be further formatted as the fstype + provided in the storageclass. VolumeType can not be modified once + volume has been provisioned. + enum: + - ZVOL + - DATASET + type: string + required: + - capacity + - ownerNodeID + - poolName + - volumeType + type: object + status: + description: SnapStatus string that reflects if the snapshot was created + successfully + properties: + state: + type: string + type: object + required: + - spec + - status + type: object + served: true + storage: true + - name: v1alpha1 + schema: + openAPIV3Schema: + description: ZFSSnapshot represents a ZFS Snapshot of the zfsvolume + 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: VolumeInfo defines ZFS volume parameters for all modes in + which ZFS volumes can be created like - ZFS volume with filesystem, + ZFS Volume exposed as zfs or ZFS volume exposed as raw block device. + Some of the parameters can be only set during creation time (as specified + in the details of the parameter), and a few are editable. In case of + Cloned volumes, the parameters are assigned the same values as the source + volume. + properties: + capacity: + description: Capacity of the volume + minLength: 1 + type: string + compression: + description: 'Compression specifies the block-level compression algorithm + to be applied to the ZFS Volume. The value "on" indicates ZFS to + use the default compression algorithm. The default compression algorithm + used by ZFS will be either lzjb or, if the lz4_compress feature + is enabled, lz4. Compression property can be edited after the volume + has been created. The change will only be applied to the newly-written + data. For instance, if the Volume was created with "off" and the + next day the compression was modified to "on", the data written + prior to setting "on" will not be compressed. Default Value: off.' + pattern: ^(on|off|lzjb|gzip|gzip-[1-9]|zle|lz4)$ + type: string + dedup: + description: 'Deduplication is the process for removing redundant + data at the block level, reducing the total amount of data stored. + If a file system has the dedup property enabled, duplicate data + blocks are removed synchronously. The result is that only unique + data is stored and common components are shared among files. Deduplication + can consume significant processing power (CPU) and memory as well + as generate additional disk IO. Before creating a pool with deduplication + enabled, ensure that you have planned your hardware requirements + appropriately and implemented appropriate recovery practices, such + as regular backups. As an alternative to deduplication consider + using compression=lz4, as a less resource-intensive alternative. + should be enabled on the zvol. Dedup property can be edited after + the volume has been created. Default Value: off.' + enum: + - "on" + - "off" + type: string + encryption: + description: 'Enabling the encryption feature allows for the creation + of encrypted filesystems and volumes. ZFS will encrypt file and + zvol data, file attributes, ACLs, permission bits, directory listings, + FUID mappings, and userused / groupused data. ZFS will not encrypt + metadata related to the pool structure, including dataset and snapshot + names, dataset hierarchy, properties, file size, file holes, and + deduplication tables (though the deduplicated data itself is encrypted). + Default Value: off.' + pattern: ^(on|off|aes-128-[c,g]cm|aes-192-[c,g]cm|aes-256-[c,g]cm)$ + type: string + fsType: + description: 'FsType specifies filesystem type for the zfs volume/dataset. + If FsType is provided as "zfs", then the driver will create a ZFS + dataset, formatting is not required as underlying filesystem is + ZFS anyway. If FsType is ext2, ext3, ext4 or xfs, then the driver + will create a ZVOL and format the volume accordingly. FsType can + not be modified once volume has been provisioned. Default Value: + ext4.' + type: string + keyformat: + description: KeyFormat specifies format of the encryption key The + supported KeyFormats are passphrase, raw, hex. + enum: + - passphrase + - raw + - hex + type: string + keylocation: + description: KeyLocation is the location of key for the encryption + type: string + ownerNodeID: + description: OwnerNodeID is the Node ID where the ZPOOL is running + which is where the volume has been provisioned. OwnerNodeID can + not be edited after the volume has been provisioned. + minLength: 1 + type: string + poolName: + description: poolName specifies the name of the pool where the volume + has been created. PoolName can not be edited after the volume has + been provisioned. + minLength: 1 + type: string + recordsize: + description: 'Specifies a suggested block size for files in the file + system. The size specified must be a power of two greater than or + equal to 512 and less than or equal to 128 Kbytes. RecordSize property + can be edited after the volume has been created. Changing the file + system''s recordsize affects only files created afterward; existing + files are unaffected. Default Value: 128k.' + minLength: 1 + type: string + snapname: + description: SnapName specifies the name of the snapshot where the + volume has been cloned from. Snapname can not be edited after the + volume has been provisioned. + type: string + thinProvision: + description: 'ThinProvision describes whether space reservation for + the source volume is required or not. The value "yes" indicates + that volume should be thin provisioned and "no" means thick provisioning + of the volume. If thinProvision is set to "yes" then volume can + be provisioned even if the ZPOOL does not have the enough capacity. + If thinProvision is set to "no" then volume can be provisioned only + if the ZPOOL has enough capacity and capacity required by volume + can be reserved. ThinProvision can not be modified once volume has + been provisioned. Default Value: no.' + enum: + - "yes" + - "no" + type: string + volblocksize: + description: 'VolBlockSize specifies the block size for the zvol. + The volsize can only be set to a multiple of volblocksize, and cannot + be zero. VolBlockSize can not be edited after the volume has been + provisioned. Default Value: 8k.' + minLength: 1 + type: string + volumeType: + description: volumeType determines whether the volume is of type "DATASET" + or "ZVOL". If fstype provided in the storageclass is "zfs", a volume + of type dataset will be created. If "ext4", "ext3", "ext2" or "xfs" + is mentioned as fstype in the storageclass, then a volume of type + zvol will be created, which will be further formatted as the fstype + provided in the storageclass. VolumeType can not be modified once + volume has been provisioned. + enum: + - ZVOL + - DATASET + type: string + required: + - capacity + - ownerNodeID + - poolName + - volumeType + type: object + status: + description: SnapStatus string that reflects if the snapshot was created + successfully + properties: + state: + type: string + type: object + required: + - spec + - status + type: object + served: true + storage: false +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/helm/openebs/charts/zfs-localpv/crds/zfsvolume.yaml b/helm/openebs/charts/zfs-localpv/crds/zfsvolume.yaml new file mode 100644 index 0000000..aeb00f5 --- /dev/null +++ b/helm/openebs/charts/zfs-localpv/crds/zfsvolume.yaml @@ -0,0 +1,449 @@ + + +############################################## +########### ############ +########### ZFSVolume CRD ############ +########### ############ +############################################## + +# ZFSVolume CRD is autogenerated via `make manifests` command. +# Do the modification in the code and run the `make manifests` command +# to generate the CRD definition + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.4.0 + creationTimestamp: null + name: zfsvolumes.zfs.openebs.io +spec: + group: zfs.openebs.io + names: + kind: ZFSVolume + listKind: ZFSVolumeList + plural: zfsvolumes + shortNames: + - zfsvol + - zv + singular: zfsvolume + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: ZFS Pool where the volume is created + jsonPath: .spec.poolName + name: ZPool + type: string + - description: Node where the volume is created + jsonPath: .spec.ownerNodeID + name: NodeID + type: string + - description: Size of the volume + jsonPath: .spec.capacity + name: Size + type: string + - description: Status of the volume + jsonPath: .status.state + name: Status + type: string + - description: filesystem created on the volume + jsonPath: .spec.fsType + name: Filesystem + type: string + - description: Age of the volume + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + description: ZFSVolume represents a ZFS based volume + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: VolumeInfo defines ZFS volume parameters for all modes in + which ZFS volumes can be created like - ZFS volume with filesystem, + ZFS Volume exposed as zfs or ZFS volume exposed as raw block device. + Some of the parameters can be only set during creation time (as specified + in the details of the parameter), and a few are editable. In case of + Cloned volumes, the parameters are assigned the same values as the source + volume. + properties: + capacity: + description: Capacity of the volume + minLength: 1 + type: string + compression: + description: 'Compression specifies the block-level compression algorithm + to be applied to the ZFS Volume. The value "on" indicates ZFS to + use the default compression algorithm. The default compression algorithm + used by ZFS will be either lzjb or, if the lz4_compress feature + is enabled, lz4. Compression property can be edited after the volume + has been created. The change will only be applied to the newly-written + data. For instance, if the Volume was created with "off" and the + next day the compression was modified to "on", the data written + prior to setting "on" will not be compressed. Default Value: off.' + pattern: ^(on|off|lzjb|zstd|zstd-[1-9]|zstd-1[0-9]|gzip|gzip-[1-9]|zle|lz4)$ + type: string + dedup: + description: 'Deduplication is the process for removing redundant + data at the block level, reducing the total amount of data stored. + If a file system has the dedup property enabled, duplicate data + blocks are removed synchronously. The result is that only unique + data is stored and common components are shared among files. Deduplication + can consume significant processing power (CPU) and memory as well + as generate additional disk IO. Before creating a pool with deduplication + enabled, ensure that you have planned your hardware requirements + appropriately and implemented appropriate recovery practices, such + as regular backups. As an alternative to deduplication consider + using compression=lz4, as a less resource-intensive alternative. + should be enabled on the zvol. Dedup property can be edited after + the volume has been created. Default Value: off.' + enum: + - "on" + - "off" + type: string + encryption: + description: 'Enabling the encryption feature allows for the creation + of encrypted filesystems and volumes. ZFS will encrypt file and + zvol data, file attributes, ACLs, permission bits, directory listings, + FUID mappings, and userused / groupused data. ZFS will not encrypt + metadata related to the pool structure, including dataset and snapshot + names, dataset hierarchy, properties, file size, file holes, and + deduplication tables (though the deduplicated data itself is encrypted). + Default Value: off.' + pattern: ^(on|off|aes-128-[c,g]cm|aes-192-[c,g]cm|aes-256-[c,g]cm)$ + type: string + fsType: + description: 'FsType specifies filesystem type for the zfs volume/dataset. + If FsType is provided as "zfs", then the driver will create a ZFS + dataset, formatting is not required as underlying filesystem is + ZFS anyway. If FsType is ext2, ext3, ext4 or xfs, then the driver + will create a ZVOL and format the volume accordingly. FsType can + not be modified once volume has been provisioned. Default Value: + ext4.' + type: string + keyformat: + description: KeyFormat specifies format of the encryption key The + supported KeyFormats are passphrase, raw, hex. + enum: + - passphrase + - raw + - hex + type: string + keylocation: + description: KeyLocation is the location of key for the encryption + type: string + ownerNodeID: + description: OwnerNodeID is the Node ID where the ZPOOL is running + which is where the volume has been provisioned. OwnerNodeID can + not be edited after the volume has been provisioned. + minLength: 1 + type: string + poolName: + description: poolName specifies the name of the pool where the volume + has been created. PoolName can not be edited after the volume has + been provisioned. + minLength: 1 + type: string + recordsize: + description: 'Specifies a suggested block size for files in the file + system. The size specified must be a power of two greater than or + equal to 512 and less than or equal to 128 Kbytes. RecordSize property + can be edited after the volume has been created. Changing the file + system''s recordsize affects only files created afterward; existing + files are unaffected. Default Value: 128k.' + minLength: 1 + type: string + shared: + description: Shared specifies whether the volume can be shared among + multiple pods. If it is not set to "yes", then the ZFS-LocalPV Driver + will not allow the volumes to be mounted by more than one pods. + enum: + - "yes" + - "no" + type: string + snapname: + description: SnapName specifies the name of the snapshot where the + volume has been cloned from. Snapname can not be edited after the + volume has been provisioned. + type: string + thinProvision: + description: 'ThinProvision describes whether space reservation for + the source volume is required or not. The value "yes" indicates + that volume should be thin provisioned and "no" means thick provisioning + of the volume. If thinProvision is set to "yes" then volume can + be provisioned even if the ZPOOL does not have the enough capacity. + If thinProvision is set to "no" then volume can be provisioned only + if the ZPOOL has enough capacity and capacity required by volume + can be reserved. ThinProvision can not be modified once volume has + been provisioned. Default Value: no.' + enum: + - "yes" + - "no" + type: string + volblocksize: + description: 'VolBlockSize specifies the block size for the zvol. + The volsize can only be set to a multiple of volblocksize, and cannot + be zero. VolBlockSize can not be edited after the volume has been + provisioned. Default Value: 8k.' + minLength: 1 + type: string + volumeType: + description: volumeType determines whether the volume is of type "DATASET" + or "ZVOL". If fstype provided in the storageclass is "zfs", a volume + of type dataset will be created. If "ext4", "ext3", "ext2" or "xfs" + is mentioned as fstype in the storageclass, then a volume of type + zvol will be created, which will be further formatted as the fstype + provided in the storageclass. VolumeType can not be modified once + volume has been provisioned. + enum: + - ZVOL + - DATASET + type: string + required: + - capacity + - ownerNodeID + - poolName + - volumeType + type: object + status: + description: VolStatus string that specifies the current state of the + volume provisioning request. + properties: + state: + description: State specifies the current state of the volume provisioning + request. The state "Pending" means that the volume creation request + has not processed yet. The state "Ready" means that the volume has + been created and it is ready for the use. + enum: + - Pending + - Ready + - Failed + type: string + type: object + required: + - spec + type: object + served: true + storage: true + subresources: {} + - additionalPrinterColumns: + - description: ZFS Pool where the volume is created + jsonPath: .spec.poolName + name: ZPool + type: string + - description: Node where the volume is created + jsonPath: .spec.ownerNodeID + name: Node + type: string + - description: Size of the volume + jsonPath: .spec.capacity + name: Size + type: string + - description: Status of the volume + jsonPath: .status.state + name: Status + type: string + - description: filesystem created on the volume + jsonPath: .spec.fsType + name: Filesystem + type: string + - description: Age of the volume + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: ZFSVolume represents a ZFS based volume + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: VolumeInfo defines ZFS volume parameters for all modes in + which ZFS volumes can be created like - ZFS volume with filesystem, + ZFS Volume exposed as zfs or ZFS volume exposed as raw block device. + Some of the parameters can be only set during creation time (as specified + in the details of the parameter), and a few are editable. In case of + Cloned volumes, the parameters are assigned the same values as the source + volume. + properties: + capacity: + description: Capacity of the volume + minLength: 1 + type: string + compression: + description: 'Compression specifies the block-level compression algorithm + to be applied to the ZFS Volume. The value "on" indicates ZFS to + use the default compression algorithm. The default compression algorithm + used by ZFS will be either lzjb or, if the lz4_compress feature + is enabled, lz4. Compression property can be edited after the volume + has been created. The change will only be applied to the newly-written + data. For instance, if the Volume was created with "off" and the + next day the compression was modified to "on", the data written + prior to setting "on" will not be compressed. Default Value: off.' + pattern: ^(on|off|lzjb|gzip|gzip-[1-9]|zle|lz4)$ + type: string + dedup: + description: 'Deduplication is the process for removing redundant + data at the block level, reducing the total amount of data stored. + If a file system has the dedup property enabled, duplicate data + blocks are removed synchronously. The result is that only unique + data is stored and common components are shared among files. Deduplication + can consume significant processing power (CPU) and memory as well + as generate additional disk IO. Before creating a pool with deduplication + enabled, ensure that you have planned your hardware requirements + appropriately and implemented appropriate recovery practices, such + as regular backups. As an alternative to deduplication consider + using compression=lz4, as a less resource-intensive alternative. + should be enabled on the zvol. Dedup property can be edited after + the volume has been created. Default Value: off.' + enum: + - "on" + - "off" + type: string + encryption: + description: 'Enabling the encryption feature allows for the creation + of encrypted filesystems and volumes. ZFS will encrypt file and + zvol data, file attributes, ACLs, permission bits, directory listings, + FUID mappings, and userused / groupused data. ZFS will not encrypt + metadata related to the pool structure, including dataset and snapshot + names, dataset hierarchy, properties, file size, file holes, and + deduplication tables (though the deduplicated data itself is encrypted). + Default Value: off.' + pattern: ^(on|off|aes-128-[c,g]cm|aes-192-[c,g]cm|aes-256-[c,g]cm)$ + type: string + fsType: + description: 'FsType specifies filesystem type for the zfs volume/dataset. + If FsType is provided as "zfs", then the driver will create a ZFS + dataset, formatting is not required as underlying filesystem is + ZFS anyway. If FsType is ext2, ext3, ext4 or xfs, then the driver + will create a ZVOL and format the volume accordingly. FsType can + not be modified once volume has been provisioned. Default Value: + ext4.' + type: string + keyformat: + description: KeyFormat specifies format of the encryption key The + supported KeyFormats are passphrase, raw, hex. + enum: + - passphrase + - raw + - hex + type: string + keylocation: + description: KeyLocation is the location of key for the encryption + type: string + ownerNodeID: + description: OwnerNodeID is the Node ID where the ZPOOL is running + which is where the volume has been provisioned. OwnerNodeID can + not be edited after the volume has been provisioned. + minLength: 1 + type: string + poolName: + description: poolName specifies the name of the pool where the volume + has been created. PoolName can not be edited after the volume has + been provisioned. + minLength: 1 + type: string + recordsize: + description: 'Specifies a suggested block size for files in the file + system. The size specified must be a power of two greater than or + equal to 512 and less than or equal to 128 Kbytes. RecordSize property + can be edited after the volume has been created. Changing the file + system''s recordsize affects only files created afterward; existing + files are unaffected. Default Value: 128k.' + minLength: 1 + type: string + snapname: + description: SnapName specifies the name of the snapshot where the + volume has been cloned from. Snapname can not be edited after the + volume has been provisioned. + type: string + thinProvision: + description: 'ThinProvision describes whether space reservation for + the source volume is required or not. The value "yes" indicates + that volume should be thin provisioned and "no" means thick provisioning + of the volume. If thinProvision is set to "yes" then volume can + be provisioned even if the ZPOOL does not have the enough capacity. + If thinProvision is set to "no" then volume can be provisioned only + if the ZPOOL has enough capacity and capacity required by volume + can be reserved. ThinProvision can not be modified once volume has + been provisioned. Default Value: no.' + enum: + - "yes" + - "no" + type: string + volblocksize: + description: 'VolBlockSize specifies the block size for the zvol. + The volsize can only be set to a multiple of volblocksize, and cannot + be zero. VolBlockSize can not be edited after the volume has been + provisioned. Default Value: 8k.' + minLength: 1 + type: string + volumeType: + description: volumeType determines whether the volume is of type "DATASET" + or "ZVOL". If fstype provided in the storageclass is "zfs", a volume + of type dataset will be created. If "ext4", "ext3", "ext2" or "xfs" + is mentioned as fstype in the storageclass, then a volume of type + zvol will be created, which will be further formatted as the fstype + provided in the storageclass. VolumeType can not be modified once + volume has been provisioned. + enum: + - ZVOL + - DATASET + type: string + required: + - capacity + - ownerNodeID + - poolName + - volumeType + type: object + status: + description: VolStatus string that specifies the current state of the + volume provisioning request. + properties: + state: + description: State specifies the current state of the volume provisioning + request. The state "Pending" means that the volume creation request + has not processed yet. The state "Ready" means that the volume has + been created and it is ready for the use. + enum: + - Pending + - Ready + type: string + type: object + required: + - spec + type: object + served: true + storage: false + subresources: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/helm/openebs/charts/zfs-localpv/templates/NOTES.txt b/helm/openebs/charts/zfs-localpv/templates/NOTES.txt new file mode 100644 index 0000000..c0454bc --- /dev/null +++ b/helm/openebs/charts/zfs-localpv/templates/NOTES.txt @@ -0,0 +1,5 @@ +The OpenEBS ZFS LocalPV has been installed. Check its status by running: +$ kubectl get pods -n {{ .Release.Namespace }} -l role=openebs-zfs + +For more information, visit our Slack at https://openebs.io/community or view +the documentation online at http://docs.openebs.io/. diff --git a/helm/openebs/charts/zfs-localpv/templates/_helpers.tpl b/helm/openebs/charts/zfs-localpv/templates/_helpers.tpl new file mode 100644 index 0000000..84830c9 --- /dev/null +++ b/helm/openebs/charts/zfs-localpv/templates/_helpers.tpl @@ -0,0 +1,138 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "zfslocalpv.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create a default fully qualified localpv provisioner 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 "zfslocalpv.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 "zfslocalpv.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + + +{{/* +Create the name of the service account for controller +*/}} +{{- define "zfslocalpv.zfsController.serviceAccountName" -}} +{{- if .Values.serviceAccount.zfsController.create }} +{{- default (include "zfslocalpv.fullname" .) .Values.serviceAccount.zfsController.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.zfsController.name }} +{{- end -}} +{{- end -}} + +{{/* +Create the name of the service account to use +*/}} +{{- define "zfslocalpv.zfsNode.serviceAccountName" -}} +{{- if .Values.serviceAccount.zfsNode.create }} +{{- default (include "zfslocalpv.fullname" .) .Values.serviceAccount.zfsNode.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.zfsNode.name }} +{{- end -}} +{{- end -}} + +{{/* +Define meta labels for openebs zfs-localpv components +*/}} +{{- define "zfslocalpv.common.metaLabels" -}} +chart: {{ template "zfslocalpv.chart" . }} +heritage: {{ .Release.Service }} +openebs.io/version: {{ .Values.release.version | quote }} +role: {{ .Values.role | quote }} +{{- end -}} + +{{/* +Create match labels for openebs zfs-localpv controller +*/}} +{{- define "zfslocalpv.zfsController.matchLabels" -}} +app: {{ .Values.zfsController.componentName | quote }} +release: {{ .Release.Name }} +component: {{ .Values.zfsController.componentName | quote }} +{{- end -}} + +{{/* +Create component labels for zfslocalpv controller +*/}} +{{- define "zfslocalpv.zfsController.componentLabels" -}} +openebs.io/component-name: {{ .Values.zfsController.componentName | quote }} +{{- end -}} + + +{{/* +Create labels for openebs zfs-localpv controller +*/}} +{{- define "zfslocalpv.zfsController.labels" -}} +{{ include "zfslocalpv.common.metaLabels" . }} +{{ include "zfslocalpv.zfsController.matchLabels" . }} +{{ include "zfslocalpv.zfsController.componentLabels" . }} +{{- end -}} + +{{/* +Create match labels for openebs zfs-localpv node daemon +*/}} +{{- define "zfslocalpv.zfsNode.matchLabels" -}} +name: {{ .Values.zfsNode.componentName | quote }} +release: {{ .Release.Name }} +{{- end -}} + +{{/* +Create component labels openebs zfs-localpv node daemon +*/}} +{{- define "zfslocalpv.zfsNode.componentLabels" -}} +openebs.io/component-name: {{ .Values.zfsNode.componentName | quote }} +{{- end -}} + + +{{/* +Create labels for openebs zfs-localpv node daemon +*/}} +{{- define "zfslocalpv.zfsNode.labels" -}} +{{ include "zfslocalpv.common.metaLabels" . }} +{{ include "zfslocalpv.zfsNode.matchLabels" . }} +{{ include "zfslocalpv.zfsNode.componentLabels" . }} +{{- end -}} + +{{/* +Create the name of the priority class for csi node plugin +*/}} +{{- define "zfslocalpv.zfsNode.priorityClassName" -}} +{{- if .Values.zfsNode.priorityClass.create }} +{{- printf "%s-%s" .Release.Name .Values.zfsNode.priorityClass.name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s" .Values.zfsNode.priorityClass.name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} + +{{/* +Create the name of the priority class for csi controller plugin +*/}} +{{- define "zfslocalpv.zfsController.priorityClassName" -}} +{{- if .Values.zfsController.priorityClass.create }} +{{- printf "%s-%s" .Release.Name .Values.zfsController.priorityClass.name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s" .Values.zfsController.priorityClass.name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} diff --git a/helm/openebs/charts/zfs-localpv/templates/configmap.yaml b/helm/openebs/charts/zfs-localpv/templates/configmap.yaml new file mode 100644 index 0000000..5f1b334 --- /dev/null +++ b/helm/openebs/charts/zfs-localpv/templates/configmap.yaml @@ -0,0 +1,17 @@ +kind: ConfigMap +apiVersion: v1 +metadata: + name: openebs-zfspv-bin + namespace: {{ .Release.Namespace }} # should be the same namespace where it is getting mounted + labels: + {{- include "zfslocalpv.zfsNode.labels" . | nindent 4 }} +data: + zfs: | + #!/bin/sh + if [ -x /host/sbin/zfs ]; then + chroot /host /sbin/zfs "$@" + elif [ -x /host/usr/sbin/zfs ]; then + chroot /host /usr/sbin/zfs "$@" + else + chroot /host "{{ .Values.zfs.bin }}" "$@" + fi diff --git a/helm/openebs/charts/zfs-localpv/templates/csidriver.yaml b/helm/openebs/charts/zfs-localpv/templates/csidriver.yaml new file mode 100644 index 0000000..c14b146 --- /dev/null +++ b/helm/openebs/charts/zfs-localpv/templates/csidriver.yaml @@ -0,0 +1,10 @@ +# Create the CSI Driver object +apiVersion: storage.k8s.io/v1 +kind: CSIDriver +metadata: + name: zfs.csi.openebs.io +spec: + # do not require volumeattachment + attachRequired: false + podInfoOnMount: false + storageCapacity: {{ .Values.feature.storageCapacity }} diff --git a/helm/openebs/charts/zfs-localpv/templates/priority-class.yaml b/helm/openebs/charts/zfs-localpv/templates/priority-class.yaml new file mode 100644 index 0000000..71ad435 --- /dev/null +++ b/helm/openebs/charts/zfs-localpv/templates/priority-class.yaml @@ -0,0 +1,19 @@ +{{- if .Values.zfsController.priorityClass.create }} +apiVersion: scheduling.k8s.io/v1 +kind: PriorityClass +metadata: + name: {{ template "zfslocalpv.zfsController.priorityClassName" . }} +value: 900000000 +globalDefault: false +description: "This priority class should be used for the CStor CSI driver controller deployment only." +{{- end }} +--- +{{- if .Values.zfsNode.priorityClass.create }} +apiVersion: scheduling.k8s.io/v1 +kind: PriorityClass +metadata: + name: {{ template "zfslocalpv.zfsNode.priorityClassName" . }} +value: 900001000 +globalDefault: false +description: "This priority class should be used for the CStor CSI driver node deployment only." +{{- end }} diff --git a/helm/openebs/charts/zfs-localpv/templates/psp.yaml b/helm/openebs/charts/zfs-localpv/templates/psp.yaml new file mode 100644 index 0000000..33be4dc --- /dev/null +++ b/helm/openebs/charts/zfs-localpv/templates/psp.yaml @@ -0,0 +1,24 @@ +{{- if .Values.rbac.pspEnabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: openebs-zfs-node-psp + labels: + {{- include "zfslocalpv.zfsNode.labels" . | nindent 4 }} +spec: + privileged: true + allowPrivilegeEscalation: true + allowedCapabilities: ['*'] + volumes: ['*'] + hostNetwork: true + hostIPC: true + hostPID: true + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'RunAsAny' + fsGroup: + rule: 'RunAsAny' +{{- end }} diff --git a/helm/openebs/charts/zfs-localpv/templates/rbac.yaml b/helm/openebs/charts/zfs-localpv/templates/rbac.yaml new file mode 100644 index 0000000..c287cde --- /dev/null +++ b/helm/openebs/charts/zfs-localpv/templates/rbac.yaml @@ -0,0 +1,200 @@ +{{- if .Values.serviceAccount.zfsController.create -}} +kind: ServiceAccount +apiVersion: v1 +metadata: + name: {{ .Values.serviceAccount.zfsController.name }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "zfslocalpv.zfsController.labels" . | nindent 4 }} +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: openebs-zfs-provisioner-role + labels: + {{- include "zfslocalpv.zfsController.labels" . | nindent 4 }} +rules: + - apiGroups: [""] + resources: ["secrets"] + verbs: ["get", "list"] + - apiGroups: [""] + resources: ["namespaces"] + verbs: ["*"] + - apiGroups: [""] + resources: ["persistentvolumes", "services"] + verbs: ["get", "list", "watch", "create", "delete", "update", "patch"] + - apiGroups: [""] + resources: ["persistentvolumeclaims"] + verbs: ["get", "list", "watch", "update"] + - apiGroups: [""] + resources: ["persistentvolumeclaims/status"] + verbs: ["update", "patch"] + - apiGroups: ["storage.k8s.io"] + resources: ["storageclasses", "csinodes"] + verbs: ["get", "list", "watch"] + - apiGroups: [ "storage.k8s.io" ] + resources: [ "csistoragecapacities"] + verbs: ["*"] + - apiGroups: [""] + resources: ["events"] + verbs: ["list", "watch", "create", "update", "patch"] + - apiGroups: ["coordination.k8s.io"] + resources: ["leases"] + verbs: ["get", "watch", "list", "delete", "update", "create"] + - apiGroups: [""] + resources: ["nodes"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["pods"] + verbs: ["get", "list", "watch", "update", "patch"] + - apiGroups: [""] + resources: ["pods"] + verbs: ["get", "list", "watch", "update", "patch"] + - apiGroups: ["*"] + resources: ["zfsvolumes", "zfssnapshots", "zfsbackups", "zfsrestores", "zfsnodes"] + verbs: ["*"] +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: openebs-zfs-provisioner-binding + labels: + {{- include "zfslocalpv.zfsController.labels" . | nindent 4 }} +subjects: + - kind: ServiceAccount + name: {{ .Values.serviceAccount.zfsController.name }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: openebs-zfs-provisioner-role + apiGroup: rbac.authorization.k8s.io +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: openebs-zfs-snapshotter-role + labels: + {{- include "zfslocalpv.zfsController.labels" . | nindent 4 }} +rules: + - apiGroups: [""] + resources: ["persistentvolumes"] + verbs: ["get", "list", "watch"] + - apiGroups: [""] + resources: ["persistentvolumeclaims"] + verbs: ["get", "list", "watch"] + - 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: ["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"] + verbs: ["get", "list", "watch", "update", "patch"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshotcontents/status"] + verbs: ["update"] + - apiGroups: ["snapshot.storage.k8s.io"] + resources: ["volumesnapshots/status"] + verbs: ["update"] + - apiGroups: ["apiextensions.k8s.io"] + resources: ["customresourcedefinitions"] + verbs: ["create", "list", "watch", "delete"] +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: openebs-zfs-snapshotter-binding + labels: + {{- include "zfslocalpv.zfsController.labels" . | nindent 4 }} +subjects: + - kind: ServiceAccount + name: {{ .Values.serviceAccount.zfsController.name }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: openebs-zfs-snapshotter-role + apiGroup: rbac.authorization.k8s.io +--- +{{- end }} +{{- if .Values.serviceAccount.zfsNode.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .Values.serviceAccount.zfsNode.name }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "zfslocalpv.zfsNode.labels" . | nindent 4 }} +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: openebs-zfs-driver-registrar-role + labels: + {{- include "zfslocalpv.zfsNode.labels" . | nindent 4 }} +rules: + - apiGroups: [""] + resources: ["events"] + verbs: ["get", "list", "watch", "create", "update", "patch"] + - apiGroups: [""] + resources: ["persistentvolumes", "nodes", "services"] + verbs: ["get", "list"] + - apiGroups: ["*"] + resources: ["zfsvolumes", "zfssnapshots", "zfsbackups", "zfsrestores", "zfsnodes"] + verbs: ["get", "list", "watch", "create", "update", "patch"] +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: openebs-zfs-driver-registrar-binding + labels: + {{- include "zfslocalpv.zfsNode.labels" . | nindent 4 }} +subjects: + - kind: ServiceAccount + name: {{ .Values.serviceAccount.zfsNode.name }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: openebs-zfs-driver-registrar-role + apiGroup: rbac.authorization.k8s.io + +{{- if .Values.rbac.pspEnabled }} +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: openebs-zfs-node-role + labels: + {{- include "zfslocalpv.zfsNode.labels" . | nindent 4 }} +rules: +- apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - openebs-zfs-node-psp +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: openebs-zfs-node-binding + labels: + {{- include "zfslocalpv.zfsNode.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: openebs-zfs-node-role +subjects: + - kind: ServiceAccount + name: {{ .Values.serviceAccount.zfsNode.name }} + namespace: {{ $.Release.Namespace }} +{{- end }} +{{- end }} diff --git a/helm/openebs/charts/zfs-localpv/templates/zfs-contoller.yaml b/helm/openebs/charts/zfs-localpv/templates/zfs-contoller.yaml new file mode 100644 index 0000000..1be7d2a --- /dev/null +++ b/helm/openebs/charts/zfs-localpv/templates/zfs-contoller.yaml @@ -0,0 +1,153 @@ +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ template "zfslocalpv.fullname" . }}-controller + namespace: {{ .Release.Namespace }} + {{- with .Values.zfsController.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "zfslocalpv.zfsController.labels" . | nindent 4 }} +spec: + selector: + matchLabels: + {{- include "zfslocalpv.zfsController.matchLabels" . | nindent 6 }} + serviceName: "{{ .Values.zfsController.serviceName }}" + replicas: {{ .Values.zfsController.replicas }} + template: + metadata: + {{- with .Values.zfsController.podAnnotations }} + annotations: {{ toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "zfslocalpv.zfsController.labels" . | nindent 8 }} + {{- with .Values.zfsController.podLabels}} + {{ toYaml . | nindent 8 }} + {{- end}} + spec: + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: app + operator: In + values: + - openebs-zfs-controller + topologyKey: "kubernetes.io/hostname" +{{- if .Values.zfsController.priorityClass.create }} + priorityClassName: {{ template "zfslocalpv.zfsController.priorityClassName" . }} +{{- end }} + serviceAccountName: {{ .Values.serviceAccount.zfsController.name }} +{{- if .Values.zfsController.initContainers }} + initContainers: +{{- range $key, $value := .Values.zfsController.initContainers }} + - name: {{ $key }} +{{ toYaml $value | indent 10 }} +{{- end }} +{{- end }} + containers: + - name: {{ .Values.zfsController.resizer.name }} + image: "{{ .Values.zfsController.resizer.image.registry }}{{ .Values.zfsController.resizer.image.repository }}:{{ .Values.zfsController.resizer.image.tag }}" + args: + - "--v=5" + - "--csi-address=$(ADDRESS)" + - "--leader-election" + env: + - name: ADDRESS + value: /var/lib/csi/sockets/pluginproxy/csi.sock + imagePullPolicy: {{ .Values.zfsController.resizer.image.pullPolicy }} + volumeMounts: + - name: socket-dir + mountPath: /var/lib/csi/sockets/pluginproxy/ + - name: {{ .Values.zfsController.snapshotter.name }} + image: "{{ .Values.zfsController.snapshotter.image.registry }}{{ .Values.zfsController.snapshotter.image.repository }}:{{ .Values.zfsController.snapshotter.image.tag }}" + imagePullPolicy: {{ .Values.zfsController.snapshotter.image.pullPolicy }} + args: + - "--csi-address=$(ADDRESS)" + - "--leader-election" + env: + - name: ADDRESS + value: /var/lib/csi/sockets/pluginproxy/csi.sock + volumeMounts: + - name: socket-dir + mountPath: /var/lib/csi/sockets/pluginproxy/ + - name: {{ .Values.zfsController.snapshotController.name }} + image: "{{ .Values.zfsController.snapshotController.image.registry }}{{ .Values.zfsController.snapshotController.image.repository }}:{{ .Values.zfsController.snapshotController.image.tag }}" + args: + - "--v=5" + - "--leader-election=true" + imagePullPolicy: {{ .Values.zfsController.snapshotController.image.pullPolicy }} + - name: {{ .Values.zfsController.provisioner.name }} + image: "{{ .Values.zfsController.provisioner.image.registry }}{{ .Values.zfsController.provisioner.image.repository }}:{{ .Values.zfsController.provisioner.image.tag }}" + imagePullPolicy: {{ .Values.zfsController.provisioner.image.pullPolicy }} + args: + - "--csi-address=$(ADDRESS)" + - "--v=5" + - "--feature-gates=Topology=true" + - "--strict-topology" + - "--leader-election" + - "--enable-capacity={{ .Values.feature.storageCapacity }}" + - "--extra-create-metadata=true" + - "--default-fstype=ext4" + env: + - name: ADDRESS + value: /var/lib/csi/sockets/pluginproxy/csi.sock + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + volumeMounts: + - name: socket-dir + mountPath: /var/lib/csi/sockets/pluginproxy/ + - name: {{ .Values.zfsPlugin.name }} + image: "{{ .Values.zfsPlugin.image.registry }}{{ .Values.zfsPlugin.image.repository }}:{{ .Values.zfsPlugin.image.tag }}" + imagePullPolicy: {{ .Values.zfsPlugin.image.pullPolicy }} + env: + - name: OPENEBS_CONTROLLER_DRIVER + value: controller + - name: OPENEBS_CSI_ENDPOINT + value: unix:///var/lib/csi/sockets/pluginproxy/csi.sock + - name: OPENEBS_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: OPENEBS_IO_INSTALLER_TYPE + value: "zfs-localpv-helm" + - name: OPENEBS_IO_ENABLE_ANALYTICS + value: "{{ .Values.analytics.enabled }}" + args : + - "--endpoint=$(OPENEBS_CSI_ENDPOINT)" + - "--plugin=$(OPENEBS_CONTROLLER_DRIVER)" + volumeMounts: + - name: socket-dir + mountPath: /var/lib/csi/sockets/pluginproxy/ + volumes: + - name: socket-dir + emptyDir: {} +{{- if .Values.zfsController.additionalVolumes }} +{{- range $name, $config := .Values.zfsController.additionalVolumes }} + - name: {{ $name }} +{{- tpl (toYaml $config) $ | nindent 10 }} +{{- end }} +{{- end }} +{{- if .Values.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | indent 2 }} +{{- end }} +{{- if .Values.zfsController.nodeSelector }} + nodeSelector: +{{ toYaml .Values.zfsController.nodeSelector | indent 8 }} +{{- end }} +{{- if .Values.zfsController.securityContext }} + securityContext: +{{ toYaml .Values.zfsController.securityContext | indent 8 }} +{{- end }} +{{- if .Values.zfsController.tolerations }} + tolerations: +{{ toYaml .Values.zfsController.tolerations | indent 8 }} +{{- end }} diff --git a/helm/openebs/charts/zfs-localpv/templates/zfs-node.yaml b/helm/openebs/charts/zfs-localpv/templates/zfs-node.yaml new file mode 100644 index 0000000..58762c8 --- /dev/null +++ b/helm/openebs/charts/zfs-localpv/templates/zfs-node.yaml @@ -0,0 +1,164 @@ +kind: DaemonSet +apiVersion: apps/v1 +metadata: + name: {{ template "zfslocalpv.fullname" . }}-node + namespace: {{ .Release.Namespace }} + {{- with .Values.zfsNode.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "zfslocalpv.zfsNode.labels" . | nindent 4 }} +spec: + selector: + matchLabels: + {{- include "zfslocalpv.zfsNode.matchLabels" . | nindent 6 }} + updateStrategy: + rollingUpdate: + maxUnavailable: 100% + type: RollingUpdate + template: + metadata: + {{- with .Values.zfsNode.podAnnotations }} + annotations: {{ toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "zfslocalpv.zfsNode.labels" . | nindent 8 }} + {{- with .Values.zfsNode.podLabels}} + {{ toYaml . | nindent 8 }} + {{- end}} + spec: +{{- if .Values.zfsNode.priorityClass.create }} + priorityClassName: {{ template "zfslocalpv.zfsNode.priorityClassName" . }} +{{- end }} + serviceAccountName: {{ .Values.serviceAccount.zfsNode.name }} + hostNetwork: true +{{- if .Values.zfsNode.initContainers }} + initContainers: +{{- range $key, $value := .Values.zfsNode.initContainers }} + - name: {{ $key }} +{{ toYaml $value | indent 10 }} +{{- end }} +{{- end }} + containers: + - name: {{ .Values.zfsNode.driverRegistrar.name }} + image: "{{ .Values.zfsNode.driverRegistrar.image.registry }}{{ .Values.zfsNode.driverRegistrar.image.repository }}:{{ .Values.zfsNode.driverRegistrar.image.tag }}" + imagePullPolicy: {{ .Values.zfsNode.driverRegistrar.image.pullPolicy }} + args: + - "--v=5" + - "--csi-address=$(ADDRESS)" + - "--kubelet-registration-path=$(DRIVER_REG_SOCK_PATH)" + lifecycle: + preStop: + exec: + command: ["/bin/sh", "-c", "rm -rf /registration/zfs-localpv /registration/zfs-localpv-reg.sock"] + env: + - name: ADDRESS + value: /plugin/csi.sock + - name: DRIVER_REG_SOCK_PATH + value: {{ .Values.zfsNode.kubeletDir }}plugins/zfs-localpv/csi.sock + - name: KUBE_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: NODE_DRIVER + value: openebs-zfs + volumeMounts: + - name: plugin-dir + mountPath: /plugin + - name: registration-dir + mountPath: /registration + - name: {{ .Values.zfsPlugin.name }} + securityContext: + privileged: true + allowPrivilegeEscalation: true + image: "{{ .Values.zfsPlugin.image.registry }}{{ .Values.zfsPlugin.image.repository }}:{{ .Values.zfsPlugin.image.tag }}" + imagePullPolicy: {{ .Values.zfsPlugin.image.pullPolicy }} + args: + - "--nodename=$(OPENEBS_NODE_NAME)" + - "--endpoint=$(OPENEBS_CSI_ENDPOINT)" + - "--plugin=$(OPENEBS_NODE_DRIVER)" + env: + - name: OPENEBS_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: OPENEBS_CSI_ENDPOINT + value: unix:///plugin/csi.sock + - name: OPENEBS_NODE_DRIVER + value: agent + - name: OPENEBS_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: ALLOWED_TOPOLOGIES + value: "{{ .Values.zfsNode.allowedTopologyKeys }}" + volumeMounts: + - name: plugin-dir + mountPath: /plugin + - name: device-dir + mountPath: /dev + - name: encr-keys + mountPath: /home/keys + - name: chroot-zfs + mountPath: /sbin/zfs + subPath: zfs + - name: host-root + mountPath: /host + mountPropagation: "HostToContainer" + readOnly: true + - name: pods-mount-dir + mountPath: {{ .Values.zfsNode.kubeletDir }} + # needed so that any mounts setup inside this container are + # propagated back to the host machine. + mountPropagation: "Bidirectional" + volumes: + - name: device-dir + hostPath: + path: /dev + type: Directory + - name: encr-keys + hostPath: + path: /home/keys + type: DirectoryOrCreate + - name: chroot-zfs + configMap: + defaultMode: 0555 + name: openebs-zfspv-bin + - name: host-root + hostPath: + path: / + type: Directory + - name: registration-dir + hostPath: + path: {{ .Values.zfsNode.kubeletDir }}plugins_registry/ + type: DirectoryOrCreate + - name: plugin-dir + hostPath: + path: {{ .Values.zfsNode.kubeletDir }}plugins/zfs-localpv/ + type: DirectoryOrCreate + - name: pods-mount-dir + hostPath: + path: {{ .Values.zfsNode.kubeletDir }} + type: Directory +{{- if .Values.zfsNode.additionalVolumes }} +{{- range $name, $config := .Values.zfsNode.additionalVolumes }} + - name: {{ $name }} +{{- tpl (toYaml $config) $ | nindent 10 }} +{{- end }} +{{- end }} +{{- if .Values.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.imagePullSecrets | indent 2 }} +{{- end }} +{{- if .Values.zfsNode.nodeSelector }} + nodeSelector: +{{ toYaml .Values.zfsNode.nodeSelector | indent 8 }} +{{- end }} +{{- if .Values.zfsNode.securityContext }} + securityContext: +{{ toYaml .Values.zfsNode.securityContext | indent 8 }} +{{- end }} +{{- if .Values.zfsNode.tolerations }} + tolerations: +{{ toYaml .Values.zfsNode.tolerations | indent 8 }} +{{- end }} diff --git a/helm/openebs/charts/zfs-localpv/values.yaml b/helm/openebs/charts/zfs-localpv/values.yaml new file mode 100644 index 0000000..ae0e21d --- /dev/null +++ b/helm/openebs/charts/zfs-localpv/values.yaml @@ -0,0 +1,172 @@ +# Default values for openebs-zfslocalpv. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. +release: + version: "2.3.1" + +imagePullSecrets: +# - name: "image-pull-secret" + +feature: + # enable storage capacity tracking feature + # Ref: https://kubernetes:io/docs/concepts/storage/storage-capacity + storageCapacity: true + +rbac: + # rbac.pspEnabled: `true` if PodSecurityPolicy resources should be created + pspEnabled: false + +# zfsNode contains the configurables for +# the zfs node daemonset +zfsNode: + componentName: openebs-zfs-node + driverRegistrar: + name: "csi-node-driver-registrar" + image: + # Make sure that registry name end with a '/'. + # For example : registry.k8s.io/ is a correct value here and quay.io is incorrect + registry: registry.k8s.io/ + repository: sig-storage/csi-node-driver-registrar + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: v2.8.0 + updateStrategy: + type: RollingUpdate + annotations: {} + podAnnotations: {} + resources: {} + # This can be configured to run on various different k8s distributions like + # microk8s where kubelet dir is different + kubeletDir: "/var/lib/kubelet/" + # limits: + # cpu: 10m + # memory: 32Mi + # requests: + # cpu: 10m + # memory: 32Mi + ## Labels to be added to openebs-zfs node pods + podLabels: {} + nodeSelector: {} + tolerations: [] + securityContext: {} + labels: {} + priorityClass: + create: true + name: zfs-csi-node-critical + # allowed topologykeys for csi driver + # The desired comma separated keys can be added here, + # by default all the node label keys are allowed. + # For example: + # allowedTopologyKeys: "kubernetes.io/hostname,openebs.io/rack" + allowedTopologyKeys: "All" + initContainers: [] + additionalVolumes: [] + +# zfsController contains the configurables for +# the zfs controller statefulset +zfsController: + componentName: openebs-zfs-controller + initContainers: [] + additionalVolumes: [] + replicas: 1 + serviceName: openebs-zfs + resizer: + name: "csi-resizer" + image: + # Make sure that registry name end with a '/'. + # For example : registry.k8s.io/ is a correct value here and quay.io is incorrect + registry: registry.k8s.io/ + repository: sig-storage/csi-resizer + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: v1.8.0 + snapshotter: + name: "csi-snapshotter" + image: + # Make sure that registry name end with a '/'. + # For example : registry.k8s.io/ is a correct value here and quay.io is incorrect + registry: registry.k8s.io/ + repository: sig-storage/csi-snapshotter + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: v6.2.2 + snapshotController: + name: "snapshot-controller" + image: + # Make sure that registry name end with a '/'. + # For example : registry.k8s.io/ is a correct value here and quay.io is incorrect + registry: registry.k8s.io/ + repository: sig-storage/snapshot-controller + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: v6.2.2 + provisioner: + name: "csi-provisioner" + image: + # Make sure that registry name end with a '/'. + # For example : registry.k8s.io/ is a correct value here and quay.io is incorrect + registry: registry.k8s.io/ + repository: sig-storage/csi-provisioner + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: v3.5.0 + updateStrategy: + type: RollingUpdate + annotations: {} + podAnnotations: {} + resources: {} + # limits: + # cpu: 10m + # memory: 32Mi + # requests: + # cpu: 10m + # memory: 32Mi + ## Labels to be added to openebs-zfs controller pods + podLabels: + name: openebs-zfs-controller + nodeSelector: {} + tolerations: [] + securityContext: {} + priorityClass: + create: true + name: zfs-csi-controller-critical + + +# zfsPlugin is the common csi container used by the +# controller statefulset and node daemonset +zfsPlugin: + name: "openebs-zfs-plugin" + image: + # Make sure that registry name end with a '/'. + # For example : registry.k8s.io/ is a correct value here and quay.io is incorrect + registry: + repository: openebs/zfs-driver + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: 2.3.0 + +role: openebs-zfs + +crd: + enableInstall: true + +serviceAccount: + zfsController: + # Specifies whether a service account should be created + create: true + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: openebs-zfs-controller-sa + zfsNode: + # Specifies whether a service account should be created + create: true + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: openebs-zfs-node-sa + +analytics: + enabled: true +zfs: + # If you use a non-standard path to the zfs binary, specify it here + # bin: /run/current-system/sw/bin/zfs + bin: zfs diff --git a/helm/openebs/crds/blockdevice.yaml b/helm/openebs/crds/blockdevice.yaml new file mode 100644 index 0000000..95f4070 --- /dev/null +++ b/helm/openebs/crds/blockdevice.yaml @@ -0,0 +1,241 @@ + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.5.0 + creationTimestamp: null + name: blockdevices.openebs.io +spec: + group: openebs.io + names: + kind: BlockDevice + listKind: BlockDeviceList + plural: blockdevices + shortNames: + - bd + singular: blockdevice + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.nodeAttributes.nodeName + name: NodeName + type: string + - jsonPath: .spec.path + name: Path + priority: 1 + type: string + - jsonPath: .spec.filesystem.fsType + name: FSType + priority: 1 + type: string + - jsonPath: .spec.capacity.storage + name: Size + type: string + - jsonPath: .status.claimState + name: ClaimState + type: string + - jsonPath: .status.state + name: Status + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: BlockDevice is the Schema for the blockdevices 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: DeviceSpec defines the properties and runtime status of a BlockDevice + properties: + aggregateDevice: + description: AggregateDevice was intended to store the hierarchical information in cases of LVM. However this is currently not implemented and may need to be re-looked into for better design. To be deprecated + type: string + capacity: + description: Capacity + properties: + logicalSectorSize: + description: LogicalSectorSize is blockdevice logical-sector size in bytes + format: int32 + type: integer + physicalSectorSize: + description: PhysicalSectorSize is blockdevice physical-Sector size in bytes + format: int32 + type: integer + storage: + description: Storage is the blockdevice capacity in bytes + format: int64 + type: integer + required: + - storage + type: object + claimRef: + description: ClaimRef is the reference to the BDC which has claimed this BD + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: 'If referring to a piece of an object instead of an entire object, this string should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. For example, if the object reference is to a container within a pod, this would take on a value like: "spec.containers{name}" (where "name" refers to the name of the container that triggered the event) or if no container name is specified "spec.containers[2]" (container with index 2 in this pod). This syntax is chosen only to have some well-defined way of referencing a part of an object. TODO: this design is not final and this field is subject to change in the future.' + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: 'Specific resourceVersion to which this reference is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + details: + description: Details contain static attributes of BD like model,serial, and so forth + properties: + compliance: + description: Compliance is standards/specifications version implemented by device firmware such as SPC-1, SPC-2, etc + type: string + deviceType: + description: DeviceType represents the type of device like sparse, disk, partition, lvm, crypt + enum: + - disk + - partition + - sparse + - loop + - lvm + - crypt + - dm + - mpath + type: string + driveType: + description: DriveType is the type of backing drive, HDD/SSD + enum: + - HDD + - SSD + - Unknown + - "" + type: string + firmwareRevision: + description: FirmwareRevision is the disk firmware revision + type: string + hardwareSectorSize: + description: HardwareSectorSize is the hardware sector size in bytes + format: int32 + type: integer + logicalBlockSize: + description: LogicalBlockSize is the logical block size in bytes reported by /sys/class/block/sda/queue/logical_block_size + format: int32 + type: integer + model: + description: Model is model of disk + type: string + physicalBlockSize: + description: PhysicalBlockSize is the physical block size in bytes reported by /sys/class/block/sda/queue/physical_block_size + format: int32 + type: integer + serial: + description: Serial is serial number of disk + type: string + vendor: + description: Vendor is vendor of disk + type: string + type: object + devlinks: + description: DevLinks contains soft links of a block device like /dev/by-id/... /dev/by-uuid/... + items: + description: DeviceDevLink holds the mapping between type and links like by-id type or by-path type link + properties: + kind: + description: Kind is the type of link like by-id or by-path. + enum: + - by-id + - by-path + type: string + links: + description: Links are the soft links + items: + type: string + type: array + type: object + type: array + filesystem: + description: FileSystem contains mountpoint and filesystem type + properties: + fsType: + description: Type represents the FileSystem type of the block device + type: string + mountPoint: + description: MountPoint represents the mountpoint of the block device. + type: string + type: object + nodeAttributes: + description: NodeAttributes has the details of the node on which BD is attached + properties: + nodeName: + description: NodeName is the name of the Kubernetes node resource on which the device is attached + type: string + type: object + parentDevice: + description: "ParentDevice was intended to store the UUID of the parent Block Device as is the case for partitioned block devices. \n For example: /dev/sda is the parent for /dev/sda1 To be deprecated" + type: string + partitioned: + description: Partitioned represents if BlockDevice has partitions or not (Yes/No) Currently always default to No. To be deprecated + enum: + - "Yes" + - "No" + type: string + path: + description: Path contain devpath (e.g. /dev/sdb) + type: string + required: + - capacity + - devlinks + - nodeAttributes + - path + type: object + status: + description: DeviceStatus defines the observed state of BlockDevice + properties: + claimState: + description: ClaimState represents the claim state of the block device + enum: + - Claimed + - Unclaimed + - Released + type: string + state: + description: State is the current state of the blockdevice (Active/Inactive/Unknown) + enum: + - Active + - Inactive + - Unknown + type: string + required: + - claimState + - state + type: object + type: object + served: true + storage: true + subresources: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/helm/openebs/crds/blockdeviceclaim.yaml b/helm/openebs/crds/blockdeviceclaim.yaml new file mode 100644 index 0000000..81b9a35 --- /dev/null +++ b/helm/openebs/crds/blockdeviceclaim.yaml @@ -0,0 +1,144 @@ + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.5.0 + creationTimestamp: null + name: blockdeviceclaims.openebs.io +spec: + group: openebs.io + names: + kind: BlockDeviceClaim + listKind: BlockDeviceClaimList + plural: blockdeviceclaims + shortNames: + - bdc + singular: blockdeviceclaim + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.blockDeviceName + name: BlockDeviceName + type: string + - jsonPath: .status.phase + name: Phase + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: BlockDeviceClaim is the Schema for the blockdeviceclaims 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: DeviceClaimSpec defines the request details for a BlockDevice + properties: + blockDeviceName: + description: BlockDeviceName is the reference to the block-device backing this claim + type: string + blockDeviceNodeAttributes: + description: BlockDeviceNodeAttributes is the attributes on the node from which a BD should be selected for this claim. It can include nodename, failure domain etc. + properties: + hostName: + description: HostName represents the hostname of the Kubernetes node resource where the BD should be present + type: string + nodeName: + description: NodeName represents the name of the Kubernetes node resource where the BD should be present + type: string + type: object + deviceClaimDetails: + description: Details of the device to be claimed + properties: + allowPartition: + description: AllowPartition represents whether to claim a full block device or a device that is a partition + type: boolean + blockVolumeMode: + description: 'BlockVolumeMode represents whether to claim a device in Block mode or Filesystem mode. These are use cases of BlockVolumeMode: 1) Not specified: VolumeMode check will not be effective 2) VolumeModeBlock: BD should not have any filesystem or mountpoint 3) VolumeModeFileSystem: BD should have a filesystem and mountpoint. If DeviceFormat is specified then the format should match with the FSType in BD' + type: string + formatType: + description: Format of the device required, eg:ext4, xfs + type: string + type: object + deviceType: + description: DeviceType represents the type of drive like SSD, HDD etc., + nullable: true + type: string + hostName: + description: Node name from where blockdevice has to be claimed. To be deprecated. Use NodeAttributes.HostName instead + type: string + resources: + description: Resources will help with placing claims on Capacity, IOPS + properties: + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum resources required. eg: if storage resource of 10G is requested minimum capacity of 10G should be available TODO for validating' + type: object + required: + - requests + type: object + selector: + description: Selector is used to find block devices to be considered for claiming + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + type: object + status: + description: DeviceClaimStatus defines the observed state of BlockDeviceClaim + properties: + phase: + description: Phase represents the current phase of the claim + type: string + required: + - phase + type: object + type: object + served: true + storage: true + subresources: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/helm/openebs/override_values.yaml b/helm/openebs/override_values.yaml new file mode 100644 index 0000000..d29f625 --- /dev/null +++ b/helm/openebs/override_values.yaml @@ -0,0 +1,14 @@ +# Directory used by the OpenEBS to store debug information and so forth +# that are generated in the course of running OpenEBS containers. +varDirectoryPath: + baseDir: "/mnt/openebs" + +localprovisioner: + basePath: "/mnt/openebs/local" + + hostpathClass: + reclaimPolicy: Retain + +ndm: + sparse: + path: "/openebs/sparse" diff --git a/helm/openebs/templates/NOTES.txt b/helm/openebs/templates/NOTES.txt new file mode 100644 index 0000000..64a9645 --- /dev/null +++ b/helm/openebs/templates/NOTES.txt @@ -0,0 +1,53 @@ + +Successfully installed OpenEBS. + +Check the status by running: kubectl get pods -n {{ .Release.Namespace }} + +The default values will install NDM and enable OpenEBS hostpath and device +storage engines along with their default StorageClasses. Use `kubectl get sc` +to see the list of installed OpenEBS StorageClasses. + +**Note**: If you are upgrading from the older helm chart that was using cStor +and Jiva (non-csi) volumes, you will have to run the following command to include +the older provisioners: + +helm upgrade {{ .Release.Name }} openebs/openebs \ + --namespace {{ .Release.Namespace }} \ + --set legacy.enabled=true \ + --reuse-values + +For other engines, you will need to perform a few more additional steps to +enable the engine, configure the engines (e.g. creating pools) and create +StorageClasses. + +For example, cStor can be enabled using commands like: + +helm upgrade {{ .Release.Name }} openebs/openebs \ + --namespace {{ .Release.Namespace }} \ + --set cstor.enabled=true \ + --reuse-values + +For more information, +- view the online documentation at https://openebs.io/docs or +- connect with an active community on Kubernetes slack #openebs channel. +{{- /* +The section below can be removed once enableDeviceClass and enableHostpathClass +options are removed. +*/}} +{{ if or (eq .Values.localprovisioner.enableHostpathClass false) (eq .Values.localprovisioner.enableDeviceClass false) }} + +DEPRECATION NOTICE: +------------------- +The options 'enableHostpathClass' and 'enableDeviceClass' are deprecated and +will be removed in future releases. + +Please use the options hostpathClass.enabled and deviceClass.enabled instead. + +Example: + +helm install {{ .Release.Name }} openebs/openebs \ + --namespace {{ .Release.Namespace }} \ + --set localprovisioner.deviceClass.enabled="false" + +{{ end }} + diff --git a/helm/openebs/templates/_helpers.tpl b/helm/openebs/templates/_helpers.tpl new file mode 100644 index 0000000..09a9f4c --- /dev/null +++ b/helm/openebs/templates/_helpers.tpl @@ -0,0 +1,160 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "openebs.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 "openebs.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 "openebs.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create the name of the service account to use +*/}} +{{- define "openebs.serviceAccountName" -}} +{{- if .Values.serviceAccount.create -}} + {{ default (include "openebs.fullname" .) .Values.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.serviceAccount.name }} +{{- end -}} +{{- end -}} + + +{{/* +Define meta labels for openebs components +*/}} +{{- define "openebs.common.metaLabels" -}} +chart: {{ template "openebs.chart" . }} +heritage: {{ .Release.Service }} +openebs.io/version: {{ .Values.release.version | quote }} +{{- end -}} + + +{{- define "openebs.ndm-cluster-exporter.name" -}} +{{- $ndmName := default .Chart.Name .Values.ndmExporter.clusterExporter.nameOverride | trunc 63 | trimSuffix "-" }} +{{- $componentName := .Values.ndmExporter.clusterExporter.name | trunc 63 | trimSuffix "-" }} +{{- printf "%s-%s" $ndmName $componentName | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified ndm cluster exporter 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 "openebs.ndm-cluster-exporter.fullname" -}} +{{- if .Values.ndmExporter.clusterExporter.fullnameOverride }} +{{- .Values.ndmExporter.clusterExporter.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $ndmClusterExporterName := include "openebs.ndm-cluster-exporter.name" .}} + +{{- $name := default $ndmClusterExporterName .Values.ndmExporter.clusterExporter.nameOverride }} +{{- if contains .Release.Name $name }} +{{- $name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{- define "openebs.ndm-node-exporter.name" -}} +{{- $ndmName := default .Chart.Name .Values.ndmExporter.nodeExporter.nameOverride | trunc 63 | trimSuffix "-" }} +{{- $componentName := .Values.ndmExporter.nodeExporter.name | trunc 63 | trimSuffix "-" }} +{{- printf "%s-%s" $ndmName $componentName | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified ndm node exporter 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 "openebs.ndm-node-exporter.fullname" -}} +{{- if .Values.ndmExporter.nodeExporter.fullnameOverride }} +{{- .Values.ndmExporter.nodeExporter.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $ndmNodeExporterName := include "openebs.ndm-node-exporter.name" .}} + +{{- $name := default $ndmNodeExporterName .Values.ndmExporter.nodeExporter.nameOverride }} +{{- if contains .Release.Name $name }} +{{- $name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create match labels for ndm cluster exporter deployment +*/}} +{{- define "openebs.ndm-cluster-exporter.matchLabels" -}} +app: {{ template "openebs.ndm-cluster-exporter.name" . }} +release: {{ .Release.Name }} +component: {{ default (include "openebs.ndm-cluster-exporter.name" .) .Values.ndmExporter.clusterExporter.componentName }} +{{- end -}} + +{{/* +Create component labels for ndm cluster exporter component +*/}} +{{- define "openebs.ndm-cluster-exporter.componentLabels" -}} +name: {{ template "openebs.ndm-node-exporter.name" . }} +openebs.io/component-name: {{ default (include "openebs.ndm-cluster-exporter.name" .) .Values.ndmExporter.clusterExporter.componentName }} +{{- end -}} + + +{{/* +Create labels for ndm cluster exporter component +*/}} +{{- define "openebs.ndm-cluster-exporter.labels" -}} +{{ include "openebs.common.metaLabels" . }} +{{ include "openebs.ndm-cluster-exporter.matchLabels" . }} +{{ include "openebs.ndm-cluster-exporter.componentLabels" . }} +{{- end -}} + +{{/* +Create match labels for ndm node exporter deployment +*/}} +{{- define "openebs.ndm-node-exporter.matchLabels" -}} +app: {{ template "openebs.ndm-node-exporter.name" . }} +release: {{ .Release.Name }} +component: {{ default (include "openebs.ndm-node-exporter.name" .) .Values.ndmExporter.nodeExporter.componentName }} +{{- end -}} + +{{/* +Create component labels for ndm node exporter component +*/}} +{{- define "openebs.ndm-node-exporter.componentLabels" -}} +name: {{ template "openebs.ndm-node-exporter.name" . }} +openebs.io/component-name: {{ default (include "openebs.ndm-node-exporter.name" .) .Values.ndmExporter.nodeExporter.componentName }} +{{- end -}} + + +{{/* +Create labels for ndm cluster node component +*/}} +{{- define "openebs.ndm-node-exporter.labels" -}} +{{ include "openebs.common.metaLabels" . }} +{{ include "openebs.ndm-node-exporter.matchLabels" . }} +{{ include "openebs.ndm-node-exporter.componentLabels" . }} +{{- end -}} diff --git a/helm/openebs/templates/clusterrole.yaml b/helm/openebs/templates/clusterrole.yaml new file mode 100644 index 0000000..3a8d3ce --- /dev/null +++ b/helm/openebs/templates/clusterrole.yaml @@ -0,0 +1,50 @@ +{{- if .Values.rbac.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "openebs.fullname" . }} + labels: + app: {{ template "openebs.name" . }} + chart: {{ template "openebs.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +rules: +- apiGroups: ["*"] + resources: ["nodes", "nodes/proxy"] + verbs: ["*"] +- apiGroups: ["*"] + resources: ["namespaces", "services", "pods", "pods/exec", "deployments", "deployments/finalizers", "replicationcontrollers", "replicasets", "events", "endpoints", "configmaps", "secrets", "jobs", "cronjobs" ] + verbs: ["*"] +- apiGroups: ["*"] + resources: ["statefulsets", "daemonsets"] + verbs: ["*"] +- apiGroups: ["*"] + resources: ["resourcequotas", "limitranges"] + verbs: ["list", "watch"] +- apiGroups: ["*"] + resources: ["ingresses", "horizontalpodautoscalers", "verticalpodautoscalers", "poddisruptionbudgets", "certificatesigningrequests"] + verbs: ["list", "watch"] +- apiGroups: ["*"] + resources: ["storageclasses", "persistentvolumeclaims", "persistentvolumes"] + verbs: ["*"] +- apiGroups: ["volumesnapshot.external-storage.k8s.io"] + resources: ["volumesnapshots", "volumesnapshotdatas"] + verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] +- apiGroups: ["apiextensions.k8s.io"] + resources: ["customresourcedefinitions"] + verbs: [ "get", "list", "create", "update", "delete", "patch"] +- apiGroups: ["openebs.io"] + resources: [ "*"] + verbs: ["*" ] +- apiGroups: ["cstor.openebs.io"] + resources: [ "*"] + verbs: ["*" ] +- apiGroups: ["coordination.k8s.io"] + resources: ["leases"] + verbs: ["get", "watch", "list", "delete", "update", "create"] +- apiGroups: ["admissionregistration.k8s.io"] + resources: ["validatingwebhookconfigurations", "mutatingwebhookconfigurations"] + verbs: ["get", "create", "list", "delete", "update", "patch"] +- nonResourceURLs: ["/metrics"] + verbs: ["get"] +{{- end }} diff --git a/helm/openebs/templates/clusterrolebinding.yaml b/helm/openebs/templates/clusterrolebinding.yaml new file mode 100644 index 0000000..0ada25c --- /dev/null +++ b/helm/openebs/templates/clusterrolebinding.yaml @@ -0,0 +1,19 @@ +{{- if .Values.rbac.create }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "openebs.fullname" . }} + labels: + app: {{ template "openebs.name" . }} + chart: {{ template "openebs.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "openebs.fullname" . }} +subjects: +- kind: ServiceAccount + name: {{ template "openebs.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +{{- end }} diff --git a/helm/openebs/templates/kyverno/allow-capabilities.yaml b/helm/openebs/templates/kyverno/allow-capabilities.yaml new file mode 100644 index 0000000..5f11254 --- /dev/null +++ b/helm/openebs/templates/kyverno/allow-capabilities.yaml @@ -0,0 +1,30 @@ +{{- if .Values.rbac.kyvernoEnabled }} +apiVersion: kyverno.io/v1 +kind: Policy +metadata: + name: allow-add-capabilities + annotations: + policies.kyverno.io/category: Pod Security Standards + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: Pod + policies.kyverno.io/description: >- + Provides a list of capabilities that are allowed to be added to a container. +spec: + validationFailureAction: enforce + background: true + rules: + - name: capabilities + match: + resources: + kinds: + - Pod + validate: + message: >- + Default set of capabilities are allowed. + pattern: + spec: + containers: + - =(securityContext): + =(capabilities): + =(add): "*" +{{- end }} \ No newline at end of file diff --git a/helm/openebs/templates/kyverno/allow-host-namespaces.yaml b/helm/openebs/templates/kyverno/allow-host-namespaces.yaml new file mode 100644 index 0000000..527178d --- /dev/null +++ b/helm/openebs/templates/kyverno/allow-host-namespaces.yaml @@ -0,0 +1,32 @@ +{{- if .Values.rbac.kyvernoEnabled }} +apiVersion: kyverno.io/v1 +kind: Policy +metadata: + name: allow-host-namespaces + annotations: + policies.kyverno.io/category: Pod Security Standards + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: Pod + policies.kyverno.io/description: >- + Host namespaces (Process ID namespace, Inter-Process Communication namespace, and + network namespace) allow access to shared information and can be used to elevate + privileges. Pods should allowed access to host namespaces. +spec: + validationFailureAction: enforce + background: true + rules: + - name: host-namespaces + match: + resources: + kinds: + - Pod + validate: + message: >- + Sharing the host namespaces is allowed. The fields spec.hostNetwork, + spec.hostIPC, and spec.hostPID must be set to true. + pattern: + spec: + =(hostPID): "true" + =(hostIPC): "true" + =(hostNetwork): "true" +{{- end }} \ No newline at end of file diff --git a/helm/openebs/templates/kyverno/allow-host-ports.yaml b/helm/openebs/templates/kyverno/allow-host-ports.yaml new file mode 100644 index 0000000..477b594 --- /dev/null +++ b/helm/openebs/templates/kyverno/allow-host-ports.yaml @@ -0,0 +1,31 @@ +{{- if .Values.rbac.kyvernoEnabled }} +apiVersion: kyverno.io/v1 +kind: Policy +metadata: + name: allow-host-ports + annotations: + policies.kyverno.io/category: Pod Security Standards (Privileged) + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: Pod + policies.kyverno.io/description: >- + Access to host ports allows potential snooping of network traffic and should be + allowed, or at minimum restricted to a known list. +spec: + validationFailureAction: enforce + background: true + rules: + - name: host-ports + match: + resources: + kinds: + - Pod + validate: + message: >- + Use of host ports is allowed. The fields spec.containers[*].ports[*].hostPort + should contain value in range [1,65535). + pattern: + spec: + containers: + - =(ports): + - =(hostPort): ">0 & <65535" +{{- end }} \ No newline at end of file diff --git a/helm/openebs/templates/kyverno/allow-privilege-escalation.yaml b/helm/openebs/templates/kyverno/allow-privilege-escalation.yaml new file mode 100644 index 0000000..323ad65 --- /dev/null +++ b/helm/openebs/templates/kyverno/allow-privilege-escalation.yaml @@ -0,0 +1,30 @@ +{{- if .Values.rbac.kyvernoEnabled }} +apiVersion: kyverno.io/v1 +kind: Policy +metadata: + name: allow-privileged-escalation + annotations: + policies.kyverno.io/category: Pod Security Standards (Privileged) + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: Pod + policies.kyverno.io/description: >- + Privilege escalation, such as via set-user-ID or set-group-ID file mode, should be allowed. +spec: + validationFailureAction: enforce + background: true + rules: + - name: priviledged-escalation + match: + resources: + kinds: + - Pod + validate: + message: >- + Privilege escalation is allowed. The fields spec.containers[*].securityContext.allowPrivilegeEscalation + must be defined or set to `true`. + pattern: + spec: + containers: + - =(securityContext): + =(allowPrivilegeEscalation): "true" +{{- end }} \ No newline at end of file diff --git a/helm/openebs/templates/kyverno/allow-privileged-containers.yaml b/helm/openebs/templates/kyverno/allow-privileged-containers.yaml new file mode 100644 index 0000000..699c9ab --- /dev/null +++ b/helm/openebs/templates/kyverno/allow-privileged-containers.yaml @@ -0,0 +1,30 @@ +{{- if .Values.rbac.kyvernoEnabled }} +apiVersion: kyverno.io/v1 +kind: Policy +metadata: + name: allow-privileged-containers + annotations: + policies.kyverno.io/category: Pod Security Standards (Privileged) + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: Pod + policies.kyverno.io/description: >- + Privileged policies only allow the OpenEBS containers to use privileged mode. +spec: + validationFailureAction: enforce + background: true + rules: + - name: priviledged-containers + match: + resources: + kinds: + - Pod + validate: + message: >- + Privileged mode is allowed. The fields spec.containers[*].securityContext.privileged + must be defined or set to true. + pattern: + spec: + containers: + - =(securityContext): + =(privileged): "true" +{{- end }} \ No newline at end of file diff --git a/helm/openebs/templates/kyverno/allow-proc-mount.yaml b/helm/openebs/templates/kyverno/allow-proc-mount.yaml new file mode 100644 index 0000000..76a2a00 --- /dev/null +++ b/helm/openebs/templates/kyverno/allow-proc-mount.yaml @@ -0,0 +1,31 @@ +{{- if .Values.rbac.kyvernoEnabled }} +apiVersion: kyverno.io/v1 +kind: Policy +metadata: + name: require-default-proc-mount + annotations: + policies.kyverno.io/category: Pod Security Standards (Baseline) + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: Pod + policies.kyverno.io/description: >- + The default /proc masks are set up to reduce attack surface and should be required. +spec: + validationFailureAction: enforce + background: true + rules: + - name: check-proc-mount + match: + resources: + kinds: + - Pod + validate: + message: >- + Changing the proc mount from the default is not allowed. The fields + spec.containers[*].securityContext.procMount should be defined or set + to Default + pattern: + spec: + containers: + - =(securityContext): + =(procMount): "Default" +{{- end }} \ No newline at end of file diff --git a/helm/openebs/templates/kyverno/allow-selinux.yaml b/helm/openebs/templates/kyverno/allow-selinux.yaml new file mode 100644 index 0000000..bbf6c30 --- /dev/null +++ b/helm/openebs/templates/kyverno/allow-selinux.yaml @@ -0,0 +1,34 @@ +{{- if .Values.rbac.kyvernoEnabled }} +apiVersion: kyverno.io/v1 +kind: Policy +metadata: + name: allow-selinux + annotations: + policies.kyverno.io/title: Allow SELinux + policies.kyverno.io/category: Pod Security Standards (Baseline) + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: Pod + policies.kyverno.io/description: >- + SELinux options can be used to escalate privileges and should be allowed. +spec: + validationFailureAction: enforce + background: true + rules: + - name: seLinux + match: + resources: + kinds: + - Pod + validate: + message: >- + Setting custom SELinux options is allowed. The fields + spec.securityContext.seLinuxOptions, spec.containers[*].securityContext.seLinuxOptions, + and spec.initContainers[*].securityContext.seLinuxOptions must be empty. + pattern: + spec: + =(securityContext): + =(seLinuxOptions): "on" + containers: + - =(securityContext): + =(seLinuxOptions): "on" +{{- end }} \ No newline at end of file diff --git a/helm/openebs/templates/kyverno/require-user-groups.yaml b/helm/openebs/templates/kyverno/require-user-groups.yaml new file mode 100644 index 0000000..4683f28 --- /dev/null +++ b/helm/openebs/templates/kyverno/require-user-groups.yaml @@ -0,0 +1,56 @@ +{{- if .Values.rbac.kyvernoEnabled }} +apiVersion: kyverno.io/v1 +kind: Policy +metadata: + name: require-user-groups + annotations: + policies.kyverno.io/category: Pod Security Standards (Privileged) + policies.kyverno.io/severity: medium + policies.kyverno.io/subject: Pod + policies.kyverno.io/description: >- + Containers should allow to run with a root primary or supplementary GID. +spec: + validationFailureAction: enforce + background: true + rules: + - name: check-runasuser + match: + resources: + kinds: + - Pod + validate: + message: >- + Running the user IDs are allowed. + pattern: + spec: + =(securityContext): + =(runAsUser): ">=0" + containers: + - =(securityContext): + =(runAsUser): ">=0" + - name: check-supplementalGroups + match: + resources: + kinds: + - Pod + validate: + message: >- + Adding of supplemental group IDs is allowed. + pattern: + spec: + =(securityContext): + =(supplementalGroups): + - ">=0" + - name: check-fsGroup + match: + resources: + kinds: + - Pod + validate: + message: >- + Changing to root group ID is allowed. + pattern: + spec: + =(securityContext): + =(fsGroup): ">=0" +{{- end }} \ No newline at end of file diff --git a/helm/openebs/templates/legacy/cleanup-webhook.yaml b/helm/openebs/templates/legacy/cleanup-webhook.yaml new file mode 100644 index 0000000..911ee7a --- /dev/null +++ b/helm/openebs/templates/legacy/cleanup-webhook.yaml @@ -0,0 +1,49 @@ +{{- if and (.Values.webhook.enabled) (.Values.legacy.enabled) }} +# HELM first deletes RBAC, then it tries to delete other resources like SPC and PVC. +# We've got validating webhook on SPC and PVC. +# But even that the policy of this webhook is Ignore, it fails because the ServiceAccount +# does not have permission to access resources like BDC anymore which are used for validation. +# Therefore we first need to delete webhook so we can delete the rest of the deployments. +{{- $kubeMinor := .Capabilities.KubeVersion.Minor | replace "+" "" }} +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ template "openebs.fullname" . }}-webhook-cleanup + namespace: {{ .Release.Namespace }} + annotations: + "helm.sh/hook": pre-delete + "helm.sh/hook-delete-policy": hook-succeeded + labels: + app: {{ template "openebs.name" . }} +spec: + template: + metadata: + name: {{ template "openebs.fullname" . }}-webhook-cleanup + labels: + app: {{ template "openebs.name" . }} + spec: + {{- if .Values.cleanup.image.imagePullSecrets }} + imagePullSecrets: +{{ toYaml .Values.cleanup.image.imagePullSecrets | indent 8 }} + {{- end }} + serviceAccountName: {{ template "openebs.serviceAccountName" . }} + {{- if .Values.webhook.tolerations }} + tolerations: +{{ toYaml .Values.webhook.tolerations | indent 8 }} + {{- end }} + containers: + - name: kubectl + {{- /* bitnami maintains an image for all k8s versions */}} + {{- /* see: https://hub.docker.com/r/bitnami/kubectl */}} + {{- if .Values.cleanup.image.tag }} + image: "{{ .Values.cleanup.image.registry }}{{ .Values.cleanup.image.repository }}:{{ .Values.cleanup.image.tag }}" + {{- else }} + image: "{{ .Values.cleanup.image.registry }}{{ .Values.cleanup.image.repository }}:{{ .Capabilities.KubeVersion.Major }}.{{ $kubeMinor }}" + {{- end }} + command: + - /bin/sh + - -c + - > + kubectl delete validatingWebhookConfiguration openebs-validation-webhook-cfg || true; + restartPolicy: OnFailure +{{- end }} diff --git a/helm/openebs/templates/legacy/deployment-admission-server.yaml b/helm/openebs/templates/legacy/deployment-admission-server.yaml new file mode 100644 index 0000000..c0bb570 --- /dev/null +++ b/helm/openebs/templates/legacy/deployment-admission-server.yaml @@ -0,0 +1,84 @@ +{{- if and (.Values.webhook.enabled) (.Values.legacy.enabled) }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "openebs.fullname" . }}-admission-server + labels: + app: admission-webhook + chart: {{ template "openebs.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + component: admission-webhook + openebs.io/component-name: admission-webhook + openebs.io/version: {{ .Values.release.version }} +spec: + replicas: {{ .Values.webhook.replicas }} + strategy: + type: "Recreate" + rollingUpdate: null + selector: + matchLabels: + app: admission-webhook + template: + metadata: + labels: + app: admission-webhook + name: admission-webhook + release: {{ .Release.Name }} + openebs.io/version: {{ .Values.release.version }} + openebs.io/component-name: admission-webhook + spec: +{{- if .Values.webhook.hostNetwork }} + hostNetwork: true +{{- end }} +{{- if .Values.webhook.nodeSelector }} + nodeSelector: +{{ toYaml .Values.webhook.nodeSelector | indent 8 }} +{{- end }} +{{- if .Values.webhook.tolerations }} + tolerations: +{{ toYaml .Values.webhook.tolerations | indent 8 }} +{{- end }} +{{- if .Values.webhook.affinity }} + affinity: +{{ toYaml .Values.webhook.affinity | indent 8 }} +{{- end }} + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ template "openebs.serviceAccountName" . }} + containers: + - name: admission-webhook + image: "{{ .Values.image.repository }}{{ .Values.webhook.image }}:{{ .Values.webhook.imageTag }}" +{{- if .Values.webhook.resources }} + resources: +{{ toYaml .Values.webhook.resources | trimSuffix "\n" | indent 12 }} +{{- end }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + args: + - -alsologtostderr + - -v=2 + - 2>&1 + env: + - name: OPENEBS_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: ADMISSION_WEBHOOK_FAILURE_POLICY + value: "{{ .Values.webhook.failurePolicy }}" + # Process name used for matching is limited to the 15 characters + # present in the pgrep output. + # So fullname can't be used here with pgrep (>15 chars).A regular expression + # Anchor `^` : matches any string that starts with `admission-serve` + # `.*`: matche any string that has `admission-serve` followed by zero or more char + # that matches the entire command name has to specified. + livenessProbe: + exec: + command: + - sh + - -c + - test `pgrep -c "^admission-serve.*"` = 1 + initialDelaySeconds: {{ .Values.webhook.healthCheck.initialDelaySeconds }} + periodSeconds: {{ .Values.webhook.healthCheck.periodSeconds }} +{{- end }} diff --git a/helm/openebs/templates/legacy/deployment-maya-apiserver.yaml b/helm/openebs/templates/legacy/deployment-maya-apiserver.yaml new file mode 100644 index 0000000..63e10d8 --- /dev/null +++ b/helm/openebs/templates/legacy/deployment-maya-apiserver.yaml @@ -0,0 +1,178 @@ +{{- if and (.Values.apiserver.enabled) (.Values.legacy.enabled) }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "openebs.fullname" . }}-apiserver + labels: + app: {{ template "openebs.name" . }} + chart: {{ template "openebs.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + component: apiserver + name: maya-apiserver + openebs.io/component-name: maya-apiserver + openebs.io/version: {{ .Values.release.version }} +spec: + replicas: {{ .Values.apiserver.replicas }} + strategy: + type: "Recreate" + rollingUpdate: null + selector: + matchLabels: + app: {{ template "openebs.name" . }} + release: {{ .Release.Name }} + template: + metadata: + labels: + app: {{ template "openebs.name" . }} + release: {{ .Release.Name }} + component: apiserver + name: maya-apiserver + openebs.io/component-name: maya-apiserver + openebs.io/version: {{ .Values.release.version }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ template "openebs.serviceAccountName" . }} + containers: + - name: {{ template "openebs.name" . }}-apiserver + image: "{{ .Values.image.repository }}{{ .Values.apiserver.image }}:{{ .Values.apiserver.imageTag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} +{{- if .Values.apiserver.resources }} + resources: +{{ toYaml .Values.apiserver.resources | trimSuffix "\n" | indent 10 }} +{{- end }} + ports: + - containerPort: {{ .Values.apiserver.ports.internalPort }} + env: + # OPENEBS_IO_KUBE_CONFIG enables maya api service to connect to K8s + # based on this config. This is ignored if empty. + # This is supported for maya api server version 0.5.2 onwards + #- name: OPENEBS_IO_KUBE_CONFIG + # value: "/home/ubuntu/.kube/config" + # OPENEBS_IO_K8S_MASTER enables maya api service to connect to K8s + # based on this address. This is ignored if empty. + # This is supported for maya api server version 0.5.2 onwards + #- name: OPENEBS_IO_K8S_MASTER + # value: "http://172.28.128.3:8080" + # OPENEBS_NAMESPACE provides the namespace of this deployment as an + # environment variable + - name: OPENEBS_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + # OPENEBS_SERVICE_ACCOUNT provides the service account of this pod as + # environment variable + - name: OPENEBS_SERVICE_ACCOUNT + valueFrom: + fieldRef: + fieldPath: spec.serviceAccountName + # OPENEBS_MAYA_POD_NAME provides the name of this pod as + # environment variable + - name: OPENEBS_MAYA_POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: MY_POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + # If OPENEBS_IO_CREATE_DEFAULT_STORAGE_CONFIG is false then OpenEBS default + # storageclass and storagepool will not be created. + - name: OPENEBS_IO_CREATE_DEFAULT_STORAGE_CONFIG + value: "{{ .Values.defaultStorageConfig.enabled }}" + # OPENEBS_IO_INSTALL_DEFAULT_CSTOR_SPARSE_POOL decides whether default cstor sparse pool should be + # configured as a part of openebs installation. + # If "true" a default cstor sparse pool will be configured, if "false" it will not be configured. + # This value takes effect only if OPENEBS_IO_CREATE_DEFAULT_STORAGE_CONFIG + # is set to true + - name: OPENEBS_IO_INSTALL_DEFAULT_CSTOR_SPARSE_POOL + value: "{{ .Values.apiserver.sparse.enabled }}" + # OPENEBS_IO_CSTOR_TARGET_DIR can be used to specify the hostpath + # to be used for saving the shared content between the side cars + # of cstor volume pod. + # The default path used is /var/openebs/sparse + - name: OPENEBS_IO_CSTOR_TARGET_DIR + value: "{{ .Values.ndm.sparse.path }}" + # OPENEBS_IO_CSTOR_POOL_SPARSE_DIR can be used to specify the hostpath + # to be used for saving the shared content between the side cars + # of cstor pool pod. This ENV is also used to indicate the location + # of the sparse devices. + # The default path used is /var/openebs/sparse + - name: OPENEBS_IO_CSTOR_POOL_SPARSE_DIR + value: "{{ .Values.ndm.sparse.path }}" + # OPENEBS_IO_JIVA_POOL_DIR can be used to specify the hostpath + # to be used for default Jiva StoragePool loaded by OpenEBS + # The default path used is /var/openebs + # This value takes effect only if OPENEBS_IO_CREATE_DEFAULT_STORAGE_CONFIG + # is set to true + - name: OPENEBS_IO_JIVA_POOL_DIR + value: "{{ .Values.jiva.defaultStoragePath }}" + # OPENEBS_IO_LOCALPV_HOSTPATH_DIR can be used to specify the hostpath + # to be used for default openebs-hostpath storageclass loaded by OpenEBS + # The default path used is /var/openebs/local + # This value takes effect only if OPENEBS_IO_CREATE_DEFAULT_STORAGE_CONFIG + # is set to true + - name: OPENEBS_IO_LOCALPV_HOSTPATH_DIR + value: "{{ .Values.localprovisioner.basePath }}" + # OPENEBS_IO_BASE_DIR used by the OpenEBS to store debug information and + # so forth that are generated in the course of running OpenEBS containers. + - name: OPENEBS_IO_BASE_DIR + value: "{{ .Values.varDirectoryPath.baseDir }}" + - name: OPENEBS_IO_JIVA_CONTROLLER_IMAGE + value: "{{ .Values.image.repository }}{{ .Values.jiva.image }}:{{ .Values.jiva.imageTag }}" + - name: OPENEBS_IO_JIVA_REPLICA_IMAGE + value: "{{ .Values.image.repository }}{{ .Values.jiva.image }}:{{ .Values.jiva.imageTag }}" + - name: OPENEBS_IO_JIVA_REPLICA_COUNT + value: "{{ .Values.jiva.replicas }}" + - name: OPENEBS_IO_CSTOR_TARGET_IMAGE + value: "{{ .Values.image.repository }}{{ .Values.cstor.target.image }}:{{ .Values.cstor.target.imageTag }}" + - name: OPENEBS_IO_CSTOR_POOL_IMAGE + value: "{{ .Values.image.repository }}{{ .Values.cstor.pool.image }}:{{ .Values.cstor.pool.imageTag }}" + - name: OPENEBS_IO_CSTOR_POOL_MGMT_IMAGE + value: "{{ .Values.image.repository }}{{ .Values.cstor.poolMgmt.image }}:{{ .Values.cstor.poolMgmt.imageTag }}" + - name: OPENEBS_IO_CSTOR_VOLUME_MGMT_IMAGE + value: "{{ .Values.image.repository }}{{ .Values.cstor.volumeMgmt.image }}:{{ .Values.cstor.volumeMgmt.imageTag }}" + - name: OPENEBS_IO_VOLUME_MONITOR_IMAGE + value: "{{ .Values.image.repository }}{{ .Values.policies.monitoring.image }}:{{ .Values.policies.monitoring.imageTag }}" + - name: OPENEBS_IO_CSTOR_POOL_EXPORTER_IMAGE + value: "{{ .Values.image.repository }}{{ .Values.policies.monitoring.image }}:{{ .Values.policies.monitoring.imageTag }}" + - name: OPENEBS_IO_HELPER_IMAGE + value: "{{ .Values.image.repository }}{{ .Values.helper.image }}:{{ .Values.helper.imageTag }}" + # OPENEBS_IO_ENABLE_ANALYTICS if set to true sends anonymous usage + # events to Google Analytics + - name: OPENEBS_IO_ENABLE_ANALYTICS + value: "{{ .Values.analytics.enabled }}" + # OPENEBS_IO_ANALYTICS_PING_INTERVAL can be used to specify the duration (in hours) + # for periodic ping events sent to Google Analytics. Default is 24 hours. + - name: OPENEBS_IO_ANALYTICS_PING_INTERVAL + value: "{{ .Values.analytics.pingInterval }}" + - name: OPENEBS_IO_INSTALLER_TYPE + value: "charts-helm" + # OPENEBS_IO_INSTALL_CRD environment variable is used to enable/disable CRD installation + # from Maya API server. By default the CRDs will be installed + - name: OPENEBS_IO_INSTALL_CRD + value: "{{ .Values.crd.enableInstall }}" + livenessProbe: + exec: + command: + - /bin/sh + - -c + - /usr/local/bin/mayactl -m $MY_POD_IP version + initialDelaySeconds: {{ .Values.apiserver.healthCheck.initialDelaySeconds }} + periodSeconds: {{ .Values.apiserver.healthCheck.periodSeconds }} +{{- if .Values.apiserver.nodeSelector }} + nodeSelector: +{{ toYaml .Values.apiserver.nodeSelector | indent 8 }} +{{- end }} +{{- if .Values.apiserver.tolerations }} + tolerations: +{{ toYaml .Values.apiserver.tolerations | indent 8 }} +{{- end }} +{{- if .Values.apiserver.affinity }} + affinity: +{{ toYaml .Values.apiserver.affinity | indent 8 }} +{{- end }} +{{- end }} diff --git a/helm/openebs/templates/legacy/deployment-maya-provisioner.yaml b/helm/openebs/templates/legacy/deployment-maya-provisioner.yaml new file mode 100644 index 0000000..1007b39 --- /dev/null +++ b/helm/openebs/templates/legacy/deployment-maya-provisioner.yaml @@ -0,0 +1,115 @@ +{{- if and (.Values.provisioner.enabled) (.Values.legacy.enabled) }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "openebs.fullname" . }}-provisioner + labels: + app: {{ template "openebs.name" . }} + chart: {{ template "openebs.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + component: provisioner + name: openebs-provisioner + openebs.io/component-name: openebs-provisioner + openebs.io/version: {{ .Values.release.version }} +spec: + replicas: {{ .Values.provisioner.replicas }} + strategy: + type: "Recreate" + rollingUpdate: null + selector: + matchLabels: + app: {{ template "openebs.name" . }} + release: {{ .Release.Name }} + template: + metadata: + labels: + app: {{ template "openebs.name" . }} + release: {{ .Release.Name }} + component: provisioner + name: openebs-provisioner + openebs.io/component-name: openebs-provisioner + openebs.io/version: {{ .Values.release.version }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ template "openebs.serviceAccountName" . }} + containers: + - name: {{ template "openebs.name" . }}-provisioner + image: "{{ .Values.image.repository }}{{ .Values.provisioner.image }}:{{ .Values.provisioner.imageTag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} +{{- if .Values.provisioner.resources }} + resources: +{{ toYaml .Values.provisioner.resources | trimSuffix "\n" | indent 10 }} +{{- end }} + env: + # OPENEBS_IO_K8S_MASTER enables openebs provisioner to connect to K8s + # based on this address. This is ignored if empty. + # This is supported for openebs provisioner version 0.5.2 onwards + #- name: OPENEBS_IO_K8S_MASTER + # value: "http://10.128.0.12:8080" + # OPENEBS_IO_KUBE_CONFIG enables openebs provisioner to connect to K8s + # based on this config. This is ignored if empty. + # This is supported for openebs provisioner version 0.5.2 onwards + #- name: OPENEBS_IO_KUBE_CONFIG + # value: "/home/ubuntu/.kube/config" + # OPENEBS_NAMESPACE is the namespace that this provisioner will + # lookup to find maya api service + - name: OPENEBS_NAMESPACE + value: "{{ .Release.Namespace }}" + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + # OPENEBS_MAYA_SERVICE_NAME provides the maya-apiserver K8s service name, + # that provisioner should forward the volume create/delete requests. + # If not present, "maya-apiserver-service" will be used for lookup. + # This is supported for openebs provisioner version 0.5.3-RC1 onwards + - name: OPENEBS_MAYA_SERVICE_NAME + value: "{{ template "openebs.fullname" . }}-apiservice" + # LEADER_ELECTION_ENABLED is used to enable/disable leader election. By default + # leader election is enabled. + - name: LEADER_ELECTION_ENABLED + value: "{{ .Values.provisioner.enableLeaderElection }}" + # OPENEBS_IO_JIVA_PATCH_NODE_AFFINITY is used to enable/disable setting node affinity + # to the jiva replica deployments. Default is `enabled`. The valid values are + # `enabled` and `disabled`. + - name: OPENEBS_IO_JIVA_PATCH_NODE_AFFINITY + value: "{{ .Values.provisioner.patchJivaNodeAffinity }}" + # The following values will be set as annotations to the PV object. + # Refer : https://github.com/openebs/external-storage/pull/15 + #- name: OPENEBS_MONITOR_URL + # value: "{{ .Values.provisioner.monitorUrl }}" + #- name: OPENEBS_MONITOR_VOLKEY + # value: "{{ .Values.provisioner.monitorVolumeKey }}" + #- name: MAYA_PORTAL_URL + # value: "{{ .Values.provisioner.mayaPortalUrl }}" + # Process name used for matching is limited to the 15 characters + # present in the pgrep output. + # So fullname can't be used here with pgrep (>15 chars).A regular expression + # that matches the entire command name has to specified. + # Anchor `^` : matches any string that starts with `openebs-provis` + # `.*`: matches any string that has `openebs-provis` followed by zero or more char + livenessProbe: + exec: + command: + - sh + - -c + - test `pgrep "^openebs-provisi.*"` = 1 + initialDelaySeconds: {{ .Values.provisioner.healthCheck.initialDelaySeconds }} + periodSeconds: {{ .Values.provisioner.healthCheck.periodSeconds }} +{{- if .Values.provisioner.nodeSelector }} + nodeSelector: +{{ toYaml .Values.provisioner.nodeSelector | indent 8 }} +{{- end }} +{{- if .Values.provisioner.tolerations }} + tolerations: +{{ toYaml .Values.provisioner.tolerations | indent 8 }} +{{- end }} +{{- if .Values.provisioner.affinity }} + affinity: +{{ toYaml .Values.provisioner.affinity | indent 8 }} +{{- end }} +{{- end }} diff --git a/helm/openebs/templates/legacy/deployment-maya-snapshot-operator.yaml b/helm/openebs/templates/legacy/deployment-maya-snapshot-operator.yaml new file mode 100644 index 0000000..92959fd --- /dev/null +++ b/helm/openebs/templates/legacy/deployment-maya-snapshot-operator.yaml @@ -0,0 +1,147 @@ +{{- if and (.Values.snapshotOperator.enabled) (.Values.legacy.enabled) }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "openebs.fullname" . }}-snapshot-operator + labels: + app: {{ template "openebs.name" . }} + chart: {{ template "openebs.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + component: snapshot-operator + openebs.io/component-name: openebs-snapshot-operator + openebs.io/version: {{ .Values.release.version }} +spec: + replicas: {{ .Values.snapshotOperator.replicas }} + selector: + matchLabels: + app: {{ template "openebs.name" . }} + release: {{ .Release.Name }} + strategy: + type: "Recreate" + rollingUpdate: null + template: + metadata: + labels: + app: {{ template "openebs.name" . }} + release: {{ .Release.Name }} + component: snapshot-operator + name: openebs-snapshot-operator + openebs.io/version: {{ .Values.release.version }} + openebs.io/component-name: openebs-snapshot-operator + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ template "openebs.serviceAccountName" . }} + containers: + - name: {{ template "openebs.name" . }}-snapshot-controller + image: "{{ .Values.image.repository }}{{ .Values.snapshotOperator.controller.image }}:{{ .Values.snapshotOperator.controller.imageTag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} +{{- if .Values.snapshotOperator.controller.resources }} + resources: +{{ toYaml .Values.snapshotOperator.controller.resources | trimSuffix "\n" | indent 10 }} +{{- end }} + env: + # OPENEBS_IO_K8S_MASTER enables openebs snapshot controller to connect to K8s + # based on this address. This is ignored if empty. + # This is supported for openebs snapshot controller version 0.6-RC1 onwards + #- name: OPENEBS_IO_K8S_MASTER + # value: "http://10.128.0.12:8080" + # OPENEBS_IO_KUBE_CONFIG enables openebs snapshot controller to connect to K8s + # based on this config. This is ignored if empty. + # This is supported for openebs snapshot controller version 0.6-RC1 onwards + #- name: OPENEBS_IO_KUBE_CONFIG + # value: "/home/ubuntu/.kube/config" + # OPENEBS_NAMESPACE is the namespace that this snapshot controller will + # lookup to find maya api service + - name: OPENEBS_NAMESPACE + value: "{{ .Release.Namespace }}" + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + # OPENEBS_MAYA_SERVICE_NAME provides the maya-apiserver K8s service name, + # that snapshot controller should forward the volume snapshot requests. + # If not present, "maya-apiserver-service" will be used for lookup. + # This is supported for openebs snapshot controller version 0.6-RC1 onwards + - name: OPENEBS_MAYA_SERVICE_NAME + value: "{{ template "openebs.fullname" . }}-apiservice" + # Process name used for matching is limited to the 15 characters + # present in the pgrep output. + # So fullname can't be used here with pgrep (>15 chars).A regular expression + # that matches the entire command name has to specified. + # Anchor `^` : matches any string that starts with `snapshot-contro` + # `.*`: matches any string that has `snapshot-contro` followed by zero or more char + livenessProbe: + exec: + command: + - sh + - -c + - test `pgrep -c "^snapshot-contro.*"` = 1 + initialDelaySeconds: {{ .Values.snapshotOperator.healthCheck.initialDelaySeconds }} + periodSeconds: {{ .Values.snapshotOperator.healthCheck.periodSeconds }} + - name: {{ template "openebs.name" . }}-snapshot-provisioner + image: "{{ .Values.image.repository }}{{ .Values.snapshotOperator.provisioner.image }}:{{ .Values.snapshotOperator.provisioner.imageTag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} +{{- if .Values.snapshotOperator.provisioner.resources }} + resources: +{{ toYaml .Values.snapshotOperator.provisioner.resources | trimSuffix "\n" | indent 10 }} +{{- end }} + env: + # OPENEBS_IO_K8S_MASTER enables openebs snapshot provisioner to connect to K8s + # based on this address. This is ignored if empty. + # This is supported for openebs snapshot provisioner version 0.6-RC1 onwards + #- name: OPENEBS_IO_K8S_MASTER + # value: "http://10.128.0.12:8080" + # OPENEBS_IO_KUBE_CONFIG enables openebs snapshot provisioner to connect to K8s + # based on this config. This is ignored if empty. + # This is supported for openebs snapshot provisioner version 0.6-RC1 onwards + #- name: OPENEBS_IO_KUBE_CONFIG + # value: "/home/ubuntu/.kube/config" + # OPENEBS_NAMESPACE is the namespace that this snapshot provisioner will + # lookup to find maya api service + - name: OPENEBS_NAMESPACE + value: "{{ .Release.Namespace }}" + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + # OPENEBS_MAYA_SERVICE_NAME provides the maya-apiserver K8s service name, + # that snapshot provisioner should forward the volume snapshot PV requests. + # If not present, "maya-apiserver-service" will be used for lookup. + # This is supported for openebs snapshot provisioner version 0.6-RC1 onwards + - name: OPENEBS_MAYA_SERVICE_NAME + value: "{{ template "openebs.fullname" . }}-apiservice" + # LEADER_ELECTION_ENABLED is used to enable/disable leader election. By default + # leader election is enabled. + - name: LEADER_ELECTION_ENABLED + value: "{{ .Values.snapshotOperator.enableLeaderElection }}" + # Process name used for matching is limited to the 15 characters + # present in the pgrep output. + # So fullname can't be used here with pgrep (>15 chars).A regular expression + # that matches the entire command name has to specified. + # Anchor `^` : matches any string that starts with `snapshot-provis` + # `.*`: matches any string that has `snapshot-provis` followed by zero or more char + livenessProbe: + exec: + command: + - sh + - -c + - test `pgrep -c "^snapshot-provis.*"` = 1 + initialDelaySeconds: {{ .Values.snapshotOperator.healthCheck.initialDelaySeconds }} + periodSeconds: {{ .Values.snapshotOperator.healthCheck.periodSeconds }} +{{- if .Values.snapshotOperator.nodeSelector }} + nodeSelector: +{{ toYaml .Values.snapshotOperator.nodeSelector | indent 8 }} +{{- end }} +{{- if .Values.snapshotOperator.tolerations }} + tolerations: +{{ toYaml .Values.snapshotOperator.tolerations | indent 8 }} +{{- end }} +{{- if .Values.snapshotOperator.affinity }} + affinity: +{{ toYaml .Values.snapshotOperator.affinity | indent 8 }} +{{- end }} +{{- end }} diff --git a/helm/openebs/templates/legacy/service-maya-apiserver.yaml b/helm/openebs/templates/legacy/service-maya-apiserver.yaml new file mode 100644 index 0000000..425a0d8 --- /dev/null +++ b/helm/openebs/templates/legacy/service-maya-apiserver.yaml @@ -0,0 +1,23 @@ +{{- if and (.Values.apiserver.enabled) (.Values.legacy.enabled) }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "openebs.fullname" . }}-apiservice + labels: + app: {{ template "openebs.name" . }} + chart: {{ template "openebs.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + openebs.io/component-name: maya-apiserver-svc +spec: + ports: + - name: api + port: {{ .Values.apiserver.ports.externalPort }} + targetPort: {{ .Values.apiserver.ports.internalPort }} + protocol: TCP + selector: + app: {{ template "openebs.name" . }} + release: {{ .Release.Name }} + component: apiserver + sessionAffinity: None +{{- end }} diff --git a/helm/openebs/templates/localprovisioner/deployment-local-provisioner.yaml b/helm/openebs/templates/localprovisioner/deployment-local-provisioner.yaml new file mode 100644 index 0000000..45a9e6b --- /dev/null +++ b/helm/openebs/templates/localprovisioner/deployment-local-provisioner.yaml @@ -0,0 +1,128 @@ +{{- if not .Values.mayastor.enabled -}} +{{- if .Values.localprovisioner.enabled }} +{{- $localpvprovisionerValues := index .Values "localpv-provisioner" }} +{{- if not $localpvprovisionerValues.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "openebs.fullname" . }}-localpv-provisioner + labels: + app: {{ template "openebs.name" . }} + chart: {{ template "openebs.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + component: localpv-provisioner + openebs.io/component-name: openebs-localpv-provisioner + openebs.io/version: {{ .Values.release.version }} +spec: + replicas: {{ .Values.localprovisioner.replicas }} + strategy: + type: "Recreate" + rollingUpdate: null + selector: + matchLabels: + app: {{ template "openebs.name" . }} + release: {{ .Release.Name }} + template: + metadata: + labels: + app: {{ template "openebs.name" . }} + release: {{ .Release.Name }} + component: localpv-provisioner + name: openebs-localpv-provisioner + openebs.io/component-name: openebs-localpv-provisioner + openebs.io/version: {{ .Values.release.version }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ template "openebs.serviceAccountName" . }} + containers: + - name: {{ template "openebs.name" . }}-localpv-provisioner + image: "{{ .Values.image.repository }}{{ .Values.localprovisioner.image }}:{{ .Values.localprovisioner.imageTag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} +{{- if .Values.localprovisioner.resources }} + resources: +{{ toYaml .Values.localprovisioner.resources | trimSuffix "\n" | indent 10 }} +{{- end }} + args: + - "--bd-time-out=$(BDC_BD_BIND_RETRIES)" + env: + # OPENEBS_IO_K8S_MASTER enables openebs provisioner to connect to K8s + # based on this address. This is ignored if empty. + # This is supported for openebs provisioner version 0.5.2 onwards + #- name: OPENEBS_IO_K8S_MASTER + # value: "http://10.128.0.12:8080" + # OPENEBS_IO_KUBE_CONFIG enables openebs provisioner to connect to K8s + # based on this config. This is ignored if empty. + # This is supported for openebs provisioner version 0.5.2 onwards + #- name: OPENEBS_IO_KUBE_CONFIG + # value: "/home/ubuntu/.kube/config" + # This sets the number of times the provisioner should try + # with a polling interval of 5 seconds, to get the Blockdevice + # Name from a BlockDeviceClaim, before the BlockDeviceClaim + # is deleted. E.g. 12 * 5 seconds = 60 seconds timeout + - name: BDC_BD_BIND_RETRIES + value: "{{ .Values.localprovisioner.waitForBDBindTimeoutRetryCount }}" + # OPENEBS_NAMESPACE is the namespace that this provisioner will + # lookup to find maya api service + - name: OPENEBS_NAMESPACE + value: "{{ .Release.Namespace }}" + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + # OPENEBS_SERVICE_ACCOUNT provides the service account of this pod as + # environment variable + - name: OPENEBS_SERVICE_ACCOUNT + valueFrom: + fieldRef: + fieldPath: spec.serviceAccountName + # OPENEBS_IO_BASE_PATH is the environment variable that provides the + # default base path on the node where host-path PVs will be provisioned. + - name: OPENEBS_IO_ENABLE_ANALYTICS + value: "{{ .Values.analytics.enabled }}" + - name: OPENEBS_IO_BASE_PATH + value: "{{ .Values.localprovisioner.basePath }}" + - name: OPENEBS_IO_HELPER_IMAGE + value: "{{ .Values.image.repository }}{{ .Values.helper.image }}:{{ .Values.helper.imageTag }}" + - name: OPENEBS_IO_INSTALLER_TYPE + value: "charts-helm" + # LEADER_ELECTION_ENABLED is used to enable/disable leader election. By default + # leader election is enabled. + - name: LEADER_ELECTION_ENABLED + value: "{{ .Values.localprovisioner.enableLeaderElection }}" +{{- if .Values.imagePullSecrets }} + - name: OPENEBS_IO_IMAGE_PULL_SECRETS + value: "{{- range $.Values.imagePullSecrets }}{{ .name }},{{- end }}" +{{- end }} + # Process name used for matching is limited to the 15 characters + # present in the pgrep output. + # So fullname can't be used here with pgrep (>15 chars).A regular expression + # that matches the entire command name has to specified. + # Anchor `^` : matches any string that starts with `provisioner-loc` + # `.*`: matches any string that has `provisioner-loc` followed by zero or more char + livenessProbe: + exec: + command: + - sh + - -c + - test `pgrep -c "^provisioner-loc.*"` = 1 + initialDelaySeconds: {{ .Values.localprovisioner.healthCheck.initialDelaySeconds }} + periodSeconds: {{ .Values.localprovisioner.healthCheck.periodSeconds }} +{{- if .Values.localprovisioner.nodeSelector }} + nodeSelector: +{{ toYaml .Values.localprovisioner.nodeSelector | indent 8 }} +{{- end }} +{{- if .Values.localprovisioner.tolerations }} + tolerations: +{{ toYaml .Values.localprovisioner.tolerations | indent 8 }} +{{- end }} +{{- if .Values.localprovisioner.affinity }} + affinity: +{{ toYaml .Values.localprovisioner.affinity | indent 8 }} +{{ end }} +{{ end }} +{{ end }} +{{ end }} diff --git a/helm/openebs/templates/localprovisioner/device-class.yaml b/helm/openebs/templates/localprovisioner/device-class.yaml new file mode 100644 index 0000000..dafe0d1 --- /dev/null +++ b/helm/openebs/templates/localprovisioner/device-class.yaml @@ -0,0 +1,40 @@ +{{- if not .Values.mayastor.enabled -}} +{{- if .Values.localprovisioner.enabled }} +{{- $localpvprovisionerValues := index .Values "localpv-provisioner" }} +{{- if not $localpvprovisionerValues.enabled }} +# The second operand in the AND operation can be removed +# when enableDeviceClass is deprecated. +{{- if and .Values.localprovisioner.deviceClass.enabled .Values.localprovisioner.enableDeviceClass }} +apiVersion: storage.k8s.io/v1 +kind: StorageClass +metadata: + name: {{ .Values.localprovisioner.deviceClass.name }} + annotations: + openebs.io/cas-type: local + cas.openebs.io/config: | + - name: StorageType + value: "device" +{{- if .Values.localprovisioner.deviceClass.fsType }} + - name: FSType + value: {{ .Values.localprovisioner.deviceClass.fsType | quote }} +{{- end }} +{{- if .Values.localprovisioner.deviceClass.blockDeviceSelectors }} + - name: BlockDeviceSelectors + data: +{{ toYaml .Values.localprovisioner.deviceClass.blockDeviceSelectors | indent 10 }} +{{- end }} +{{- if .Values.localprovisioner.deviceClass.nodeAffinityLabels }} + - name: NodeAffinityLabels + list: +{{ toYaml .Values.localprovisioner.deviceClass.nodeAffinityLabels | indent 10 }} +{{- end }} +{{- if .Values.localprovisioner.deviceClass.isDefaultClass }} + storageclass.kubernetes.io/is-default-class: "true" +{{- end }} +provisioner: openebs.io/local +volumeBindingMode: WaitForFirstConsumer +reclaimPolicy: {{ .Values.localprovisioner.deviceClass.reclaimPolicy }} +{{- end }} +{{- end }} +{{- end }} +{{- end }} diff --git a/helm/openebs/templates/localprovisioner/hostpath-class.yaml b/helm/openebs/templates/localprovisioner/hostpath-class.yaml new file mode 100644 index 0000000..b1eb41e --- /dev/null +++ b/helm/openebs/templates/localprovisioner/hostpath-class.yaml @@ -0,0 +1,49 @@ +{{- if not .Values.mayastor.enabled -}} +{{- if .Values.localprovisioner.enabled }} +{{- $localpvprovisionerValues := index .Values "localpv-provisioner" }} +{{- if not $localpvprovisionerValues.enabled }} +# The second operand in the AND operation can be removed +# when enableHostpathClass is deprecated. +{{- if and .Values.localprovisioner.hostpathClass.enabled .Values.localprovisioner.enableHostpathClass }} +apiVersion: storage.k8s.io/v1 +kind: StorageClass +metadata: + name: {{ .Values.localprovisioner.hostpathClass.name }} + annotations: + openebs.io/cas-type: local + cas.openebs.io/config: | + - name: StorageType + value: "hostpath" +{{- if or .Values.localprovisioner.basePath .Values.localprovisioner.hostpathClass.basePath }} + - name: BasePath + value: {{ .Values.localprovisioner.hostpathClass.basePath | default .Values.localprovisioner.basePath | quote }} +{{- end }} +{{- if .Values.localprovisioner.hostpathClass.nodeAffinityLabels }} + - name: NodeAffinityLabels + list: +{{ toYaml .Values.localprovisioner.hostpathClass.nodeAffinityLabels | indent 10 }} +{{- end }} +{{- if .Values.localprovisioner.hostpathClass.xfsQuota.enabled }} + - name: XFSQuota + enabled: "{{ .Values.localprovisioner.hostpathClass.xfsQuota.enabled }}" + data: + softLimitGrace: "{{ .Values.localprovisioner.hostpathClass.xfsQuota.softLimitGrace }}" + hardLimitGrace: "{{ .Values.localprovisioner.hostpathClass.xfsQuota.hardLimitGrace }}" +{{- end }} +{{- if .Values.localprovisioner.hostpathClass.ext4Quota.enabled }} + - name: EXT4Quota + enabled: "{{ .Values.localprovisioner.hostpathClass.ext4Quota.enabled }}" + data: + softLimitGrace: "{{ .Values.localprovisioner.hostpathClass.ext4Quota.softLimitGrace }}" + hardLimitGrace: "{{ .Values.localprovisioner.hostpathClass.ext4Quota.hardLimitGrace }}" +{{- end }} +{{- if .Values.localprovisioner.hostpathClass.isDefaultClass }} + storageclass.kubernetes.io/is-default-class: "true" +{{- end }} +provisioner: openebs.io/local +volumeBindingMode: WaitForFirstConsumer +reclaimPolicy: {{ .Values.localprovisioner.hostpathClass.reclaimPolicy }} +{{- end }} +{{- end }} +{{- end }} +{{- end }} diff --git a/helm/openebs/templates/ndm/cluster-exporter-service.yaml b/helm/openebs/templates/ndm/cluster-exporter-service.yaml new file mode 100644 index 0000000..3dd07dc --- /dev/null +++ b/helm/openebs/templates/ndm/cluster-exporter-service.yaml @@ -0,0 +1,25 @@ +{{- if not .Values.mayastor.enabled -}} +{{- if .Values.ndm.enabled }} +{{- if and .Values.ndmExporter.enabled .Values.ndmExporter.clusterExporter.metricsPort }} +{{- $ndmValues := index .Values "openebs-ndm" }} +{{- if not $ndmValues.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "openebs.ndm-cluster-exporter.fullname" . }}-service + labels: + {{- include "openebs.ndm-cluster-exporter.labels" . | nindent 4 }} +spec: + clusterIP: None + ports: + - name: metrics + port: {{ .Values.ndmExporter.clusterExporter.metricsPort }} + targetPort: {{ .Values.ndmExporter.clusterExporter.metricsPort }} + selector: + {{- with .Values.ndmExporter.clusterExporter.podLabels }} + {{ toYaml . }} + {{- end }} +{{- end }} +{{- end }} +{{- end }} +{{- end }} diff --git a/helm/openebs/templates/ndm/cluster-exporter.yaml b/helm/openebs/templates/ndm/cluster-exporter.yaml new file mode 100644 index 0000000..da6fe9d --- /dev/null +++ b/helm/openebs/templates/ndm/cluster-exporter.yaml @@ -0,0 +1,53 @@ +{{- if not .Values.mayastor.enabled -}} +{{- if and (.Values.ndm.enabled) (.Values.ndmExporter.enabled) }} +{{- $ndmValues := index .Values "openebs-ndm" }} +{{- if not $ndmValues.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "openebs.ndm-cluster-exporter.fullname" . }} + labels: + {{- include "openebs.ndm-cluster-exporter.labels" . | nindent 4 }} +spec: + replicas: 1 + strategy: + type: Recreate + selector: + matchLabels: + {{- include "openebs.ndm-cluster-exporter.matchLabels" . | nindent 6 }} + template: + metadata: + labels: + {{- include "openebs.ndm-cluster-exporter.labels" . | nindent 8 }} + {{- with .Values.ndmExporter.clusterExporter.podLabels }} + {{ toYaml . }} + {{- end }} + spec: + serviceAccountName: {{ template "openebs.serviceAccountName" . }} + containers: + - name: {{ template "openebs.ndm-cluster-exporter.fullname" . }} + image: "{{ .Values.ndmExporter.image.registry }}{{ .Values.ndmExporter.image.repository }}:{{ .Values.ndmExporter.image.tag }}" + command: + - /usr/local/bin/exporter + args: + - "start" + - "--mode=cluster" + - "--port=$(METRICS_LISTEN_PORT)" + - "--metrics=/metrics" + ports: + - containerPort: {{ .Values.ndmExporter.clusterExporter.metricsPort }} + protocol: TCP + name: metrics + imagePullPolicy: {{ .Values.ndmExporter.image.pullPolicy }} + env: + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + {{- if .Values.ndmExporter.clusterExporter.metricsPort }} + - name: METRICS_LISTEN_PORT + value: :{{ .Values.ndmExporter.clusterExporter.metricsPort }} + {{- end }} +{{- end }} +{{- end }} +{{- end }} diff --git a/helm/openebs/templates/ndm/cm-node-disk-manager.yaml b/helm/openebs/templates/ndm/cm-node-disk-manager.yaml new file mode 100644 index 0000000..ab57b37 --- /dev/null +++ b/helm/openebs/templates/ndm/cm-node-disk-manager.yaml @@ -0,0 +1,50 @@ +{{- if not .Values.mayastor.enabled -}} +{{- if .Values.ndm.enabled }} +{{- $ndmValues := index .Values "openebs-ndm" }} +{{- if not $ndmValues.enabled }} +# This is the node-disk-manager related config. +# It can be used to customize the disks probes and filters +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "openebs.fullname" . }}-ndm-config + labels: + app: {{ template "openebs.name" . }} + chart: {{ template "openebs.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + component: ndm-config + openebs.io/component-name: ndm-config +data: + # udev-probe is default or primary probe which should be enabled to run ndm + # filterconfigs contains configs of filters - in the form of include + # and exclude comma separated strings + node-disk-manager.config: | + probeconfigs: + - key: udev-probe + name: udev probe + state: true + - key: seachest-probe + name: seachest probe + state: {{ .Values.ndm.probes.enableSeachest }} + - key: smart-probe + name: smart probe + state: true + filterconfigs: + - key: os-disk-exclude-filter + name: os disk exclude filter + state: {{ .Values.ndm.filters.enableOsDiskExcludeFilter }} + exclude: "{{ .Values.ndm.filters.osDiskExcludePaths }}" + - key: vendor-filter + name: vendor filter + state: {{ .Values.ndm.filters.enableVendorFilter }} + include: "" + exclude: "{{ .Values.ndm.filters.excludeVendors }}" + - key: path-filter + name: path filter + state: {{ .Values.ndm.filters.enablePathFilter }} + include: "{{ .Values.ndm.filters.includePaths }}" + exclude: "{{ .Values.ndm.filters.excludePaths }}" +{{- end }} +{{- end }} +{{- end }} diff --git a/helm/openebs/templates/ndm/daemonset-ndm.yaml b/helm/openebs/templates/ndm/daemonset-ndm.yaml new file mode 100644 index 0000000..11026c9 --- /dev/null +++ b/helm/openebs/templates/ndm/daemonset-ndm.yaml @@ -0,0 +1,188 @@ +{{- if not .Values.mayastor.enabled -}} +{{- if .Values.ndm.enabled }} +{{- $ndmValues := index .Values "openebs-ndm" }} +{{- if not $ndmValues.enabled }} +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: {{ template "openebs.fullname" . }}-ndm + labels: + app: {{ template "openebs.name" . }} + chart: {{ template "openebs.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + component: ndm + openebs.io/component-name: ndm + openebs.io/version: {{ .Values.release.version }} +spec: + updateStrategy: + type: "RollingUpdate" + selector: + matchLabels: + app: {{ template "openebs.name" . }} + release: {{ .Release.Name }} + component: ndm + template: + metadata: + labels: + app: {{ template "openebs.name" . }} + release: {{ .Release.Name }} + component: ndm + openebs.io/component-name: ndm + name: openebs-ndm + openebs.io/version: {{ .Values.release.version }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ template "openebs.serviceAccountName" . }} + hostNetwork: true + # host PID is used to check status of iSCSI Service when the NDM + # API service is enabled +{{- if .Values.featureGates.enabled }} +{{- if .Values.featureGates.APIService.enabled }} + hostPID: true +{{- end}} +{{- end}} + containers: + - name: {{ template "openebs.name" . }}-ndm + image: "{{ .Values.image.repository }}{{ .Values.ndm.image }}:{{ .Values.ndm.imageTag }}" + args: + - -v=4 +{{- if .Values.featureGates.enabled }} +{{- if .Values.featureGates.GPTBasedUUID.enabled }} + - --feature-gates={{ .Values.featureGates.GPTBasedUUID.featureGateFlag }} +{{- end}} +{{- if .Values.featureGates.APIService.enabled }} + - --feature-gates={{ .Values.featureGates.APIService.featureGateFlag }} + - --api-service-address={{ .Values.featureGates.APIService.address }} +{{- end}} +{{- if .Values.featureGates.UseOSDisk.enabled }} + - --feature-gates={{ .Values.featureGates.UseOSDisk.featureGateFlag }} +{{- end}} +{{- if .Values.featureGates.ChangeDetection.enabled }} + - --feature-gates={{ .Values.featureGates.ChangeDetection.featureGateFlag }} +{{- end}} +{{- if .Values.featureGates.PartitionTableUUID.enabled }} + - --feature-gates={{ .Values.featureGates.PartitionTableUUID.featureGateFlag }} +{{- end}} +{{- end}} + imagePullPolicy: {{ .Values.image.pullPolicy }} +{{- if .Values.ndm.resources }} + resources: +{{ toYaml .Values.ndm.resources | trimSuffix "\n" | indent 10 }} +{{- end }} + securityContext: + privileged: true + env: + # namespace in which NDM is installed will be passed to NDM Daemonset + # as environment variable + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + # pass hostname as env variable using downward API to the NDM container + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName +{{- if .Values.ndm.sparse }} +{{- if .Values.ndm.sparse.path }} + # specify the directory where the sparse files need to be created. + # if not specified, then sparse files will not be created. + - name: SPARSE_FILE_DIR + value: "{{ .Values.ndm.sparse.path }}" +{{- end }} +{{- if .Values.ndm.sparse.size }} + # Size(bytes) of the sparse file to be created. + - name: SPARSE_FILE_SIZE + value: "{{ .Values.ndm.sparse.size }}" +{{- end }} +{{- if .Values.ndm.sparse.count }} + # Specify the number of sparse files to be created + - name: SPARSE_FILE_COUNT + value: "{{ .Values.ndm.sparse.count }}" +{{- end }} +{{- end }} + # Process name used for matching is limited to the 15 characters + # present in the pgrep output. + # So fullname can be used here with pgrep (cmd is < 15 chars). + livenessProbe: + exec: + command: + - pgrep + - "ndm" + initialDelaySeconds: {{ .Values.ndm.healthCheck.initialDelaySeconds }} + periodSeconds: {{ .Values.ndm.healthCheck.periodSeconds }} + volumeMounts: + - name: config + mountPath: /host/node-disk-manager.config + subPath: node-disk-manager.config + readOnly: true + - name: udev + mountPath: /run/udev + - name: procmount + mountPath: /host/proc + readOnly: true + - name: devmount + mountPath: /dev + - name: basepath + mountPath: /var/openebs/ndm +{{- if .Values.ndm.sparse }} +{{- if .Values.ndm.sparse.path }} + - name: sparsepath + mountPath: {{ .Values.ndm.sparse.path }} +{{- end }} +{{- end }} + volumes: + - name: config + configMap: + name: {{ template "openebs.fullname" . }}-ndm-config + - name: udev + hostPath: + path: /run/udev + type: Directory + # mount /proc (to access mount file of process 1 of host) inside container + # to read mount-point of disks and partitions + - name: procmount + hostPath: + path: /proc + type: Directory + # the /dev directory is mounted so that we have access to the devices that + # are connected at runtime of the pod. + - name: devmount + hostPath: + path: /dev + type: Directory + - name: basepath + hostPath: + path: "{{ .Values.varDirectoryPath.baseDir }}/ndm" + type: DirectoryOrCreate +{{- if .Values.ndm.sparse }} +{{- if .Values.ndm.sparse.path }} + - name: sparsepath + hostPath: + path: {{ .Values.ndm.sparse.path }} +{{- end }} +{{- end }} + # By default the node-disk-manager will be run on all kubernetes nodes + # If you would like to limit this to only some nodes, say the nodes + # that have storage attached, you could label those node and use + # nodeSelector. + # + # e.g. label the storage nodes with - "openebs.io/nodegroup"="storage-node" + # kubectl label node "openebs.io/nodegroup"="storage-node" + #nodeSelector: + # "openebs.io/nodegroup": "storage-node" +{{- if .Values.ndm.nodeSelector }} + nodeSelector: +{{ toYaml .Values.ndm.nodeSelector | indent 8 }} +{{- end }} +{{- if .Values.ndm.tolerations }} + tolerations: +{{ toYaml .Values.ndm.tolerations | indent 8 }} +{{- end }} +{{- end }} +{{- end }} +{{- end }} diff --git a/helm/openebs/templates/ndm/deployment-ndm-operator.yaml b/helm/openebs/templates/ndm/deployment-ndm-operator.yaml new file mode 100644 index 0000000..9d60b8e --- /dev/null +++ b/helm/openebs/templates/ndm/deployment-ndm-operator.yaml @@ -0,0 +1,93 @@ +{{- if not .Values.mayastor.enabled -}} +{{- if .Values.ndmOperator.enabled }} +{{- $ndmValues := index .Values "openebs-ndm" }} +{{- if not $ndmValues.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "openebs.fullname" . }}-ndm-operator + labels: + app: {{ template "openebs.name" . }} + chart: {{ template "openebs.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + component: ndm-operator + openebs.io/component-name: ndm-operator + openebs.io/version: {{ .Values.release.version }} + name: ndm-operator +spec: + replicas: {{ .Values.ndmOperator.replicas }} + strategy: + type: "Recreate" + rollingUpdate: null + selector: + matchLabels: + app: {{ template "openebs.name" . }} + release: {{ .Release.Name }} + template: + metadata: + labels: + app: {{ template "openebs.name" . }} + release: {{ .Release.Name }} + component: ndm-operator + name: ndm-operator + openebs.io/component-name: ndm-operator + openebs.io/version: {{ .Values.release.version }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ template "openebs.serviceAccountName" . }} + containers: + - name: {{ template "openebs.fullname" . }}-ndm-operator + image: "{{ .Values.image.repository }}{{ .Values.ndmOperator.image }}:{{ .Values.ndmOperator.imageTag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} +{{- if .Values.ndmOperator.resources }} + resources: +{{ toYaml .Values.ndmOperator.resources | trimSuffix "\n" | indent 10 }} +{{- end }} + livenessProbe: + httpGet: + path: /healthz + port: 8585 + initialDelaySeconds: {{ .Values.ndmOperator.healthCheck.initialDelaySeconds }} + periodSeconds: {{ .Values.ndmOperator.healthCheck.periodSeconds }} + readinessProbe: + httpGet: + path: /readyz + port: 8585 + initialDelaySeconds: {{ .Values.ndmOperator.readinessCheck.initialDelaySeconds }} + periodSeconds: {{ .Values.ndmOperator.readinessCheck.periodSeconds }} + env: + - name: WATCH_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: SERVICE_ACCOUNT + valueFrom: + fieldRef: + fieldPath: spec.serviceAccountName + - name: OPERATOR_NAME + value: "node-disk-operator" + - name: CLEANUP_JOB_IMAGE + value: "{{ .Values.image.repository }}{{ .Values.helper.image }}:{{ .Values.helper.imageTag }}" +{{- if .Values.imagePullSecrets }} + - name: OPENEBS_IO_IMAGE_PULL_SECRETS + value: "{{- range $index, $secret := .Values.imagePullSecrets}}{{if $index}},{{end}}{{ $secret.name }}{{- end}}" +{{- end }} +{{- if .Values.ndmOperator.nodeSelector }} + nodeSelector: +{{ toYaml .Values.ndmOperator.nodeSelector | indent 8 }} +{{- end }} +{{- if .Values.ndmOperator.tolerations }} + tolerations: +{{ toYaml .Values.ndmOperator.tolerations | indent 8 }} +{{- end }} +{{- end }} +{{- end }} +{{- end }} diff --git a/helm/openebs/templates/ndm/node-exporter-service.yaml b/helm/openebs/templates/ndm/node-exporter-service.yaml new file mode 100644 index 0000000..419f924 --- /dev/null +++ b/helm/openebs/templates/ndm/node-exporter-service.yaml @@ -0,0 +1,25 @@ +{{- if not .Values.mayastor.enabled -}} +{{- if .Values.ndm.enabled }} +{{- if and .Values.ndmExporter.enabled .Values.ndmExporter.nodeExporter.metricsPort }} +{{- $ndmValues := index .Values "openebs-ndm" }} +{{- if not $ndmValues.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "openebs.ndm-node-exporter.fullname" . }}-service + labels: + {{- include "openebs.ndm-node-exporter.labels" . | nindent 4 }} +spec: + clusterIP: None + ports: + - name: metrics + port: {{ .Values.ndmExporter.nodeExporter.metricsPort }} + targetPort: {{ .Values.ndmExporter.nodeExporter.metricsPort }} + selector: + {{- with .Values.ndmExporter.nodeExporter.podLabels }} + {{ toYaml . }} + {{- end }} +{{- end }} +{{- end }} +{{- end }} +{{- end }} diff --git a/helm/openebs/templates/ndm/node-exporter.yaml b/helm/openebs/templates/ndm/node-exporter.yaml new file mode 100644 index 0000000..77d7851 --- /dev/null +++ b/helm/openebs/templates/ndm/node-exporter.yaml @@ -0,0 +1,54 @@ +{{- if not .Values.mayastor.enabled -}} +{{- if and .Values.ndm.enabled .Values.ndmExporter.enabled }} +{{- $ndmValues := index .Values "openebs-ndm" }} +{{- if not $ndmValues.enabled }} +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: {{ template "openebs.ndm-node-exporter.fullname" . }} + labels: + {{- include "openebs.ndm-node-exporter.labels" . | nindent 4 }} +spec: + updateStrategy: + type: RollingUpdate + selector: + matchLabels: + {{- include "openebs.ndm-node-exporter.matchLabels" . | nindent 6 }} + template: + metadata: + labels: + {{- include "openebs.ndm-node-exporter.labels" . | nindent 8 }} + {{- with .Values.ndmExporter.nodeExporter.podLabels }} + {{ toYaml . }} + {{- end }} + spec: + serviceAccountName: {{ template "openebs.serviceAccountName" . }} + containers: + - name: {{ template "openebs.ndm-node-exporter.fullname" . }} + image: "{{ .Values.ndmExporter.image.registry }}{{ .Values.ndmExporter.image.repository }}:{{ .Values.ndmExporter.image.tag }}" + command: + - /usr/local/bin/exporter + args: + - "start" + - "--mode=node" + - "--port=$(METRICS_LISTEN_PORT)" + - "--metrics=/metrics" + ports: + - containerPort: {{ .Values.ndmExporter.nodeExporter.metricsPort }} + protocol: TCP + name: metrics + imagePullPolicy: {{ .Values.ndmExporter.image.pullPolicy }} + securityContext: + privileged: true + env: + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + {{- if .Values.ndmExporter.nodeExporter.metricsPort }} + - name: METRICS_LISTEN_PORT + value: :{{ .Values.ndmExporter.nodeExporter.metricsPort }} + {{- end }} +{{- end }} +{{- end }} +{{- end }} diff --git a/helm/openebs/templates/psp-clusterrole.yaml b/helm/openebs/templates/psp-clusterrole.yaml new file mode 100644 index 0000000..a6c4807 --- /dev/null +++ b/helm/openebs/templates/psp-clusterrole.yaml @@ -0,0 +1,14 @@ +{{- if and .Values.rbac.create .Values.rbac.pspEnabled }} +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ template "openebs.fullname" . }}-psp + labels: + app: {{ template "openebs.name" . }} +rules: +- apiGroups: ['extensions'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ template "openebs.fullname" . }}-psp +{{- end }} diff --git a/helm/openebs/templates/psp-clusterrolebinding.yaml b/helm/openebs/templates/psp-clusterrolebinding.yaml new file mode 100644 index 0000000..5a42058 --- /dev/null +++ b/helm/openebs/templates/psp-clusterrolebinding.yaml @@ -0,0 +1,17 @@ +{{- if and .Values.rbac.create .Values.rbac.pspEnabled }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "openebs.fullname" . }}-psp + labels: + app: {{ template "openebs.name" . }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "openebs.fullname" . }}-psp +subjects: + - kind: ServiceAccount + name: {{ template "openebs.serviceAccountName" . }} + namespace: {{ $.Release.Namespace }} +{{- end }} + diff --git a/helm/openebs/templates/psp.yaml b/helm/openebs/templates/psp.yaml new file mode 100644 index 0000000..0442f0e --- /dev/null +++ b/helm/openebs/templates/psp.yaml @@ -0,0 +1,28 @@ +{{- if and .Values.rbac.create .Values.rbac.pspEnabled }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "openebs.fullname" . }}-psp + namespace: {{ $.Release.Namespace }} + labels: + app: {{ template "openebs.name" . }} +spec: + privileged: true + allowPrivilegeEscalation: true + allowedCapabilities: ['*'] + volumes: ['*'] + hostNetwork: true + hostPorts: + - min: 0 + max: 65535 + hostIPC: true + hostPID: true + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'RunAsAny' + fsGroup: + rule: 'RunAsAny' +{{- end }} diff --git a/helm/openebs/templates/serviceaccount.yaml b/helm/openebs/templates/serviceaccount.yaml new file mode 100644 index 0000000..31a5004 --- /dev/null +++ b/helm/openebs/templates/serviceaccount.yaml @@ -0,0 +1,11 @@ +{{- if .Values.serviceAccount.create }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "openebs.serviceAccountName" . }} + labels: + app: {{ template "openebs.name" . }} + chart: {{ template "openebs.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +{{- end }} diff --git a/helm/openebs/values.yaml b/helm/openebs/values.yaml new file mode 100644 index 0000000..a5afbf8 --- /dev/null +++ b/helm/openebs/values.yaml @@ -0,0 +1,980 @@ +# Default values for openebs. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +rbac: + # Specifies whether RBAC resources should be created + create: true + pspEnabled: false + # rbac.kyvernoEnabled: `true` if Kyverno Policy resources should be created + kyvernoEnabled: false + +serviceAccount: + create: true + name: + +imagePullSecrets: [] + # - name: image-pull-secret + +release: + # "openebs.io/version" label for control plane components + version: "3.9.0" + +# Legacy components will be installed if it is enabled. +# Legacy components are - admission-server, maya api-server, snapshot-operator +# and k8s-provisioner +legacy: + enabled: false + +image: + pullPolicy: IfNotPresent + repository: "" + +apiserver: + enabled: true + image: "openebs/m-apiserver" + imageTag: "2.12.2" + replicas: 1 + ports: + externalPort: 5656 + internalPort: 5656 + sparse: + enabled: "false" + nodeSelector: {} + tolerations: [] + affinity: {} + healthCheck: + initialDelaySeconds: 30 + periodSeconds: 60 + ## apiserver resource requests and limits + ## Reference: http://kubernetes.io/docs/user-guide/compute-resources/ + resources: {} + # limits: + # cpu: 1000m + # memory: 2Gi + # requests: + # cpu: 500m + # memory: 1Gi + + +defaultStorageConfig: + enabled: "true" + +# Directory used by the OpenEBS to store debug information and so forth +# that are generated in the course of running OpenEBS containers. +varDirectoryPath: + baseDir: "/var/openebs" + +provisioner: + enabled: true + image: "openebs/openebs-k8s-provisioner" + imageTag: "2.12.2" + replicas: 1 + enableLeaderElection: true + patchJivaNodeAffinity: enabled + nodeSelector: {} + tolerations: [] + affinity: {} + healthCheck: + initialDelaySeconds: 30 + periodSeconds: 60 + ## provisioner resource requests and limits + ## Reference: http://kubernetes.io/docs/user-guide/compute-resources/ + resources: {} + # limits: + # cpu: 1000m + # memory: 2Gi + # requests: + # cpu: 500m + # memory: 1Gi + +# If you want to enable local pv as a dependency chart then set +# `localprovisioner.enabled: false` and enable it as dependency chart. +# If you are using custom configuration then update those configuration +# under `localpv-provisioner` key. +localprovisioner: + enabled: true + image: "openebs/provisioner-localpv" + imageTag: "3.4.0" + replicas: 1 + enableLeaderElection: true + # These fields are deprecated. Please use the fields (see below) + # - deviceClass.enabled + # - hostpathClass.enabled + enableDeviceClass: true + enableHostpathClass: true + # This sets default directory used by the provisioner to provision + # hostpath volumes. + basePath: "/var/openebs/local" + # This sets the number of times the provisioner should try + # with a polling interval of 5 seconds, to get the Blockdevice + # Name from a BlockDeviceClaim, before the BlockDeviceClaim + # is deleted. E.g. 12 * 5 seconds = 60 seconds timeout + waitForBDBindTimeoutRetryCount: "12" + nodeSelector: {} + tolerations: [] + affinity: {} + healthCheck: + initialDelaySeconds: 30 + periodSeconds: 60 + ## localprovisioner resource requests and limits + ## Reference: http://kubernetes.io/docs/user-guide/compute-resources/ + resources: {} + # limits: + # cpu: 1000m + # memory: 2Gi + # requests: + # cpu: 500m + # memory: 1Gi + + deviceClass: + # Name of default device StorageClass. + name: openebs-device + # If true, enables creation of the openebs-device StorageClass + enabled: true + # Available reclaim policies: Delete/Retain, defaults: Delete. + reclaimPolicy: Delete + # If true, sets the openebs-device StorageClass as the default StorageClass + isDefaultClass: false + # Custom node affinity label(s) for example "openebs.io/node-affinity-value" + # that will be used instead of hostnames + # This helps in cases where the hostname changes when the node is removed and + # added back with the disks still intact. + # Example: + # nodeAffinityLabels: + # - "openebs.io/node-affinity-key-1" + # - "openebs.io/node-affinity-key-2" + nodeAffinityLabels: [] + # Sets the filesystem to be written to the blockdevice before + # mounting (filesystem volumes) + # This is only usable if the selected BlockDevice does not already + # have a filesystem + # Valid values: "ext4", "xfs" + fsType: "ext4" + # Label block devices in the cluster that you would like the openEBS localPV + # Provisioner to pick up those specific block devices available on the node. + # Set the label key and value as shown in the example below. + # + # To read more: https://github.com/openebs/dynamic-localpv-provisioner/blob/develop/docs/tutorials/device/blockdevicetag.md + # + # Example: + # blockDeviceSelectors: + # ndm.io/driveType: "SSD" + # ndm.io/fsType: "none" + blockDeviceSelectors: {} + + hostpathClass: + # Name of the default hostpath StorageClass + name: openebs-hostpath + # If true, enables creation of the openebs-hostpath StorageClass + enabled: true + # Available reclaim policies: Delete/Retain, defaults: Delete. + reclaimPolicy: Delete + # If true, sets the openebs-hostpath StorageClass as the default StorageClass + isDefaultClass: false + # Path on the host where local volumes of this storage class are mounted under. + # NOTE: If not specified, this defaults to the value of localprovisioner.basePath. + basePath: "" + # Custom node affinity label(s) for example "openebs.io/node-affinity-value" + # that will be used instead of hostnames + # This helps in cases where the hostname changes when the node is removed and + # added back with the disks still intact. + # Example: + # nodeAffinityLabels: + # - "openebs.io/node-affinity-key-1" + # - "openebs.io/node-affinity-key-2" + nodeAffinityLabels: [] + # Prerequisite: XFS Quota requires an XFS filesystem mounted with + # the 'pquota' or 'prjquota' mount option. + xfsQuota: + # If true, enables XFS project quota + enabled: false + # Detailed configuration options for XFS project quota. + # If XFS Quota is enabled with the default values, the usage limit + # is set at the storage capacity specified in the PVC. + softLimitGrace: "0%" + hardLimitGrace: "0%" + # Prerequisite: EXT4 Quota requires an EXT4 filesystem mounted with + # the 'prjquota' mount option. + ext4Quota: + # If true, enables XFS project quota + enabled: false + # Detailed configuration options for EXT4 project quota. + # If EXT4 Quota is enabled with the default values, the usage limit + # is set at the storage capacity specified in the PVC. + softLimitGrace: "0%" + hardLimitGrace: "0%" + +snapshotOperator: + enabled: true + controller: + image: "openebs/snapshot-controller" + imageTag: "2.12.2" + ## snapshot controller resource requests and limits + ## Reference: http://kubernetes.io/docs/user-guide/compute-resources/ + resources: {} + # limits: + # cpu: 1000m + # memory: 2Gi + # requests: + # cpu: 500m + # memory: 1Gi + provisioner: + image: "openebs/snapshot-provisioner" + imageTag: "2.12.2" + ## snapshot provisioner resource requests and limits + ## Reference: http://kubernetes.io/docs/user-guide/compute-resources/ + resources: {} + # limits: + # cpu: 1000m + # memory: 2Gi + # requests: + # cpu: 500m + # memory: 1Gi + replicas: 1 + enableLeaderElection: true + upgradeStrategy: "Recreate" + nodeSelector: {} + tolerations: [] + affinity: {} + healthCheck: + initialDelaySeconds: 30 + periodSeconds: 60 + +# If you want to enable openebs as a dependency chart then set `ndm.enabled: false`, +# `ndmOperator.enabled: false` and enable it as dependency chart. If you are using +# custom configuration then update those configuration under `openebs-ndm` key. +ndm: + enabled: true + image: "openebs/node-disk-manager" + imageTag: "2.1.0" + sparse: + path: "/var/openebs/sparse" + size: "10737418240" + count: "0" + filters: + enableOsDiskExcludeFilter: true + osDiskExcludePaths: "/,/etc/hosts,/boot" + enableVendorFilter: true + excludeVendors: "CLOUDBYT,OpenEBS" + enablePathFilter: true + includePaths: "" + excludePaths: "/dev/loop,/dev/fd0,/dev/sr0,/dev/ram,/dev/dm-,/dev/md,/dev/rbd,/dev/zd" + probes: + enableSeachest: false + nodeSelector: {} + tolerations: [] + healthCheck: + initialDelaySeconds: 30 + periodSeconds: 60 + ## ndm resource requests and limits + ## Reference: http://kubernetes.io/docs/user-guide/compute-resources/ + resources: {} + # limits: + # cpu: 1000m + # memory: 2Gi + # requests: + # cpu: 500m + # memory: 1Gi + +# If you want to enable openebs as a dependency chart then set `ndm.enabled: false`, +# `ndmOperator.enabled: false` and enable it as dependency chart. If you are using +# custom configuration then update those configuration under `openebs-ndm` key. +ndmOperator: + enabled: true + image: "openebs/node-disk-operator" + imageTag: "2.1.0" + replicas: 1 + upgradeStrategy: Recreate + nodeSelector: {} + tolerations: [] + healthCheck: + initialDelaySeconds: 15 + periodSeconds: 20 + readinessCheck: + initialDelaySeconds: 5 + periodSeconds: 10 + ## ndmOperator resource requests and limits + ## Reference: http://kubernetes.io/docs/user-guide/compute-resources/ + resources: {} + # limits: + # cpu: 1000m + # memory: 2Gi + # requests: + # cpu: 500m + # memory: 1Gi + +ndmExporter: + enabled: false + image: + registry: + repository: openebs/node-disk-exporter + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: 2.1.0 + nodeExporter: + name: ndm-node-exporter + podLabels: + name: openebs-ndm-node-exporter + # The TCP port number used for exposing ndm-node-exporter metrics. + # If not set, service will not be created to expose metrics endpoint to serviceMonitor + # and listen-port flag will not be set and container port will be empty. + metricsPort: 9101 + clusterExporter: + name: ndm-cluster-exporter + podLabels: + name: openebs-ndm-cluster-exporter + # The TCP port number used for exposing ndm-cluster-exporter metrics. + # If not set, service will not be created to expose metrics endpoint to serviceMonitor + # and listen-port flag will not be set and container port will be empty. + metricsPort: 9100 + +webhook: + enabled: true + image: "openebs/admission-server" + imageTag: "2.12.2" + failurePolicy: "Fail" + replicas: 1 + healthCheck: + initialDelaySeconds: 30 + periodSeconds: 60 + nodeSelector: {} + tolerations: [] + affinity: {} + hostNetwork: false + ## admission-server resource requests and limits + ## Reference: http://kubernetes.io/docs/user-guide/compute-resources/ + resources: {} + # limits: + # cpu: 500m + # memory: 1Gi + # requests: + # cpu: 250m + # memory: 500Mi + +# If you are migrating from 2.x to 3.x and if you are using custom values +# then put this configuration under `localpv-provisioner` and `openebs-ndm` key. +helper: + image: "openebs/linux-utils" + imageTag: "3.4.0" + +# These are ndm related configuration. If you want to enable openebs as a dependency +# chart then set `ndm.enabled: false`, `ndmOperator.enabled: false` and enable it as +# dependency chart. If you are using custom configuration then update those configuration +# under `openebs-ndm` key. +featureGates: + enabled: true + GPTBasedUUID: + enabled: true + featureGateFlag: "GPTBasedUUID" + APIService: + enabled: false + featureGateFlag: "APIService" + address: "0.0.0.0:9115" + UseOSDisk: + enabled: false + featureGateFlag: "UseOSDisk" + ChangeDetection: + enabled: false + featureGateFlag: "ChangeDetection" + PartitionTableUUID: + enabled: false + featureGateFlag: "PartitionTableUUID" + +crd: + enableInstall: true + +# If you are migrating from 2.x to 3.x and if you are using custom values +# then put these configuration under `cstor` key. +policies: + monitoring: + enabled: true + image: "openebs/m-exporter" + imageTag: "2.12.2" + +analytics: + enabled: true + # Specify in hours the duration after which a ping event needs to be sent. + pingInterval: "24h" + +mayastor: + # -- Enable Mayastor storage engine + # Note: Enabling this will remove LocalPV Provisioner and NDM (default chart components). + enabled: false + + # Sample configuration, if you want to configure mayastor with custom values. + # This is a small part of the full configuration. Full configuration available + # here - https://github.com/openebs/mayastor-extensions/blob/v2.4.0/chart/values.yaml + + image: + # -- Image registry to pull Mayastor product images + registry: docker.io + # -- Image registry's namespace + repo: openebs + # -- Release tag for Mayastor images + tag: v2.4.0 + # -- ImagePullPolicy for Mayastor images + pullPolicy: IfNotPresent + + # -- Pod scheduling priority + # ref: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/ + # priorityClassName: "" + + # base: + # # docker-secrets required to pull images if the container registry from image.Registry is protected + # imagePullSecrets: + # # -- Enable imagePullSecrets for pulling our container images + # enabled: false + # # Name of the imagePullSecret in the installed namespace + # secrets: + # - name: login + + # metrics: + # # -- Enable the metrics exporter + # enabled: true + + # jaeger: + # # -- Enable jaeger tracing + # enabled: false + + # operators: + # pool: + # # -- Log level for diskpool operator service + # logLevel: info + + # jaeger-operator: + # # Name of jaeger operator + # name: "{{ .Release.Name }}" + # crd: + # # Install jaeger CRDs + # install: false + # jaeger: + # # Install jaeger-operator + # create: false + # rbac: + # # Create a clusterRole for Jaeger + # clusterRole: true + + # agents: + # core: + # # -- Log level for the core service + # logLevel: info + # capacity: + # thin: + # # -- The allowed pool commitment limit when dealing with thin provisioned volumes. + # # Example: If the commitment is 250 and the pool is 10GiB we can overcommit the pool + # # up to 25GiB (create 2 10GiB and 1 5GiB volume) but no further. + # poolCommitment: "250%" + # # -- When creating replicas for an existing volume, each replica pool must have at least + # # this much free space percentage of the volume size. + # # Example: if this value is 40, the pool has 40GiB free, then the max volume size allowed + # # to be created on the pool is 100GiB. + # volumeCommitment: "40%" + # # -- Same as the `volumeCommitment` argument, but applicable only when creating replicas + # # for a new volume. + # volumeCommitmentInitial: "40%" + # ha: + # enabled: true + # node: + # # -- Log level for the ha node service + # logLevel: info + # cluster: + # # -- Log level for the ha cluster service + # logLevel: info + + # apis: + # rest: + # # -- Log level for the rest service + # logLevel: info + # # -- Number of replicas of rest + # replicaCount: 1 + + # csi: + # image: + # # -- Image registry to pull all CSI Sidecar images + # registry: registry.k8s.io + # # -- Image registry's namespace + # repo: sig-storage + # # -- imagePullPolicy for all CSI Sidecar images + # pullPolicy: IfNotPresent + # # -- csi-provisioner image release tag + # provisionerTag: v3.5.0 + # # -- csi-attacher image release tag + # attacherTag: v4.3.0 + # # -- csi-snapshotter image release tag + # snapshotterTag: v6.2.1 + # # -- csi-snapshot-controller image release tag + # snapshotControllerTag: v6.2.1 + # # -- csi-node-driver-registrar image release tag + # registrarTag: v2.8.0 + + # controller: + # # -- Log level for the csi controller + # logLevel: info + # resources: + # limits: + # # -- Cpu limits for csi controller + # cpu: "32m" + # # -- Memory limits for csi controller + # memory: "128Mi" + # requests: + # # -- Cpu requests for csi controller + # cpu: "16m" + # # -- Memory requests for csi controller + # memory: "64Mi" + # # -- Set tolerations, overrides global + # tolerations: [] + # # -- Set PriorityClass, overrides global + # priorityClassName: "" + # node: + # logLevel: info + # topology: + # segments: + # openebs.io/csi-node: mayastor + # # -- Add topology segments to the csi-node daemonset node selector + # nodeSelector: false + # resources: + # limits: + # # -- Cpu limits for csi node plugin + # cpu: "100m" + # # -- Memory limits for csi node plugin + # memory: "128Mi" + # requests: + # # -- Cpu requests for csi node plugin + # cpu: "100m" + # # -- Memory requests for csi node plugin + # memory: "64Mi" + # nvme: + # # -- The nvme_core module io timeout in seconds + # io_timeout: "30" + # # -- The ctrl_loss_tmo (controller loss timeout) in seconds + # ctrl_loss_tmo: "1980" + # # Kato (keep alive timeout) in seconds + # keep_alive_tmo: "" + # # -- The kubeletDir directory for the csi-node plugin + # kubeletDir: /var/lib/kubelet + # pluginMounthPath: /csi + # socketPath: csi.sock + # # -- Set tolerations, overrides global + # tolerations: [] + # # -- Set PriorityClass, overrides global + # priorityClassName: "" + + # io_engine: + # # -- Log level for the io-engine service + # logLevel: info + # api: "v1" + # target: + # nvmf: + # # -- NVMF target interface (ip, mac, name or subnet) + # iface: "" + # # -- Reservations Persist Through Power Loss State + # ptpl: true + # # NVMF target Command Retry Delay for volume target initiators + # hostCmdRetryDelay: + # # A command retry delay in seconds. A value of 0 means no delay, host may retry immediately + # crdt1: 30 + + # etcd: + # # Pod labels; okay to remove the openebs logging label if required + # podLabels: + # app: etcd + # openebs.io/logging: "true" + # # -- Number of replicas of etcd + # replicaCount: 3 + # persistence: + # # -- If true, use a Persistent Volume Claim. If false, use emptyDir. + # enabled: true + # # -- Will define which storageClass to use in etcd's StatefulSets + # # a `manual` storageClass will provision a hostpath PV on the same node + # # an empty storageClass will use the default StorageClass on the cluster + # storageClass: "" + # # -- Volume size + # size: 2Gi + # podAntiAffinityPreset: "hard" + + # loki-stack: + # # -- Enable loki log collection for Mayastor components + # enabled: true + + # obs: + # callhome: + # # -- Enable callhome + # enabled: true + # # -- Log level for callhome + # logLevel: "info" + + # localpv-provisioner: + # # -- Enables the openebs dynamic-localpv provisioner. If disabled, modify etcd and loki-stack storage class accordingly. + # enabled: true + # # Enable/disable the openebs NDM sub-chart. It's recommended to keep this disabled. + # openebsNDM: + # enabled: false + # # Enable/disable the creation of the openebs-device StorageClass. It's recommended to keep this disabled. + # deviceClass: + # enabled: false + # hostpathClass: + # enabled: false + + +jiva: + # non csi configuration + image: "openebs/jiva" + imageTag: "2.12.2" + replicas: 3 + defaultStoragePath: "/var/openebs" + + # jiva csi driver configuration + # do not enable or configure any sub dependency here + # only jiva csi related settings can be added here + # ref - https://openebs.github.io/jiva-operator + + # jiva chart dependency tree is here - + # jiva + # | - localpv-provisioner + # | | - openebs-ndm + + # Enable localpv-provisioner and openebs-ndm as root dependency not as + # sub dependency. + # openebs + # | - jiva(enable) + # | | - localpv-provisioner(disable) + # | | | - openebs-ndm(disable) + # | - localpv-provisioner(enable) + # | - openebs-ndm(enable) + + enabled: false + openebsLocalpv: + enabled: false + localpv-provisioner: + openebsNDM: + enabled: false + + # Sample configuration if you want to configure jiva csi driver with custom values. + # This is a small part of the full configuration. Full configuration available + # here - https://openebs.github.io/jiva-operator + +# rbac: +# create: true +# pspEnabled: false +# +# jivaOperator: +# controller: +# image: +# registry: quay.io/ +# repository: openebs/jiva +# tag: 3.5.0 +# replica: +# image: +# registry: quay.io/ +# repository: openebs/jiva +# tag: 3.5.0 +# image: +# registry: quay.io/ +# repository: openebs/jiva-operator +# pullPolicy: IfNotPresent +# tag: 3.5.0 +# +# jivaCSIPlugin: +# remount: "true" +# image: +# registry: quay.io/ +# repository: openebs/jiva-csi +# pullPolicy: IfNotPresent +# tag: 3.5.0 + +cstor: + + # non csi configuration + pool: + image: "openebs/cstor-pool" + imageTag: "2.12.2" + poolMgmt: + image: "openebs/cstor-pool-mgmt" + imageTag: "2.12.2" + target: + image: "openebs/cstor-istgt" + imageTag: "2.12.2" + volumeMgmt: + image: "openebs/cstor-volume-mgmt" + imageTag: "2.12.2" + + # cstor csi driver configuration + # do not enable or configure any sub dependency here + # only cstor csi related settings can be added here + # ref - https://openebs.github.io/cstor-operators + + # cstor chart dependency tree is here - + # cstor + # | - openebs-ndm + + # Enable openebs-ndm as root dependency not as sub dependency. + # openebs + # | - cstor(enable) + # | | - openebs-ndm(disable) + # | - openebs-ndm(enable) + enabled: false + openebsNDM: + enabled: false + + # Sample configuration if you want to configure cstor csi driver with custom values. + # This is a small part of the full configuration. Full configuration available + # here - https://openebs.github.io/cstor-operators + +# imagePullSecrets: [] +# +# rbac: +# create: true +# pspEnabled: false +# +# cspcOperator: +# poolManager: +# image: +# registry: quay.io/ +# repository: openebs/cstor-pool-manager +# tag: 3.5.0 +# cstorPool: +# image: +# registry: quay.io/ +# repository: openebs/cstor-pool +# tag: 3.5.0 +# cstorPoolExporter: +# image: +# registry: quay.io/ +# repository: openebs/m-exporter +# tag: 3.5.0 +# image: +# registry: quay.io/ +# repository: openebs/cspc-operator +# pullPolicy: IfNotPresent +# tag: 3.5.0 +# +# cvcOperator: +# target: +# image: +# registry: quay.io/ +# repository: openebs/cstor-istgt +# tag: 3.5.0 +# volumeMgmt: +# image: +# registry: quay.io/ +# repository: openebs/cstor-volume-manager +# tag: 3.5.0 +# volumeExporter: +# image: +# registry: quay.io/ +# repository: openebs/m-exporter +# tag: 3.5.0 +# image: +# registry: quay.io/ +# repository: openebs/cvc-operator +# pullPolicy: IfNotPresent +# tag: 3.5.0 +# +# cstorCSIPlugin: +# image: +# registry: quay.io/ +# repository: openebs/cstor-csi-driver +# pullPolicy: IfNotPresent +# tag: 3.5.0 +# +# admissionServer: +# componentName: cstor-admission-webhook +# image: +# registry: quay.io/ +# repository: openebs/cstor-webhook +# pullPolicy: IfNotPresent +# tag: 3.5.0 + +# ndm configuration goes here +# https://openebs.github.io/node-disk-manager +openebs-ndm: + enabled: false + + # Sample configuration if you want to configure openebs ndm with custom values. + # This is a small part of the full configuration. Full configuration available + # here - https://openebs.github.io/node-disk-manager + +# imagePullSecrets: [] +# +# ndm: +# image: +# registry: quay.io/ +# repository: openebs/node-disk-manager +# pullPolicy: IfNotPresent +# tag: 2.1.0 +# sparse: +# path: "/var/openebs/sparse" +# size: "10737418240" +# count: "0" +# filters: +# enableOsDiskExcludeFilter: true +# osDiskExcludePaths: "/,/etc/hosts,/boot" +# enableVendorFilter: true +# excludeVendors: "CLOUDBYT,OpenEBS" +# enablePathFilter: true +# includePaths: "" +# excludePaths: "loop,fd0,sr0,/dev/ram,/dev/dm-,/dev/md,/dev/rbd,/dev/zd" +# probes: +# enableSeachest: false +# enableUdevProbe: true +# enableSmartProbe: true +# +# ndmOperator: +# image: +# registry: quay.io/ +# repository: openebs/node-disk-operator +# pullPolicy: IfNotPresent +# tag: 2.1.0 +# +# helperPod: +# image: +# registry: quay.io/ +# repository: openebs/linux-utils +# pullPolicy: IfNotPresent +# tag: 3.4.0 +# +# featureGates: +# enabled: true +# GPTBasedUUID: +# enabled: true +# featureGateFlag: "GPTBasedUUID" +# APIService: +# enabled: false +# featureGateFlag: "APIService" +# address: "0.0.0.0:9115" +# UseOSDisk: +# enabled: false +# featureGateFlag: "UseOSDisk" +# ChangeDetection: +# enabled: false +# featureGateFlag: "ChangeDetection" +# +# varDirectoryPath: +# baseDir: "/var/openebs" + + # local pv provisioner configuration goes here + # do not enable or configure any sub dependency here + # ref - https://openebs.github.io/dynamic-localpv-provisioner + + # local pv chart dependency tree is here - + # localpv-provisioner + # | - openebs-ndm + + # Enable openebs-ndm as root dependency not as sub dependency. + # openebs + # | - localpv-provisioner(enable) + # | | - openebs-ndm(disable) + # | - openebs-ndm(enable) +localpv-provisioner: + enabled: false + openebsNDM: + enabled: false + + # Sample configuration if you want to configure openebs locapv with custom values. + # This is a small part of the full configuration. Full configuration available + # here - https://openebs.github.io/dynamic-localpv-provisioner + +# imagePullSecrets: [] +# +# rbac: +# create: true +# pspEnabled: false +# +# localpv: +# image: +# registry: quay.io/ +# repository: openebs/provisioner-localpv +# tag: 3.4.0 +# pullPolicy: IfNotPresent +# healthCheck: +# initialDelaySeconds: 30 +# periodSeconds: 60 +# replicas: 1 +# enableLeaderElection: true +# basePath: "/var/openebs/local" +# +# helperPod: +# image: +# registry: quay.io/ +# repository: openebs/linux-utils +# pullPolicy: IfNotPresent +# tag: 3.4.0 + +# zfs local pv configuration goes here +# ref - https://openebs.github.io/zfs-localpv +zfs-localpv: + enabled: false + + # Sample configuration if you want to configure zfs locapv with custom values. + # This is a small part of the full configuration. Full configuration available + # here - https://openebs.github.io/zfs-localpv + +# imagePullSecrets: [] +# +# rbac: +# pspEnabled: false +# +# zfsPlugin: +# image: +# registry: quay.io/ +# repository: openebs/zfs-driver +# pullPolicy: IfNotPresent +# tag: 2.3.0 + +# lvm local pv configuration goes here +# ref - https://openebs.github.io/lvm-localpv +lvm-localpv: + enabled: false + + # Sample configuration if you want to configure lvm localpv with custom values. + # This is a small part of the full configuration. Full configuration available + # here - https://openebs.github.io/lvm-localpv + +# imagePullSecrets: [] +# +# rbac: +# pspEnabled: false +# +# lvmPlugin: +# image: +# registry: quay.io/ +# repository: openebs/lvm-driver +# pullPolicy: IfNotPresent +# tag: 1.3.0 + +# openebs nfs provisioner configuration goes here +# ref - https://openebs.github.io/dynamic-nfs-provisioner +nfs-provisioner: + enabled: false + + # Sample configuration if you want to configure nfs-provisioner with custom values. + # This is a small part of the full configuration. Full configuration available + # here - https://openebs.github.io/dynamic-nfs-provisioner + +# imagePullSecrets: [] +# +# rbac: +# pspEnabled: false +# +# nfsProvisioner: +# image: +# registry: +# repository: openebs/provisioner-nfs +# tag: 0.10.0 +# pullPolicy: IfNotPresent +# enableLeaderElection: "true" +# nfsServerAlpineImage: +# registry: +# repository: openebs/nfs-server-alpine +# tag: 0.10.0 + +cleanup: + image: + # Make sure that registry name end with a '/'. + # For example : quay.io/ is a correct value here and quay.io is incorrect + registry: + repository: bitnami/kubectl + tag: + imagePullSecrets: [] + # - name: image-pull-secret diff --git a/helm/sonarqube/.helmignore b/helm/sonarqube/.helmignore new file mode 100644 index 0000000..46fd899 --- /dev/null +++ b/helm/sonarqube/.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 +*~ +# Various IDEs +.project +.idea/ +*.tmproj +# OWNERS file for Kubernetes +OWNERS diff --git a/helm/sonarqube/CHANGELOG.md b/helm/sonarqube/CHANGELOG.md new file mode 100644 index 0000000..f4659dc --- /dev/null +++ b/helm/sonarqube/CHANGELOG.md @@ -0,0 +1,389 @@ +# SonarQube Chart Changelog +All changes to this chart will be documented in this file. + +## [10.2.1] +* Update SonarQube to 10.2.1 +* Update Chart's version to 10.2.1 + +## [10.2.0] +* Update SonarQube to 10.2.0 +* Update Chart's version to 10.2.0 +* Update curl image to 8.2.0 +* `readinessProbe.sonarWebContext`, `startupProbe.sonarWebContext`, `livenessProbe.sonarWebContext`, and `account.sonarWebContext` are deprecated, please use `sonarWebContext` at the value top level. +* Updates ingress-nginx dependency to 4.7.1 +* Fixes broken table on README + +## [10.1.0] +* Update SonarQube to 10.1.0 +* Support Kubernetes v1.27 while dropping v1.23 +* Changed default test process to wget, using sonarqube image as default +* Update Chart's version to 10.1.0 +* Fix liveness probe to detect when a failure occurs. + +## [10.0.0] +* Update SonarQube to 10.0.0 +* Helm chart versioning will now follow the SonarQube product versioning + +## [9.5.1] +* Make `jvmOpts` and `jvmCeOpts` not override env vars and sonar properties + +## [9.5.0] +* Add helm-chart-sonarqube as chart source + +## [9.4.2] +* Fixed unsupported wget parameter `--proxy off` with `--no-proxy` + +## [9.4.1] +* Fix install_plugins.sh not deleting previously installed plugins + +## [9.4.0] +* Added support for `extraVolumes` and `extraVolumeMounts` in sonar pod. + +## [9.3.1] +* Clarify doc for custom cacert secret + +## [9.3.0] +* Refactor Deployment manifest to match the Statefulset manifest + +## [9.2.0] +* Add a configurable Prometheus PodMonitor resource +* Refactor Prometheus exporter's documentation and bump to version 0.17.2 + +## [9.1.0] +* Allow setting priorityClassName for StatefulSets + +## [9.0.1] +* Adds timeoutSeconds parameter to probes + +## [9.0.0] +* Update SonarQube logo +* Bootstrap chart version 9.x.x dedicated to the future SonarQube 10.0 +## [8.0.0] +* Update SonarQube to 9.9.0 +* Bootstrap chart version 8.x.x dedicated to SonarQube 9.9 LTS + +## [7.0.2] +* Update the list of supported kubernetes versions + +## [7.0.1] +* Set a new default (maximum) allowed size of the client request body on the ingress + +## [7.0.0] +* Update SonarQube to 9.8.0 + +## [6.2.1] +* Update the postgresql chart's repository + + +## [6.2.0] +* Refactor Ingress to be compatible with static compatibitly test and 1.19 minimum requirement + +## [6.1.2] +* Updated SonarQube to 9.7.1 + +## [6.1.1] +* Refactor templating of ConfigMap for sonar.properties +* Fix the bug where sonarSecretKey was not applied without sonar.properties set + +## [6.1.0] +* Fix the installation of plugins using the standard folder `extensions/plugins` instead of `extensions/downloads` and `lib/common` +* Remove `plugins.lib` and other small edits in the documentation + +## [6.0.0] +* Updated SonarQube to 9.7.0 + +## [5.4.1] +* Fix the right-dash curly brace issue with the additional network policy parameter + +## [5.4.0] +* Allow `tests.image` to be configured and update README accordingly. +* Allow `tests.initContainers.image` to be configured and update README accordingly. + +## [5.3.0] +* Use the networkPolicy.prometheusNamespace value for the network policy namespace selector +* Uncomment default value in values.yaml for backwards compatibility + +## [5.2.0] +* Add support for monitoringPasscode passed as a secret and removal of livenessprobe httpheader defined in clear text + +## [5.1.0] +* Bump apiVersion to v2 +* Set the number of allowed replicas to 0 and 1 +* Add documentation for ingress tls +* Add documentation for sonarProperties and sonarSecretProperties +* Add the possibility of using a secret for customizing the admin password + +## [5.0.6] +* Updated SonarQube to 9.6.1 + +## [5.0.0] +* Updated SonarQube to 9.6.0 + +## [4.0.3] +* Add support for Openshift Route labels and annotations + +## [4.0.2] +* Fix issue with Openshift route name to use use fullname instead of name + +## [4.0.1] +* Add documentation for ingress annotations + +## [4.0.0] +* updated SonarQube to 9.5.0 + +## [3.0.4] +* Fix issue with additional network policy + +## [3.0.3] +* Add automount service account token flag + +## [3.0.2] +* Add documentation to setup web context via environment variable + +## [3.0.1] +* Fix for issue (#215)[https://github.com/SonarSource/helm-chart-sonarqube/issues/215], adding tolerations and affinity to change password hooks + +## [3.0.0] +* updated SonarQube to 9.4.0 + +## [2.0.7] +* Specify location of .netrc file when downloading plugins that require auth + +## [2.0.6] +* Specify service account name in change admin password hook + +## [2.0.5] +* secure admin password in k8s secret + +## [2.0.4] +* no longer automount service account token + +## [2.0.3] +* changed description of dependency postgresql chart + +## [2.0.2] +* changed links to get a better overview of sources + +## [2.0.1] +* Updated all instances of the caCerts enabled check + +## [2.0.0] +* updated SonarQube to 9.3.0 + +## [1.6.5] +* add securitycontext to wait-for-db and change-password hook + +## [1.6.4] +* properties are now correctly set + +## [1.6.3] +* `livenessProbe.failureThreshold` was never rendered + +## [1.6.2] +* added missing logic for `caCerts.enabled` + +## [1.6.1] +* fix missing `SONAR_WEB_SYSTEMPASSCODE` environment variable causing failed liveness checks + +## [1.5.1] +* added possibility to define host of a route + +## [1.5.0] +* detached sonarqube edition from version + +## [1.4.0] +* added possibility to define the ingress pathType +* added network policies +* added possibility to define ressources for the change admin password hook +* default permissions for prometheus injector now align with pod fs permissions +* updated dependencies +* admin hook now honors web context + +## [1.3.0] +* added support for multiple image pull secrets + * added `image.pullSecrets` +* deprecated support for singular image pull secret + * deprecated `image.pullSecret` +* fixed missing image pull secret in admin hook job + +## [1.2.5] +* updated SonarQube to 9.2.4 + +## [1.2.4] +* updated SonarQube to 9.2.3 + +## [1.2.3] +* updated SonarQube to 9.2.2 + +## [1.2.2] +* fix hardcoded reference to port 9000 + +## [1.2.1] +* updated SonarQube to 9.2.1 + +## [1.2.0] +* updated SonarQube to 9.2.0 + +## [1.1.11] +* fixed missing POD level security context for statefulset deployment + +## [1.1.10] +* added link to community support forum +* Use liveness endpoint instead of helth endpoint for liveness probe + +## [1.1.9] +* fixed wrong scc user reference if name was explicitly set + +## [1.1.8] +* fixed serviceaccount logic + +## [1.1.7] +* fixed wrong artifact hub images annotation + +## [1.1.6] +* updated sonarqube to 9.1.0 + +## [1.1.5] +* added resources to ui-test pod template + +## [1.1.4] +* fixed artifacthub annotations + +## [1.1.3] +* fixed `invalid: metadata.labels: Invalid value` error on the `chart` label of the pvc + +## [1.1.2] +* fixed condition check to add new certificates + +## [1.1.1] +* updated default application version to 9.0.1 +* release to helm repository + +## [1.1.0] +* update jdbc overwrite values + * replace `jdbcUrlOverride` with `jdbcOverwrite.jdbcUrl` + * remove useless `jdbcDatabaseType` (was always postgres) +* deprecate `postgresql.postgresqlServer`, `postgresql.existingSecret` and `postgresql.existingSecretPasswordKey` in favor of new `jdbcOverwrite` values +* update dependency Charts + * `bitnami/postgresql` from 8.6.4 to 10.4.8 + * `ingress-nginx/ingress-nginx` from 3.29.0 to 3.31.0 + +## [1.0.19] +* Add optional ingress parameter `ingressClassName` + +## [1.0.18] +* added route support for OpenShift deployments + +## [1.0.17] +* Add an additional configuration parameter `extraContainers` to allow an array of containers to run alongside the sonarqube container + +## [1.0.16] +* fixed usage of `sonarSecretProperties` + +## [1.0.15] +* bump jmx_exporter to 0.16.0 + +## [1.0.14] +* added hostAliases to deploymentType statefulset + +## [1.0.13] +* made prometheus exporter port configurable and support prometheus PodMonitor + +## [1.0.12] +* make sure SQ is restarted when the JMX Prometheus exporter agents configuration changes + +## [1.0.11] +* JMX Prometheus exporter agent is now also enabled on the CE process +* `prometheusExporter.ceConfig` allows specific config of the JMX Prometheus exporter agent for the CE process + +## [1.0.10] +* added prometheusExporter.noCheckCertificate option + +## [1.0.9] +* add missing imagePullSecrets in sts install type + +## [1.0.8] +* fix typo in initfs +* fix plugin installation init container permissions +* fix duplicated mount point for conf when sonar.properties are defined + +## [1.0.7] +* fix invalid yaml render in `secret.yaml` when using external postgresql + +## [1.0.6] +* added `prometheusExporter.downloadURL` (custom download URL for the agent jar) + +## [1.0.5] +* replace `rjkernick/alpine-wget` with `curlimages/curl` +* update `install-plugins` script +* fix possible issue with prometheus init container and `env` set in the `values.yaml` + +## [1.0.4] +* fix for missing `serviceAccountName` in STS deployment kind + +## [1.0.3] +* fixed prometheus config volume mount if disabled +* switched from wget to curl image per default for downloading agent +* added support for proxy envs + +## [1.0.2] +* added option to configure CE java opts separately + +## [1.0.1] +* fixed missing conditional that was introduced in 0.9.2.2 to sonarqube-sts.yaml +* updated default application version to 8.9 + +## [1.0.0] +* changed default deployment from replica set to statefull set +* added default support for prometheus jmx exporter +* added init filesystem container +* added nginx-ingress as optional dependency +* updated application version to 8.8-community +* improved readiness/startup and liveness probes +* improved documentation + +## [0.9.6.2] +* Change order of env variables to better support 7.9-lts + +## [0.9.6.1] +* Add support for setting custom annotations in admin hook job. + +## [0.9.6.0] +* Add the possibility of definining the secret key name of the postgres password. + +## [0.9.5.0] +* Add Ingress default backend for GCE class + +## [0.9.2.3] +* Added namespace to port-foward command in notes. + +## [0.9.2.2] +* Added a condition to deployment.yaml so that `wait-for-db` initContainer is only created if `postgresql.enabled=true` + +## [0.9.2.1] +* Updated the configuration table to include the additional keys added in release 9.2.0. + +## [0.9.2.0] +* Added functionality for deployments to OpenShift clusters. + * .Values.OpenShift flag to signify if deploying to OpenShift. + * Ability to have chart generate an SCC allowing the init-sysctl container to run as privileged. + * Setting of a seperate securityContext section for the main SonarQube container to avoid running as root. + * Exposing additional `postreSQL` keys in values.yaml to support configuring postgres to run under standard "restricted" or "anyuid"/"nonroot" SCCs on OpenShift. +* Added initContainer `wait-for-db` to await postgreSQL successful startup before starting SonarQube, to avoid race conditions. + +## [0.9.1.1] +* Update SonarQube to 8.5.1. +* **Fix:** Purge plugins directory before download. + +## [0.9.0.0] +* Update SonarQube to 8.5. +* **Breaking change:** Rework init containers. + * Move global defaults from `plugins` section to `initContainers`. + * Update container images. +* **Deprecation:** `elasticsearch.configureNode` in favor of `initSysctl.enabled`. +* Rework sysctl with support for custom values. +* Rework plugins installation via `opt/sonarqube/extensions/downloads` folder that is handled by SonarQube itself. + * **Breaking change:** remove `plugins.deleteDefaultPlugins` as SonarQube stores bundled plugins out of `opt/sonarqube/extensions`. +* Rename deprecated `SONARQUBE_` environment variables to `SONAR_` ones. +* **Breaking change:** Rename `enabledTests` to `tests.enabled`. +* Add `terminationGracePeriodSeconds`. diff --git a/helm/sonarqube/Chart.lock b/helm/sonarqube/Chart.lock new file mode 100644 index 0000000..2b70c1e --- /dev/null +++ b/helm/sonarqube/Chart.lock @@ -0,0 +1,9 @@ +dependencies: +- name: postgresql + repository: https://raw.githubusercontent.com/bitnami/charts/pre-2022/bitnami + version: 10.15.0 +- name: ingress-nginx + repository: https://kubernetes.github.io/ingress-nginx + version: 4.7.1 +digest: sha256:16a5362bfe5ceca82723c85608da059005c70bc46bfc72fc9d976b42a49f2120 +generated: "2023-08-04T14:18:34.978582+02:00" diff --git a/helm/sonarqube/Chart.yaml b/helm/sonarqube/Chart.yaml new file mode 100644 index 0000000..4603f79 --- /dev/null +++ b/helm/sonarqube/Chart.yaml @@ -0,0 +1,56 @@ +annotations: + artifacthub.io/changes: | + - kind: changed + description: "Upgrading SonarQube to 10.2.1" + - kind: changed + description: "Update Chart's version to 10.2.1" + artifacthub.io/containsSecurityUpdates: "false" + artifacthub.io/images: | + - name: sonarqube + image: sonarqube:10.2.1-community + artifacthub.io/links: | + - name: support + url: https://community.sonarsource.com/ + - name: Chart Source + url: https://github.com/SonarSource/helm-chart-sonarqube/tree/master/charts/sonarqube +apiVersion: v2 +appVersion: 10.2.1 +dependencies: +- condition: postgresql.enabled + name: postgresql + repository: https://raw.githubusercontent.com/bitnami/charts/pre-2022/bitnami + version: 10.15.0 +- condition: nginx.enabled + name: ingress-nginx + repository: https://kubernetes.github.io/ingress-nginx + version: 4.7.1 +description: SonarQube is a self-managed, automatic code review tool that systematically + helps you deliver clean code. As a core element of our Sonar solution, SonarQube + integrates into your existing workflow and detects issues in your code to help you + perform continuous code inspections of your projects. The tool analyses 30+ different + programming languages and integrates into your CI pipeline and DevOps platform to + ensure that your code meets high-quality standards. +home: https://www.sonarqube.org/ +icon: https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/helm/SonarQubeLogo.svg +keywords: +- coverage +- security +- code +- quality +kubeVersion: '>= 1.24.0-0' +maintainers: +- email: leo.geoffroy+helm@sonarsource.com + name: leo-geoffroy-sonarsource +- email: carmine.vassallo@sonarsource.com + name: carminevassallo +- email: jeremy.cotineau@sonarsource.com + name: jCOTINEAU +- email: davi.koscianski-vidal@sonarsource.com + name: davividal +name: sonarqube +sources: +- https://github.com/SonarSource/helm-chart-sonarqube +- https://github.com/SonarSource/docker-sonarqube +- https://github.com/SonarSource/sonarqube +type: application +version: 10.2.1+800 diff --git a/helm/sonarqube/README.md b/helm/sonarqube/README.md new file mode 100644 index 0000000..0c66f3d --- /dev/null +++ b/helm/sonarqube/README.md @@ -0,0 +1,528 @@ +# SonarQube + +Code better in up to 27 languages. Improve Code Quality and Code Security throughout your workflow. [SonarQube](https://www.sonarqube.org/) can detect Bugs, Vulnerabilities, Security Hotspots and Code Smells and give you the guidance to fix them. + +## Introduction + +This chart bootstraps an instance of the latest SonarQube version with a PostgreSQL database. + +The latest version of the chart installs the latest SonarQube version. + +To install the version of the chart for SonarQube 9.9 LTS, please read the section [below](#installing-the-sonarqube-99-lts-chart). Deciding between LTS and Latest? [This may help](https://www.sonarsource.com/products/sonarqube/downloads/lts/) + +Please note that this chart only supports SonarQube Community, Developer, and Enterprise editions. + +## Compatibility + +Compatible SonarQube Version: `10.2.1` + +Supported Kubernetes Versions: From `1.24` to `1.27` + +## Installing the chart + +To install the chart: + +```bash +helm repo add sonarqube https://SonarSource.github.io/helm-chart-sonarqube +helm repo update +kubectl create namespace sonarqube +helm upgrade --install -n sonarqube sonarqube sonarqube/sonarqube +``` + +The above command deploys SonarQube on the Kubernetes cluster in the default configuration in the sonarqube namespace. The [configuration](#configuration) section lists the parameters that can be configured during installation. + +The default login is admin/admin. + +## Installing the SonarQube 9.9 LTS chart + +The version of the chart for the SonarQube 9.9 LTS is being distributed as the `8.x.x` version of this chart. + +In order to use it, please set the version constraint `~8`, which is equivalent to `>=8.0.0 && <= 9.0.0`. That version parameter **must** be used in every helm related command including `install`, `upgrade`, `template`, and `diff` (don't treat this as an exhaustive list). + +Example: +``` +helm upgrade --install -n sonarqube --version ~8 sonarqube sonarqube/sonarqube +``` + +To upgrade from the old and unmaintained [sonarqube-lts chart](https://artifacthub.io/packages/helm/sonarqube/sonarqube-lts), please follow the steps described [in this section](#upgrade-from-the-old-sonarqube-lts-to-this-chart). + +## How to use it + +Take some time to read the Deploy on [SonarQube on Kubernetes](https://docs.sonarqube.org/latest/setup/sonarqube-on-kubernetes/) page. +SonarQube deployment on Kubernetes has been tested with the recommendations and constraints documented there, and deployment has some limitations. + +## Uninstalling the chart + +To uninstall/delete the deployment: + +```bash +$ helm list +NAME REVISION UPDATED STATUS CHART NAMESPACE +kindly-newt 1 Mon Oct 2 15:05:44 2017 DEPLOYED sonarqube-0.1.0 sonarqube +$ helm delete kindly-newt +``` + +## Prerequisites and suggested settings for production + +Please read the official documentation prerequisites [here](https://docs.sonarqube.org/latest/requirements/prerequisites-and-overview/). + +### Kubernetes - Pod Security Standards + +The following [Pod Security levels](https://kubernetes.io/docs/concepts/security/pod-security-admission/#pod-security-levels) cannot be used in combination with SonarQube's chart: + +* Baseline. The `init-sysctl` container requires `securityContext.privileged=true`. +* Restricted. In addition to the previous requirement, + * The `sonarqube-postgresql`, `wait-for-db`, `init-sysctl`, and `sonarqube` containers require `securityContext.allowPrivilegeEscalation=true`, unrestricted capabilities, running as `root`, and a `seccompProfile` different from `RuntimeDefault` or `localhost`. + +### Elasticsearch prerequisites + +SonarQube runs Elasticsearch under the hood. + +Elasticsearch is rolling out (strict) prerequisites that cannot be disabled when running in production context (see [this](https://www.elastic.co/blog/bootstrap_checks_annoying_instead_of_devastating) blog post regarding bootstrap checks, and the [official guide](https://www.elastic.co/guide/en/elasticsearch/reference/5.0/bootstrap-checks.html)). + +Because of such constraints, even when running in Docker containers, SonarQube requires some settings at the host/kernel level. + +Please carefully read the following and make sure these configurations are set up at the host level: + +- [vm.max_map_count](https://www.elastic.co/guide/en/elasticsearch/reference/current/vm-max-map-count.html#vm-max-map-count) +- [seccomp filter should be available](https://github.com/SonarSource/docker-sonarqube/issues/614) + +In general, please carefully read the Elasticsearch's [documentation](https://www.elastic.co/guide/en/elasticsearch/reference/current/system-config.html). + +### Production use case + +The SonarQube helm chart is packed with multiple features enabling users to install and test SonarQube on Kubernetes easily. + +Nonetheless, if you intend to run a production-grade SonarQube please follow these recommendations. + +- Set `nginx.enabled` to **false**. This parameter would run the nginx chart. This is useful for testing purposes only. Ingress controllers are critical Kubernetes components, we advise users to install their own. +- Set `postgresql.enabled` to **false**. This parameter would run the postgresql pre-2022 bitnami chart. That is useful for testing purposes, however, given that the database is at the hearth of SonarQube, we advise users to be careful with it and use a well-maintained database as a service or deploy their own database on top of Kubernetes. +- Set `initSysctl.enabled` to **false**. This parameter would run **root** `sysctl` commands, while those sysctl-related values should be set by the Kubernetes administrator at the node level (see [here](#elasticsearch-prerequisites)) +- Set `initFs.enabled` to **false**. This parameter would run **root** `chown` commands. The parameter exists to fix non-posix, CSI, or deprecated drivers. + +## Upgrade + +1. Read through the [SonarQube Upgrade Guide](https://docs.sonarqube.org/latest/setup/upgrading/) to familiarize yourself with the general upgrade process (most importantly, back up your database) +2. Change the SonarQube version on `values.yaml` +3. Redeploy SonarQube with the same helm chart (see [Install instructions](#installing-the-chart)) +4. Browse to http://yourSonarQubeServerURL/setup and follow the setup instructions +5. Reanalyze your projects to get fresh data + +### Upgrade from the old sonarqube-lts to this chart + +Please refer to the Helm upgrade section accessible [here](https://docs.sonarqube.org/latest/setup-and-upgrade/upgrade-the-server/upgrade-guide/) + +## Ingress + +### Path + +Some cloud may need the path to be `/*` instead of `/.` Try this first if you are having issues getting traffic through the ingress. + +### Default Backend + +if you use GCP as a cloud provider you need to set a default backend to avoid useless default backend created by the gce controller. To add this default backend you must set "ingress.class" annotation with "gce" or "gce-internal" value. + +Example: + +```yaml +--- +ingress: + enabled: true + hosts: + - name: sonarqube.example.com + path: "/*" + annotations: + kubernetes.io/ingress.class: "gce-internal" + kubernetes.io/ingress.allow-http: "false" +``` + +## Monitoring + +This Helm chart offers the possibility to monitor SonarQube with Prometheus. + +### Export JMX metrics + +The prometheus exporter (`prometheusExporter.enabled=true`) converts the JMX metrics into a format that Prometheus can understand. After the metrics are exported, you can connect your Prometheus instance and scrape them. + +Per default the JMX metrics for the Web Bean and the CE Bean are exposed on port 8000 and 8001. These values can be configured with `prometheusExporter.webBeanPort` and `prometheusExporter.ceBeanPort`. + +### PodMonitor + +If a Prometheus Operator is deployed in your cluster, you can enable a PodMonitor resource with `prometheusMonitoring.podMonitor.enabled`. It scrapes the Prometheus endpoint `/api/monitoring/metrics` exposed by the SonarQube application. + +## Configuration + +The following table lists the configurable parameters of the SonarQube chart and their default values. + +### Global + +| Parameter | Description | Default | +| --------- | ----------- | ------- | +| `deploymentType` | Deployment Type (supported values are `StatefulSet` or `Deployment`) | `StatefulSet` | +| `replicaCount` | Number of replicas deployed (supported values are 0 and 1) | `1` | +| `deploymentStrategy` | Deployment strategy | `{}` | +| `priorityClassName` | Schedule pods on priority (e.g. `high-priority`) | `None` | +| `schedulerName` | Kubernetes scheduler name | `None` | +| `affinity` | Node / Pod affinities | `{}` | +| `tolerations` | List of node taints to tolerate | `[]` | +| `nodeSelector` | Node labels for pod assignment | `{}` | +| `hostAliases` | Aliases for IPs in /etc/hosts | `[]` | +| `podLabels` | Map of labels to add to the pods | `{}` | +| `env` | Environment variables to attach to the pods | `{}`| +| `annotations` | SonarQube Pod annotations | `{}` | +| `edition` | SonarQube Edition to use (e.g. `community`, `developer` or `enterprise`) | `community` | +| `sonarWebContext` | SonarQube web context, also serve as default value for `ingress.path`, `account.sonarWebContext` and probes path. | `` | + +### NetworkPolicies + +| Parameter | Description | Default | +| --------- | ----------- | ------- | +| `networkPolicy.enabled` | Create NetworkPolicies | `false` | +| `networkPolicy.prometheusNamespace` | Allow incoming traffic to monitoring ports from this namespace | `nil` | +| `networkPolicy.additionalNetworkPolicys` | User defined NetworkPolicies (usefull for external database) | `nil` | + +### OpenShift + +| Parameter | Description | Default | +| --------- | ----------- | ------- | +| `OpenShift.enabled` | Define if this deployment is for OpenShift | `false` | +| `OpenShift.createSCC` | If this deployment is for OpenShift, define if SCC should be created for sonarqube pod | `true` | + +### Image + +| Parameter | Description | Default | +| --------- | ----------- |--------------------------------| +| `image.repository` | image repository | `sonarqube` | +| `image.tag` | `sonarqube` image tag. | `10.2.1-{{ .Values.edition }}` | +| `image.pullPolicy` | Image pull policy | `IfNotPresent` | +| `image.pullSecret` | (DEPRECATED) imagePullSecret to use for private repository | `None` | +| `image.pullSecrets` | imagePullSecrets to use for private repository | `None` | + +### Security + +| Parameter | Description | Default | +| --------- | ----------- | ------- | +| `securityContext.fsGroup` | Group applied to mounted directories/files | `1000` | +| `containerSecurityContext.runAsUser` | User to run containers in sonarqube pod as, unless overwritten (such as for init-sysctl container) | `1000` | + +### Elasticsearch + +| Parameter | Description | Default | +| --------- | ----------- | ------- | +| `elasticsearch.configureNode` | [DEPRECATED] Use initSysctl.enabled instead. | `true` | +| `elasticsearch.bootstrapChecks` | Enables/disables Elasticsearch bootstrap checks | `true` | + +### Service + +| Parameter | Description | Default | +| --------- | ----------- | ------- | +| `service.type` | Kubernetes service type | `ClusterIP` | +| `service.externalPort` | Kubernetes service port | `9000` | +| `service.internalPort` | Kubernetes container port | `9000` | +| `service.labels` | Kubernetes service labels | `None` | +| `service.annotations` | Kubernetes service annotations | `None` | +| `service.loadBalancerSourceRanges` | Kubernetes service LB Allowed inbound IP addresses | `None` | +| `service.loadBalancerIP` | Kubernetes service LB Optional fixed external IP | `None` | + +### Ingress + +| Parameter | Description | Default | +| --------- | ----------- | ------- | +| `nginx.enabled` | Also install Nginx Ingress Helm | `false` | +| `ingress.enabled` | Flag to enable Ingress | `false` | +| `ingress.labels` | Ingress additional labels | `{}` | +| `ingress.hosts[0].name` | Hostname to your SonarQube installation | `sonarqube.your-org.com` | +| `ingress.hosts[0].path` | Path within the URL structure | `/` | +| `ingress.hosts[0].serviceName` | Optional field to override the default serviceName of a path | `None` | +| `ingress.hosts[0].servicePort` | Optional field to override the default servicePort of a path | `None` | +| `ingress.tls` | Ingress secrets for TLS certificates | `[]` | +| `ingress.ingressClassName` | Optional field to configure ingress class name | `None` | +| `ingress.annotations` | Field to add extra annotations to the ingress | {`nginx.ingress.kubernetes.io/proxy-body-size=64m`} | +| `ingress.annotations.nginx.ingress.kubernetes.io/proxy-body-size` | Field to set the maximum allowed size of the client request body | `64m` | + +### Route + +| Parameter | Description | Default | +| --------- | ----------- | ------- | +| `route.enabled` | Flag to enable OpenShift Route | `false` | +| `route.host` | Host of the route | `""` | +| `route.tls.termination` | TLS termination type. Currently supported values are `edge` and `passthrough` | `edge` | +| `route.annotations` | Optional field to add extra annotations to the route | `None` | +| `route.labels` | Route additional labels | `{}` | + +### Probes + +| Parameter | Description | Default | +| --------- | ----------- | ------- | +| `readinessProbe.initialDelaySeconds` | ReadinessProbe initial delay for SonarQube checking | `60` | +| `readinessProbe.periodSeconds` | ReadinessProbe period between checking SonarQube | `30` | +| `readinessProbe.failureThreshold` | ReadinessProbe threshold for marking as failed | `6` | +| `readinessProbe.timeoutSeconds`| ReadinessProbe timeout delay | `1` | +| `readinessProbe.sonarWebContext` | (DEPRECATED) SonarQube web context for readinessProbe, please use sonarWebContext at the value top level instead | `/` | +| `livenessProbe.initialDelaySeconds` | LivenessProbe initial delay for SonarQube checking | `60` | +| `livenessProbe.periodSeconds` | LivenessProbe period between checking SonarQube | `30` | +| `livenessProbe.sonarWebContext` | (DEPRECATED) SonarQube web context for LivenessProbe, please use sonarWebContext at the value top level instead | `/` | +| `livenessProbe.failureThreshold` | LivenessProbe threshold for marking as dead | `6` | +| `livenessProbe.timeoutSeconds`| LivenessProbe timeout delay | `1` | +| `startupProbe.initialDelaySeconds` | StartupProbe initial delay for SonarQube checking | `30` | +| `startupProbe.periodSeconds` | StartupProbe period between checking SonarQube | `10` | +| `startupProbe.sonarWebContext` | (DEPRECATED) SonarQube web context for StartupProbe, please use sonarWebContext at the value top level instead | `/` | +| `startupProbe.failureThreshold` | StartupProbe threshold for marking as failed | `24` | +| `startupProbe.timeoutSeconds`| StartupProbe timeout delay | `1` | + +### InitContainers + +| Parameter | Description | Default | +| --------- | ----------- | ------- | +| `initContainers.image` | Change init container image | `busybox:1.32` | +| `initContainers.securityContext` | SecurityContext for init containers | `None` | +| `initContainers.resources` | Resources for init containers | `{}` | +| `extraInitContainers` | Extra init containers to e.g. download required artifacts | `{}` | +| `caCerts.enabled` | Flag for enabling additional CA certificates | `false` | +| `caCerts.image` | Change init CA certificates container image | `adoptopenjdk/openjdk11:alpine` | +| `caCerts.secret` | Name of the secret containing additional CA certificates | `None` | +| `initSysctl.enabled` | Modify k8s worker to conform to system requirements | `true` | +| `initSysctl.vmMaxMapCount` | Set init sysctl container vm.max_map_count | `524288` | +| `initSysctl.fsFileMax` | Set init sysctl container fs.file-max | `131072` | +| `initSysctl.nofile` | Set init sysctl container open file descriptors limit | `131072` | +| `initSysctl.nproc` | Set init sysctl container open threads limit | `8192 ` | +| `initSysctl.image` | Change init sysctl container image | `busybox:1.32` | +| `initSysctl.securityContext` | InitSysctl container security context | `{privileged: true}` | +| `initSysctl.resources` | InitSysctl container resource requests & limits | `{}` | +| `initFs.enabled` | Enable file permission change with init container | `true` | +| `initFs.image` | InitFS container image | `busybox:1.32` | +| `initFs.securityContext.privileged` | InitFS container needs to run privileged | `true` | + +### Monitoring (Prometheus Exporter) + +| Parameter | Description | Default | +| --------- | ----------- | ------- | +| `prometheusExporter.enabled` | Use the Prometheus JMX exporter | `false` | +| `prometheusExporter.version` | jmx_prometheus_javaagent version to download from Maven Central | `0.17.2` | +| `prometheusExporter.noCheckCertificate` | Flag to not check server's certificate when downloading jmx_prometheus_javaagent | `false` | +| `prometheusExporter.webBeanPort` | Port where the jmx_prometheus_javaagent exposes the metrics for the webBean | `8000` | +| `prometheusExporter.ceBeanPort` | Port where the jmx_prometheus_javaagent exposes the metrics for the ceBean | `8001` | +| `prometheusExporter.downloadURL` | Alternative full download URL for the jmx_prometheus_javaagent.jar (overrides `prometheusExporter.version`) | `""` | +| `prometheusExporter.config` | Prometheus JMX exporter config yaml for the web process, and the CE process if `prometheusExporter.ceConfig` is not set | see `values.yaml` | +| `prometheusExporter.ceConfig` | Prometheus JMX exporter config yaml for the CE process (by default, `prometheusExporter.config` is used) | `None` | +| `prometheusExporter.httpProxy` | HTTP proxy for downloading JMX agent | `""` | +| `prometheusExporter.httpsProxy` | HTTPS proxy for downloading JMX agent | `""` | +| `prometheusExporter.noProxy` | No proxy for downloading JMX agent | `""` | +| `prometheusExporter.securityContext` | Security context for downloading the jmx agent | see `values.yaml` | + +### Monitoring (Prometheus PodMonitor) + +| Parameter | Description | Default | +| --------- | ----------- | ------- | +| `prometheusMonitoring.podMonitor.enabled` | Enable Prometheus PodMonitor | `false` | +| `prometheusMonitoring.podMonitor.namespace` | Specify a custom namespace where the PodMonitor will be created | `default` | +| `prometheusMonitoring.podMonitor.interval` | Specify the interval how often metrics should be scraped | `30s` | +| `prometheusMonitoring.podMonitor.scrapeTimeout` | Specify the timeout after a scrape is ended | `None` | +| `prometheusMonitoring.podMonitor.jobLabel` | Name of the label on target services that prometheus uses as job name | `None` | + + +### Plugins + +| Parameter | Description | Default | +| --------- | ----------- | ------- | +| `plugins.install` | Link(s) to the plugin JARs to download and install | `[]` | +| `plugins.resources` | Plugin Pod resource requests & limits | `{}` | +| `plugins.httpProxy` | For use behind a corporate proxy when downloading plugins | `""` | +| `plugins.httpsProxy` | For use behind a corporate proxy when downloading plugins | `""` | +| `plugins.noProxy` | For use behind a corporate proxy when downloading plugins | `""` | +| `plugins.image` | Image for plugins container | `""`| +| `plugins.resources` | Resources for plugins container | `{}` | +| `plugins.netrcCreds` | Name of the secret containing .netrc file to use creds when downloading plugins | `""` | +| `plugins.noCheckCertificate` | Flag to not check server's certificate when downloading plugins | `false` | +| `plugins.securityContext` | Security context for the container to download plugins | see `values.yaml` | + +### SonarQube Specific + +| Parameter | Description | Default | +| --------- | ----------- | ------- | +| `jvmOpts` | (DEPRECATED) Values to add to SONARQUBE_WEB_JVM_OPTS | `""` | +| `jvmCeOpts` | (DEPRECATED) Values to add to SONAR_CE_JAVAOPTS | `""` | +| `sonarqubeFolder` | Directory name of SonarQube | `/opt/sonarqube` | +| `sonarProperties` | Custom `sonar.properties` key-value pairs (e.g., "sonarProperties.sonar.forceAuthentication=true") | `None` | +| `sonarSecretProperties` | Additional `sonar.properties` key-value pairs to load from a secret | `None` | +| `sonarSecretKey` | Name of existing secret used for settings encryption | `None` | +| `monitoringPasscode` | Value for sonar.web.systemPasscode needed for LivenessProbes (encoded to Base64 format) | `define_it` | +| `monitoringPasscodeSecretName` | Name of the secret where to load `monitoringPasscode` | `None` | +| `monitoringPasscodeSecretKey` | Key of an existing secret containing `monitoringPasscode` | `None` | +| `extraContainers` | Array of extra containers to run alongside the `sonarqube` container (aka. Sidecars) | `[]` | +| `extraVolumes` | Array of extra volumes to add to the SonarQube deployment | `[]` | +| `extraVolumeMounts` | Array of extra volume mounts to add to the SonarQube deployment | `[]` | + +### Resources + +| Parameter | Description | Default | +| --------- | ----------- | ------- | +| `resources.requests.memory` | SonarQube memory request | `2Gi` | +| `resources.requests.cpu` | SonarQube cpu request | `400m` | +| `resources.limits.memory` | SonarQube memory limit | `4Gi` | +| `resources.limits.cpu` | SonarQube cpu limit | `800m` | + +### Persistence + +| Parameter | Description | Default | +| --------- | ----------- | ------- | +| `persistence.enabled` | Flag for enabling persistent storage | `false` | +| `persistence.annotations` | Kubernetes pvc annotations | `{}` | +| `persistence.existingClaim` | Do not create a new PVC but use this one | `None` | +| `persistence.storageClass` | Storage class to be used | `""` | +| `persistence.accessMode` | Volumes access mode to be set | `ReadWriteOnce` | +| `persistence.size` | Size of the volume | `5Gi` | +| `persistence.volumes` | Specify extra volumes. Refer to ".spec.volumes" specification | `[]` | +| `persistence.mounts` | Specify extra mounts. Refer to ".spec.containers.volumeMounts" specification | `[]` | +| `emptyDir` | Configuration of resources for `emptyDir` | `{}` | + +### JDBC Overwrite + +| Parameter | Description | Default | +| --------- | ----------- | ------- | +| `jdbcOverwrite.enable` | Enable JDBC overwrites for external Databases (disables `postgresql.enabled`) | `false` | +| `jdbcOverwrite.jdbcUrl` | The JDBC url to connect the external DB | `jdbc:postgresql://myPostgress/myDatabase?socketTimeout=1500` | +| `jdbcOverwrite.jdbcUsername` | The DB user that should be used for the JDBC connection | `sonarUser` | +| `jdbcOverwrite.jdbcPassword` | The DB password that should be used for the JDBC connection (Use this if you don't mind the DB password getting stored in plain text within the values file) | `sonarPass` | +| `jdbcOverwrite.jdbcSecretName` | Alternatively, use a pre-existing k8s secret containing the DB password | `None` | +| `jdbcOverwrite.jdbcSecretPasswordKey` | If the pre-existing k8s secret is used this allows the user to overwrite the 'key' of the password property in the secret | `None` | + +### Bundled Postgres Chart + +| Parameter | Description | Default | +| --------- | ----------- | ------- | +| `postgresql.enabled` | Set to `false` to use external server | `true` | +| `postgresql.existingSecret` | existingSecret Name of existing secret to use for PostgreSQL passwords | `nil` | +| `postgresql.postgresqlServer` | (DEPRECATED) Hostname of the external Postgresql server | `nil` | +| `postgresql.postgresqlUsername` | Postgresql database user | `sonarUser` | +| `postgresql.postgresqlPassword` | Postgresql database password | `sonarPass` | +| `postgresql.postgresqlDatabase` | Postgresql database name | `sonarDB` | +| `postgresql.service.port` | Postgresql port | `5432` | +| `postgresql.resources.requests.memory` | Postgresql memory request | `256Mi` | +| `postgresql.resources.requests.cpu` | Postgresql cpu request | `250m` | +| `postgresql.resources.limits.memory` | Postgresql memory limit | `2Gi` | +| `postgresql.resources.limits.cpu` | Postgresql cpu limit | `2` | +| `postgresql.persistence.enabled` | Postgresql persistence en/disabled | `true` | +| `postgresql.persistence.accessMode` | Postgresql persistence accessMode | `ReadWriteOnce` | +| `postgresql.persistence.size` | Postgresql persistence size | `20Gi` | +| `postgresql.persistence.storageClass` | Postgresql persistence storageClass | `""` | +| `postgresql.securityContext.enabled` | Postgresql securityContext en/disabled | `true` | +| `postgresql.securityContext.fsGroup` | Postgresql securityContext fsGroup | `1001` | +| `postgresql.securityContext.runAsUser` | Postgresql securityContext runAsUser | `1001` | +| `postgresql.volumePermissions.enabled` | Postgres vol permissions en/disabled | `false` | +| `postgresql.volumePermissions.securityContext.runAsUser` | Postgres vol permissions secContext runAsUser | `0` | +| `postgresql.shmVolume.chmod.enabled` | Postgresql shared memory vol en/disabled | `false` | +| `postgresql.serivceAccount.enabled` | Postgresql service Account creation en/disabled | `false` | +| `postgresql.serivceAccount.name` | Postgresql service Account name | `""` | + +### Tests + +| Parameter | Description | Default | +|------------------------------|---------------------------------------------------------------| ------- | +| `tests.enabled` | Flag that allows tests to be excluded from the generated yaml | `true` | +| `tests.image` | Change test container image | `` | + +### ServiceAccount + +| Parameter | Description | Default | +|---------------------------------|--------------------------------------------------------------------------------------|-----------------------| +| `serviceAccount.create` | If set to true, create a serviceAccount | `false` | +| `serviceAccount.name` | Name of the serviceAccount to create/use | `sonarqube-sonarqube` | +| `serviceAccount.automountToken` | Manage `automountServiceAccountToken` field for mounting service account credentials | `false` | +| `serviceAccount.annotations` | Additional serviceAccount annotations | `{}` | + +### ExtraConfig + +| Parameter | Description | Default | +| --------- | ----------- | ------- | +| `extraConfig.secrets` | A list of `Secret`s (which must contain key/value pairs) which may be loaded into the Scanner as environment variables | `[]` | +| `extraConfig.configmaps` | A list of `ConfigMap`s (which must contain key/value pairs) which may be loaded into the Scanner as environment variables | `[]` | + +### Advanced Options + +| Parameter | Description | Default | +| --------- | ----------- | ------- | +| `account.adminPassword` | Custom admin password | `admin` | +| `account.currentAdminPassword` | Current admin password | `admin` | +| `account.adminPasswordSecretName` | Secret containing `password` (custom password) and `currentPassword` (current password) keys for admin | `None` | +| `account.resources.requests.memory` | Memory request for Admin hook | `128Mi` | +| `account.resources.requests.cpu` | CPU request for Admin hook | `100m` | +| `account.resources.limits.memory` | Memory limit for Admin hook | `128Mi` | +| `account.resources.limits.cpu` | CPU limit for Admin hook | `100m` | +| `account.sonarWebContext` | (DEPRECATED) SonarQube web context for Admin hook. please use sonarWebContext at the value top level instead | `nil` | +| `account.securityContext` | SecurityContext for change-password-hook | `{}` | +| `curlContainerImage` | Curl container image | `curlimages/curl:8.2.0` | +| `adminJobAnnotations` | Custom annotations for admin hook Job | `{}` | +| `terminationGracePeriodSeconds` | Configuration of `terminationGracePeriodSeconds` | `60` | + +You can also configure values for the PostgreSQL database via the Postgresql [Chart](https://hub.helm.sh/charts/bitnami/postgresql) + +For overriding variables see: [Customizing the chart](https://helm.sh/docs/intro/using_helm/#customizing-the-chart-before-installing) + +### Use custom `cacerts` + +In environments with air-gapped setup, especially with internal tooling (repos) and self-signed certificates it is required to provide an adequate `cacerts` which overrides the default one: + +1. Create a yaml file `cacerts.yaml` with a secret that contains one or more keys to represent the certificates that you want including + + ```yaml + apiVersion: v1 + kind: Secret + metadata: + name: my-cacerts + stringData: + cert-1.crt: | + xxxxxxxxxxxxxxxxxxxxxxx + ``` + +2. Upload your `cacerts.yaml` to a secret in the cluster you are installing SonarQube to. + + ```shell + kubectl apply -f cacerts.yaml + ``` + +3. Set the following values of the chart: + + ```yaml + caCerts: + enabled: true + secret: my-cacerts + ``` + +### Elasticsearch Settings + +Since SonarQube comes bundled with an Elasticsearch instance, some [bootstrap checks](https://www.elastic.co/guide/en/elasticsearch/reference/master/bootstrap-checks.html) of the host settings are done at start. + +This chart offers the option to use an initContainer in privilaged mode to automatically set certain kernel settings on the kube worker. While this can ensure proper functionality of Elasticsearch, modifying the underlying kernel settings on the Kubernetes node can impact other users. It may be best to work with your cluster administrator to either provide specific nodes with the proper kernel settings, or ensure they are set cluster wide. + +To enable auto-configuration of the kube worker node, set `elasticsearch.configureNode` to `true`. This is the default behavior, so you do not need to explicitly set this. + +This will run `sysctl -w vm.max_map_count=262144` on the worker where the sonarqube pod(s) get scheduled. This needs to be set to `262144` but normally defaults to `65530`. Other kernel settings are recommended by the [docker image](https://hub.docker.com/_/sonarqube/#requirements), but the defaults work fine in most cases. + +To disable worker node configuration, set `elasticsearch.configureNode` to `false`. Note that if node configuration is not enabled, then you will likely need to also disable the Elasticsearch bootstrap checks. These can be explicitly disabled by setting `elasticsearch.bootstrapChecks` to `false`. + +### Extra Config + +For environments where another tool, such as terraform or ansible, is used to provision infrastructure or passwords then setting databases addresses and credentials via helm becomes less than ideal. Ditto for environments where this config may be visible. + +In such environments, configuration may be read, via environment variables, from Secrets and ConfigMaps. + +1. Create a `ConfigMap` (or `Secret`) containing key/value pairs, as expected by SonarQube. + + ```yaml + apiVersion: v1 + kind: ConfigMap + metadata: + name: external-sonarqube-opts + data: + SONARQUBE_JDBC_USERNAME: foo + SONARQUBE_JDBC_URL: jdbc:postgresql://db.example.com:5432/sonar + ``` + +2. Set the following in your `values.yaml` (using the key `extraConfig.secrets` to reference `Secret`s) + + ```yaml + extraConfig: + configmaps: + - external-sonarqube-opts + ``` diff --git a/helm/sonarqube/charts/ingress-nginx/.helmignore b/helm/sonarqube/charts/ingress-nginx/.helmignore new file mode 100644 index 0000000..50af031 --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/.helmignore @@ -0,0 +1,22 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/helm/sonarqube/charts/ingress-nginx/CHANGELOG.md b/helm/sonarqube/charts/ingress-nginx/CHANGELOG.md new file mode 100644 index 0000000..7d81ac1 --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/CHANGELOG.md @@ -0,0 +1,460 @@ +# Changelog + +This file documents all notable changes to [ingress-nginx](https://github.com/kubernetes/ingress-nginx) Helm Chart. The release numbering uses [semantic versioning](http://semver.org). + +### 4.4.0 + +* Adding support for disabling liveness and readiness probes to the Helm chart by @njegosrailic in https://github.com/kubernetes/ingress-nginx/pull/9238 +* add:(admission-webhooks) ability to set securityContext by @ybelMekk in https://github.com/kubernetes/ingress-nginx/pull/9186 +* #7652 - Updated Helm chart to use the fullname for the electionID if not specified. by @FutureMatt in https://github.com/kubernetes/ingress-nginx/pull/9133 +* Rename controller-wehbooks-networkpolicy.yaml. by @Gacko in https://github.com/kubernetes/ingress-nginx/pull/9123 + +### 4.3.0 +- Support for Kubernetes v.1.25.0 was added and support for endpoint slices +- Support for Kubernetes v1.20.0 and v1.21.0 was removed +- [8890](https://github.com/kubernetes/ingress-nginx/pull/8890) migrate to endpointslices +- [9059](https://github.com/kubernetes/ingress-nginx/pull/9059) kubewebhookcertgen sha change after go1191 +- [9046](https://github.com/kubernetes/ingress-nginx/pull/9046) Parameterize metrics port name +- [9104](https://github.com/kubernetes/ingress-nginx/pull/9104) Fix yaml formatting error with multiple annotations + +### 4.2.1 + +- The sha of kube-webhook-certgen image & the opentelemetry image, in values file, was changed to new images built on alpine-v3.16.1 +- "[8896](https://github.com/kubernetes/ingress-nginx/pull/8896) updated to new images built today" + +### 4.2.0 + +- Support for Kubernetes v1.19.0 was removed +- "[8810](https://github.com/kubernetes/ingress-nginx/pull/8810) Prepare for v1.3.0" +- "[8808](https://github.com/kubernetes/ingress-nginx/pull/8808) revert arch var name" +- "[8805](https://github.com/kubernetes/ingress-nginx/pull/8805) Bump k8s.io/klog/v2 from 2.60.1 to 2.70.1" +- "[8803](https://github.com/kubernetes/ingress-nginx/pull/8803) Update to nginx base with alpine v3.16" +- "[8802](https://github.com/kubernetes/ingress-nginx/pull/8802) chore: start v1.3.0 release process" +- "[8798](https://github.com/kubernetes/ingress-nginx/pull/8798) Add v1.24.0 to test matrix" +- "[8796](https://github.com/kubernetes/ingress-nginx/pull/8796) fix: add MAC_OS variable for static-check" +- "[8793](https://github.com/kubernetes/ingress-nginx/pull/8793) changed to alpine-v3.16" +- "[8781](https://github.com/kubernetes/ingress-nginx/pull/8781) Bump github.com/stretchr/testify from 1.7.5 to 1.8.0" +- "[8778](https://github.com/kubernetes/ingress-nginx/pull/8778) chore: remove stable.txt from release process" +- "[8775](https://github.com/kubernetes/ingress-nginx/pull/8775) Remove stable" +- "[8773](https://github.com/kubernetes/ingress-nginx/pull/8773) Bump github/codeql-action from 2.1.14 to 2.1.15" +- "[8772](https://github.com/kubernetes/ingress-nginx/pull/8772) Bump ossf/scorecard-action from 1.1.1 to 1.1.2" +- "[8771](https://github.com/kubernetes/ingress-nginx/pull/8771) fix bullet md format" +- "[8770](https://github.com/kubernetes/ingress-nginx/pull/8770) Add condition for monitoring.coreos.com/v1 API" +- "[8769](https://github.com/kubernetes/ingress-nginx/pull/8769) Fix typos and add links to developer guide" +- "[8767](https://github.com/kubernetes/ingress-nginx/pull/8767) change v1.2.0 to v1.2.1 in deploy doc URLs" +- "[8765](https://github.com/kubernetes/ingress-nginx/pull/8765) Bump github/codeql-action from 1.0.26 to 2.1.14" +- "[8752](https://github.com/kubernetes/ingress-nginx/pull/8752) Bump github.com/spf13/cobra from 1.4.0 to 1.5.0" +- "[8751](https://github.com/kubernetes/ingress-nginx/pull/8751) Bump github.com/stretchr/testify from 1.7.2 to 1.7.5" +- "[8750](https://github.com/kubernetes/ingress-nginx/pull/8750) added announcement" +- "[8740](https://github.com/kubernetes/ingress-nginx/pull/8740) change sha e2etestrunner and echoserver" +- "[8738](https://github.com/kubernetes/ingress-nginx/pull/8738) Update docs to make it easier for noobs to follow step by step" +- "[8737](https://github.com/kubernetes/ingress-nginx/pull/8737) updated baseimage sha" +- "[8736](https://github.com/kubernetes/ingress-nginx/pull/8736) set ld-musl-path" +- "[8733](https://github.com/kubernetes/ingress-nginx/pull/8733) feat: migrate leaderelection lock to leases" +- "[8726](https://github.com/kubernetes/ingress-nginx/pull/8726) prometheus metric: upstream_latency_seconds" +- "[8720](https://github.com/kubernetes/ingress-nginx/pull/8720) Ci pin deps" +- "[8719](https://github.com/kubernetes/ingress-nginx/pull/8719) Working OpenTelemetry sidecar (base nginx image)" +- "[8714](https://github.com/kubernetes/ingress-nginx/pull/8714) Create Openssf scorecard" +- "[8708](https://github.com/kubernetes/ingress-nginx/pull/8708) Bump github.com/prometheus/common from 0.34.0 to 0.35.0" +- "[8703](https://github.com/kubernetes/ingress-nginx/pull/8703) Bump actions/dependency-review-action from 1 to 2" +- "[8701](https://github.com/kubernetes/ingress-nginx/pull/8701) Fix several typos" +- "[8699](https://github.com/kubernetes/ingress-nginx/pull/8699) fix the gosec test and a make target for it" +- "[8698](https://github.com/kubernetes/ingress-nginx/pull/8698) Bump actions/upload-artifact from 2.3.1 to 3.1.0" +- "[8697](https://github.com/kubernetes/ingress-nginx/pull/8697) Bump actions/setup-go from 2.2.0 to 3.2.0" +- "[8695](https://github.com/kubernetes/ingress-nginx/pull/8695) Bump actions/download-artifact from 2 to 3" +- "[8694](https://github.com/kubernetes/ingress-nginx/pull/8694) Bump crazy-max/ghaction-docker-buildx from 1.6.2 to 3.3.1" + +### 4.1.2 + +- "[8587](https://github.com/kubernetes/ingress-nginx/pull/8587) Add CAP_SYS_CHROOT to DS/PSP when needed" +- "[8458](https://github.com/kubernetes/ingress-nginx/pull/8458) Add portNamePreffix Helm chart parameter" +- "[8522](https://github.com/kubernetes/ingress-nginx/pull/8522) Add documentation for controller.service.loadBalancerIP in Helm chart" + +### 4.1.0 + +- "[8481](https://github.com/kubernetes/ingress-nginx/pull/8481) Fix log creation in chroot script" +- "[8479](https://github.com/kubernetes/ingress-nginx/pull/8479) changed nginx base img tag to img built with alpine3.14.6" +- "[8478](https://github.com/kubernetes/ingress-nginx/pull/8478) update base images and protobuf gomod" +- "[8468](https://github.com/kubernetes/ingress-nginx/pull/8468) Fallback to ngx.var.scheme for redirectScheme with use-forward-headers when X-Forwarded-Proto is empty" +- "[8456](https://github.com/kubernetes/ingress-nginx/pull/8456) Implement object deep inspector" +- "[8455](https://github.com/kubernetes/ingress-nginx/pull/8455) Update dependencies" +- "[8454](https://github.com/kubernetes/ingress-nginx/pull/8454) Update index.md" +- "[8447](https://github.com/kubernetes/ingress-nginx/pull/8447) typo fixing" +- "[8446](https://github.com/kubernetes/ingress-nginx/pull/8446) Fix suggested annotation-value-word-blocklist" +- "[8444](https://github.com/kubernetes/ingress-nginx/pull/8444) replace deprecated topology key in example with current one" +- "[8443](https://github.com/kubernetes/ingress-nginx/pull/8443) Add dependency review enforcement" +- "[8434](https://github.com/kubernetes/ingress-nginx/pull/8434) added new auth-tls-match-cn annotation" +- "[8426](https://github.com/kubernetes/ingress-nginx/pull/8426) Bump github.com/prometheus/common from 0.32.1 to 0.33.0" + +### 4.0.18 + +- "[8291](https://github.com/kubernetes/ingress-nginx/pull/8291) remove git tag env from cloud build" +- "[8286](https://github.com/kubernetes/ingress-nginx/pull/8286) Fix OpenTelemetry sidecar image build" +- "[8277](https://github.com/kubernetes/ingress-nginx/pull/8277) Add OpenSSF Best practices badge" +- "[8273](https://github.com/kubernetes/ingress-nginx/pull/8273) Issue#8241" +- "[8267](https://github.com/kubernetes/ingress-nginx/pull/8267) Add fsGroup value to admission-webhooks/job-patch charts" +- "[8262](https://github.com/kubernetes/ingress-nginx/pull/8262) Updated confusing error" +- "[8256](https://github.com/kubernetes/ingress-nginx/pull/8256) fix: deny locations with invalid auth-url annotation" +- "[8253](https://github.com/kubernetes/ingress-nginx/pull/8253) Add a certificate info metric" +- "[8236](https://github.com/kubernetes/ingress-nginx/pull/8236) webhook: remove useless code." +- "[8227](https://github.com/kubernetes/ingress-nginx/pull/8227) Update libraries in webhook image" +- "[8225](https://github.com/kubernetes/ingress-nginx/pull/8225) fix inconsistent-label-cardinality for prometheus metrics: nginx_ingress_controller_requests" +- "[8221](https://github.com/kubernetes/ingress-nginx/pull/8221) Do not validate ingresses with unknown ingress class in admission webhook endpoint" +- "[8210](https://github.com/kubernetes/ingress-nginx/pull/8210) Bump github.com/prometheus/client_golang from 1.11.0 to 1.12.1" +- "[8209](https://github.com/kubernetes/ingress-nginx/pull/8209) Bump google.golang.org/grpc from 1.43.0 to 1.44.0" +- "[8204](https://github.com/kubernetes/ingress-nginx/pull/8204) Add Artifact Hub lint" +- "[8203](https://github.com/kubernetes/ingress-nginx/pull/8203) Fix Indentation of example and link to cert-manager tutorial" +- "[8201](https://github.com/kubernetes/ingress-nginx/pull/8201) feat(metrics): add path and method labels to requests countera" +- "[8199](https://github.com/kubernetes/ingress-nginx/pull/8199) use functional options to reduce number of methods creating an EchoDeployment" +- "[8196](https://github.com/kubernetes/ingress-nginx/pull/8196) docs: fix inconsistent controller annotation" +- "[8191](https://github.com/kubernetes/ingress-nginx/pull/8191) Using Go install for misspell" +- "[8186](https://github.com/kubernetes/ingress-nginx/pull/8186) prometheus+grafana using servicemonitor" +- "[8185](https://github.com/kubernetes/ingress-nginx/pull/8185) Append elements on match, instead of removing for cors-annotations" +- "[8179](https://github.com/kubernetes/ingress-nginx/pull/8179) Bump github.com/opencontainers/runc from 1.0.3 to 1.1.0" +- "[8173](https://github.com/kubernetes/ingress-nginx/pull/8173) Adding annotations to the controller service account" +- "[8163](https://github.com/kubernetes/ingress-nginx/pull/8163) Update the $req_id placeholder description" +- "[8162](https://github.com/kubernetes/ingress-nginx/pull/8162) Versioned static manifests" +- "[8159](https://github.com/kubernetes/ingress-nginx/pull/8159) Adding some geoip variables and default values" +- "[8155](https://github.com/kubernetes/ingress-nginx/pull/8155) #7271 feat: avoid-pdb-creation-when-default-backend-disabled-and-replicas-gt-1" +- "[8151](https://github.com/kubernetes/ingress-nginx/pull/8151) Automatically generate helm docs" +- "[8143](https://github.com/kubernetes/ingress-nginx/pull/8143) Allow to configure delay before controller exits" +- "[8136](https://github.com/kubernetes/ingress-nginx/pull/8136) add ingressClass option to helm chart - back compatibility with ingress.class annotations" +- "[8126](https://github.com/kubernetes/ingress-nginx/pull/8126) Example for JWT" + + +### 4.0.15 + +- [8120] https://github.com/kubernetes/ingress-nginx/pull/8120 Update go in runner and release v1.1.1 +- [8119] https://github.com/kubernetes/ingress-nginx/pull/8119 Update to go v1.17.6 +- [8118] https://github.com/kubernetes/ingress-nginx/pull/8118 Remove deprecated libraries, update other libs +- [8117] https://github.com/kubernetes/ingress-nginx/pull/8117 Fix codegen errors +- [8115] https://github.com/kubernetes/ingress-nginx/pull/8115 chart/ghaction: set the correct permission to have access to push a release +- [8098] https://github.com/kubernetes/ingress-nginx/pull/8098 generating SHA for CA only certs in backend_ssl.go + comparison of P… +- [8088] https://github.com/kubernetes/ingress-nginx/pull/8088 Fix Edit this page link to use main branch +- [8072] https://github.com/kubernetes/ingress-nginx/pull/8072 Expose GeoIP2 Continent code as variable +- [8061] https://github.com/kubernetes/ingress-nginx/pull/8061 docs(charts): using helm-docs for chart +- [8058] https://github.com/kubernetes/ingress-nginx/pull/8058 Bump github.com/spf13/cobra from 1.2.1 to 1.3.0 +- [8054] https://github.com/kubernetes/ingress-nginx/pull/8054 Bump google.golang.org/grpc from 1.41.0 to 1.43.0 +- [8051] https://github.com/kubernetes/ingress-nginx/pull/8051 align bug report with feature request regarding kind documentation +- [8046] https://github.com/kubernetes/ingress-nginx/pull/8046 Report expired certificates (#8045) +- [8044] https://github.com/kubernetes/ingress-nginx/pull/8044 remove G109 check till gosec resolves issues +- [8042] https://github.com/kubernetes/ingress-nginx/pull/8042 docs_multiple_instances_one_cluster_ticket_7543 +- [8041] https://github.com/kubernetes/ingress-nginx/pull/8041 docs: fix typo'd executable name +- [8035] https://github.com/kubernetes/ingress-nginx/pull/8035 Comment busy owners +- [8029] https://github.com/kubernetes/ingress-nginx/pull/8029 Add stream-snippet as a ConfigMap and Annotation option +- [8023] https://github.com/kubernetes/ingress-nginx/pull/8023 fix nginx compilation flags +- [8021] https://github.com/kubernetes/ingress-nginx/pull/8021 Disable default modsecurity_rules_file if modsecurity-snippet is specified +- [8019] https://github.com/kubernetes/ingress-nginx/pull/8019 Revise main documentation page +- [8018] https://github.com/kubernetes/ingress-nginx/pull/8018 Preserve order of plugin invocation +- [8015] https://github.com/kubernetes/ingress-nginx/pull/8015 Add newline indenting to admission webhook annotations +- [8014] https://github.com/kubernetes/ingress-nginx/pull/8014 Add link to example error page manifest in docs +- [8009] https://github.com/kubernetes/ingress-nginx/pull/8009 Fix spelling in documentation and top-level files +- [8008] https://github.com/kubernetes/ingress-nginx/pull/8008 Add relabelings in controller-servicemonitor.yaml +- [8003] https://github.com/kubernetes/ingress-nginx/pull/8003 Minor improvements (formatting, consistency) in install guide +- [8001] https://github.com/kubernetes/ingress-nginx/pull/8001 fix: go-grpc Dockerfile +- [7999] https://github.com/kubernetes/ingress-nginx/pull/7999 images: use k8s-staging-test-infra/gcb-docker-gcloud +- [7996] https://github.com/kubernetes/ingress-nginx/pull/7996 doc: improvement +- [7983] https://github.com/kubernetes/ingress-nginx/pull/7983 Fix a couple of misspellings in the annotations documentation. +- [7979] https://github.com/kubernetes/ingress-nginx/pull/7979 allow set annotations for admission Jobs +- [7977] https://github.com/kubernetes/ingress-nginx/pull/7977 Add ssl_reject_handshake to default server +- [7975] https://github.com/kubernetes/ingress-nginx/pull/7975 add legacy version update v0.50.0 to main changelog +- [7972] https://github.com/kubernetes/ingress-nginx/pull/7972 updated service upstream definition + +### 4.0.14 + +- [8061] https://github.com/kubernetes/ingress-nginx/pull/8061 Using helm-docs to populate values table in README.md + +### 4.0.13 + +- [8008] https://github.com/kubernetes/ingress-nginx/pull/8008 Add relabelings in controller-servicemonitor.yaml + +### 4.0.12 + +- [7978] https://github.com/kubernetes/ingress-nginx/pull/7979 Support custom annotations in admissions Jobs + +### 4.0.11 + +- [7873] https://github.com/kubernetes/ingress-nginx/pull/7873 Makes the [appProtocol](https://kubernetes.io/docs/concepts/services-networking/_print/#application-protocol) field optional. + +### 4.0.10 + +- [7964] https://github.com/kubernetes/ingress-nginx/pull/7964 Update controller version to v1.1.0 + +### 4.0.9 + +- [6992] https://github.com/kubernetes/ingress-nginx/pull/6992 Add ability to specify labels for all resources + +### 4.0.7 + +- [7923] https://github.com/kubernetes/ingress-nginx/pull/7923 Release v1.0.5 of ingress-nginx +- [7806] https://github.com/kubernetes/ingress-nginx/pull/7806 Choice option for internal/external loadbalancer type service + +### 4.0.6 + +- [7804] https://github.com/kubernetes/ingress-nginx/pull/7804 Release v1.0.4 of ingress-nginx +- [7651] https://github.com/kubernetes/ingress-nginx/pull/7651 Support ipFamilyPolicy and ipFamilies fields in Helm Chart +- [7798] https://github.com/kubernetes/ingress-nginx/pull/7798 Exoscale: use HTTP Healthcheck mode +- [7793] https://github.com/kubernetes/ingress-nginx/pull/7793 Update kube-webhook-certgen to v1.1.1 + +### 4.0.5 + +- [7740] https://github.com/kubernetes/ingress-nginx/pull/7740 Release v1.0.3 of ingress-nginx + +### 4.0.3 + +- [7707] https://github.com/kubernetes/ingress-nginx/pull/7707 Release v1.0.2 of ingress-nginx + +### 4.0.2 + +- [7681] https://github.com/kubernetes/ingress-nginx/pull/7681 Release v1.0.1 of ingress-nginx + +### 4.0.1 + +- [7535] https://github.com/kubernetes/ingress-nginx/pull/7535 Release v1.0.0 ingress-nginx + +### 3.34.0 + +- [7256] https://github.com/kubernetes/ingress-nginx/pull/7256 Add namespace field in the namespace scoped resource templates + +### 3.33.0 + +- [7164] https://github.com/kubernetes/ingress-nginx/pull/7164 Update nginx to v1.20.1 + +### 3.32.0 + +- [7117] https://github.com/kubernetes/ingress-nginx/pull/7117 Add annotations for HPA + +### 3.31.0 + +- [7137] https://github.com/kubernetes/ingress-nginx/pull/7137 Add support for custom probes + +### 3.30.0 + +- [#7092](https://github.com/kubernetes/ingress-nginx/pull/7092) Removes the possibility of using localhost in ExternalNames as endpoints + +### 3.29.0 + +- [X] [#6945](https://github.com/kubernetes/ingress-nginx/pull/7020) Add option to specify job label for ServiceMonitor + +### 3.28.0 + +- [ ] [#6900](https://github.com/kubernetes/ingress-nginx/pull/6900) Support existing PSPs + +### 3.27.0 + +- Update ingress-nginx v0.45.0 + +### 3.26.0 + +- [X] [#6979](https://github.com/kubernetes/ingress-nginx/pull/6979) Changed servicePort value for metrics + +### 3.25.0 + +- [X] [#6957](https://github.com/kubernetes/ingress-nginx/pull/6957) Add ability to specify automountServiceAccountToken + +### 3.24.0 + +- [X] [#6908](https://github.com/kubernetes/ingress-nginx/pull/6908) Add volumes to default-backend deployment + +### 3.23.0 + +- Update ingress-nginx v0.44.0 + +### 3.22.0 + +- [X] [#6802](https://github.com/kubernetes/ingress-nginx/pull/6802) Add value for configuring a custom Diffie-Hellman parameters file +- [X] [#6815](https://github.com/kubernetes/ingress-nginx/pull/6815) Allow use of numeric namespaces in helm chart + +### 3.21.0 + +- [X] [#6783](https://github.com/kubernetes/ingress-nginx/pull/6783) Add custom annotations to ScaledObject +- [X] [#6761](https://github.com/kubernetes/ingress-nginx/pull/6761) Adding quotes in the serviceAccount name in Helm values +- [X] [#6767](https://github.com/kubernetes/ingress-nginx/pull/6767) Remove ClusterRole when scope option is enabled +- [X] [#6785](https://github.com/kubernetes/ingress-nginx/pull/6785) Update kube-webhook-certgen image to v1.5.1 + +### 3.20.1 + +- Do not create KEDA in case of DaemonSets. +- Fix KEDA v2 definition + +### 3.20.0 + +- [X] [#6730](https://github.com/kubernetes/ingress-nginx/pull/6730) Do not create HPA for defaultBackend if not enabled. + +### 3.19.0 + +- Update ingress-nginx v0.43.0 + +### 3.18.0 + +- [X] [#6688](https://github.com/kubernetes/ingress-nginx/pull/6688) Allow volume-type emptyDir in controller podsecuritypolicy +- [X] [#6691](https://github.com/kubernetes/ingress-nginx/pull/6691) Improve parsing of helm parameters + +### 3.17.0 + +- Update ingress-nginx v0.42.0 + +### 3.16.1 + +- Fix chart-releaser action + +### 3.16.0 + +- [X] [#6646](https://github.com/kubernetes/ingress-nginx/pull/6646) Added LoadBalancerIP value for internal service + +### 3.15.1 + +- Fix chart-releaser action + +### 3.15.0 + +- [X] [#6586](https://github.com/kubernetes/ingress-nginx/pull/6586) Fix 'maxmindLicenseKey' location in values.yaml + +### 3.14.0 + +- [X] [#6469](https://github.com/kubernetes/ingress-nginx/pull/6469) Allow custom service names for controller and backend + +### 3.13.0 + +- [X] [#6544](https://github.com/kubernetes/ingress-nginx/pull/6544) Fix default backend HPA name variable + +### 3.12.0 + +- [X] [#6514](https://github.com/kubernetes/ingress-nginx/pull/6514) Remove helm2 support and update docs + +### 3.11.1 + +- [X] [#6505](https://github.com/kubernetes/ingress-nginx/pull/6505) Reorder HPA resource list to work with GitOps tooling + +### 3.11.0 + +- Support Keda Autoscaling + +### 3.10.1 + +- Fix regression introduced in 0.41.0 with external authentication + +### 3.10.0 + +- Fix routing regression introduced in 0.41.0 with PathType Exact + +### 3.9.0 + +- [X] [#6423](https://github.com/kubernetes/ingress-nginx/pull/6423) Add Default backend HPA autoscaling + +### 3.8.0 + +- [X] [#6395](https://github.com/kubernetes/ingress-nginx/pull/6395) Update jettech/kube-webhook-certgen image +- [X] [#6377](https://github.com/kubernetes/ingress-nginx/pull/6377) Added loadBalancerSourceRanges for internal lbs +- [X] [#6356](https://github.com/kubernetes/ingress-nginx/pull/6356) Add securitycontext settings on defaultbackend +- [X] [#6401](https://github.com/kubernetes/ingress-nginx/pull/6401) Fix controller service annotations +- [X] [#6403](https://github.com/kubernetes/ingress-nginx/pull/6403) Initial helm chart changelog + +### 3.7.1 + +- [X] [#6326](https://github.com/kubernetes/ingress-nginx/pull/6326) Fix liveness and readiness probe path in daemonset chart + +### 3.7.0 + +- [X] [#6316](https://github.com/kubernetes/ingress-nginx/pull/6316) Numerals in podAnnotations in quotes [#6315](https://github.com/kubernetes/ingress-nginx/issues/6315) + +### 3.6.0 + +- [X] [#6305](https://github.com/kubernetes/ingress-nginx/pull/6305) Add default linux nodeSelector + +### 3.5.1 + +- [X] [#6299](https://github.com/kubernetes/ingress-nginx/pull/6299) Fix helm chart release + +### 3.5.0 + +- [X] [#6260](https://github.com/kubernetes/ingress-nginx/pull/6260) Allow Helm Chart to customize admission webhook's annotations, timeoutSeconds, namespaceSelector, objectSelector and cert files locations + +### 3.4.0 + +- [X] [#6268](https://github.com/kubernetes/ingress-nginx/pull/6268) Update to 0.40.2 in helm chart #6288 + +### 3.3.1 + +- [X] [#6259](https://github.com/kubernetes/ingress-nginx/pull/6259) Release helm chart +- [X] [#6258](https://github.com/kubernetes/ingress-nginx/pull/6258) Fix chart markdown link +- [X] [#6253](https://github.com/kubernetes/ingress-nginx/pull/6253) Release v0.40.0 + +### 3.3.1 + +- [X] [#6233](https://github.com/kubernetes/ingress-nginx/pull/6233) Add admission controller e2e test + +### 3.3.0 + +- [X] [#6203](https://github.com/kubernetes/ingress-nginx/pull/6203) Refactor parsing of key values +- [X] [#6162](https://github.com/kubernetes/ingress-nginx/pull/6162) Add helm chart options to expose metrics service as NodePort +- [X] [#6180](https://github.com/kubernetes/ingress-nginx/pull/6180) Fix helm chart admissionReviewVersions regression +- [X] [#6169](https://github.com/kubernetes/ingress-nginx/pull/6169) Fix Typo in example prometheus rules + +### 3.0.0 + +- [X] [#6167](https://github.com/kubernetes/ingress-nginx/pull/6167) Update chart requirements + +### 2.16.0 + +- [X] [#6154](https://github.com/kubernetes/ingress-nginx/pull/6154) add `topologySpreadConstraint` to controller + +### 2.15.0 + +- [X] [#6087](https://github.com/kubernetes/ingress-nginx/pull/6087) Adding parameter for externalTrafficPolicy in internal controller service spec + +### 2.14.0 + +- [X] [#6104](https://github.com/kubernetes/ingress-nginx/pull/6104) Misc fixes for nginx-ingress chart for better keel and prometheus-operator integration + +### 2.13.0 + +- [X] [#6093](https://github.com/kubernetes/ingress-nginx/pull/6093) Release v0.35.0 + +### 2.13.0 + +- [X] [#6093](https://github.com/kubernetes/ingress-nginx/pull/6093) Release v0.35.0 +- [X] [#6080](https://github.com/kubernetes/ingress-nginx/pull/6080) Switch images to k8s.gcr.io after Vanity Domain Flip + +### 2.12.1 + +- [X] [#6075](https://github.com/kubernetes/ingress-nginx/pull/6075) Sync helm chart affinity examples + +### 2.12.0 + +- [X] [#6039](https://github.com/kubernetes/ingress-nginx/pull/6039) Add configurable serviceMonitor metricRelabelling and targetLabels +- [X] [#6044](https://github.com/kubernetes/ingress-nginx/pull/6044) Fix YAML linting + +### 2.11.3 + +- [X] [#6038](https://github.com/kubernetes/ingress-nginx/pull/6038) Bump chart version PATCH + +### 2.11.2 + +- [X] [#5951](https://github.com/kubernetes/ingress-nginx/pull/5951) Bump chart patch version + +### 2.11.1 + +- [X] [#5900](https://github.com/kubernetes/ingress-nginx/pull/5900) Release helm chart for v0.34.1 + +### 2.11.0 + +- [X] [#5879](https://github.com/kubernetes/ingress-nginx/pull/5879) Update helm chart for v0.34.0 +- [X] [#5671](https://github.com/kubernetes/ingress-nginx/pull/5671) Make liveness probe more fault tolerant than readiness probe + +### 2.10.0 + +- [X] [#5843](https://github.com/kubernetes/ingress-nginx/pull/5843) Update jettech/kube-webhook-certgen image + +### 2.9.1 + +- [X] [#5823](https://github.com/kubernetes/ingress-nginx/pull/5823) Add quoting to sysctls because numeric values need to be presented as strings (#5823) + +### 2.9.0 + +- [X] [#5795](https://github.com/kubernetes/ingress-nginx/pull/5795) Use fully qualified images to avoid cri-o issues + + +### TODO + +Keep building the changelog using *git log charts* checking the tag diff --git a/helm/sonarqube/charts/ingress-nginx/Chart.yaml b/helm/sonarqube/charts/ingress-nginx/Chart.yaml new file mode 100644 index 0000000..28db08f --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/Chart.yaml @@ -0,0 +1,25 @@ +annotations: + artifacthub.io/changes: | + - "Added a doc line to the missing helm value service.internal.loadBalancerIP (#9406)" + - "feat(helm): Add loadBalancerClass (#9562)" + - "added helmshowvalues example (#10019)" + - "Update Ingress-Nginx version controller-v1.8.1" + artifacthub.io/prerelease: "false" +apiVersion: v2 +appVersion: 1.8.1 +description: Ingress controller for Kubernetes using NGINX as a reverse proxy and + load balancer +home: https://github.com/kubernetes/ingress-nginx +icon: https://upload.wikimedia.org/wikipedia/commons/thumb/c/c5/Nginx_logo.svg/500px-Nginx_logo.svg.png +keywords: +- ingress +- nginx +kubeVersion: '>=1.20.0-0' +maintainers: +- name: rikatz +- name: strongjz +- name: tao12345666333 +name: ingress-nginx +sources: +- https://github.com/kubernetes/ingress-nginx +version: 4.7.1 diff --git a/helm/sonarqube/charts/ingress-nginx/OWNERS b/helm/sonarqube/charts/ingress-nginx/OWNERS new file mode 100644 index 0000000..6b7e049 --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/OWNERS @@ -0,0 +1,10 @@ +# See the OWNERS docs: https://github.com/kubernetes/community/blob/master/contributors/guide/owners.md + +approvers: +- ingress-nginx-helm-maintainers + +reviewers: +- ingress-nginx-helm-reviewers + +labels: +- area/helm diff --git a/helm/sonarqube/charts/ingress-nginx/README.md b/helm/sonarqube/charts/ingress-nginx/README.md new file mode 100644 index 0000000..9550918 --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/README.md @@ -0,0 +1,507 @@ +# ingress-nginx + +[ingress-nginx](https://github.com/kubernetes/ingress-nginx) Ingress controller for Kubernetes using NGINX as a reverse proxy and load balancer + +![Version: 4.7.1](https://img.shields.io/badge/Version-4.7.1-informational?style=flat-square) ![AppVersion: 1.8.1](https://img.shields.io/badge/AppVersion-1.8.1-informational?style=flat-square) + +To use, add `ingressClassName: nginx` spec field or the `kubernetes.io/ingress.class: nginx` annotation to your Ingress resources. + +This chart bootstraps an ingress-nginx deployment on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. + +## Requirements + +Kubernetes: `>=1.20.0-0` + +## Get Repo Info + +```console +helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx +helm repo update +``` + +## Install Chart + +**Important:** only helm3 is supported + +```console +helm install [RELEASE_NAME] ingress-nginx/ingress-nginx +``` + +The command deploys ingress-nginx on the Kubernetes cluster in the default configuration. + +_See [configuration](#configuration) below._ + +_See [helm install](https://helm.sh/docs/helm/helm_install/) for command documentation._ + +## Uninstall Chart + +```console +helm uninstall [RELEASE_NAME] +``` + +This removes all the Kubernetes components associated with the chart and deletes the release. + +_See [helm uninstall](https://helm.sh/docs/helm/helm_uninstall/) for command documentation._ + +## Upgrading Chart + +```console +helm upgrade [RELEASE_NAME] [CHART] --install +``` + +_See [helm upgrade](https://helm.sh/docs/helm/helm_upgrade/) for command documentation._ + +### Migrating from stable/nginx-ingress + +There are two main ways to migrate a release from `stable/nginx-ingress` to `ingress-nginx/ingress-nginx` chart: + +1. For Nginx Ingress controllers used for non-critical services, the easiest method is to [uninstall](#uninstall-chart) the old release and [install](#install-chart) the new one +1. For critical services in production that require zero-downtime, you will want to: + 1. [Install](#install-chart) a second Ingress controller + 1. Redirect your DNS traffic from the old controller to the new controller + 1. Log traffic from both controllers during this changeover + 1. [Uninstall](#uninstall-chart) the old controller once traffic has fully drained from it + +Note that there are some different and upgraded configurations between the two charts, described by Rimas Mocevicius from JFrog in the "Upgrading to ingress-nginx Helm chart" section of [Migrating from Helm chart nginx-ingress to ingress-nginx](https://rimusz.net/migrating-to-ingress-nginx). As the `ingress-nginx/ingress-nginx` chart continues to update, you will want to check current differences by running [helm configuration](#configuration) commands on both charts. + +## Configuration + +See [Customizing the Chart Before Installing](https://helm.sh/docs/intro/using_helm/#customizing-the-chart-before-installing). To see all configurable options with detailed comments, visit the chart's [values.yaml](./values.yaml), or run these configuration commands: + +```console +helm show values ingress-nginx/ingress-nginx +``` + +### PodDisruptionBudget + +Note that the PodDisruptionBudget resource will only be defined if the replicaCount is greater than one, +else it would make it impossible to evacuate a node. See [gh issue #7127](https://github.com/helm/charts/issues/7127) for more info. + +### Prometheus Metrics + +The Ingress-Nginx Controller can export Prometheus metrics, by setting `controller.metrics.enabled` to `true`. + +You can add Prometheus annotations to the metrics service using `controller.metrics.service.annotations`. +Alternatively, if you use the Prometheus Operator, you can enable ServiceMonitor creation using `controller.metrics.serviceMonitor.enabled`. And set `controller.metrics.serviceMonitor.additionalLabels.release="prometheus"`. "release=prometheus" should match the label configured in the prometheus servicemonitor ( see `kubectl get servicemonitor prometheus-kube-prom-prometheus -oyaml -n prometheus`) + +### ingress-nginx nginx\_status page/stats server + +Previous versions of this chart had a `controller.stats.*` configuration block, which is now obsolete due to the following changes in Ingress-Nginx Controller: + +- In [0.16.1](https://github.com/kubernetes/ingress-nginx/blob/main/Changelog.md#0161), the vts (virtual host traffic status) dashboard was removed +- In [0.23.0](https://github.com/kubernetes/ingress-nginx/blob/main/Changelog.md#0230), the status page at port 18080 is now a unix socket webserver only available at localhost. + You can use `curl --unix-socket /tmp/nginx-status-server.sock http://localhost/nginx_status` inside the controller container to access it locally, or use the snippet from [nginx-ingress changelog](https://github.com/kubernetes/ingress-nginx/blob/main/Changelog.md#0230) to re-enable the http server + +### ExternalDNS Service Configuration + +Add an [ExternalDNS](https://github.com/kubernetes-sigs/external-dns) annotation to the LoadBalancer service: + +```yaml +controller: + service: + annotations: + external-dns.alpha.kubernetes.io/hostname: kubernetes-example.com. +``` + +### AWS L7 ELB with SSL Termination + +Annotate the controller as shown in the [nginx-ingress l7 patch](https://github.com/kubernetes/ingress-nginx/blob/ab3a789caae65eec4ad6e3b46b19750b481b6bce/deploy/aws/l7/service-l7.yaml): + +```yaml +controller: + service: + targetPorts: + http: http + https: http + annotations: + service.beta.kubernetes.io/aws-load-balancer-ssl-cert: arn:aws:acm:XX-XXXX-X:XXXXXXXXX:certificate/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX + service.beta.kubernetes.io/aws-load-balancer-backend-protocol: "http" + service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "https" + service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout: '3600' +``` + +### Additional Internal Load Balancer + +This setup is useful when you need both external and internal load balancers but don't want to have multiple ingress controllers and multiple ingress objects per application. + +By default, the ingress object will point to the external load balancer address, but if correctly configured, you can make use of the internal one if the URL you are looking up resolves to the internal load balancer's URL. + +You'll need to set both the following values: + +`controller.service.internal.enabled` +`controller.service.internal.annotations` + +If one of them is missing the internal load balancer will not be deployed. Example you may have `controller.service.internal.enabled=true` but no annotations set, in this case no action will be taken. + +`controller.service.internal.annotations` varies with the cloud service you're using. + +Example for AWS: + +```yaml +controller: + service: + internal: + enabled: true + annotations: + # Create internal NLB + service.beta.kubernetes.io/aws-load-balancer-scheme: "internal" + # Create internal ELB(Deprecated) + # service.beta.kubernetes.io/aws-load-balancer-internal: "true" + # Any other annotation can be declared here. +``` + +Example for GCE: + +```yaml +controller: + service: + internal: + enabled: true + annotations: + # Create internal LB. More information: https://cloud.google.com/kubernetes-engine/docs/how-to/internal-load-balancing + # For GKE versions 1.17 and later + networking.gke.io/load-balancer-type: "Internal" + # For earlier versions + # cloud.google.com/load-balancer-type: "Internal" + + # Any other annotation can be declared here. +``` + +Example for Azure: + +```yaml +controller: + service: + annotations: + # Create internal LB + service.beta.kubernetes.io/azure-load-balancer-internal: "true" + # Any other annotation can be declared here. +``` + +Example for Oracle Cloud Infrastructure: + +```yaml +controller: + service: + annotations: + # Create internal LB + service.beta.kubernetes.io/oci-load-balancer-internal: "true" + # Any other annotation can be declared here. +``` + +The load balancer annotations of more cloud service providers can be found: [Internal load balancer](https://kubernetes.io/docs/concepts/services-networking/service/#internal-load-balancer). + +An use case for this scenario is having a split-view DNS setup where the public zone CNAME records point to the external balancer URL while the private zone CNAME records point to the internal balancer URL. This way, you only need one ingress kubernetes object. + +Optionally you can set `controller.service.loadBalancerIP` if you need a static IP for the resulting `LoadBalancer`. + +### Ingress Admission Webhooks + +With nginx-ingress-controller version 0.25+, the Ingress-Nginx Controller pod exposes an endpoint that will integrate with the `validatingwebhookconfiguration` Kubernetes feature to prevent bad ingress from being added to the cluster. +**This feature is enabled by default since 0.31.0.** + +With nginx-ingress-controller in 0.25.* work only with kubernetes 1.14+, 0.26 fix [this issue](https://github.com/kubernetes/ingress-nginx/pull/4521) + +#### How the Chart Configures the Hooks +A validating and configuration requires the endpoint to which the request is sent to use TLS. It is possible to set up custom certificates to do this, but in most cases, a self-signed certificate is enough. The setup of this component requires some more complex orchestration when using helm. The steps are created to be idempotent and to allow turning the feature on and off without running into helm quirks. + +1. A pre-install hook provisions a certificate into the same namespace using a format compatible with provisioning using end user certificates. If the certificate already exists, the hook exits. +2. The Ingress-Nginx Controller pod is configured to use a TLS proxy container, which will load that certificate. +3. Validating and Mutating webhook configurations are created in the cluster. +4. A post-install hook reads the CA from the secret created by step 1 and patches the Validating and Mutating webhook configurations. This process will allow a custom CA provisioned by some other process to also be patched into the webhook configurations. The chosen failure policy is also patched into the webhook configurations + +#### Alternatives +It should be possible to use [cert-manager/cert-manager](https://github.com/cert-manager/cert-manager) if a more complete solution is required. + +You can enable automatic self-signed TLS certificate provisioning via cert-manager by setting the `controller.admissionWebhooks.certManager.enabled` value to true. + +Please ensure that cert-manager is correctly installed and configured. + +### Helm Error When Upgrading: spec.clusterIP: Invalid value: "" + +If you are upgrading this chart from a version between 0.31.0 and 1.2.2 then you may get an error like this: + +```console +Error: UPGRADE FAILED: Service "?????-controller" is invalid: spec.clusterIP: Invalid value: "": field is immutable +``` + +Detail of how and why are in [this issue](https://github.com/helm/charts/pull/13646) but to resolve this you can set `xxxx.service.omitClusterIP` to `true` where `xxxx` is the service referenced in the error. + +As of version `1.26.0` of this chart, by simply not providing any clusterIP value, `invalid: spec.clusterIP: Invalid value: "": field is immutable` will no longer occur since `clusterIP: ""` will not be rendered. + +## Values + +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| commonLabels | object | `{}` | | +| controller.addHeaders | object | `{}` | Will add custom headers before sending response traffic to the client according to: https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/#add-headers | +| controller.admissionWebhooks.annotations | object | `{}` | | +| controller.admissionWebhooks.certManager.admissionCert.duration | string | `""` | | +| controller.admissionWebhooks.certManager.enabled | bool | `false` | | +| controller.admissionWebhooks.certManager.rootCert.duration | string | `""` | | +| controller.admissionWebhooks.certificate | string | `"/usr/local/certificates/cert"` | | +| controller.admissionWebhooks.createSecretJob.resources | object | `{}` | | +| controller.admissionWebhooks.createSecretJob.securityContext.allowPrivilegeEscalation | bool | `false` | | +| controller.admissionWebhooks.enabled | bool | `true` | | +| controller.admissionWebhooks.existingPsp | string | `""` | Use an existing PSP instead of creating one | +| controller.admissionWebhooks.extraEnvs | list | `[]` | Additional environment variables to set | +| controller.admissionWebhooks.failurePolicy | string | `"Fail"` | Admission Webhook failure policy to use | +| controller.admissionWebhooks.key | string | `"/usr/local/certificates/key"` | | +| controller.admissionWebhooks.labels | object | `{}` | Labels to be added to admission webhooks | +| controller.admissionWebhooks.namespaceSelector | object | `{}` | | +| controller.admissionWebhooks.networkPolicyEnabled | bool | `false` | | +| controller.admissionWebhooks.objectSelector | object | `{}` | | +| controller.admissionWebhooks.patch.enabled | bool | `true` | | +| controller.admissionWebhooks.patch.image.digest | string | `"sha256:543c40fd093964bc9ab509d3e791f9989963021f1e9e4c9c7b6700b02bfb227b"` | | +| controller.admissionWebhooks.patch.image.image | string | `"ingress-nginx/kube-webhook-certgen"` | | +| controller.admissionWebhooks.patch.image.pullPolicy | string | `"IfNotPresent"` | | +| controller.admissionWebhooks.patch.image.registry | string | `"registry.k8s.io"` | | +| controller.admissionWebhooks.patch.image.tag | string | `"v20230407"` | | +| controller.admissionWebhooks.patch.labels | object | `{}` | Labels to be added to patch job resources | +| controller.admissionWebhooks.patch.nodeSelector."kubernetes.io/os" | string | `"linux"` | | +| controller.admissionWebhooks.patch.podAnnotations | object | `{}` | | +| controller.admissionWebhooks.patch.priorityClassName | string | `""` | Provide a priority class name to the webhook patching job # | +| controller.admissionWebhooks.patch.securityContext.fsGroup | int | `2000` | | +| controller.admissionWebhooks.patch.securityContext.runAsNonRoot | bool | `true` | | +| controller.admissionWebhooks.patch.securityContext.runAsUser | int | `2000` | | +| controller.admissionWebhooks.patch.tolerations | list | `[]` | | +| controller.admissionWebhooks.patchWebhookJob.resources | object | `{}` | | +| controller.admissionWebhooks.patchWebhookJob.securityContext.allowPrivilegeEscalation | bool | `false` | | +| controller.admissionWebhooks.port | int | `8443` | | +| controller.admissionWebhooks.service.annotations | object | `{}` | | +| controller.admissionWebhooks.service.externalIPs | list | `[]` | | +| controller.admissionWebhooks.service.loadBalancerSourceRanges | list | `[]` | | +| controller.admissionWebhooks.service.servicePort | int | `443` | | +| controller.admissionWebhooks.service.type | string | `"ClusterIP"` | | +| controller.affinity | object | `{}` | Affinity and anti-affinity rules for server scheduling to nodes # Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity # | +| controller.allowSnippetAnnotations | bool | `true` | This configuration defines if Ingress Controller should allow users to set their own *-snippet annotations, otherwise this is forbidden / dropped when users add those annotations. Global snippets in ConfigMap are still respected | +| controller.annotations | object | `{}` | Annotations to be added to the controller Deployment or DaemonSet # | +| controller.autoscaling.annotations | object | `{}` | | +| controller.autoscaling.behavior | object | `{}` | | +| controller.autoscaling.enabled | bool | `false` | | +| controller.autoscaling.maxReplicas | int | `11` | | +| controller.autoscaling.minReplicas | int | `1` | | +| controller.autoscaling.targetCPUUtilizationPercentage | int | `50` | | +| controller.autoscaling.targetMemoryUtilizationPercentage | int | `50` | | +| controller.autoscalingTemplate | list | `[]` | | +| controller.config | object | `{}` | Will add custom configuration options to Nginx https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/ | +| controller.configAnnotations | object | `{}` | Annotations to be added to the controller config configuration configmap. | +| controller.configMapNamespace | string | `""` | Allows customization of the configmap / nginx-configmap namespace; defaults to $(POD_NAMESPACE) | +| controller.containerName | string | `"controller"` | Configures the controller container name | +| controller.containerPort | object | `{"http":80,"https":443}` | Configures the ports that the nginx-controller listens on | +| controller.customTemplate.configMapKey | string | `""` | | +| controller.customTemplate.configMapName | string | `""` | | +| controller.dnsConfig | object | `{}` | Optionally customize the pod dnsConfig. | +| controller.dnsPolicy | string | `"ClusterFirst"` | Optionally change this to ClusterFirstWithHostNet in case you have 'hostNetwork: true'. By default, while using host network, name resolution uses the host's DNS. If you wish nginx-controller to keep resolving names inside the k8s network, use ClusterFirstWithHostNet. | +| controller.electionID | string | `""` | Election ID to use for status update, by default it uses the controller name combined with a suffix of 'leader' | +| controller.enableMimalloc | bool | `true` | Enable mimalloc as a drop-in replacement for malloc. # ref: https://github.com/microsoft/mimalloc # | +| controller.enableTopologyAwareRouting | bool | `false` | This configuration enables Topology Aware Routing feature, used together with service annotation service.kubernetes.io/topology-aware-hints="auto" Defaults to false | +| controller.existingPsp | string | `""` | Use an existing PSP instead of creating one | +| controller.extraArgs | object | `{}` | Additional command line arguments to pass to Ingress-Nginx Controller E.g. to specify the default SSL certificate you can use | +| controller.extraContainers | list | `[]` | Additional containers to be added to the controller pod. See https://github.com/lemonldap-ng-controller/lemonldap-ng-controller as example. | +| controller.extraEnvs | list | `[]` | Additional environment variables to set | +| controller.extraInitContainers | list | `[]` | Containers, which are run before the app containers are started. | +| controller.extraModules | list | `[]` | Modules, which are mounted into the core nginx image. See values.yaml for a sample to add opentelemetry module | +| controller.extraVolumeMounts | list | `[]` | Additional volumeMounts to the controller main container. | +| controller.extraVolumes | list | `[]` | Additional volumes to the controller pod. | +| controller.healthCheckHost | string | `""` | Address to bind the health check endpoint. It is better to set this option to the internal node address if the Ingress-Nginx Controller is running in the `hostNetwork: true` mode. | +| controller.healthCheckPath | string | `"/healthz"` | Path of the health check endpoint. All requests received on the port defined by the healthz-port parameter are forwarded internally to this path. | +| controller.hostNetwork | bool | `false` | Required for use with CNI based kubernetes installations (such as ones set up by kubeadm), since CNI and hostport don't mix yet. Can be deprecated once https://github.com/kubernetes/kubernetes/issues/23920 is merged | +| controller.hostPort.enabled | bool | `false` | Enable 'hostPort' or not | +| controller.hostPort.ports.http | int | `80` | 'hostPort' http port | +| controller.hostPort.ports.https | int | `443` | 'hostPort' https port | +| controller.hostname | object | `{}` | Optionally customize the pod hostname. | +| controller.image.allowPrivilegeEscalation | bool | `true` | | +| controller.image.chroot | bool | `false` | | +| controller.image.digest | string | `"sha256:e5c4824e7375fcf2a393e1c03c293b69759af37a9ca6abdb91b13d78a93da8bd"` | | +| controller.image.digestChroot | string | `"sha256:e0d4121e3c5e39de9122e55e331a32d5ebf8d4d257227cb93ab54a1b912a7627"` | | +| controller.image.image | string | `"ingress-nginx/controller"` | | +| controller.image.pullPolicy | string | `"IfNotPresent"` | | +| controller.image.registry | string | `"registry.k8s.io"` | | +| controller.image.runAsUser | int | `101` | | +| controller.image.tag | string | `"v1.8.1"` | | +| controller.ingressClass | string | `"nginx"` | For backwards compatibility with ingress.class annotation, use ingressClass. Algorithm is as follows, first ingressClassName is considered, if not present, controller looks for ingress.class annotation | +| controller.ingressClassByName | bool | `false` | Process IngressClass per name (additionally as per spec.controller). | +| controller.ingressClassResource.controllerValue | string | `"k8s.io/ingress-nginx"` | Controller-value of the controller that is processing this ingressClass | +| controller.ingressClassResource.default | bool | `false` | Is this the default ingressClass for the cluster | +| controller.ingressClassResource.enabled | bool | `true` | Is this ingressClass enabled or not | +| controller.ingressClassResource.name | string | `"nginx"` | Name of the ingressClass | +| controller.ingressClassResource.parameters | object | `{}` | Parameters is a link to a custom resource containing additional configuration for the controller. This is optional if the controller does not require extra parameters. | +| controller.keda.apiVersion | string | `"keda.sh/v1alpha1"` | | +| controller.keda.behavior | object | `{}` | | +| controller.keda.cooldownPeriod | int | `300` | | +| controller.keda.enabled | bool | `false` | | +| controller.keda.maxReplicas | int | `11` | | +| controller.keda.minReplicas | int | `1` | | +| controller.keda.pollingInterval | int | `30` | | +| controller.keda.restoreToOriginalReplicaCount | bool | `false` | | +| controller.keda.scaledObject.annotations | object | `{}` | | +| controller.keda.triggers | list | `[]` | | +| controller.kind | string | `"Deployment"` | Use a `DaemonSet` or `Deployment` | +| controller.labels | object | `{}` | Labels to be added to the controller Deployment or DaemonSet and other resources that do not have option to specify labels # | +| controller.lifecycle | object | `{"preStop":{"exec":{"command":["/wait-shutdown"]}}}` | Improve connection draining when ingress controller pod is deleted using a lifecycle hook: With this new hook, we increased the default terminationGracePeriodSeconds from 30 seconds to 300, allowing the draining of connections up to five minutes. If the active connections end before that, the pod will terminate gracefully at that time. To effectively take advantage of this feature, the Configmap feature worker-shutdown-timeout new value is 240s instead of 10s. # | +| controller.livenessProbe.failureThreshold | int | `5` | | +| controller.livenessProbe.httpGet.path | string | `"/healthz"` | | +| controller.livenessProbe.httpGet.port | int | `10254` | | +| controller.livenessProbe.httpGet.scheme | string | `"HTTP"` | | +| controller.livenessProbe.initialDelaySeconds | int | `10` | | +| controller.livenessProbe.periodSeconds | int | `10` | | +| controller.livenessProbe.successThreshold | int | `1` | | +| controller.livenessProbe.timeoutSeconds | int | `1` | | +| controller.maxmindLicenseKey | string | `""` | Maxmind license key to download GeoLite2 Databases. # https://blog.maxmind.com/2019/12/18/significant-changes-to-accessing-and-using-geolite2-databases | +| controller.metrics.enabled | bool | `false` | | +| controller.metrics.port | int | `10254` | | +| controller.metrics.portName | string | `"metrics"` | | +| controller.metrics.prometheusRule.additionalLabels | object | `{}` | | +| controller.metrics.prometheusRule.enabled | bool | `false` | | +| controller.metrics.prometheusRule.rules | list | `[]` | | +| controller.metrics.service.annotations | object | `{}` | | +| controller.metrics.service.externalIPs | list | `[]` | List of IP addresses at which the stats-exporter service is available # Ref: https://kubernetes.io/docs/concepts/services-networking/service/#external-ips # | +| controller.metrics.service.labels | object | `{}` | Labels to be added to the metrics service resource | +| controller.metrics.service.loadBalancerSourceRanges | list | `[]` | | +| controller.metrics.service.servicePort | int | `10254` | | +| controller.metrics.service.type | string | `"ClusterIP"` | | +| controller.metrics.serviceMonitor.additionalLabels | object | `{}` | | +| controller.metrics.serviceMonitor.enabled | bool | `false` | | +| controller.metrics.serviceMonitor.metricRelabelings | list | `[]` | | +| controller.metrics.serviceMonitor.namespace | string | `""` | | +| controller.metrics.serviceMonitor.namespaceSelector | object | `{}` | | +| controller.metrics.serviceMonitor.relabelings | list | `[]` | | +| controller.metrics.serviceMonitor.scrapeInterval | string | `"30s"` | | +| controller.metrics.serviceMonitor.targetLabels | list | `[]` | | +| controller.minAvailable | int | `1` | Minimum available pods set in PodDisruptionBudget. Define either 'minAvailable' or 'maxUnavailable', never both. | +| controller.minReadySeconds | int | `0` | `minReadySeconds` to avoid killing pods before we are ready # | +| controller.name | string | `"controller"` | | +| controller.nodeSelector | object | `{"kubernetes.io/os":"linux"}` | Node labels for controller pod assignment # Ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/ # | +| controller.opentelemetry.containerSecurityContext.allowPrivilegeEscalation | bool | `false` | | +| controller.opentelemetry.enabled | bool | `false` | | +| controller.opentelemetry.image | string | `"registry.k8s.io/ingress-nginx/opentelemetry:v20230527@sha256:fd7ec835f31b7b37187238eb4fdad4438806e69f413a203796263131f4f02ed0"` | | +| controller.podAnnotations | object | `{}` | Annotations to be added to controller pods # | +| controller.podLabels | object | `{}` | Labels to add to the pod container metadata | +| controller.podSecurityContext | object | `{}` | Security Context policies for controller pods | +| controller.priorityClassName | string | `""` | | +| controller.proxySetHeaders | object | `{}` | Will add custom headers before sending traffic to backends according to https://github.com/kubernetes/ingress-nginx/tree/main/docs/examples/customization/custom-headers | +| controller.publishService | object | `{"enabled":true,"pathOverride":""}` | Allows customization of the source of the IP address or FQDN to report in the ingress status field. By default, it reads the information provided by the service. If disable, the status field reports the IP address of the node or nodes where an ingress controller pod is running. | +| controller.publishService.enabled | bool | `true` | Enable 'publishService' or not | +| controller.publishService.pathOverride | string | `""` | Allows overriding of the publish service to bind to Must be / | +| controller.readinessProbe.failureThreshold | int | `3` | | +| controller.readinessProbe.httpGet.path | string | `"/healthz"` | | +| controller.readinessProbe.httpGet.port | int | `10254` | | +| controller.readinessProbe.httpGet.scheme | string | `"HTTP"` | | +| controller.readinessProbe.initialDelaySeconds | int | `10` | | +| controller.readinessProbe.periodSeconds | int | `10` | | +| controller.readinessProbe.successThreshold | int | `1` | | +| controller.readinessProbe.timeoutSeconds | int | `1` | | +| controller.replicaCount | int | `1` | | +| controller.reportNodeInternalIp | bool | `false` | Bare-metal considerations via the host network https://kubernetes.github.io/ingress-nginx/deploy/baremetal/#via-the-host-network Ingress status was blank because there is no Service exposing the Ingress-Nginx Controller in a configuration using the host network, the default --publish-service flag used in standard cloud setups does not apply | +| controller.resources.requests.cpu | string | `"100m"` | | +| controller.resources.requests.memory | string | `"90Mi"` | | +| controller.scope.enabled | bool | `false` | Enable 'scope' or not | +| controller.scope.namespace | string | `""` | Namespace to limit the controller to; defaults to $(POD_NAMESPACE) | +| controller.scope.namespaceSelector | string | `""` | When scope.enabled == false, instead of watching all namespaces, we watching namespaces whose labels only match with namespaceSelector. Format like foo=bar. Defaults to empty, means watching all namespaces. | +| controller.service.annotations | object | `{}` | | +| controller.service.appProtocol | bool | `true` | If enabled is adding an appProtocol option for Kubernetes service. An appProtocol field replacing annotations that were using for setting a backend protocol. Here is an example for AWS: service.beta.kubernetes.io/aws-load-balancer-backend-protocol: http It allows choosing the protocol for each backend specified in the Kubernetes service. See the following GitHub issue for more details about the purpose: https://github.com/kubernetes/kubernetes/issues/40244 Will be ignored for Kubernetes versions older than 1.20 # | +| controller.service.enableHttp | bool | `true` | | +| controller.service.enableHttps | bool | `true` | | +| controller.service.enabled | bool | `true` | | +| controller.service.external.enabled | bool | `true` | | +| controller.service.externalIPs | list | `[]` | List of IP addresses at which the controller services are available # Ref: https://kubernetes.io/docs/concepts/services-networking/service/#external-ips # | +| controller.service.internal.annotations | object | `{}` | Annotations are mandatory for the load balancer to come up. Varies with the cloud service. | +| controller.service.internal.enabled | bool | `false` | Enables an additional internal load balancer (besides the external one). | +| controller.service.internal.loadBalancerIP | string | `""` | Used by cloud providers to connect the resulting internal LoadBalancer to a pre-existing static IP. Make sure to add to the service the needed annotation to specify the subnet which the static IP belongs to. For instance, `networking.gke.io/internal-load-balancer-subnet` for GCP and `service.beta.kubernetes.io/aws-load-balancer-subnets` for AWS. | +| controller.service.internal.loadBalancerSourceRanges | list | `[]` | Restrict access For LoadBalancer service. Defaults to 0.0.0.0/0. | +| controller.service.internal.ports | object | `{}` | Custom port mapping for internal service | +| controller.service.internal.targetPorts | object | `{}` | Custom target port mapping for internal service | +| controller.service.ipFamilies | list | `["IPv4"]` | List of IP families (e.g. IPv4, IPv6) assigned to the service. This field is usually assigned automatically based on cluster configuration and the ipFamilyPolicy field. # Ref: https://kubernetes.io/docs/concepts/services-networking/dual-stack/ | +| controller.service.ipFamilyPolicy | string | `"SingleStack"` | Represents the dual-stack-ness requested or required by this Service. Possible values are SingleStack, PreferDualStack or RequireDualStack. The ipFamilies and clusterIPs fields depend on the value of this field. # Ref: https://kubernetes.io/docs/concepts/services-networking/dual-stack/ | +| controller.service.labels | object | `{}` | | +| controller.service.loadBalancerClass | string | `""` | Used by cloud providers to select a load balancer implementation other than the cloud provider default. https://kubernetes.io/docs/concepts/services-networking/service/#load-balancer-class | +| controller.service.loadBalancerIP | string | `""` | Used by cloud providers to connect the resulting `LoadBalancer` to a pre-existing static IP according to https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer | +| controller.service.loadBalancerSourceRanges | list | `[]` | | +| controller.service.nodePorts.http | string | `""` | | +| controller.service.nodePorts.https | string | `""` | | +| controller.service.nodePorts.tcp | object | `{}` | | +| controller.service.nodePorts.udp | object | `{}` | | +| controller.service.ports.http | int | `80` | | +| controller.service.ports.https | int | `443` | | +| controller.service.targetPorts.http | string | `"http"` | | +| controller.service.targetPorts.https | string | `"https"` | | +| controller.service.type | string | `"LoadBalancer"` | | +| controller.shareProcessNamespace | bool | `false` | | +| controller.sysctls | object | `{}` | See https://kubernetes.io/docs/tasks/administer-cluster/sysctl-cluster/ for notes on enabling and using sysctls | +| controller.tcp.annotations | object | `{}` | Annotations to be added to the tcp config configmap | +| controller.tcp.configMapNamespace | string | `""` | Allows customization of the tcp-services-configmap; defaults to $(POD_NAMESPACE) | +| controller.terminationGracePeriodSeconds | int | `300` | `terminationGracePeriodSeconds` to avoid killing pods before we are ready # wait up to five minutes for the drain of connections # | +| controller.tolerations | list | `[]` | Node tolerations for server scheduling to nodes with taints # Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ # | +| controller.topologySpreadConstraints | list | `[]` | Topology spread constraints rely on node labels to identify the topology domain(s) that each Node is in. # Ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ # | +| controller.udp.annotations | object | `{}` | Annotations to be added to the udp config configmap | +| controller.udp.configMapNamespace | string | `""` | Allows customization of the udp-services-configmap; defaults to $(POD_NAMESPACE) | +| controller.updateStrategy | object | `{}` | The update strategy to apply to the Deployment or DaemonSet # | +| controller.watchIngressWithoutClass | bool | `false` | Process Ingress objects without ingressClass annotation/ingressClassName field Overrides value for --watch-ingress-without-class flag of the controller binary Defaults to false | +| defaultBackend.affinity | object | `{}` | | +| defaultBackend.autoscaling.annotations | object | `{}` | | +| defaultBackend.autoscaling.enabled | bool | `false` | | +| defaultBackend.autoscaling.maxReplicas | int | `2` | | +| defaultBackend.autoscaling.minReplicas | int | `1` | | +| defaultBackend.autoscaling.targetCPUUtilizationPercentage | int | `50` | | +| defaultBackend.autoscaling.targetMemoryUtilizationPercentage | int | `50` | | +| defaultBackend.containerSecurityContext | object | `{}` | Security Context policies for controller main container. See https://kubernetes.io/docs/tasks/administer-cluster/sysctl-cluster/ for notes on enabling and using sysctls # | +| defaultBackend.enabled | bool | `false` | | +| defaultBackend.existingPsp | string | `""` | Use an existing PSP instead of creating one | +| defaultBackend.extraArgs | object | `{}` | | +| defaultBackend.extraEnvs | list | `[]` | Additional environment variables to set for defaultBackend pods | +| defaultBackend.extraVolumeMounts | list | `[]` | | +| defaultBackend.extraVolumes | list | `[]` | | +| defaultBackend.image.allowPrivilegeEscalation | bool | `false` | | +| defaultBackend.image.image | string | `"defaultbackend-amd64"` | | +| defaultBackend.image.pullPolicy | string | `"IfNotPresent"` | | +| defaultBackend.image.readOnlyRootFilesystem | bool | `true` | | +| defaultBackend.image.registry | string | `"registry.k8s.io"` | | +| defaultBackend.image.runAsNonRoot | bool | `true` | | +| defaultBackend.image.runAsUser | int | `65534` | | +| defaultBackend.image.tag | string | `"1.5"` | | +| defaultBackend.labels | object | `{}` | Labels to be added to the default backend resources | +| defaultBackend.livenessProbe.failureThreshold | int | `3` | | +| defaultBackend.livenessProbe.initialDelaySeconds | int | `30` | | +| defaultBackend.livenessProbe.periodSeconds | int | `10` | | +| defaultBackend.livenessProbe.successThreshold | int | `1` | | +| defaultBackend.livenessProbe.timeoutSeconds | int | `5` | | +| defaultBackend.minAvailable | int | `1` | | +| defaultBackend.minReadySeconds | int | `0` | `minReadySeconds` to avoid killing pods before we are ready # | +| defaultBackend.name | string | `"defaultbackend"` | | +| defaultBackend.nodeSelector | object | `{"kubernetes.io/os":"linux"}` | Node labels for default backend pod assignment # Ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/ # | +| defaultBackend.podAnnotations | object | `{}` | Annotations to be added to default backend pods # | +| defaultBackend.podLabels | object | `{}` | Labels to add to the pod container metadata | +| defaultBackend.podSecurityContext | object | `{}` | Security Context policies for controller pods See https://kubernetes.io/docs/tasks/administer-cluster/sysctl-cluster/ for notes on enabling and using sysctls # | +| defaultBackend.port | int | `8080` | | +| defaultBackend.priorityClassName | string | `""` | | +| defaultBackend.readinessProbe.failureThreshold | int | `6` | | +| defaultBackend.readinessProbe.initialDelaySeconds | int | `0` | | +| defaultBackend.readinessProbe.periodSeconds | int | `5` | | +| defaultBackend.readinessProbe.successThreshold | int | `1` | | +| defaultBackend.readinessProbe.timeoutSeconds | int | `5` | | +| defaultBackend.replicaCount | int | `1` | | +| defaultBackend.resources | object | `{}` | | +| defaultBackend.service.annotations | object | `{}` | | +| defaultBackend.service.externalIPs | list | `[]` | List of IP addresses at which the default backend service is available # Ref: https://kubernetes.io/docs/concepts/services-networking/service/#external-ips # | +| defaultBackend.service.loadBalancerSourceRanges | list | `[]` | | +| defaultBackend.service.servicePort | int | `80` | | +| defaultBackend.service.type | string | `"ClusterIP"` | | +| defaultBackend.serviceAccount.automountServiceAccountToken | bool | `true` | | +| defaultBackend.serviceAccount.create | bool | `true` | | +| defaultBackend.serviceAccount.name | string | `""` | | +| defaultBackend.tolerations | list | `[]` | Node tolerations for server scheduling to nodes with taints # Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ # | +| defaultBackend.updateStrategy | object | `{}` | The update strategy to apply to the Deployment or DaemonSet # | +| dhParam | string | `""` | A base64-encoded Diffie-Hellman parameter. This can be generated with: `openssl dhparam 4096 2> /dev/null | base64` # Ref: https://github.com/kubernetes/ingress-nginx/tree/main/docs/examples/customization/ssl-dh-param | +| imagePullSecrets | list | `[]` | Optional array of imagePullSecrets containing private registry credentials # Ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ | +| podSecurityPolicy.enabled | bool | `false` | | +| portNamePrefix | string | `""` | Prefix for TCP and UDP ports names in ingress controller service # Some cloud providers, like Yandex Cloud may have a requirements for a port name regex to support cloud load balancer integration | +| rbac.create | bool | `true` | | +| rbac.scope | bool | `false` | | +| revisionHistoryLimit | int | `10` | Rollback limit # | +| serviceAccount.annotations | object | `{}` | Annotations for the controller service account | +| serviceAccount.automountServiceAccountToken | bool | `true` | | +| serviceAccount.create | bool | `true` | | +| serviceAccount.name | string | `""` | | +| tcp | object | `{}` | TCP service key-value pairs # Ref: https://github.com/kubernetes/ingress-nginx/blob/main/docs/user-guide/exposing-tcp-udp-services.md # | +| udp | object | `{}` | UDP service key-value pairs # Ref: https://github.com/kubernetes/ingress-nginx/blob/main/docs/user-guide/exposing-tcp-udp-services.md # | diff --git a/helm/sonarqube/charts/ingress-nginx/README.md.gotmpl b/helm/sonarqube/charts/ingress-nginx/README.md.gotmpl new file mode 100644 index 0000000..17b029b --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/README.md.gotmpl @@ -0,0 +1,229 @@ +{{ template "chart.header" . }} +[ingress-nginx](https://github.com/kubernetes/ingress-nginx) Ingress controller for Kubernetes using NGINX as a reverse proxy and load balancer + +{{ template "chart.versionBadge" . }}{{ template "chart.typeBadge" . }}{{ template "chart.appVersionBadge" . }} + +To use, add `ingressClassName: nginx` spec field or the `kubernetes.io/ingress.class: nginx` annotation to your Ingress resources. + +This chart bootstraps an ingress-nginx deployment on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. + +{{ template "chart.requirementsSection" . }} + +## Get Repo Info + +```console +helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx +helm repo update +``` + +## Install Chart + +**Important:** only helm3 is supported + +```console +helm install [RELEASE_NAME] ingress-nginx/ingress-nginx +``` + +The command deploys ingress-nginx on the Kubernetes cluster in the default configuration. + +_See [configuration](#configuration) below._ + +_See [helm install](https://helm.sh/docs/helm/helm_install/) for command documentation._ + +## Uninstall Chart + +```console +helm uninstall [RELEASE_NAME] +``` + +This removes all the Kubernetes components associated with the chart and deletes the release. + +_See [helm uninstall](https://helm.sh/docs/helm/helm_uninstall/) for command documentation._ + +## Upgrading Chart + +```console +helm upgrade [RELEASE_NAME] [CHART] --install +``` + +_See [helm upgrade](https://helm.sh/docs/helm/helm_upgrade/) for command documentation._ + +### Migrating from stable/nginx-ingress + +There are two main ways to migrate a release from `stable/nginx-ingress` to `ingress-nginx/ingress-nginx` chart: + +1. For Nginx Ingress controllers used for non-critical services, the easiest method is to [uninstall](#uninstall-chart) the old release and [install](#install-chart) the new one +1. For critical services in production that require zero-downtime, you will want to: + 1. [Install](#install-chart) a second Ingress controller + 1. Redirect your DNS traffic from the old controller to the new controller + 1. Log traffic from both controllers during this changeover + 1. [Uninstall](#uninstall-chart) the old controller once traffic has fully drained from it + +Note that there are some different and upgraded configurations between the two charts, described by Rimas Mocevicius from JFrog in the "Upgrading to ingress-nginx Helm chart" section of [Migrating from Helm chart nginx-ingress to ingress-nginx](https://rimusz.net/migrating-to-ingress-nginx). As the `ingress-nginx/ingress-nginx` chart continues to update, you will want to check current differences by running [helm configuration](#configuration) commands on both charts. + +## Configuration + +See [Customizing the Chart Before Installing](https://helm.sh/docs/intro/using_helm/#customizing-the-chart-before-installing). To see all configurable options with detailed comments, visit the chart's [values.yaml](./values.yaml), or run these configuration commands: + +```console +helm show values ingress-nginx/ingress-nginx +``` + +### PodDisruptionBudget + +Note that the PodDisruptionBudget resource will only be defined if the replicaCount is greater than one, +else it would make it impossible to evacuate a node. See [gh issue #7127](https://github.com/helm/charts/issues/7127) for more info. + +### Prometheus Metrics + +The Ingress-Nginx Controller can export Prometheus metrics, by setting `controller.metrics.enabled` to `true`. + +You can add Prometheus annotations to the metrics service using `controller.metrics.service.annotations`. +Alternatively, if you use the Prometheus Operator, you can enable ServiceMonitor creation using `controller.metrics.serviceMonitor.enabled`. And set `controller.metrics.serviceMonitor.additionalLabels.release="prometheus"`. "release=prometheus" should match the label configured in the prometheus servicemonitor ( see `kubectl get servicemonitor prometheus-kube-prom-prometheus -oyaml -n prometheus`) + +### ingress-nginx nginx\_status page/stats server + +Previous versions of this chart had a `controller.stats.*` configuration block, which is now obsolete due to the following changes in Ingress-Nginx Controller: + +- In [0.16.1](https://github.com/kubernetes/ingress-nginx/blob/main/Changelog.md#0161), the vts (virtual host traffic status) dashboard was removed +- In [0.23.0](https://github.com/kubernetes/ingress-nginx/blob/main/Changelog.md#0230), the status page at port 18080 is now a unix socket webserver only available at localhost. + You can use `curl --unix-socket /tmp/nginx-status-server.sock http://localhost/nginx_status` inside the controller container to access it locally, or use the snippet from [nginx-ingress changelog](https://github.com/kubernetes/ingress-nginx/blob/main/Changelog.md#0230) to re-enable the http server + +### ExternalDNS Service Configuration + +Add an [ExternalDNS](https://github.com/kubernetes-sigs/external-dns) annotation to the LoadBalancer service: + +```yaml +controller: + service: + annotations: + external-dns.alpha.kubernetes.io/hostname: kubernetes-example.com. +``` + +### AWS L7 ELB with SSL Termination + +Annotate the controller as shown in the [nginx-ingress l7 patch](https://github.com/kubernetes/ingress-nginx/blob/ab3a789caae65eec4ad6e3b46b19750b481b6bce/deploy/aws/l7/service-l7.yaml): + +```yaml +controller: + service: + targetPorts: + http: http + https: http + annotations: + service.beta.kubernetes.io/aws-load-balancer-ssl-cert: arn:aws:acm:XX-XXXX-X:XXXXXXXXX:certificate/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXX + service.beta.kubernetes.io/aws-load-balancer-backend-protocol: "http" + service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "https" + service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout: '3600' +``` + +### Additional Internal Load Balancer + +This setup is useful when you need both external and internal load balancers but don't want to have multiple ingress controllers and multiple ingress objects per application. + +By default, the ingress object will point to the external load balancer address, but if correctly configured, you can make use of the internal one if the URL you are looking up resolves to the internal load balancer's URL. + +You'll need to set both the following values: + +`controller.service.internal.enabled` +`controller.service.internal.annotations` + +If one of them is missing the internal load balancer will not be deployed. Example you may have `controller.service.internal.enabled=true` but no annotations set, in this case no action will be taken. + +`controller.service.internal.annotations` varies with the cloud service you're using. + +Example for AWS: + +```yaml +controller: + service: + internal: + enabled: true + annotations: + # Create internal NLB + service.beta.kubernetes.io/aws-load-balancer-scheme: "internal" + # Create internal ELB(Deprecated) + # service.beta.kubernetes.io/aws-load-balancer-internal: "true" + # Any other annotation can be declared here. +``` + +Example for GCE: + +```yaml +controller: + service: + internal: + enabled: true + annotations: + # Create internal LB. More information: https://cloud.google.com/kubernetes-engine/docs/how-to/internal-load-balancing + # For GKE versions 1.17 and later + networking.gke.io/load-balancer-type: "Internal" + # For earlier versions + # cloud.google.com/load-balancer-type: "Internal" + + # Any other annotation can be declared here. +``` + +Example for Azure: + +```yaml +controller: + service: + annotations: + # Create internal LB + service.beta.kubernetes.io/azure-load-balancer-internal: "true" + # Any other annotation can be declared here. +``` + +Example for Oracle Cloud Infrastructure: + +```yaml +controller: + service: + annotations: + # Create internal LB + service.beta.kubernetes.io/oci-load-balancer-internal: "true" + # Any other annotation can be declared here. +``` + +The load balancer annotations of more cloud service providers can be found: [Internal load balancer](https://kubernetes.io/docs/concepts/services-networking/service/#internal-load-balancer). + +An use case for this scenario is having a split-view DNS setup where the public zone CNAME records point to the external balancer URL while the private zone CNAME records point to the internal balancer URL. This way, you only need one ingress kubernetes object. + +Optionally you can set `controller.service.loadBalancerIP` if you need a static IP for the resulting `LoadBalancer`. + +### Ingress Admission Webhooks + +With nginx-ingress-controller version 0.25+, the Ingress-Nginx Controller pod exposes an endpoint that will integrate with the `validatingwebhookconfiguration` Kubernetes feature to prevent bad ingress from being added to the cluster. +**This feature is enabled by default since 0.31.0.** + +With nginx-ingress-controller in 0.25.* work only with kubernetes 1.14+, 0.26 fix [this issue](https://github.com/kubernetes/ingress-nginx/pull/4521) + +#### How the Chart Configures the Hooks +A validating and configuration requires the endpoint to which the request is sent to use TLS. It is possible to set up custom certificates to do this, but in most cases, a self-signed certificate is enough. The setup of this component requires some more complex orchestration when using helm. The steps are created to be idempotent and to allow turning the feature on and off without running into helm quirks. + +1. A pre-install hook provisions a certificate into the same namespace using a format compatible with provisioning using end user certificates. If the certificate already exists, the hook exits. +2. The Ingress-Nginx Controller pod is configured to use a TLS proxy container, which will load that certificate. +3. Validating and Mutating webhook configurations are created in the cluster. +4. A post-install hook reads the CA from the secret created by step 1 and patches the Validating and Mutating webhook configurations. This process will allow a custom CA provisioned by some other process to also be patched into the webhook configurations. The chosen failure policy is also patched into the webhook configurations + +#### Alternatives +It should be possible to use [cert-manager/cert-manager](https://github.com/cert-manager/cert-manager) if a more complete solution is required. + +You can enable automatic self-signed TLS certificate provisioning via cert-manager by setting the `controller.admissionWebhooks.certManager.enabled` value to true. + +Please ensure that cert-manager is correctly installed and configured. + +### Helm Error When Upgrading: spec.clusterIP: Invalid value: "" + +If you are upgrading this chart from a version between 0.31.0 and 1.2.2 then you may get an error like this: + +```console +Error: UPGRADE FAILED: Service "?????-controller" is invalid: spec.clusterIP: Invalid value: "": field is immutable +``` + +Detail of how and why are in [this issue](https://github.com/helm/charts/pull/13646) but to resolve this you can set `xxxx.service.omitClusterIP` to `true` where `xxxx` is the service referenced in the error. + +As of version `1.26.0` of this chart, by simply not providing any clusterIP value, `invalid: spec.clusterIP: Invalid value: "": field is immutable` will no longer occur since `clusterIP: ""` will not be rendered. + +{{ template "chart.valuesSection" . }} diff --git a/helm/sonarqube/charts/ingress-nginx/changelog.md.gotmpl b/helm/sonarqube/charts/ingress-nginx/changelog.md.gotmpl new file mode 100644 index 0000000..de98856 --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/changelog.md.gotmpl @@ -0,0 +1,9 @@ +# Changelog + +This file documents all notable changes to [ingress-nginx](https://github.com/kubernetes/ingress-nginx) Helm Chart. The release numbering uses [semantic versioning](http://semver.org). + +### {{ .NewHelmChartVersion }} +{{ with .HelmUpdates }} +{{ range . }}* {{ . }} +{{ end }}{{ end }} +**Full Changelog**: https://github.com/kubernetes/ingress-nginx/compare/helm-chart-{{ .PreviousHelmChartVersion }}...helm-chart-{{ .NewHelmChartVersion }} diff --git a/helm/sonarqube/charts/ingress-nginx/changelog/.gitkeep b/helm/sonarqube/charts/ingress-nginx/changelog/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/helm/sonarqube/charts/ingress-nginx/changelog/Changelog-4.5.2.md b/helm/sonarqube/charts/ingress-nginx/changelog/Changelog-4.5.2.md new file mode 100644 index 0000000..b6d8a3b --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/changelog/Changelog-4.5.2.md @@ -0,0 +1,13 @@ +# Changelog + +This file documents all notable changes to [ingress-nginx](https://github.com/kubernetes/ingress-nginx) Helm Chart. The release numbering uses [semantic versioning](http://semver.org). + +### 4.5.2 + +* add lint on chart before release (#9570) +* ci: remove setup-helm step (#9404) +* feat(helm): Optionally use cert-manager instead admission patch (#9279) +* run helm release on main only and when the chart/value changes only (#9290) +* Update Ingress-Nginx version controller-v1.6.4 + +**Full Changelog**: https://github.com/kubernetes/ingress-nginx/compare/helm-chart-4.4.3...helm-chart-4.5.2 diff --git a/helm/sonarqube/charts/ingress-nginx/changelog/Changelog-4.6.0.md b/helm/sonarqube/charts/ingress-nginx/changelog/Changelog-4.6.0.md new file mode 100644 index 0000000..469aaba --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/changelog/Changelog-4.6.0.md @@ -0,0 +1,24 @@ +# Changelog + +This file documents all notable changes to [ingress-nginx](https://github.com/kubernetes/ingress-nginx) Helm Chart. The release numbering uses [semantic versioning](http://semver.org). + +### 4.5.3 + +* docs(helm): fix value key in readme for enabling certManager (#9640) +* Upgrade alpine 3.17.2 +* Upgrade golang 1.20 +* Drop testing/support for Kubernetes 1.23 +* docs(helm): fix value key in readme for enabling certManager (#9640) +* Update Ingress-Nginx version controller-v1.7.0 +* feat: OpenTelemetry module integration (#9062) +* canary-weight-total annotation ignored in rule backends (#9729) +* fix controller psp's volume config (#9740) +* Fix several Helm YAML issues with extraModules and extraInitContainers (#9709) +* Chart: Drop `controller.headers`, rework DH param secret. (#9659) +* Deployment/DaemonSet: Label pods using `ingress-nginx.labels`. (#9732) +* HPA: autoscaling/v2beta1 deprecated, bump apiVersion to v2 for defaultBackend (#9731) +* Fix incorrect annotation name in upstream hashing configuration (#9617) + +* Update Ingress-Nginx version controller-v1.7.0 + +**Full Changelog**: https://github.com/kubernetes/ingress-nginx/compare/helm-chart-4.5.2...helm-chart-4.6.0 diff --git a/helm/sonarqube/charts/ingress-nginx/changelog/Changelog-4.6.1.md b/helm/sonarqube/charts/ingress-nginx/changelog/Changelog-4.6.1.md new file mode 100644 index 0000000..57d99b8 --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/changelog/Changelog-4.6.1.md @@ -0,0 +1,11 @@ +# Changelog + +This file documents all notable changes to [ingress-nginx](https://github.com/kubernetes/ingress-nginx) Helm Chart. The release numbering uses [semantic versioning](http://semver.org). + +### 4.6.1 + +* [helm] Support custom port configuration for internal service (#9846) +* Adding resource type to default HPA configuration to resolve issues with Terraform helm chart usage (#9803) +* Update Ingress-Nginx version controller-v1.7.1 + +**Full Changelog**: https://github.com/kubernetes/ingress-nginx/compare/helm-chart-4.6.0...helm-chart-4.6.1 diff --git a/helm/sonarqube/charts/ingress-nginx/changelog/Changelog-4.7.0.md b/helm/sonarqube/charts/ingress-nginx/changelog/Changelog-4.7.0.md new file mode 100644 index 0000000..7399da7 --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/changelog/Changelog-4.7.0.md @@ -0,0 +1,14 @@ +# Changelog + +This file documents all notable changes to [ingress-nginx](https://github.com/kubernetes/ingress-nginx) Helm Chart. The release numbering uses [semantic versioning](http://semver.org). + +### 4.7.0 + +* helm: Fix opentelemetry module installation for daemonset (#9792) +* Update charts/* to keep project name display aligned (#9931) +* HPA: Use capabilites & align manifests. (#9521) +* PodDisruptionBudget spec logic update (#9904) +* add option for annotations in PodDisruptionBudget (#9843) +* Update Ingress-Nginx version controller-v1.8.0 + +**Full Changelog**: https://github.com/kubernetes/ingress-nginx/compare/helm-chart-4.6.1...helm-chart-4.7.0 diff --git a/helm/sonarqube/charts/ingress-nginx/changelog/Changelog-4.7.1.md b/helm/sonarqube/charts/ingress-nginx/changelog/Changelog-4.7.1.md new file mode 100644 index 0000000..4d69a71 --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/changelog/Changelog-4.7.1.md @@ -0,0 +1,12 @@ +# Changelog + +This file documents all notable changes to [ingress-nginx](https://github.com/kubernetes/ingress-nginx) Helm Chart. The release numbering uses [semantic versioning](http://semver.org). + +### 4.7.1 + +* Added a doc line to the missing helm value service.internal.loadBalancerIP (#9406) +* feat(helm): Add loadBalancerClass (#9562) +* added helmshowvalues example (#10019) +* Update Ingress-Nginx version controller-v1.8.1 + +**Full Changelog**: https://github.com/kubernetes/ingress-nginx/compare/helm-chart-4.7.0...helm-chart-4.7.1 diff --git a/helm/sonarqube/charts/ingress-nginx/ci/controller-admission-tls-cert-manager-values.yaml b/helm/sonarqube/charts/ingress-nginx/ci/controller-admission-tls-cert-manager-values.yaml new file mode 100644 index 0000000..a13241c --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/ci/controller-admission-tls-cert-manager-values.yaml @@ -0,0 +1,6 @@ +controller: + admissionWebhooks: + certManager: + enabled: true + service: + type: ClusterIP diff --git a/helm/sonarqube/charts/ingress-nginx/ci/controller-custom-ingressclass-flags.yaml b/helm/sonarqube/charts/ingress-nginx/ci/controller-custom-ingressclass-flags.yaml new file mode 100644 index 0000000..b28a232 --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/ci/controller-custom-ingressclass-flags.yaml @@ -0,0 +1,7 @@ +controller: + watchIngressWithoutClass: true + ingressClassResource: + name: custom-nginx + enabled: true + default: true + controllerValue: "k8s.io/custom-nginx" diff --git a/helm/sonarqube/charts/ingress-nginx/ci/daemonset-customconfig-values.yaml b/helm/sonarqube/charts/ingress-nginx/ci/daemonset-customconfig-values.yaml new file mode 100644 index 0000000..4393a5b --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/ci/daemonset-customconfig-values.yaml @@ -0,0 +1,14 @@ +controller: + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null + kind: DaemonSet + allowSnippetAnnotations: false + admissionWebhooks: + enabled: false + service: + type: ClusterIP + + config: + use-proxy-protocol: "true" diff --git a/helm/sonarqube/charts/ingress-nginx/ci/daemonset-customnodeport-values.yaml b/helm/sonarqube/charts/ingress-nginx/ci/daemonset-customnodeport-values.yaml new file mode 100644 index 0000000..1d94be2 --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/ci/daemonset-customnodeport-values.yaml @@ -0,0 +1,22 @@ +controller: + kind: DaemonSet + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null + admissionWebhooks: + enabled: false + + service: + type: NodePort + nodePorts: + tcp: + 9000: 30090 + udp: + 9001: 30091 + +tcp: + 9000: "default/test:8080" + +udp: + 9001: "default/test:8080" diff --git a/helm/sonarqube/charts/ingress-nginx/ci/daemonset-extra-modules.yaml b/helm/sonarqube/charts/ingress-nginx/ci/daemonset-extra-modules.yaml new file mode 100644 index 0000000..f299dbf --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/ci/daemonset-extra-modules.yaml @@ -0,0 +1,10 @@ +controller: + kind: DaemonSet + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + service: + type: ClusterIP + extraModules: + - name: opentelemetry + image: busybox diff --git a/helm/sonarqube/charts/ingress-nginx/ci/daemonset-headers-values.yaml b/helm/sonarqube/charts/ingress-nginx/ci/daemonset-headers-values.yaml new file mode 100644 index 0000000..ab7d47b --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/ci/daemonset-headers-values.yaml @@ -0,0 +1,14 @@ +controller: + kind: DaemonSet + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null + admissionWebhooks: + enabled: false + addHeaders: + X-Frame-Options: deny + proxySetHeaders: + X-Forwarded-Proto: https + service: + type: ClusterIP diff --git a/helm/sonarqube/charts/ingress-nginx/ci/daemonset-internal-lb-values.yaml b/helm/sonarqube/charts/ingress-nginx/ci/daemonset-internal-lb-values.yaml new file mode 100644 index 0000000..0a200a7 --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/ci/daemonset-internal-lb-values.yaml @@ -0,0 +1,14 @@ +controller: + kind: DaemonSet + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null + admissionWebhooks: + enabled: false + service: + type: ClusterIP + internal: + enabled: true + annotations: + service.beta.kubernetes.io/aws-load-balancer-internal: "true" diff --git a/helm/sonarqube/charts/ingress-nginx/ci/daemonset-nodeport-values.yaml b/helm/sonarqube/charts/ingress-nginx/ci/daemonset-nodeport-values.yaml new file mode 100644 index 0000000..3b7aa2f --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/ci/daemonset-nodeport-values.yaml @@ -0,0 +1,10 @@ +controller: + kind: DaemonSet + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null + admissionWebhooks: + enabled: false + service: + type: NodePort diff --git a/helm/sonarqube/charts/ingress-nginx/ci/daemonset-podannotations-values.yaml b/helm/sonarqube/charts/ingress-nginx/ci/daemonset-podannotations-values.yaml new file mode 100644 index 0000000..0b55306 --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/ci/daemonset-podannotations-values.yaml @@ -0,0 +1,17 @@ +controller: + kind: DaemonSet + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null + admissionWebhooks: + enabled: false + metrics: + enabled: true + service: + type: ClusterIP + podAnnotations: + prometheus.io/path: /metrics + prometheus.io/port: "10254" + prometheus.io/scheme: http + prometheus.io/scrape: "true" diff --git a/helm/sonarqube/charts/ingress-nginx/ci/daemonset-tcp-udp-configMapNamespace-values.yaml b/helm/sonarqube/charts/ingress-nginx/ci/daemonset-tcp-udp-configMapNamespace-values.yaml new file mode 100644 index 0000000..acd86a7 --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/ci/daemonset-tcp-udp-configMapNamespace-values.yaml @@ -0,0 +1,20 @@ +controller: + kind: DaemonSet + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null + admissionWebhooks: + enabled: false + service: + type: ClusterIP + tcp: + configMapNamespace: default + udp: + configMapNamespace: default + +tcp: + 9000: "default/test:8080" + +udp: + 9001: "default/test:8080" diff --git a/helm/sonarqube/charts/ingress-nginx/ci/daemonset-tcp-udp-portNamePrefix-values.yaml b/helm/sonarqube/charts/ingress-nginx/ci/daemonset-tcp-udp-portNamePrefix-values.yaml new file mode 100644 index 0000000..90b0f57 --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/ci/daemonset-tcp-udp-portNamePrefix-values.yaml @@ -0,0 +1,18 @@ +controller: + kind: DaemonSet + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null + admissionWebhooks: + enabled: false + service: + type: ClusterIP + +tcp: + 9000: "default/test:8080" + +udp: + 9001: "default/test:8080" + +portNamePrefix: "port" diff --git a/helm/sonarqube/charts/ingress-nginx/ci/daemonset-tcp-udp-values.yaml b/helm/sonarqube/charts/ingress-nginx/ci/daemonset-tcp-udp-values.yaml new file mode 100644 index 0000000..25ee64d --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/ci/daemonset-tcp-udp-values.yaml @@ -0,0 +1,16 @@ +controller: + kind: DaemonSet + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null + admissionWebhooks: + enabled: false + service: + type: ClusterIP + +tcp: + 9000: "default/test:8080" + +udp: + 9001: "default/test:8080" diff --git a/helm/sonarqube/charts/ingress-nginx/ci/daemonset-tcp-values.yaml b/helm/sonarqube/charts/ingress-nginx/ci/daemonset-tcp-values.yaml new file mode 100644 index 0000000..380c8b4 --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/ci/daemonset-tcp-values.yaml @@ -0,0 +1,14 @@ +controller: + kind: DaemonSet + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null + admissionWebhooks: + enabled: false + service: + type: ClusterIP + +tcp: + 9000: "default/test:8080" + 9001: "default/test:8080" diff --git a/helm/sonarqube/charts/ingress-nginx/ci/deamonset-default-values.yaml b/helm/sonarqube/charts/ingress-nginx/ci/deamonset-default-values.yaml new file mode 100644 index 0000000..82fa23e --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/ci/deamonset-default-values.yaml @@ -0,0 +1,10 @@ +controller: + kind: DaemonSet + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null + admissionWebhooks: + enabled: false + service: + type: ClusterIP diff --git a/helm/sonarqube/charts/ingress-nginx/ci/deamonset-metrics-values.yaml b/helm/sonarqube/charts/ingress-nginx/ci/deamonset-metrics-values.yaml new file mode 100644 index 0000000..cb3cb54 --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/ci/deamonset-metrics-values.yaml @@ -0,0 +1,12 @@ +controller: + kind: DaemonSet + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null + admissionWebhooks: + enabled: false + metrics: + enabled: true + service: + type: ClusterIP diff --git a/helm/sonarqube/charts/ingress-nginx/ci/deamonset-psp-values.yaml b/helm/sonarqube/charts/ingress-nginx/ci/deamonset-psp-values.yaml new file mode 100644 index 0000000..8026a63 --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/ci/deamonset-psp-values.yaml @@ -0,0 +1,13 @@ +controller: + kind: DaemonSet + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null + admissionWebhooks: + enabled: false + service: + type: ClusterIP + +podSecurityPolicy: + enabled: true diff --git a/helm/sonarqube/charts/ingress-nginx/ci/deamonset-webhook-and-psp-values.yaml b/helm/sonarqube/charts/ingress-nginx/ci/deamonset-webhook-and-psp-values.yaml new file mode 100644 index 0000000..fccdb13 --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/ci/deamonset-webhook-and-psp-values.yaml @@ -0,0 +1,13 @@ +controller: + kind: DaemonSet + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null + admissionWebhooks: + enabled: true + service: + type: ClusterIP + +podSecurityPolicy: + enabled: true diff --git a/helm/sonarqube/charts/ingress-nginx/ci/deamonset-webhook-values.yaml b/helm/sonarqube/charts/ingress-nginx/ci/deamonset-webhook-values.yaml new file mode 100644 index 0000000..54d364d --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/ci/deamonset-webhook-values.yaml @@ -0,0 +1,10 @@ +controller: + kind: DaemonSet + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null + admissionWebhooks: + enabled: true + service: + type: ClusterIP diff --git a/helm/sonarqube/charts/ingress-nginx/ci/deployment-autoscaling-behavior-values.yaml b/helm/sonarqube/charts/ingress-nginx/ci/deployment-autoscaling-behavior-values.yaml new file mode 100644 index 0000000..dca3f35 --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/ci/deployment-autoscaling-behavior-values.yaml @@ -0,0 +1,14 @@ +controller: + autoscaling: + enabled: true + behavior: + scaleDown: + stabilizationWindowSeconds: 300 + policies: + - type: Pods + value: 1 + periodSeconds: 180 + admissionWebhooks: + enabled: false + service: + type: ClusterIP diff --git a/helm/sonarqube/charts/ingress-nginx/ci/deployment-autoscaling-values.yaml b/helm/sonarqube/charts/ingress-nginx/ci/deployment-autoscaling-values.yaml new file mode 100644 index 0000000..b8b3ac6 --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/ci/deployment-autoscaling-values.yaml @@ -0,0 +1,11 @@ +controller: + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null + autoscaling: + enabled: true + admissionWebhooks: + enabled: false + service: + type: ClusterIP diff --git a/helm/sonarqube/charts/ingress-nginx/ci/deployment-customconfig-values.yaml b/helm/sonarqube/charts/ingress-nginx/ci/deployment-customconfig-values.yaml new file mode 100644 index 0000000..1749418 --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/ci/deployment-customconfig-values.yaml @@ -0,0 +1,12 @@ +controller: + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null + config: + use-proxy-protocol: "true" + allowSnippetAnnotations: false + admissionWebhooks: + enabled: false + service: + type: ClusterIP diff --git a/helm/sonarqube/charts/ingress-nginx/ci/deployment-customnodeport-values.yaml b/helm/sonarqube/charts/ingress-nginx/ci/deployment-customnodeport-values.yaml new file mode 100644 index 0000000..a564eaf --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/ci/deployment-customnodeport-values.yaml @@ -0,0 +1,20 @@ +controller: + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null + admissionWebhooks: + enabled: false + service: + type: NodePort + nodePorts: + tcp: + 9000: 30090 + udp: + 9001: 30091 + +tcp: + 9000: "default/test:8080" + +udp: + 9001: "default/test:8080" diff --git a/helm/sonarqube/charts/ingress-nginx/ci/deployment-default-values.yaml b/helm/sonarqube/charts/ingress-nginx/ci/deployment-default-values.yaml new file mode 100644 index 0000000..9f46b4e --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/ci/deployment-default-values.yaml @@ -0,0 +1,8 @@ +# Left blank to test default values +controller: + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null + service: + type: ClusterIP diff --git a/helm/sonarqube/charts/ingress-nginx/ci/deployment-extra-modules-default-container-sec-context.yaml b/helm/sonarqube/charts/ingress-nginx/ci/deployment-extra-modules-default-container-sec-context.yaml new file mode 100644 index 0000000..2310c34 --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/ci/deployment-extra-modules-default-container-sec-context.yaml @@ -0,0 +1,12 @@ +controller: + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null + service: + type: ClusterIP + containerSecurityContext: + allowPrivilegeEscalation: false + extraModules: + - name: opentelemetry + image: busybox diff --git a/helm/sonarqube/charts/ingress-nginx/ci/deployment-extra-modules-specific-container-sec-context.yaml b/helm/sonarqube/charts/ingress-nginx/ci/deployment-extra-modules-specific-container-sec-context.yaml new file mode 100644 index 0000000..bd2f011 --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/ci/deployment-extra-modules-specific-container-sec-context.yaml @@ -0,0 +1,12 @@ +controller: + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null + service: + type: ClusterIP + extraModules: + - name: opentelemetry + image: busybox + containerSecurityContext: + allowPrivilegeEscalation: false diff --git a/helm/sonarqube/charts/ingress-nginx/ci/deployment-extra-modules.yaml b/helm/sonarqube/charts/ingress-nginx/ci/deployment-extra-modules.yaml new file mode 100644 index 0000000..ec59235 --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/ci/deployment-extra-modules.yaml @@ -0,0 +1,10 @@ +controller: + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null + service: + type: ClusterIP + extraModules: + - name: opentelemetry + image: busybox diff --git a/helm/sonarqube/charts/ingress-nginx/ci/deployment-headers-values.yaml b/helm/sonarqube/charts/ingress-nginx/ci/deployment-headers-values.yaml new file mode 100644 index 0000000..17a11ac --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/ci/deployment-headers-values.yaml @@ -0,0 +1,13 @@ +controller: + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null + admissionWebhooks: + enabled: false + addHeaders: + X-Frame-Options: deny + proxySetHeaders: + X-Forwarded-Proto: https + service: + type: ClusterIP diff --git a/helm/sonarqube/charts/ingress-nginx/ci/deployment-internal-lb-values.yaml b/helm/sonarqube/charts/ingress-nginx/ci/deployment-internal-lb-values.yaml new file mode 100644 index 0000000..663ccb9 --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/ci/deployment-internal-lb-values.yaml @@ -0,0 +1,19 @@ +controller: + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null + admissionWebhooks: + enabled: false + service: + type: ClusterIP + internal: + enabled: true + annotations: + service.beta.kubernetes.io/aws-load-balancer-internal: "true" + ports: + http: 443 + https: 80 + targetPorts: + http: 443 + https: 80 diff --git a/helm/sonarqube/charts/ingress-nginx/ci/deployment-metrics-values.yaml b/helm/sonarqube/charts/ingress-nginx/ci/deployment-metrics-values.yaml new file mode 100644 index 0000000..9209ad5 --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/ci/deployment-metrics-values.yaml @@ -0,0 +1,11 @@ +controller: + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null + admissionWebhooks: + enabled: false + metrics: + enabled: true + service: + type: ClusterIP diff --git a/helm/sonarqube/charts/ingress-nginx/ci/deployment-nodeport-values.yaml b/helm/sonarqube/charts/ingress-nginx/ci/deployment-nodeport-values.yaml new file mode 100644 index 0000000..cd9b323 --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/ci/deployment-nodeport-values.yaml @@ -0,0 +1,9 @@ +controller: + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null + admissionWebhooks: + enabled: false + service: + type: NodePort diff --git a/helm/sonarqube/charts/ingress-nginx/ci/deployment-podannotations-values.yaml b/helm/sonarqube/charts/ingress-nginx/ci/deployment-podannotations-values.yaml new file mode 100644 index 0000000..b48d93c --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/ci/deployment-podannotations-values.yaml @@ -0,0 +1,16 @@ +controller: + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null + admissionWebhooks: + enabled: false + metrics: + enabled: true + service: + type: ClusterIP + podAnnotations: + prometheus.io/path: /metrics + prometheus.io/port: "10254" + prometheus.io/scheme: http + prometheus.io/scrape: "true" diff --git a/helm/sonarqube/charts/ingress-nginx/ci/deployment-psp-values.yaml b/helm/sonarqube/charts/ingress-nginx/ci/deployment-psp-values.yaml new file mode 100644 index 0000000..2f332a7 --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/ci/deployment-psp-values.yaml @@ -0,0 +1,10 @@ +controller: + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null + service: + type: ClusterIP + +podSecurityPolicy: + enabled: true diff --git a/helm/sonarqube/charts/ingress-nginx/ci/deployment-tcp-udp-configMapNamespace-values.yaml b/helm/sonarqube/charts/ingress-nginx/ci/deployment-tcp-udp-configMapNamespace-values.yaml new file mode 100644 index 0000000..c51a4e9 --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/ci/deployment-tcp-udp-configMapNamespace-values.yaml @@ -0,0 +1,19 @@ +controller: + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null + admissionWebhooks: + enabled: false + service: + type: ClusterIP + tcp: + configMapNamespace: default + udp: + configMapNamespace: default + +tcp: + 9000: "default/test:8080" + +udp: + 9001: "default/test:8080" diff --git a/helm/sonarqube/charts/ingress-nginx/ci/deployment-tcp-udp-portNamePrefix-values.yaml b/helm/sonarqube/charts/ingress-nginx/ci/deployment-tcp-udp-portNamePrefix-values.yaml new file mode 100644 index 0000000..56323c5 --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/ci/deployment-tcp-udp-portNamePrefix-values.yaml @@ -0,0 +1,17 @@ +controller: + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null + admissionWebhooks: + enabled: false + service: + type: ClusterIP + +tcp: + 9000: "default/test:8080" + +udp: + 9001: "default/test:8080" + +portNamePrefix: "port" diff --git a/helm/sonarqube/charts/ingress-nginx/ci/deployment-tcp-udp-values.yaml b/helm/sonarqube/charts/ingress-nginx/ci/deployment-tcp-udp-values.yaml new file mode 100644 index 0000000..5b45b69 --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/ci/deployment-tcp-udp-values.yaml @@ -0,0 +1,15 @@ +controller: + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null + admissionWebhooks: + enabled: false + service: + type: ClusterIP + +tcp: + 9000: "default/test:8080" + +udp: + 9001: "default/test:8080" diff --git a/helm/sonarqube/charts/ingress-nginx/ci/deployment-tcp-values.yaml b/helm/sonarqube/charts/ingress-nginx/ci/deployment-tcp-values.yaml new file mode 100644 index 0000000..ac0b6e6 --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/ci/deployment-tcp-values.yaml @@ -0,0 +1,11 @@ +controller: + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null + service: + type: ClusterIP + +tcp: + 9000: "default/test:8080" + 9001: "default/test:8080" diff --git a/helm/sonarqube/charts/ingress-nginx/ci/deployment-webhook-and-psp-values.yaml b/helm/sonarqube/charts/ingress-nginx/ci/deployment-webhook-and-psp-values.yaml new file mode 100644 index 0000000..6195bb3 --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/ci/deployment-webhook-and-psp-values.yaml @@ -0,0 +1,12 @@ +controller: + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null + admissionWebhooks: + enabled: true + service: + type: ClusterIP + +podSecurityPolicy: + enabled: true diff --git a/helm/sonarqube/charts/ingress-nginx/ci/deployment-webhook-extraEnvs-values.yaml b/helm/sonarqube/charts/ingress-nginx/ci/deployment-webhook-extraEnvs-values.yaml new file mode 100644 index 0000000..95487b0 --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/ci/deployment-webhook-extraEnvs-values.yaml @@ -0,0 +1,12 @@ +controller: + service: + type: ClusterIP + admissionWebhooks: + enabled: true + extraEnvs: + - name: FOO + value: foo + - name: TEST + value: test + patch: + enabled: true diff --git a/helm/sonarqube/charts/ingress-nginx/ci/deployment-webhook-resources-values.yaml b/helm/sonarqube/charts/ingress-nginx/ci/deployment-webhook-resources-values.yaml new file mode 100644 index 0000000..49ebbb0 --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/ci/deployment-webhook-resources-values.yaml @@ -0,0 +1,23 @@ +controller: + service: + type: ClusterIP + admissionWebhooks: + enabled: true + createSecretJob: + resources: + limits: + cpu: 10m + memory: 20Mi + requests: + cpu: 10m + memory: 20Mi + patchWebhookJob: + resources: + limits: + cpu: 10m + memory: 20Mi + requests: + cpu: 10m + memory: 20Mi + patch: + enabled: true diff --git a/helm/sonarqube/charts/ingress-nginx/ci/deployment-webhook-values.yaml b/helm/sonarqube/charts/ingress-nginx/ci/deployment-webhook-values.yaml new file mode 100644 index 0000000..76669a5 --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/ci/deployment-webhook-values.yaml @@ -0,0 +1,9 @@ +controller: + image: + repository: ingress-controller/controller + tag: 1.0.0-dev + digest: null + admissionWebhooks: + enabled: true + service: + type: ClusterIP diff --git a/helm/sonarqube/charts/ingress-nginx/templates/NOTES.txt b/helm/sonarqube/charts/ingress-nginx/templates/NOTES.txt new file mode 100644 index 0000000..9fe35c7 --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/templates/NOTES.txt @@ -0,0 +1,73 @@ +The ingress-nginx controller has been installed. + +{{- if contains "NodePort" .Values.controller.service.type }} +Get the application URL by running these commands: + +{{- if (not (empty .Values.controller.service.nodePorts.http)) }} + export HTTP_NODE_PORT={{ .Values.controller.service.nodePorts.http }} +{{- else }} + export HTTP_NODE_PORT=$(kubectl --namespace {{ .Release.Namespace }} get services -o jsonpath="{.spec.ports[0].nodePort}" {{ include "ingress-nginx.controller.fullname" . }}) +{{- end }} +{{- if (not (empty .Values.controller.service.nodePorts.https)) }} + export HTTPS_NODE_PORT={{ .Values.controller.service.nodePorts.https }} +{{- else }} + export HTTPS_NODE_PORT=$(kubectl --namespace {{ .Release.Namespace }} get services -o jsonpath="{.spec.ports[1].nodePort}" {{ include "ingress-nginx.controller.fullname" . }}) +{{- end }} + export NODE_IP=$(kubectl --namespace {{ .Release.Namespace }} get nodes -o jsonpath="{.items[0].status.addresses[1].address}") + + echo "Visit http://$NODE_IP:$HTTP_NODE_PORT to access your application via HTTP." + echo "Visit https://$NODE_IP:$HTTPS_NODE_PORT to access your application via HTTPS." +{{- else if contains "LoadBalancer" .Values.controller.service.type }} +It may take a few minutes for the LoadBalancer IP to be available. +You can watch the status by running 'kubectl --namespace {{ .Release.Namespace }} get services -o wide -w {{ include "ingress-nginx.controller.fullname" . }}' +{{- else if contains "ClusterIP" .Values.controller.service.type }} +Get the application URL by running these commands: + export POD_NAME=$(kubectl --namespace {{ .Release.Namespace }} get pods -o jsonpath="{.items[0].metadata.name}" -l "app={{ template "ingress-nginx.name" . }},component={{ .Values.controller.name }},release={{ .Release.Name }}") + kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:80 + echo "Visit http://127.0.0.1:8080 to access your application." +{{- end }} + +An example Ingress that makes use of the controller: + +{{- $isV1 := semverCompare ">=1" .Chart.AppVersion}} + apiVersion: networking.k8s.io/v1 + kind: Ingress + metadata: + name: example + namespace: foo + {{- if eq $isV1 false }} + annotations: + kubernetes.io/ingress.class: {{ .Values.controller.ingressClass }} + {{- end }} + spec: + {{- if $isV1 }} + ingressClassName: {{ .Values.controller.ingressClassResource.name }} + {{- end }} + rules: + - host: www.example.com + http: + paths: + - pathType: Prefix + backend: + service: + name: exampleService + port: + number: 80 + path: / + # This section is only required if TLS is to be enabled for the Ingress + tls: + - hosts: + - www.example.com + secretName: example-tls + +If TLS is enabled for the Ingress, a Secret containing the certificate and key must also be provided: + + apiVersion: v1 + kind: Secret + metadata: + name: example-tls + namespace: foo + data: + tls.crt: + tls.key: + type: kubernetes.io/tls diff --git a/helm/sonarqube/charts/ingress-nginx/templates/_helpers.tpl b/helm/sonarqube/charts/ingress-nginx/templates/_helpers.tpl new file mode 100644 index 0000000..548e8cf --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/templates/_helpers.tpl @@ -0,0 +1,216 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "ingress-nginx.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "ingress-nginx.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +*/}} +{{- define "ingress-nginx.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 -}} + + +{{/* +Container SecurityContext. +*/}} +{{- define "controller.containerSecurityContext" -}} +{{- if .Values.controller.containerSecurityContext -}} +{{- toYaml .Values.controller.containerSecurityContext -}} +{{- else -}} +capabilities: + drop: + - ALL + add: + - NET_BIND_SERVICE + {{- if .Values.controller.image.chroot }} + - SYS_CHROOT + {{- end }} +runAsUser: {{ .Values.controller.image.runAsUser }} +allowPrivilegeEscalation: {{ .Values.controller.image.allowPrivilegeEscalation }} +{{- end }} +{{- end -}} + +{{/* +Get specific image +*/}} +{{- define "ingress-nginx.image" -}} +{{- if .chroot -}} +{{- printf "%s-chroot" .image -}} +{{- else -}} +{{- printf "%s" .image -}} +{{- end }} +{{- end -}} + +{{/* +Get specific image digest +*/}} +{{- define "ingress-nginx.imageDigest" -}} +{{- if .chroot -}} +{{- if .digestChroot -}} +{{- printf "@%s" .digestChroot -}} +{{- end }} +{{- else -}} +{{ if .digest -}} +{{- printf "@%s" .digest -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Create a default fully qualified controller name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +*/}} +{{- define "ingress-nginx.controller.fullname" -}} +{{- printf "%s-%s" (include "ingress-nginx.fullname" .) .Values.controller.name | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Construct a unique electionID. +Users can provide an override for an explicit electionID if they want via `.Values.controller.electionID` +*/}} +{{- define "ingress-nginx.controller.electionID" -}} +{{- $defElectionID := printf "%s-leader" (include "ingress-nginx.fullname" .) -}} +{{- $electionID := default $defElectionID .Values.controller.electionID -}} +{{- print $electionID -}} +{{- end -}} + +{{/* +Construct the path for the publish-service. + +By convention this will simply use the / to match the name of the +service generated. + +Users can provide an override for an explicit service they want bound via `.Values.controller.publishService.pathOverride` + +*/}} +{{- define "ingress-nginx.controller.publishServicePath" -}} +{{- $defServiceName := printf "%s/%s" "$(POD_NAMESPACE)" (include "ingress-nginx.controller.fullname" .) -}} +{{- $servicePath := default $defServiceName .Values.controller.publishService.pathOverride }} +{{- print $servicePath | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create a default fully qualified default backend name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +*/}} +{{- define "ingress-nginx.defaultBackend.fullname" -}} +{{- printf "%s-%s" (include "ingress-nginx.fullname" .) .Values.defaultBackend.name | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Common labels +*/}} +{{- define "ingress-nginx.labels" -}} +helm.sh/chart: {{ include "ingress-nginx.chart" . }} +{{ include "ingress-nginx.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/part-of: {{ template "ingress-nginx.name" . }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- if .Values.commonLabels}} +{{ toYaml .Values.commonLabels }} +{{- end }} +{{- end -}} + +{{/* +Selector labels +*/}} +{{- define "ingress-nginx.selectorLabels" -}} +app.kubernetes.io/name: {{ include "ingress-nginx.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end -}} + +{{/* +Create the name of the controller service account to use +*/}} +{{- define "ingress-nginx.serviceAccountName" -}} +{{- if .Values.serviceAccount.create -}} + {{ default (include "ingress-nginx.fullname" .) .Values.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +Create the name of the backend service account to use - only used when podsecuritypolicy is also enabled +*/}} +{{- define "ingress-nginx.defaultBackend.serviceAccountName" -}} +{{- if .Values.defaultBackend.serviceAccount.create -}} + {{ default (printf "%s-backend" (include "ingress-nginx.fullname" .)) .Values.defaultBackend.serviceAccount.name }} +{{- else -}} + {{ default "default-backend" .Values.defaultBackend.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiGroup for PodSecurityPolicy. +*/}} +{{- define "podSecurityPolicy.apiGroup" -}} +{{- if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} +{{- print "policy" -}} +{{- else -}} +{{- print "extensions" -}} +{{- end -}} +{{- end -}} + +{{/* +Check the ingress controller version tag is at most three versions behind the last release +*/}} +{{- define "isControllerTagValid" -}} +{{- if not (semverCompare ">=0.27.0-0" .Values.controller.image.tag) -}} +{{- fail "Controller container image tag should be 0.27.0 or higher" -}} +{{- end -}} +{{- end -}} + +{{/* +IngressClass parameters. +*/}} +{{- define "ingressClass.parameters" -}} + {{- if .Values.controller.ingressClassResource.parameters -}} + parameters: +{{ toYaml .Values.controller.ingressClassResource.parameters | indent 4}} + {{ end }} +{{- end -}} + +{{/* +Extra modules. +*/}} +{{- define "extraModules" -}} + +- name: {{ .name }} + image: {{ .image }} + {{- if .distroless | default false }} + command: ['/init_module'] + {{- else }} + command: ['sh', '-c', '/usr/local/bin/init_module.sh'] + {{- end }} + {{- if .containerSecurityContext }} + securityContext: {{ .containerSecurityContext | toYaml | nindent 4 }} + {{- end }} + volumeMounts: + - name: {{ toYaml "modules"}} + mountPath: {{ toYaml "/modules_mount"}} + +{{- end -}} diff --git a/helm/sonarqube/charts/ingress-nginx/templates/_params.tpl b/helm/sonarqube/charts/ingress-nginx/templates/_params.tpl new file mode 100644 index 0000000..a1aef01 --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/templates/_params.tpl @@ -0,0 +1,65 @@ +{{- define "ingress-nginx.params" -}} +- /nginx-ingress-controller +{{- if .Values.defaultBackend.enabled }} +- --default-backend-service=$(POD_NAMESPACE)/{{ include "ingress-nginx.defaultBackend.fullname" . }} +{{- end }} +{{- if and .Values.controller.publishService.enabled .Values.controller.service.enabled }} +{{- if .Values.controller.service.external.enabled }} +- --publish-service={{ template "ingress-nginx.controller.publishServicePath" . }} +{{- else if .Values.controller.service.internal.enabled }} +- --publish-service={{ template "ingress-nginx.controller.publishServicePath" . }}-internal +{{- end }} +{{- end }} +- --election-id={{ include "ingress-nginx.controller.electionID" . }} +- --controller-class={{ .Values.controller.ingressClassResource.controllerValue }} +{{- if .Values.controller.ingressClass }} +- --ingress-class={{ .Values.controller.ingressClass }} +{{- end }} +- --configmap={{ default "$(POD_NAMESPACE)" .Values.controller.configMapNamespace }}/{{ include "ingress-nginx.controller.fullname" . }} +{{- if .Values.tcp }} +- --tcp-services-configmap={{ default "$(POD_NAMESPACE)" .Values.controller.tcp.configMapNamespace }}/{{ include "ingress-nginx.fullname" . }}-tcp +{{- end }} +{{- if .Values.udp }} +- --udp-services-configmap={{ default "$(POD_NAMESPACE)" .Values.controller.udp.configMapNamespace }}/{{ include "ingress-nginx.fullname" . }}-udp +{{- end }} +{{- if .Values.controller.scope.enabled }} +- --watch-namespace={{ default "$(POD_NAMESPACE)" .Values.controller.scope.namespace }} +{{- end }} +{{- if and (not .Values.controller.scope.enabled) .Values.controller.scope.namespaceSelector }} +- --watch-namespace-selector={{ default "" .Values.controller.scope.namespaceSelector }} +{{- end }} +{{- if and .Values.controller.reportNodeInternalIp .Values.controller.hostNetwork }} +- --report-node-internal-ip-address={{ .Values.controller.reportNodeInternalIp }} +{{- end }} +{{- if .Values.controller.admissionWebhooks.enabled }} +- --validating-webhook=:{{ .Values.controller.admissionWebhooks.port }} +- --validating-webhook-certificate={{ .Values.controller.admissionWebhooks.certificate }} +- --validating-webhook-key={{ .Values.controller.admissionWebhooks.key }} +{{- end }} +{{- if .Values.controller.maxmindLicenseKey }} +- --maxmind-license-key={{ .Values.controller.maxmindLicenseKey }} +{{- end }} +{{- if .Values.controller.healthCheckHost }} +- --healthz-host={{ .Values.controller.healthCheckHost }} +{{- end }} +{{- if not (eq .Values.controller.healthCheckPath "/healthz") }} +- --health-check-path={{ .Values.controller.healthCheckPath }} +{{- end }} +{{- if .Values.controller.ingressClassByName }} +- --ingress-class-by-name=true +{{- end }} +{{- if .Values.controller.watchIngressWithoutClass }} +- --watch-ingress-without-class=true +{{- end }} +{{- if .Values.controller.enableTopologyAwareRouting }} +- --enable-topology-aware-routing=true +{{- end }} +{{- range $key, $value := .Values.controller.extraArgs }} +{{- /* Accept keys without values or with false as value */}} +{{- if eq ($value | quote | len) 2 }} +- --{{ $key }} +{{- else }} +- --{{ $key }}={{ $value }} +{{- end }} +{{- end }} +{{- end -}} diff --git a/helm/sonarqube/charts/ingress-nginx/templates/admission-webhooks/cert-manager.yaml b/helm/sonarqube/charts/ingress-nginx/templates/admission-webhooks/cert-manager.yaml new file mode 100644 index 0000000..55fab47 --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/templates/admission-webhooks/cert-manager.yaml @@ -0,0 +1,63 @@ +{{- if and .Values.controller.admissionWebhooks.enabled .Values.controller.admissionWebhooks.certManager.enabled -}} +{{- if not .Values.controller.admissionWebhooks.certManager.issuerRef -}} +# Create a selfsigned Issuer, in order to create a root CA certificate for +# signing webhook serving certificates +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: {{ include "ingress-nginx.fullname" . }}-self-signed-issuer + namespace: {{ .Release.Namespace }} +spec: + selfSigned: {} +--- +# Generate a CA Certificate used to sign certificates for the webhook +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: {{ include "ingress-nginx.fullname" . }}-root-cert + namespace: {{ .Release.Namespace }} +spec: + secretName: {{ include "ingress-nginx.fullname" . }}-root-cert + duration: {{ .Values.controller.admissionWebhooks.certManager.rootCert.duration | default "43800h0m0s" | quote }} + issuerRef: + name: {{ include "ingress-nginx.fullname" . }}-self-signed-issuer + commonName: "ca.webhook.ingress-nginx" + isCA: true + subject: + organizations: + - ingress-nginx +--- +# Create an Issuer that uses the above generated CA certificate to issue certs +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: {{ include "ingress-nginx.fullname" . }}-root-issuer + namespace: {{ .Release.Namespace }} +spec: + ca: + secretName: {{ include "ingress-nginx.fullname" . }}-root-cert +{{- end }} +--- +# generate a server certificate for the apiservices to use +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: {{ include "ingress-nginx.fullname" . }}-admission + namespace: {{ .Release.Namespace }} +spec: + secretName: {{ include "ingress-nginx.fullname" . }}-admission + duration: {{ .Values.controller.admissionWebhooks.certManager.admissionCert.duration | default "8760h0m0s" | quote }} + issuerRef: + {{- if .Values.controller.admissionWebhooks.certManager.issuerRef }} + {{- toYaml .Values.controller.admissionWebhooks.certManager.issuerRef | nindent 4 }} + {{- else }} + name: {{ include "ingress-nginx.fullname" . }}-root-issuer + {{- end }} + dnsNames: + - {{ include "ingress-nginx.controller.fullname" . }}-admission + - {{ include "ingress-nginx.controller.fullname" . }}-admission.{{ .Release.Namespace }} + - {{ include "ingress-nginx.controller.fullname" . }}-admission.{{ .Release.Namespace }}.svc + subject: + organizations: + - ingress-nginx-admission +{{- end -}} diff --git a/helm/sonarqube/charts/ingress-nginx/templates/admission-webhooks/job-patch/clusterrole.yaml b/helm/sonarqube/charts/ingress-nginx/templates/admission-webhooks/job-patch/clusterrole.yaml new file mode 100644 index 0000000..f9ec709 --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/templates/admission-webhooks/job-patch/clusterrole.yaml @@ -0,0 +1,34 @@ +{{- if and .Values.controller.admissionWebhooks.enabled .Values.controller.admissionWebhooks.patch.enabled (not .Values.controller.admissionWebhooks.certManager.enabled) -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "ingress-nginx.fullname" . }}-admission + annotations: + "helm.sh/hook": pre-install,pre-upgrade,post-install,post-upgrade + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: admission-webhook + {{- with .Values.controller.admissionWebhooks.patch.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +rules: + - apiGroups: + - admissionregistration.k8s.io + resources: + - validatingwebhookconfigurations + verbs: + - get + - update +{{- if .Values.podSecurityPolicy.enabled }} + - apiGroups: ['extensions'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + {{- with .Values.controller.admissionWebhooks.existingPsp }} + - {{ . }} + {{- else }} + - {{ include "ingress-nginx.fullname" . }}-admission + {{- end }} +{{- end }} +{{- end }} diff --git a/helm/sonarqube/charts/ingress-nginx/templates/admission-webhooks/job-patch/clusterrolebinding.yaml b/helm/sonarqube/charts/ingress-nginx/templates/admission-webhooks/job-patch/clusterrolebinding.yaml new file mode 100644 index 0000000..8719532 --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/templates/admission-webhooks/job-patch/clusterrolebinding.yaml @@ -0,0 +1,23 @@ +{{- if and .Values.controller.admissionWebhooks.enabled .Values.controller.admissionWebhooks.patch.enabled (not .Values.controller.admissionWebhooks.certManager.enabled) -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "ingress-nginx.fullname" . }}-admission + annotations: + "helm.sh/hook": pre-install,pre-upgrade,post-install,post-upgrade + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: admission-webhook + {{- with .Values.controller.admissionWebhooks.patch.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ include "ingress-nginx.fullname" . }}-admission +subjects: + - kind: ServiceAccount + name: {{ include "ingress-nginx.fullname" . }}-admission + namespace: {{ .Release.Namespace | quote }} +{{- end }} diff --git a/helm/sonarqube/charts/ingress-nginx/templates/admission-webhooks/job-patch/job-createSecret.yaml b/helm/sonarqube/charts/ingress-nginx/templates/admission-webhooks/job-patch/job-createSecret.yaml new file mode 100644 index 0000000..d93433e --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/templates/admission-webhooks/job-patch/job-createSecret.yaml @@ -0,0 +1,80 @@ +{{- if and .Values.controller.admissionWebhooks.enabled .Values.controller.admissionWebhooks.patch.enabled (not .Values.controller.admissionWebhooks.certManager.enabled) -}} +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ include "ingress-nginx.fullname" . }}-admission-create + namespace: {{ .Release.Namespace }} + annotations: + "helm.sh/hook": pre-install,pre-upgrade + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded + {{- with .Values.controller.admissionWebhooks.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: admission-webhook + {{- with .Values.controller.admissionWebhooks.patch.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: +{{- if .Capabilities.APIVersions.Has "batch/v1alpha1" }} + # Alpha feature since k8s 1.12 + ttlSecondsAfterFinished: 0 +{{- end }} + template: + metadata: + name: {{ include "ingress-nginx.fullname" . }}-admission-create + {{- if .Values.controller.admissionWebhooks.patch.podAnnotations }} + annotations: {{ toYaml .Values.controller.admissionWebhooks.patch.podAnnotations | nindent 8 }} + {{- end }} + labels: + {{- include "ingress-nginx.labels" . | nindent 8 }} + app.kubernetes.io/component: admission-webhook + {{- with .Values.controller.admissionWebhooks.patch.labels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- if .Values.controller.admissionWebhooks.patch.priorityClassName }} + priorityClassName: {{ .Values.controller.admissionWebhooks.patch.priorityClassName }} + {{- end }} + {{- if .Values.imagePullSecrets }} + imagePullSecrets: {{ toYaml .Values.imagePullSecrets | nindent 8 }} + {{- end }} + containers: + - name: create + {{- with .Values.controller.admissionWebhooks.patch.image }} + image: "{{- if .repository -}}{{ .repository }}{{ else }}{{ .registry }}/{{ .image }}{{- end -}}:{{ .tag }}{{- if (.digest) -}} @{{.digest}} {{- end -}}" + {{- end }} + imagePullPolicy: {{ .Values.controller.admissionWebhooks.patch.image.pullPolicy }} + args: + - create + - --host={{ include "ingress-nginx.controller.fullname" . }}-admission,{{ include "ingress-nginx.controller.fullname" . }}-admission.$(POD_NAMESPACE).svc + - --namespace=$(POD_NAMESPACE) + - --secret-name={{ include "ingress-nginx.fullname" . }}-admission + env: + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + {{- if .Values.controller.admissionWebhooks.extraEnvs }} + {{- toYaml .Values.controller.admissionWebhooks.extraEnvs | nindent 12 }} + {{- end }} + {{- if .Values.controller.admissionWebhooks.createSecretJob.securityContext }} + securityContext: {{ toYaml .Values.controller.admissionWebhooks.createSecretJob.securityContext | nindent 12 }} + {{- end }} + {{- if .Values.controller.admissionWebhooks.createSecretJob.resources }} + resources: {{ toYaml .Values.controller.admissionWebhooks.createSecretJob.resources | nindent 12 }} + {{- end }} + restartPolicy: OnFailure + serviceAccountName: {{ include "ingress-nginx.fullname" . }}-admission + {{- if .Values.controller.admissionWebhooks.patch.nodeSelector }} + nodeSelector: {{ toYaml .Values.controller.admissionWebhooks.patch.nodeSelector | nindent 8 }} + {{- end }} + {{- if .Values.controller.admissionWebhooks.patch.tolerations }} + tolerations: {{ toYaml .Values.controller.admissionWebhooks.patch.tolerations | nindent 8 }} + {{- end }} + {{- if .Values.controller.admissionWebhooks.patch.securityContext }} + securityContext: + {{- toYaml .Values.controller.admissionWebhooks.patch.securityContext | nindent 8 }} + {{- end }} +{{- end }} diff --git a/helm/sonarqube/charts/ingress-nginx/templates/admission-webhooks/job-patch/job-patchWebhook.yaml b/helm/sonarqube/charts/ingress-nginx/templates/admission-webhooks/job-patch/job-patchWebhook.yaml new file mode 100644 index 0000000..0fa3ff9 --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/templates/admission-webhooks/job-patch/job-patchWebhook.yaml @@ -0,0 +1,82 @@ +{{- if and .Values.controller.admissionWebhooks.enabled .Values.controller.admissionWebhooks.patch.enabled (not .Values.controller.admissionWebhooks.certManager.enabled) -}} +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ include "ingress-nginx.fullname" . }}-admission-patch + namespace: {{ .Release.Namespace }} + annotations: + "helm.sh/hook": post-install,post-upgrade + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded + {{- with .Values.controller.admissionWebhooks.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: admission-webhook + {{- with .Values.controller.admissionWebhooks.patch.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: +{{- if .Capabilities.APIVersions.Has "batch/v1alpha1" }} + # Alpha feature since k8s 1.12 + ttlSecondsAfterFinished: 0 +{{- end }} + template: + metadata: + name: {{ include "ingress-nginx.fullname" . }}-admission-patch + {{- if .Values.controller.admissionWebhooks.patch.podAnnotations }} + annotations: {{ toYaml .Values.controller.admissionWebhooks.patch.podAnnotations | nindent 8 }} + {{- end }} + labels: + {{- include "ingress-nginx.labels" . | nindent 8 }} + app.kubernetes.io/component: admission-webhook + {{- with .Values.controller.admissionWebhooks.patch.labels }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- if .Values.controller.admissionWebhooks.patch.priorityClassName }} + priorityClassName: {{ .Values.controller.admissionWebhooks.patch.priorityClassName }} + {{- end }} + {{- if .Values.imagePullSecrets }} + imagePullSecrets: {{ toYaml .Values.imagePullSecrets | nindent 8 }} + {{- end }} + containers: + - name: patch + {{- with .Values.controller.admissionWebhooks.patch.image }} + image: "{{- if .repository -}}{{ .repository }}{{ else }}{{ .registry }}/{{ .image }}{{- end -}}:{{ .tag }}{{- if (.digest) -}} @{{.digest}} {{- end -}}" + {{- end }} + imagePullPolicy: {{ .Values.controller.admissionWebhooks.patch.image.pullPolicy }} + args: + - patch + - --webhook-name={{ include "ingress-nginx.fullname" . }}-admission + - --namespace=$(POD_NAMESPACE) + - --patch-mutating=false + - --secret-name={{ include "ingress-nginx.fullname" . }}-admission + - --patch-failure-policy={{ .Values.controller.admissionWebhooks.failurePolicy }} + env: + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + {{- if .Values.controller.admissionWebhooks.extraEnvs }} + {{- toYaml .Values.controller.admissionWebhooks.extraEnvs | nindent 12 }} + {{- end }} + {{- if .Values.controller.admissionWebhooks.patchWebhookJob.securityContext }} + securityContext: {{ toYaml .Values.controller.admissionWebhooks.patchWebhookJob.securityContext | nindent 12 }} + {{- end }} + {{- if .Values.controller.admissionWebhooks.patchWebhookJob.resources }} + resources: {{ toYaml .Values.controller.admissionWebhooks.patchWebhookJob.resources | nindent 12 }} + {{- end }} + restartPolicy: OnFailure + serviceAccountName: {{ include "ingress-nginx.fullname" . }}-admission + {{- if .Values.controller.admissionWebhooks.patch.nodeSelector }} + nodeSelector: {{ toYaml .Values.controller.admissionWebhooks.patch.nodeSelector | nindent 8 }} + {{- end }} + {{- if .Values.controller.admissionWebhooks.patch.tolerations }} + tolerations: {{ toYaml .Values.controller.admissionWebhooks.patch.tolerations | nindent 8 }} + {{- end }} + {{- if .Values.controller.admissionWebhooks.patch.securityContext }} + securityContext: + {{- toYaml .Values.controller.admissionWebhooks.patch.securityContext | nindent 8 }} + {{- end }} +{{- end }} diff --git a/helm/sonarqube/charts/ingress-nginx/templates/admission-webhooks/job-patch/networkpolicy.yaml b/helm/sonarqube/charts/ingress-nginx/templates/admission-webhooks/job-patch/networkpolicy.yaml new file mode 100644 index 0000000..08b3225 --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/templates/admission-webhooks/job-patch/networkpolicy.yaml @@ -0,0 +1,26 @@ +{{- if and .Values.controller.admissionWebhooks.enabled .Values.controller.admissionWebhooks.networkPolicyEnabled }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "ingress-nginx.fullname" . }}-admission + namespace: {{ .Release.Namespace }} + annotations: + "helm.sh/hook": pre-install,pre-upgrade,post-install,post-upgrade + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: admission-webhook + {{- with .Values.controller.admissionWebhooks.patch.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + podSelector: + matchLabels: + {{- include "ingress-nginx.labels" . | nindent 6 }} + app.kubernetes.io/component: admission-webhook + policyTypes: + - Ingress + - Egress + egress: + - {} +{{- end }} diff --git a/helm/sonarqube/charts/ingress-nginx/templates/admission-webhooks/job-patch/psp.yaml b/helm/sonarqube/charts/ingress-nginx/templates/admission-webhooks/job-patch/psp.yaml new file mode 100644 index 0000000..e19c955 --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/templates/admission-webhooks/job-patch/psp.yaml @@ -0,0 +1,41 @@ +{{- if (semverCompare "<1.25.0-0" .Capabilities.KubeVersion.Version) }} +{{- if and .Values.controller.admissionWebhooks.enabled .Values.controller.admissionWebhooks.patch.enabled .Values.podSecurityPolicy.enabled (empty .Values.controller.admissionWebhooks.existingPsp) -}} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ include "ingress-nginx.fullname" . }}-admission + annotations: + "helm.sh/hook": pre-install,pre-upgrade,post-install,post-upgrade + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: admission-webhook + {{- with .Values.controller.admissionWebhooks.patch.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + allowPrivilegeEscalation: false + fsGroup: + ranges: + - max: 65535 + min: 1 + rule: MustRunAs + requiredDropCapabilities: + - ALL + runAsUser: + rule: MustRunAsNonRoot + seLinux: + rule: RunAsAny + supplementalGroups: + ranges: + - max: 65535 + min: 1 + rule: MustRunAs + volumes: + - configMap + - emptyDir + - projected + - secret + - downwardAPI +{{- end }} +{{- end }} diff --git a/helm/sonarqube/charts/ingress-nginx/templates/admission-webhooks/job-patch/role.yaml b/helm/sonarqube/charts/ingress-nginx/templates/admission-webhooks/job-patch/role.yaml new file mode 100644 index 0000000..ea7c208 --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/templates/admission-webhooks/job-patch/role.yaml @@ -0,0 +1,24 @@ +{{- if and .Values.controller.admissionWebhooks.enabled .Values.controller.admissionWebhooks.patch.enabled (not .Values.controller.admissionWebhooks.certManager.enabled) -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ include "ingress-nginx.fullname" . }}-admission + namespace: {{ .Release.Namespace }} + annotations: + "helm.sh/hook": pre-install,pre-upgrade,post-install,post-upgrade + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: admission-webhook + {{- with .Values.controller.admissionWebhooks.patch.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +rules: + - apiGroups: + - "" + resources: + - secrets + verbs: + - get + - create +{{- end }} diff --git a/helm/sonarqube/charts/ingress-nginx/templates/admission-webhooks/job-patch/rolebinding.yaml b/helm/sonarqube/charts/ingress-nginx/templates/admission-webhooks/job-patch/rolebinding.yaml new file mode 100644 index 0000000..60c3f4f --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/templates/admission-webhooks/job-patch/rolebinding.yaml @@ -0,0 +1,24 @@ +{{- if and .Values.controller.admissionWebhooks.enabled .Values.controller.admissionWebhooks.patch.enabled (not .Values.controller.admissionWebhooks.certManager.enabled) -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ include "ingress-nginx.fullname" . }}-admission + namespace: {{ .Release.Namespace }} + annotations: + "helm.sh/hook": pre-install,pre-upgrade,post-install,post-upgrade + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: admission-webhook + {{- with .Values.controller.admissionWebhooks.patch.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ include "ingress-nginx.fullname" . }}-admission +subjects: + - kind: ServiceAccount + name: {{ include "ingress-nginx.fullname" . }}-admission + namespace: {{ .Release.Namespace | quote }} +{{- end }} diff --git a/helm/sonarqube/charts/ingress-nginx/templates/admission-webhooks/job-patch/serviceaccount.yaml b/helm/sonarqube/charts/ingress-nginx/templates/admission-webhooks/job-patch/serviceaccount.yaml new file mode 100644 index 0000000..00be54e --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/templates/admission-webhooks/job-patch/serviceaccount.yaml @@ -0,0 +1,16 @@ +{{- if and .Values.controller.admissionWebhooks.enabled .Values.controller.admissionWebhooks.patch.enabled (not .Values.controller.admissionWebhooks.certManager.enabled) -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "ingress-nginx.fullname" . }}-admission + namespace: {{ .Release.Namespace }} + annotations: + "helm.sh/hook": pre-install,pre-upgrade,post-install,post-upgrade + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: admission-webhook + {{- with .Values.controller.admissionWebhooks.patch.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/helm/sonarqube/charts/ingress-nginx/templates/admission-webhooks/validating-webhook.yaml b/helm/sonarqube/charts/ingress-nginx/templates/admission-webhooks/validating-webhook.yaml new file mode 100644 index 0000000..f27244d --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/templates/admission-webhooks/validating-webhook.yaml @@ -0,0 +1,53 @@ +{{- if .Values.controller.admissionWebhooks.enabled -}} +# before changing this value, check the required kubernetes version +# https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#prerequisites +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + annotations: + {{- if .Values.controller.admissionWebhooks.certManager.enabled }} + certmanager.k8s.io/inject-ca-from: {{ printf "%s/%s-admission" .Release.Namespace (include "ingress-nginx.fullname" .) | quote }} + cert-manager.io/inject-ca-from: {{ printf "%s/%s-admission" .Release.Namespace (include "ingress-nginx.fullname" .) | quote }} + {{- end }} + {{- if .Values.controller.admissionWebhooks.annotations }} + {{- toYaml .Values.controller.admissionWebhooks.annotations | nindent 4 }} + {{- end }} + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: admission-webhook + {{- with .Values.controller.admissionWebhooks.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ include "ingress-nginx.fullname" . }}-admission +webhooks: + - name: validate.nginx.ingress.kubernetes.io + matchPolicy: Equivalent + rules: + - apiGroups: + - networking.k8s.io + apiVersions: + - v1 + operations: + - CREATE + - UPDATE + resources: + - ingresses + failurePolicy: {{ .Values.controller.admissionWebhooks.failurePolicy | default "Fail" }} + sideEffects: None + admissionReviewVersions: + - v1 + clientConfig: + service: + namespace: {{ .Release.Namespace | quote }} + name: {{ include "ingress-nginx.controller.fullname" . }}-admission + path: /networking/v1/ingresses + {{- if .Values.controller.admissionWebhooks.timeoutSeconds }} + timeoutSeconds: {{ .Values.controller.admissionWebhooks.timeoutSeconds }} + {{- end }} + {{- if .Values.controller.admissionWebhooks.namespaceSelector }} + namespaceSelector: {{ toYaml .Values.controller.admissionWebhooks.namespaceSelector | nindent 6 }} + {{- end }} + {{- if .Values.controller.admissionWebhooks.objectSelector }} + objectSelector: {{ toYaml .Values.controller.admissionWebhooks.objectSelector | nindent 6 }} + {{- end }} +{{- end }} diff --git a/helm/sonarqube/charts/ingress-nginx/templates/clusterrole.yaml b/helm/sonarqube/charts/ingress-nginx/templates/clusterrole.yaml new file mode 100644 index 0000000..51bc500 --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/templates/clusterrole.yaml @@ -0,0 +1,102 @@ +{{- if .Values.rbac.create }} + +{{- if and .Values.rbac.scope (not .Values.controller.scope.enabled) -}} + {{ required "Invalid configuration: 'rbac.scope' should be equal to 'controller.scope.enabled' (true/false)." (index (dict) ".") }} +{{- end }} + +{{- if not .Values.rbac.scope -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + {{- with .Values.controller.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ include "ingress-nginx.fullname" . }} +rules: + - apiGroups: + - "" + resources: + - configmaps + - endpoints + - nodes + - pods + - secrets +{{- if not .Values.controller.scope.enabled }} + - namespaces +{{- end}} + verbs: + - list + - watch + - apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - list + - watch +{{- if and .Values.controller.scope.enabled .Values.controller.scope.namespace }} + - apiGroups: + - "" + resources: + - namespaces + resourceNames: + - "{{ .Values.controller.scope.namespace }}" + verbs: + - get +{{- end }} + - apiGroups: + - "" + resources: + - nodes + verbs: + - get + - apiGroups: + - "" + resources: + - services + verbs: + - get + - list + - watch + - apiGroups: + - networking.k8s.io + resources: + - ingresses + verbs: + - get + - list + - watch + - apiGroups: + - "" + resources: + - events + verbs: + - create + - patch + - apiGroups: + - networking.k8s.io + resources: + - ingresses/status + verbs: + - update + - apiGroups: + - networking.k8s.io + resources: + - ingressclasses + verbs: + - get + - list + - watch + - apiGroups: + - discovery.k8s.io + resources: + - endpointslices + verbs: + - list + - watch + - get +{{- end }} + +{{- end }} diff --git a/helm/sonarqube/charts/ingress-nginx/templates/clusterrolebinding.yaml b/helm/sonarqube/charts/ingress-nginx/templates/clusterrolebinding.yaml new file mode 100644 index 0000000..acbbd8b --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/templates/clusterrolebinding.yaml @@ -0,0 +1,19 @@ +{{- if and .Values.rbac.create (not .Values.rbac.scope) -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + {{- with .Values.controller.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ include "ingress-nginx.fullname" . }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ include "ingress-nginx.fullname" . }} +subjects: + - kind: ServiceAccount + name: {{ template "ingress-nginx.serviceAccountName" . }} + namespace: {{ .Release.Namespace | quote }} +{{- end }} diff --git a/helm/sonarqube/charts/ingress-nginx/templates/controller-configmap-addheaders.yaml b/helm/sonarqube/charts/ingress-nginx/templates/controller-configmap-addheaders.yaml new file mode 100644 index 0000000..dfd49a1 --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/templates/controller-configmap-addheaders.yaml @@ -0,0 +1,14 @@ +{{- if .Values.controller.addHeaders -}} +apiVersion: v1 +kind: ConfigMap +metadata: + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: controller + {{- with .Values.controller.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ include "ingress-nginx.fullname" . }}-custom-add-headers + namespace: {{ .Release.Namespace }} +data: {{ toYaml .Values.controller.addHeaders | nindent 2 }} +{{- end }} diff --git a/helm/sonarqube/charts/ingress-nginx/templates/controller-configmap-proxyheaders.yaml b/helm/sonarqube/charts/ingress-nginx/templates/controller-configmap-proxyheaders.yaml new file mode 100644 index 0000000..38feb72 --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/templates/controller-configmap-proxyheaders.yaml @@ -0,0 +1,14 @@ +{{- if .Values.controller.proxySetHeaders -}} +apiVersion: v1 +kind: ConfigMap +metadata: + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: controller + {{- with .Values.controller.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ include "ingress-nginx.fullname" . }}-custom-proxy-headers + namespace: {{ .Release.Namespace }} +data: {{ toYaml .Values.controller.proxySetHeaders | nindent 2 }} +{{- end }} diff --git a/helm/sonarqube/charts/ingress-nginx/templates/controller-configmap-tcp.yaml b/helm/sonarqube/charts/ingress-nginx/templates/controller-configmap-tcp.yaml new file mode 100644 index 0000000..0f6088e --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/templates/controller-configmap-tcp.yaml @@ -0,0 +1,17 @@ +{{- if .Values.tcp -}} +apiVersion: v1 +kind: ConfigMap +metadata: + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: controller + {{- with .Values.controller.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +{{- if .Values.controller.tcp.annotations }} + annotations: {{ toYaml .Values.controller.tcp.annotations | nindent 4 }} +{{- end }} + name: {{ include "ingress-nginx.fullname" . }}-tcp + namespace: {{ .Release.Namespace }} +data: {{ tpl (toYaml .Values.tcp) . | nindent 2 }} +{{- end }} diff --git a/helm/sonarqube/charts/ingress-nginx/templates/controller-configmap-udp.yaml b/helm/sonarqube/charts/ingress-nginx/templates/controller-configmap-udp.yaml new file mode 100644 index 0000000..3772ec5 --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/templates/controller-configmap-udp.yaml @@ -0,0 +1,17 @@ +{{- if .Values.udp -}} +apiVersion: v1 +kind: ConfigMap +metadata: + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: controller + {{- with .Values.controller.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +{{- if .Values.controller.udp.annotations }} + annotations: {{ toYaml .Values.controller.udp.annotations | nindent 4 }} +{{- end }} + name: {{ include "ingress-nginx.fullname" . }}-udp + namespace: {{ .Release.Namespace }} +data: {{ tpl (toYaml .Values.udp) . | nindent 2 }} +{{- end }} diff --git a/helm/sonarqube/charts/ingress-nginx/templates/controller-configmap.yaml b/helm/sonarqube/charts/ingress-nginx/templates/controller-configmap.yaml new file mode 100644 index 0000000..9ec2b83 --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/templates/controller-configmap.yaml @@ -0,0 +1,28 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: controller + {{- with .Values.controller.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +{{- if .Values.controller.configAnnotations }} + annotations: {{ toYaml .Values.controller.configAnnotations | nindent 4 }} +{{- end }} + name: {{ include "ingress-nginx.controller.fullname" . }} + namespace: {{ .Release.Namespace }} +data: + allow-snippet-annotations: "{{ .Values.controller.allowSnippetAnnotations }}" +{{- if .Values.controller.addHeaders }} + add-headers: {{ .Release.Namespace }}/{{ include "ingress-nginx.fullname" . }}-custom-add-headers +{{- end }} +{{- if .Values.controller.proxySetHeaders }} + proxy-set-headers: {{ .Release.Namespace }}/{{ include "ingress-nginx.fullname" . }}-custom-proxy-headers +{{- end }} +{{- if .Values.dhParam }} + ssl-dh-param: {{ .Release.Namespace }}/{{ include "ingress-nginx.controller.fullname" . }} +{{- end }} +{{- range $key, $value := .Values.controller.config }} + {{- $key | nindent 2 }}: {{ $value | quote }} +{{- end }} diff --git a/helm/sonarqube/charts/ingress-nginx/templates/controller-daemonset.yaml b/helm/sonarqube/charts/ingress-nginx/templates/controller-daemonset.yaml new file mode 100644 index 0000000..82abe75 --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/templates/controller-daemonset.yaml @@ -0,0 +1,239 @@ +{{- if or (eq .Values.controller.kind "DaemonSet") (eq .Values.controller.kind "Both") -}} +{{- include "isControllerTagValid" . -}} +apiVersion: apps/v1 +kind: DaemonSet +metadata: + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: controller + {{- with .Values.controller.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ include "ingress-nginx.controller.fullname" . }} + namespace: {{ .Release.Namespace }} + {{- if .Values.controller.annotations }} + annotations: {{ toYaml .Values.controller.annotations | nindent 4 }} + {{- end }} +spec: + selector: + matchLabels: + {{- include "ingress-nginx.selectorLabels" . | nindent 6 }} + app.kubernetes.io/component: controller + revisionHistoryLimit: {{ .Values.revisionHistoryLimit }} + {{- if .Values.controller.updateStrategy }} + updateStrategy: {{ toYaml .Values.controller.updateStrategy | nindent 4 }} + {{- end }} + minReadySeconds: {{ .Values.controller.minReadySeconds }} + template: + metadata: + {{- if .Values.controller.podAnnotations }} + annotations: + {{- range $key, $value := .Values.controller.podAnnotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} + labels: + {{- include "ingress-nginx.labels" . | nindent 8 }} + app.kubernetes.io/component: controller + {{- with .Values.controller.labels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.controller.podLabels }} + {{- toYaml .Values.controller.podLabels | nindent 8 }} + {{- end }} + spec: + {{- if .Values.controller.dnsConfig }} + dnsConfig: {{ toYaml .Values.controller.dnsConfig | nindent 8 }} + {{- end }} + {{- if .Values.controller.hostname }} + hostname: {{ toYaml .Values.controller.hostname | nindent 8 }} + {{- end }} + dnsPolicy: {{ .Values.controller.dnsPolicy }} + {{- if .Values.imagePullSecrets }} + imagePullSecrets: {{ toYaml .Values.imagePullSecrets | nindent 8 }} + {{- end }} + {{- if .Values.controller.priorityClassName }} + priorityClassName: {{ .Values.controller.priorityClassName | quote }} + {{- end }} + {{- if or .Values.controller.podSecurityContext .Values.controller.sysctls }} + securityContext: + {{- end }} + {{- if .Values.controller.podSecurityContext }} + {{- toYaml .Values.controller.podSecurityContext | nindent 8 }} + {{- end }} + {{- if .Values.controller.sysctls }} + sysctls: + {{- range $sysctl, $value := .Values.controller.sysctls }} + - name: {{ $sysctl | quote }} + value: {{ $value | quote }} + {{- end }} + {{- end }} + {{- if .Values.controller.shareProcessNamespace }} + shareProcessNamespace: {{ .Values.controller.shareProcessNamespace }} + {{- end }} + containers: + - name: {{ .Values.controller.containerName }} + {{- with .Values.controller.image }} + image: "{{- if .repository -}}{{ .repository }}{{ else }}{{ .registry }}/{{ include "ingress-nginx.image" . }}{{- end -}}:{{ .tag }}{{ include "ingress-nginx.imageDigest" . }}" + {{- end }} + imagePullPolicy: {{ .Values.controller.image.pullPolicy }} + {{- if .Values.controller.lifecycle }} + lifecycle: {{ toYaml .Values.controller.lifecycle | nindent 12 }} + {{- end }} + args: + {{- include "ingress-nginx.params" . | nindent 12 }} + securityContext: {{ include "controller.containerSecurityContext" . | nindent 12 }} + env: + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + {{- if .Values.controller.enableMimalloc }} + - name: LD_PRELOAD + value: /usr/local/lib/libmimalloc.so + {{- end }} + {{- if .Values.controller.extraEnvs }} + {{- toYaml .Values.controller.extraEnvs | nindent 12 }} + {{- end }} + {{- if .Values.controller.startupProbe }} + startupProbe: {{ toYaml .Values.controller.startupProbe | nindent 12 }} + {{- end }} + {{- if .Values.controller.livenessProbe }} + livenessProbe: {{ toYaml .Values.controller.livenessProbe | nindent 12 }} + {{- end }} + {{- if .Values.controller.readinessProbe }} + readinessProbe: {{ toYaml .Values.controller.readinessProbe | nindent 12 }} + {{- end }} + ports: + {{- range $key, $value := .Values.controller.containerPort }} + - name: {{ $key }} + containerPort: {{ $value }} + protocol: TCP + {{- if $.Values.controller.hostPort.enabled }} + hostPort: {{ index $.Values.controller.hostPort.ports $key | default $value }} + {{- end }} + {{- end }} + {{- if .Values.controller.metrics.enabled }} + - name: {{ .Values.controller.metrics.portName }} + containerPort: {{ .Values.controller.metrics.port }} + protocol: TCP + {{- end }} + {{- if .Values.controller.admissionWebhooks.enabled }} + - name: webhook + containerPort: {{ .Values.controller.admissionWebhooks.port }} + protocol: TCP + {{- end }} + {{- range $key, $value := .Values.tcp }} + - name: {{ if $.Values.portNamePrefix }}{{ $.Values.portNamePrefix }}-{{ end }}{{ $key }}-tcp + containerPort: {{ $key }} + protocol: TCP + {{- if $.Values.controller.hostPort.enabled }} + hostPort: {{ $key }} + {{- end }} + {{- end }} + {{- range $key, $value := .Values.udp }} + - name: {{ if $.Values.portNamePrefix }}{{ $.Values.portNamePrefix }}-{{ end }}{{ $key }}-udp + containerPort: {{ $key }} + protocol: UDP + {{- if $.Values.controller.hostPort.enabled }} + hostPort: {{ $key }} + {{- end }} + {{- end }} + {{- if (or .Values.controller.customTemplate.configMapName .Values.controller.extraVolumeMounts .Values.controller.admissionWebhooks.enabled .Values.controller.extraModules .Values.controller.opentelemetry.enabled) }} + volumeMounts: + {{- if (or .Values.controller.extraModules .Values.controller.opentelemetry.enabled) }} + - name: modules + {{ if .Values.controller.image.chroot }} + mountPath: /chroot/modules_mount + {{ else }} + mountPath: /modules_mount + {{ end }} + {{- end }} + {{- if .Values.controller.customTemplate.configMapName }} + - mountPath: /etc/nginx/template + name: nginx-template-volume + readOnly: true + {{- end }} + {{- if .Values.controller.admissionWebhooks.enabled }} + - name: webhook-cert + mountPath: /usr/local/certificates/ + readOnly: true + {{- end }} + {{- if .Values.controller.extraVolumeMounts }} + {{- toYaml .Values.controller.extraVolumeMounts | nindent 12 }} + {{- end }} + {{- end }} + {{- if .Values.controller.resources }} + resources: {{ toYaml .Values.controller.resources | nindent 12 }} + {{- end }} + {{- if .Values.controller.extraContainers }} + {{ toYaml .Values.controller.extraContainers | nindent 8 }} + {{- end }} + {{- if (or .Values.controller.extraInitContainers .Values.controller.extraModules .Values.controller.opentelemetry.enabled) }} + initContainers: + {{- if .Values.controller.extraInitContainers }} + {{ toYaml .Values.controller.extraInitContainers | nindent 8 }} + {{- end }} + {{- if .Values.controller.extraModules }} + {{- range .Values.controller.extraModules }} + {{ $containerSecurityContext := .containerSecurityContext | default $.Values.controller.containerSecurityContext }} +{{ include "extraModules" (dict "name" .name "image" .image "containerSecurityContext" $containerSecurityContext) | indent 8 }} + {{- end }} + {{- end }} + {{- if .Values.controller.opentelemetry.enabled}} + {{ $otelContainerSecurityContext := $.Values.controller.opentelemetry.containerSecurityContext | default $.Values.controller.containerSecurityContext }} + {{- include "extraModules" (dict "name" "opentelemetry" "image" .Values.controller.opentelemetry.image "containerSecurityContext" $otelContainerSecurityContext) | nindent 8}} + {{- end}} + {{- end }} + {{- if .Values.controller.hostNetwork }} + hostNetwork: {{ .Values.controller.hostNetwork }} + {{- end }} + {{- if .Values.controller.nodeSelector }} + nodeSelector: {{ toYaml .Values.controller.nodeSelector | nindent 8 }} + {{- end }} + {{- if .Values.controller.tolerations }} + tolerations: {{ toYaml .Values.controller.tolerations | nindent 8 }} + {{- end }} + {{- if .Values.controller.affinity }} + affinity: {{ toYaml .Values.controller.affinity | nindent 8 }} + {{- end }} + {{- if .Values.controller.topologySpreadConstraints }} + topologySpreadConstraints: {{ toYaml .Values.controller.topologySpreadConstraints | nindent 8 }} + {{- end }} + serviceAccountName: {{ template "ingress-nginx.serviceAccountName" . }} + terminationGracePeriodSeconds: {{ .Values.controller.terminationGracePeriodSeconds }} + {{- if (or .Values.controller.customTemplate.configMapName .Values.controller.extraVolumeMounts .Values.controller.admissionWebhooks.enabled .Values.controller.extraVolumes .Values.controller.extraModules .Values.controller.opentelemetry.enabled) }} + volumes: + {{- if (or .Values.controller.extraModules .Values.controller.opentelemetry.enabled)}} + - name: modules + emptyDir: {} + {{- end }} + {{- if .Values.controller.customTemplate.configMapName }} + - name: nginx-template-volume + configMap: + name: {{ .Values.controller.customTemplate.configMapName }} + items: + - key: {{ .Values.controller.customTemplate.configMapKey }} + path: nginx.tmpl + {{- end }} + {{- if .Values.controller.admissionWebhooks.enabled }} + - name: webhook-cert + secret: + secretName: {{ include "ingress-nginx.fullname" . }}-admission + {{- if .Values.controller.admissionWebhooks.certManager.enabled }} + items: + - key: tls.crt + path: cert + - key: tls.key + path: key + {{- end }} + {{- end }} + {{- if .Values.controller.extraVolumes }} + {{ toYaml .Values.controller.extraVolumes | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} diff --git a/helm/sonarqube/charts/ingress-nginx/templates/controller-deployment.yaml b/helm/sonarqube/charts/ingress-nginx/templates/controller-deployment.yaml new file mode 100644 index 0000000..7fe8804 --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/templates/controller-deployment.yaml @@ -0,0 +1,243 @@ +{{- if or (eq .Values.controller.kind "Deployment") (eq .Values.controller.kind "Both") -}} +{{- include "isControllerTagValid" . -}} +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: controller + {{- with .Values.controller.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ include "ingress-nginx.controller.fullname" . }} + namespace: {{ .Release.Namespace }} + {{- if .Values.controller.annotations }} + annotations: {{ toYaml .Values.controller.annotations | nindent 4 }} + {{- end }} +spec: + selector: + matchLabels: + {{- include "ingress-nginx.selectorLabels" . | nindent 6 }} + app.kubernetes.io/component: controller + {{- if not .Values.controller.autoscaling.enabled }} + replicas: {{ .Values.controller.replicaCount }} + {{- end }} + revisionHistoryLimit: {{ .Values.revisionHistoryLimit }} + {{- if .Values.controller.updateStrategy }} + strategy: + {{ toYaml .Values.controller.updateStrategy | nindent 4 }} + {{- end }} + minReadySeconds: {{ .Values.controller.minReadySeconds }} + template: + metadata: + {{- if .Values.controller.podAnnotations }} + annotations: + {{- range $key, $value := .Values.controller.podAnnotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} + labels: + {{- include "ingress-nginx.labels" . | nindent 8 }} + app.kubernetes.io/component: controller + {{- with .Values.controller.labels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.controller.podLabels }} + {{- toYaml .Values.controller.podLabels | nindent 8 }} + {{- end }} + spec: + {{- if .Values.controller.dnsConfig }} + dnsConfig: {{ toYaml .Values.controller.dnsConfig | nindent 8 }} + {{- end }} + {{- if .Values.controller.hostname }} + hostname: {{ toYaml .Values.controller.hostname | nindent 8 }} + {{- end }} + dnsPolicy: {{ .Values.controller.dnsPolicy }} + {{- if .Values.imagePullSecrets }} + imagePullSecrets: {{ toYaml .Values.imagePullSecrets | nindent 8 }} + {{- end }} + {{- if .Values.controller.priorityClassName }} + priorityClassName: {{ .Values.controller.priorityClassName | quote }} + {{- end }} + {{- if or .Values.controller.podSecurityContext .Values.controller.sysctls }} + securityContext: + {{- end }} + {{- if .Values.controller.podSecurityContext }} + {{- toYaml .Values.controller.podSecurityContext | nindent 8 }} + {{- end }} + {{- if .Values.controller.sysctls }} + sysctls: + {{- range $sysctl, $value := .Values.controller.sysctls }} + - name: {{ $sysctl | quote }} + value: {{ $value | quote }} + {{- end }} + {{- end }} + {{- if .Values.controller.shareProcessNamespace }} + shareProcessNamespace: {{ .Values.controller.shareProcessNamespace }} + {{- end }} + containers: + - name: {{ .Values.controller.containerName }} + {{- with .Values.controller.image }} + image: "{{- if .repository -}}{{ .repository }}{{ else }}{{ .registry }}/{{ include "ingress-nginx.image" . }}{{- end -}}:{{ .tag }}{{ include "ingress-nginx.imageDigest" . }}" + {{- end }} + imagePullPolicy: {{ .Values.controller.image.pullPolicy }} + {{- if .Values.controller.lifecycle }} + lifecycle: {{ toYaml .Values.controller.lifecycle | nindent 12 }} + {{- end }} + args: + {{- include "ingress-nginx.params" . | nindent 12 }} + securityContext: {{ include "controller.containerSecurityContext" . | nindent 12 }} + env: + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + {{- if .Values.controller.enableMimalloc }} + - name: LD_PRELOAD + value: /usr/local/lib/libmimalloc.so + {{- end }} + {{- if .Values.controller.extraEnvs }} + {{- toYaml .Values.controller.extraEnvs | nindent 12 }} + {{- end }} + {{- if .Values.controller.startupProbe }} + startupProbe: {{ toYaml .Values.controller.startupProbe | nindent 12 }} + {{- end }} + {{- if .Values.controller.livenessProbe }} + livenessProbe: {{ toYaml .Values.controller.livenessProbe | nindent 12 }} + {{- end }} + {{- if .Values.controller.readinessProbe }} + readinessProbe: {{ toYaml .Values.controller.readinessProbe | nindent 12 }} + {{- end }} + ports: + {{- range $key, $value := .Values.controller.containerPort }} + - name: {{ $key }} + containerPort: {{ $value }} + protocol: TCP + {{- if $.Values.controller.hostPort.enabled }} + hostPort: {{ index $.Values.controller.hostPort.ports $key | default $value }} + {{- end }} + {{- end }} + {{- if .Values.controller.metrics.enabled }} + - name: {{ .Values.controller.metrics.portName }} + containerPort: {{ .Values.controller.metrics.port }} + protocol: TCP + {{- end }} + {{- if .Values.controller.admissionWebhooks.enabled }} + - name: webhook + containerPort: {{ .Values.controller.admissionWebhooks.port }} + protocol: TCP + {{- end }} + {{- range $key, $value := .Values.tcp }} + - name: {{ if $.Values.portNamePrefix }}{{ $.Values.portNamePrefix }}-{{ end }}{{ $key }}-tcp + containerPort: {{ $key }} + protocol: TCP + {{- if $.Values.controller.hostPort.enabled }} + hostPort: {{ $key }} + {{- end }} + {{- end }} + {{- range $key, $value := .Values.udp }} + - name: {{ if $.Values.portNamePrefix }}{{ $.Values.portNamePrefix }}-{{ end }}{{ $key }}-udp + containerPort: {{ $key }} + protocol: UDP + {{- if $.Values.controller.hostPort.enabled }} + hostPort: {{ $key }} + {{- end }} + {{- end }} + {{- if (or .Values.controller.customTemplate.configMapName .Values.controller.extraVolumeMounts .Values.controller.admissionWebhooks.enabled .Values.controller.extraModules .Values.controller.opentelemetry.enabled) }} + volumeMounts: + {{- if (or .Values.controller.extraModules .Values.controller.opentelemetry.enabled) }} + - name: modules + {{ if .Values.controller.image.chroot }} + mountPath: /chroot/modules_mount + {{ else }} + mountPath: /modules_mount + {{ end }} + {{- end }} + {{- if .Values.controller.customTemplate.configMapName }} + - mountPath: /etc/nginx/template + name: nginx-template-volume + readOnly: true + {{- end }} + {{- if .Values.controller.admissionWebhooks.enabled }} + - name: webhook-cert + mountPath: /usr/local/certificates/ + readOnly: true + {{- end }} + {{- if .Values.controller.extraVolumeMounts }} + {{- toYaml .Values.controller.extraVolumeMounts | nindent 12 }} + {{- end }} + {{- end }} + {{- if .Values.controller.resources }} + resources: {{ toYaml .Values.controller.resources | nindent 12 }} + {{- end }} + {{- if .Values.controller.extraContainers }} + {{ toYaml .Values.controller.extraContainers | nindent 8 }} + {{- end }} + {{- if (or .Values.controller.extraInitContainers .Values.controller.extraModules .Values.controller.opentelemetry.enabled) }} + initContainers: + {{- if .Values.controller.extraInitContainers }} + {{ toYaml .Values.controller.extraInitContainers | nindent 8 }} + {{- end }} + {{- if .Values.controller.extraModules }} + {{- range .Values.controller.extraModules }} + {{ $containerSecurityContext := .containerSecurityContext | default $.Values.controller.containerSecurityContext }} +{{ include "extraModules" (dict "name" .name "image" .image "containerSecurityContext" $containerSecurityContext) | indent 8 }} + {{- end }} + {{- end }} + {{- if .Values.controller.opentelemetry.enabled}} + {{ $otelContainerSecurityContext := $.Values.controller.opentelemetry.containerSecurityContext | default $.Values.controller.containerSecurityContext }} + {{- include "extraModules" (dict "name" "opentelemetry" "image" .Values.controller.opentelemetry.image "containerSecurityContext" $otelContainerSecurityContext "distroless" false) | nindent 8}} + {{- end}} + {{- end }} + {{- if .Values.controller.hostNetwork }} + hostNetwork: {{ .Values.controller.hostNetwork }} + {{- end }} + {{- if .Values.controller.nodeSelector }} + nodeSelector: {{ toYaml .Values.controller.nodeSelector | nindent 8 }} + {{- end }} + {{- if .Values.controller.tolerations }} + tolerations: {{ toYaml .Values.controller.tolerations | nindent 8 }} + {{- end }} + {{- if .Values.controller.affinity }} + affinity: {{ toYaml .Values.controller.affinity | nindent 8 }} + {{- end }} + {{- if .Values.controller.topologySpreadConstraints }} + topologySpreadConstraints: {{ toYaml .Values.controller.topologySpreadConstraints | nindent 8 }} + {{- end }} + serviceAccountName: {{ template "ingress-nginx.serviceAccountName" . }} + terminationGracePeriodSeconds: {{ .Values.controller.terminationGracePeriodSeconds }} + {{- if (or .Values.controller.customTemplate.configMapName .Values.controller.extraVolumeMounts .Values.controller.admissionWebhooks.enabled .Values.controller.extraVolumes .Values.controller.extraModules .Values.controller.opentelemetry.enabled) }} + volumes: + {{- if (or .Values.controller.extraModules .Values.controller.opentelemetry.enabled)}} + - name: modules + emptyDir: {} + {{- end }} + {{- if .Values.controller.customTemplate.configMapName }} + - name: nginx-template-volume + configMap: + name: {{ .Values.controller.customTemplate.configMapName }} + items: + - key: {{ .Values.controller.customTemplate.configMapKey }} + path: nginx.tmpl + {{- end }} + {{- if .Values.controller.admissionWebhooks.enabled }} + - name: webhook-cert + secret: + secretName: {{ include "ingress-nginx.fullname" . }}-admission + {{- if .Values.controller.admissionWebhooks.certManager.enabled }} + items: + - key: tls.crt + path: cert + - key: tls.key + path: key + {{- end }} + {{- end }} + {{- if .Values.controller.extraVolumes }} + {{ toYaml .Values.controller.extraVolumes | nindent 8 }} + {{- end }} + {{- end }} +{{- end }} diff --git a/helm/sonarqube/charts/ingress-nginx/templates/controller-hpa.yaml b/helm/sonarqube/charts/ingress-nginx/templates/controller-hpa.yaml new file mode 100644 index 0000000..f212bc4 --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/templates/controller-hpa.yaml @@ -0,0 +1,47 @@ +{{- if and (or (eq .Values.controller.kind "Deployment") (eq .Values.controller.kind "Both")) .Values.controller.autoscaling.enabled (not .Values.controller.keda.enabled) -}} +apiVersion: {{ ternary "autoscaling/v2" "autoscaling/v2beta2" (.Capabilities.APIVersions.Has "autoscaling/v2") }} +kind: HorizontalPodAutoscaler +metadata: + {{- with .Values.controller.autoscaling.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: controller + {{- with .Values.controller.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ include "ingress-nginx.controller.fullname" . }} + namespace: {{ .Release.Namespace }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "ingress-nginx.controller.fullname" . }} + minReplicas: {{ .Values.controller.autoscaling.minReplicas }} + maxReplicas: {{ .Values.controller.autoscaling.maxReplicas }} + metrics: + {{- with .Values.controller.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + target: + type: Utilization + averageUtilization: {{ . }} + {{- end }} + {{- with .Values.controller.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: {{ . }} + {{- end }} + {{- with .Values.controller.autoscalingTemplate }} + {{- toYaml . | nindent 2 }} + {{- end }} + {{- with .Values.controller.autoscaling.behavior }} + behavior: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/helm/sonarqube/charts/ingress-nginx/templates/controller-ingressclass.yaml b/helm/sonarqube/charts/ingress-nginx/templates/controller-ingressclass.yaml new file mode 100644 index 0000000..9492784 --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/templates/controller-ingressclass.yaml @@ -0,0 +1,21 @@ +{{- if .Values.controller.ingressClassResource.enabled -}} +# We don't support namespaced ingressClass yet +# So a ClusterRole and a ClusterRoleBinding is required +apiVersion: networking.k8s.io/v1 +kind: IngressClass +metadata: + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: controller + {{- with .Values.controller.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ .Values.controller.ingressClassResource.name }} +{{- if .Values.controller.ingressClassResource.default }} + annotations: + ingressclass.kubernetes.io/is-default-class: "true" +{{- end }} +spec: + controller: {{ .Values.controller.ingressClassResource.controllerValue }} + {{ template "ingressClass.parameters" . }} +{{- end }} diff --git a/helm/sonarqube/charts/ingress-nginx/templates/controller-keda.yaml b/helm/sonarqube/charts/ingress-nginx/templates/controller-keda.yaml new file mode 100644 index 0000000..c0d95a9 --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/templates/controller-keda.yaml @@ -0,0 +1,47 @@ +{{- if and .Values.controller.keda.enabled (or (eq .Values.controller.kind "Deployment") (eq .Values.controller.kind "Both")) -}} +# https://keda.sh/docs/ + +apiVersion: {{ .Values.controller.keda.apiVersion }} +kind: ScaledObject +metadata: + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: controller + {{- with .Values.controller.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ include "ingress-nginx.controller.fullname" . }} + {{- if .Values.controller.keda.scaledObject.annotations }} + annotations: {{ toYaml .Values.controller.keda.scaledObject.annotations | nindent 4 }} + {{- end }} +spec: + scaleTargetRef: +{{- if eq .Values.controller.keda.apiVersion "keda.k8s.io/v1alpha1" }} + deploymentName: {{ include "ingress-nginx.controller.fullname" . }} +{{- else if eq .Values.controller.keda.apiVersion "keda.sh/v1alpha1" }} + name: {{ include "ingress-nginx.controller.fullname" . }} +{{- end }} + pollingInterval: {{ .Values.controller.keda.pollingInterval }} + cooldownPeriod: {{ .Values.controller.keda.cooldownPeriod }} + minReplicaCount: {{ .Values.controller.keda.minReplicas }} + maxReplicaCount: {{ .Values.controller.keda.maxReplicas }} +{{- with .Values.controller.keda.fallback }} + fallback: + failureThreshold: {{ .failureThreshold | default 3 }} + replicas: {{ .replicas | default $.Values.controller.keda.maxReplicas }} +{{- end }} + triggers: +{{- with .Values.controller.keda.triggers }} +{{ toYaml . | indent 2 }} +{{ end }} + advanced: + restoreToOriginalReplicaCount: {{ .Values.controller.keda.restoreToOriginalReplicaCount }} +{{- if .Values.controller.keda.behavior }} + horizontalPodAutoscalerConfig: + behavior: +{{ with .Values.controller.keda.behavior -}} +{{ toYaml . | indent 8 }} +{{ end }} + +{{- end }} +{{- end }} diff --git a/helm/sonarqube/charts/ingress-nginx/templates/controller-poddisruptionbudget.yaml b/helm/sonarqube/charts/ingress-nginx/templates/controller-poddisruptionbudget.yaml new file mode 100644 index 0000000..91be580 --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/templates/controller-poddisruptionbudget.yaml @@ -0,0 +1,26 @@ +{{- if or (and .Values.controller.autoscaling.enabled (gt (.Values.controller.autoscaling.minReplicas | int) 1)) (and (not .Values.controller.autoscaling.enabled) (gt (.Values.controller.replicaCount | int) 1)) }} +apiVersion: {{ ternary "policy/v1" "policy/v1beta1" (semverCompare ">=1.21.0-0" .Capabilities.KubeVersion.Version) }} +kind: PodDisruptionBudget +metadata: + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: controller + {{- with .Values.controller.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ include "ingress-nginx.controller.fullname" . }} + namespace: {{ .Release.Namespace }} + {{- if .Values.controller.annotations }} + annotations: {{ toYaml .Values.controller.annotations | nindent 4 }} + {{- end }} +spec: + selector: + matchLabels: + {{- include "ingress-nginx.selectorLabels" . | nindent 6 }} + app.kubernetes.io/component: controller + {{- if and .Values.controller.minAvailable (not (hasKey .Values.controller "maxUnavailable")) }} + minAvailable: {{ .Values.controller.minAvailable }} + {{- else if .Values.controller.maxUnavailable }} + maxUnavailable: {{ .Values.controller.maxUnavailable }} + {{- end }} +{{- end }} diff --git a/helm/sonarqube/charts/ingress-nginx/templates/controller-prometheusrules.yaml b/helm/sonarqube/charts/ingress-nginx/templates/controller-prometheusrules.yaml new file mode 100644 index 0000000..78b5362 --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/templates/controller-prometheusrules.yaml @@ -0,0 +1,21 @@ +{{- if and ( .Values.controller.metrics.enabled ) ( .Values.controller.metrics.prometheusRule.enabled ) ( .Capabilities.APIVersions.Has "monitoring.coreos.com/v1" ) -}} +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: {{ include "ingress-nginx.controller.fullname" . }} +{{- if .Values.controller.metrics.prometheusRule.namespace }} + namespace: {{ .Values.controller.metrics.prometheusRule.namespace | quote }} +{{- end }} + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: controller + {{- if .Values.controller.metrics.prometheusRule.additionalLabels }} + {{- toYaml .Values.controller.metrics.prometheusRule.additionalLabels | nindent 4 }} + {{- end }} +spec: +{{- if .Values.controller.metrics.prometheusRule.rules }} + groups: + - name: {{ template "ingress-nginx.name" . }} + rules: {{- toYaml .Values.controller.metrics.prometheusRule.rules | nindent 4 }} +{{- end }} +{{- end }} diff --git a/helm/sonarqube/charts/ingress-nginx/templates/controller-psp.yaml b/helm/sonarqube/charts/ingress-nginx/templates/controller-psp.yaml new file mode 100644 index 0000000..3c499b9 --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/templates/controller-psp.yaml @@ -0,0 +1,94 @@ +{{- if (semverCompare "<1.25.0-0" .Capabilities.KubeVersion.Version) }} +{{- if and .Values.podSecurityPolicy.enabled (empty .Values.controller.existingPsp) -}} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ include "ingress-nginx.fullname" . }} + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: controller + {{- with .Values.controller.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + allowedCapabilities: + - NET_BIND_SERVICE + {{- if .Values.controller.image.chroot }} + - SYS_CHROOT + {{- end }} +{{- if .Values.controller.sysctls }} + allowedUnsafeSysctls: + {{- range $sysctl, $value := .Values.controller.sysctls }} + - {{ $sysctl }} + {{- end }} +{{- end }} + privileged: false + allowPrivilegeEscalation: true + # Allow core volume types. + volumes: + - 'configMap' + - 'emptyDir' + - 'projected' + - 'secret' + - 'downwardAPI' +{{- if .Values.controller.hostNetwork }} + hostNetwork: {{ .Values.controller.hostNetwork }} +{{- end }} +{{- if or .Values.controller.hostNetwork .Values.controller.hostPort.enabled }} + hostPorts: +{{- if .Values.controller.hostNetwork }} +{{- range $key, $value := .Values.controller.containerPort }} + # {{ $key }} + - min: {{ $value }} + max: {{ $value }} +{{- end }} +{{- else if .Values.controller.hostPort.enabled }} +{{- range $key, $value := .Values.controller.hostPort.ports }} + # {{ $key }} + - min: {{ $value }} + max: {{ $value }} +{{- end }} +{{- end }} +{{- if .Values.controller.metrics.enabled }} + # metrics + - min: {{ .Values.controller.metrics.port }} + max: {{ .Values.controller.metrics.port }} +{{- end }} +{{- if .Values.controller.admissionWebhooks.enabled }} + # admission webhooks + - min: {{ .Values.controller.admissionWebhooks.port }} + max: {{ .Values.controller.admissionWebhooks.port }} +{{- end }} +{{- range $key, $value := .Values.tcp }} + # {{ $key }}-tcp + - min: {{ $key }} + max: {{ $key }} +{{- end }} +{{- range $key, $value := .Values.udp }} + # {{ $key }}-udp + - min: {{ $key }} + max: {{ $key }} +{{- end }} +{{- end }} + hostIPC: false + hostPID: false + runAsUser: + # Require the container to run without root privileges. + rule: 'MustRunAsNonRoot' + supplementalGroups: + rule: 'MustRunAs' + ranges: + # Forbid adding the root group. + - min: 1 + max: 65535 + fsGroup: + rule: 'MustRunAs' + ranges: + # Forbid adding the root group. + - min: 1 + max: 65535 + readOnlyRootFilesystem: false + seLinux: + rule: 'RunAsAny' +{{- end }} +{{- end }} diff --git a/helm/sonarqube/charts/ingress-nginx/templates/controller-role.yaml b/helm/sonarqube/charts/ingress-nginx/templates/controller-role.yaml new file mode 100644 index 0000000..d1aa9aa --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/templates/controller-role.yaml @@ -0,0 +1,101 @@ +{{- if .Values.rbac.create -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: controller + {{- with .Values.controller.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ include "ingress-nginx.fullname" . }} + namespace: {{ .Release.Namespace }} +rules: + - apiGroups: + - "" + resources: + - namespaces + verbs: + - get + - apiGroups: + - "" + resources: + - configmaps + - pods + - secrets + - endpoints + verbs: + - get + - list + - watch + - apiGroups: + - "" + resources: + - services + verbs: + - get + - list + - watch + - apiGroups: + - networking.k8s.io + resources: + - ingresses + verbs: + - get + - list + - watch + - apiGroups: + - networking.k8s.io + resources: + - ingresses/status + verbs: + - update + - apiGroups: + - networking.k8s.io + resources: + - ingressclasses + verbs: + - get + - list + - watch + - apiGroups: + - coordination.k8s.io + resources: + - leases + resourceNames: + - {{ include "ingress-nginx.controller.electionID" . }} + verbs: + - get + - update + - apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - create + - apiGroups: + - "" + resources: + - events + verbs: + - create + - patch + - apiGroups: + - discovery.k8s.io + resources: + - endpointslices + verbs: + - list + - watch + - get +{{- if .Values.podSecurityPolicy.enabled }} + - apiGroups: [{{ template "podSecurityPolicy.apiGroup" . }}] + resources: ['podsecuritypolicies'] + verbs: ['use'] + {{- with .Values.controller.existingPsp }} + resourceNames: [{{ . }}] + {{- else }} + resourceNames: [{{ include "ingress-nginx.fullname" . }}] + {{- end }} +{{- end }} +{{- end }} diff --git a/helm/sonarqube/charts/ingress-nginx/templates/controller-rolebinding.yaml b/helm/sonarqube/charts/ingress-nginx/templates/controller-rolebinding.yaml new file mode 100644 index 0000000..e846a11 --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/templates/controller-rolebinding.yaml @@ -0,0 +1,21 @@ +{{- if .Values.rbac.create -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: controller + {{- with .Values.controller.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ include "ingress-nginx.fullname" . }} + namespace: {{ .Release.Namespace }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ include "ingress-nginx.fullname" . }} +subjects: + - kind: ServiceAccount + name: {{ template "ingress-nginx.serviceAccountName" . }} + namespace: {{ .Release.Namespace | quote }} +{{- end }} diff --git a/helm/sonarqube/charts/ingress-nginx/templates/controller-secret.yaml b/helm/sonarqube/charts/ingress-nginx/templates/controller-secret.yaml new file mode 100644 index 0000000..f374423 --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/templates/controller-secret.yaml @@ -0,0 +1,15 @@ +{{- if .Values.dhParam -}} +apiVersion: v1 +kind: Secret +metadata: + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: controller + {{- with .Values.controller.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ include "ingress-nginx.controller.fullname" . }} + namespace: {{ .Release.Namespace }} +data: + dhparam.pem: {{ .Values.dhParam }} +{{- end }} diff --git a/helm/sonarqube/charts/ingress-nginx/templates/controller-service-internal.yaml b/helm/sonarqube/charts/ingress-nginx/templates/controller-service-internal.yaml new file mode 100644 index 0000000..87146b7 --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/templates/controller-service-internal.yaml @@ -0,0 +1,79 @@ +{{- if and .Values.controller.service.enabled .Values.controller.service.internal.enabled .Values.controller.service.internal.annotations}} +apiVersion: v1 +kind: Service +metadata: + annotations: + {{- range $key, $value := .Values.controller.service.internal.annotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: controller + {{- if .Values.controller.service.labels }} + {{- toYaml .Values.controller.service.labels | nindent 4 }} + {{- end }} + name: {{ include "ingress-nginx.controller.fullname" . }}-internal + namespace: {{ .Release.Namespace }} +spec: + type: "{{ .Values.controller.service.type }}" +{{- if .Values.controller.service.internal.loadBalancerIP }} + loadBalancerIP: {{ .Values.controller.service.internal.loadBalancerIP }} +{{- end }} +{{- if .Values.controller.service.internal.loadBalancerSourceRanges }} + loadBalancerSourceRanges: {{ toYaml .Values.controller.service.internal.loadBalancerSourceRanges | nindent 4 }} +{{- end }} +{{- if .Values.controller.service.internal.externalTrafficPolicy }} + externalTrafficPolicy: {{ .Values.controller.service.internal.externalTrafficPolicy }} +{{- end }} + ports: + {{- $setNodePorts := (or (eq .Values.controller.service.type "NodePort") (eq .Values.controller.service.type "LoadBalancer")) }} + {{- if .Values.controller.service.enableHttp }} + - name: http + port: {{ .Values.controller.service.internal.ports.http | default .Values.controller.service.ports.http }} + protocol: TCP + targetPort: {{ .Values.controller.service.internal.targetPorts.http | default .Values.controller.service.targetPorts.http }} + {{- if semverCompare ">=1.20" .Capabilities.KubeVersion.Version }} + appProtocol: http + {{- end }} + {{- if (and $setNodePorts (not (empty .Values.controller.service.nodePorts.http))) }} + nodePort: {{ .Values.controller.service.nodePorts.http }} + {{- end }} + {{- end }} + {{- if .Values.controller.service.enableHttps }} + - name: https + port: {{ .Values.controller.service.internal.ports.https | default .Values.controller.service.ports.https }} + protocol: TCP + targetPort: {{ .Values.controller.service.internal.targetPorts.https | default .Values.controller.service.targetPorts.https }} + {{- if semverCompare ">=1.20" .Capabilities.KubeVersion.Version }} + appProtocol: https + {{- end }} + {{- if (and $setNodePorts (not (empty .Values.controller.service.nodePorts.https))) }} + nodePort: {{ .Values.controller.service.nodePorts.https }} + {{- end }} + {{- end }} + {{- range $key, $value := .Values.tcp }} + - name: {{ if $.Values.portNamePrefix }}{{ $.Values.portNamePrefix }}-{{ end }}{{ $key }}-tcp + port: {{ $key }} + protocol: TCP + targetPort: {{ if $.Values.portNamePrefix }}{{ $.Values.portNamePrefix }}-{{ end }}{{ $key }}-tcp + {{- if $.Values.controller.service.nodePorts.tcp }} + {{- if index $.Values.controller.service.nodePorts.tcp $key }} + nodePort: {{ index $.Values.controller.service.nodePorts.tcp $key }} + {{- end }} + {{- end }} + {{- end }} + {{- range $key, $value := .Values.udp }} + - name: {{ if $.Values.portNamePrefix }}{{ $.Values.portNamePrefix }}-{{ end }}{{ $key }}-udp + port: {{ $key }} + protocol: UDP + targetPort: {{ if $.Values.portNamePrefix }}{{ $.Values.portNamePrefix }}-{{ end }}{{ $key }}-udp + {{- if $.Values.controller.service.nodePorts.udp }} + {{- if index $.Values.controller.service.nodePorts.udp $key }} + nodePort: {{ index $.Values.controller.service.nodePorts.udp $key }} + {{- end }} + {{- end }} + {{- end }} + selector: + {{- include "ingress-nginx.selectorLabels" . | nindent 4 }} + app.kubernetes.io/component: controller +{{- end }} diff --git a/helm/sonarqube/charts/ingress-nginx/templates/controller-service-metrics.yaml b/helm/sonarqube/charts/ingress-nginx/templates/controller-service-metrics.yaml new file mode 100644 index 0000000..b178401 --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/templates/controller-service-metrics.yaml @@ -0,0 +1,45 @@ +{{- if .Values.controller.metrics.enabled -}} +apiVersion: v1 +kind: Service +metadata: +{{- if .Values.controller.metrics.service.annotations }} + annotations: {{ toYaml .Values.controller.metrics.service.annotations | nindent 4 }} +{{- end }} + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: controller + {{- if .Values.controller.metrics.service.labels }} + {{- toYaml .Values.controller.metrics.service.labels | nindent 4 }} + {{- end }} + name: {{ include "ingress-nginx.controller.fullname" . }}-metrics + namespace: {{ .Release.Namespace }} +spec: + type: {{ .Values.controller.metrics.service.type }} +{{- if .Values.controller.metrics.service.clusterIP }} + clusterIP: {{ .Values.controller.metrics.service.clusterIP }} +{{- end }} +{{- if .Values.controller.metrics.service.externalIPs }} + externalIPs: {{ toYaml .Values.controller.metrics.service.externalIPs | nindent 4 }} +{{- end }} +{{- if .Values.controller.metrics.service.loadBalancerIP }} + loadBalancerIP: {{ .Values.controller.metrics.service.loadBalancerIP }} +{{- end }} +{{- if .Values.controller.metrics.service.loadBalancerSourceRanges }} + loadBalancerSourceRanges: {{ toYaml .Values.controller.metrics.service.loadBalancerSourceRanges | nindent 4 }} +{{- end }} +{{- if .Values.controller.metrics.service.externalTrafficPolicy }} + externalTrafficPolicy: {{ .Values.controller.metrics.service.externalTrafficPolicy }} +{{- end }} + ports: + - name: {{ .Values.controller.metrics.portName }} + port: {{ .Values.controller.metrics.service.servicePort }} + protocol: TCP + targetPort: {{ .Values.controller.metrics.portName }} + {{- $setNodePorts := (or (eq .Values.controller.metrics.service.type "NodePort") (eq .Values.controller.metrics.service.type "LoadBalancer")) }} + {{- if (and $setNodePorts (not (empty .Values.controller.metrics.service.nodePort))) }} + nodePort: {{ .Values.controller.metrics.service.nodePort }} + {{- end }} + selector: + {{- include "ingress-nginx.selectorLabels" . | nindent 4 }} + app.kubernetes.io/component: controller +{{- end }} diff --git a/helm/sonarqube/charts/ingress-nginx/templates/controller-service-webhook.yaml b/helm/sonarqube/charts/ingress-nginx/templates/controller-service-webhook.yaml new file mode 100644 index 0000000..2aae24f --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/templates/controller-service-webhook.yaml @@ -0,0 +1,40 @@ +{{- if .Values.controller.admissionWebhooks.enabled -}} +apiVersion: v1 +kind: Service +metadata: +{{- if .Values.controller.admissionWebhooks.service.annotations }} + annotations: {{ toYaml .Values.controller.admissionWebhooks.service.annotations | nindent 4 }} +{{- end }} + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: controller + {{- with .Values.controller.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ include "ingress-nginx.controller.fullname" . }}-admission + namespace: {{ .Release.Namespace }} +spec: + type: {{ .Values.controller.admissionWebhooks.service.type }} +{{- if .Values.controller.admissionWebhooks.service.clusterIP }} + clusterIP: {{ .Values.controller.admissionWebhooks.service.clusterIP }} +{{- end }} +{{- if .Values.controller.admissionWebhooks.service.externalIPs }} + externalIPs: {{ toYaml .Values.controller.admissionWebhooks.service.externalIPs | nindent 4 }} +{{- end }} +{{- if .Values.controller.admissionWebhooks.service.loadBalancerIP }} + loadBalancerIP: {{ .Values.controller.admissionWebhooks.service.loadBalancerIP }} +{{- end }} +{{- if .Values.controller.admissionWebhooks.service.loadBalancerSourceRanges }} + loadBalancerSourceRanges: {{ toYaml .Values.controller.admissionWebhooks.service.loadBalancerSourceRanges | nindent 4 }} +{{- end }} + ports: + - name: https-webhook + port: 443 + targetPort: webhook + {{- if semverCompare ">=1.20" .Capabilities.KubeVersion.Version }} + appProtocol: https + {{- end }} + selector: + {{- include "ingress-nginx.selectorLabels" . | nindent 4 }} + app.kubernetes.io/component: controller +{{- end }} diff --git a/helm/sonarqube/charts/ingress-nginx/templates/controller-service.yaml b/helm/sonarqube/charts/ingress-nginx/templates/controller-service.yaml new file mode 100644 index 0000000..b2735d2 --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/templates/controller-service.yaml @@ -0,0 +1,104 @@ +{{- if and .Values.controller.service.enabled .Values.controller.service.external.enabled -}} +apiVersion: v1 +kind: Service +metadata: + annotations: + {{- range $key, $value := .Values.controller.service.annotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: controller + {{- if .Values.controller.service.labels }} + {{- toYaml .Values.controller.service.labels | nindent 4 }} + {{- end }} + name: {{ include "ingress-nginx.controller.fullname" . }} + namespace: {{ .Release.Namespace }} +spec: + type: {{ .Values.controller.service.type }} +{{- if .Values.controller.service.clusterIP }} + clusterIP: {{ .Values.controller.service.clusterIP }} +{{- end }} +{{- if .Values.controller.service.externalIPs }} + externalIPs: {{ toYaml .Values.controller.service.externalIPs | nindent 4 }} +{{- end }} +{{- if .Values.controller.service.loadBalancerIP }} + loadBalancerIP: {{ .Values.controller.service.loadBalancerIP }} +{{- end }} +{{- if .Values.controller.service.loadBalancerSourceRanges }} + loadBalancerSourceRanges: {{ toYaml .Values.controller.service.loadBalancerSourceRanges | nindent 4 }} +{{- end }} +{{- if .Values.controller.service.loadBalancerClass }} + loadBalancerClass: {{ .Values.controller.service.loadBalancerClass }} +{{- end }} +{{- if .Values.controller.service.externalTrafficPolicy }} + externalTrafficPolicy: {{ .Values.controller.service.externalTrafficPolicy }} +{{- end }} +{{- if .Values.controller.service.sessionAffinity }} + sessionAffinity: {{ .Values.controller.service.sessionAffinity }} +{{- end }} +{{- if .Values.controller.service.healthCheckNodePort }} + healthCheckNodePort: {{ .Values.controller.service.healthCheckNodePort }} +{{- end }} +{{- if semverCompare ">=1.21.0-0" .Capabilities.KubeVersion.Version -}} +{{- if .Values.controller.service.ipFamilyPolicy }} + ipFamilyPolicy: {{ .Values.controller.service.ipFamilyPolicy }} +{{- end }} +{{- end }} +{{- if semverCompare ">=1.21.0-0" .Capabilities.KubeVersion.Version -}} +{{- if .Values.controller.service.ipFamilies }} + ipFamilies: {{ toYaml .Values.controller.service.ipFamilies | nindent 4 }} +{{- end }} +{{- end }} + ports: + {{- $setNodePorts := (or (eq .Values.controller.service.type "NodePort") (eq .Values.controller.service.type "LoadBalancer")) }} + {{- if .Values.controller.service.enableHttp }} + - name: http + port: {{ .Values.controller.service.ports.http }} + protocol: TCP + targetPort: {{ .Values.controller.service.targetPorts.http }} + {{- if and (semverCompare ">=1.20" .Capabilities.KubeVersion.Version) (.Values.controller.service.appProtocol) }} + appProtocol: http + {{- end }} + {{- if (and $setNodePorts (not (empty .Values.controller.service.nodePorts.http))) }} + nodePort: {{ .Values.controller.service.nodePorts.http }} + {{- end }} + {{- end }} + {{- if .Values.controller.service.enableHttps }} + - name: https + port: {{ .Values.controller.service.ports.https }} + protocol: TCP + targetPort: {{ .Values.controller.service.targetPorts.https }} + {{- if and (semverCompare ">=1.20" .Capabilities.KubeVersion.Version) (.Values.controller.service.appProtocol) }} + appProtocol: https + {{- end }} + {{- if (and $setNodePorts (not (empty .Values.controller.service.nodePorts.https))) }} + nodePort: {{ .Values.controller.service.nodePorts.https }} + {{- end }} + {{- end }} + {{- range $key, $value := .Values.tcp }} + - name: {{ if $.Values.portNamePrefix }}{{ $.Values.portNamePrefix }}-{{ end }}{{ $key }}-tcp + port: {{ $key }} + protocol: TCP + targetPort: {{ if $.Values.portNamePrefix }}{{ $.Values.portNamePrefix }}-{{ end }}{{ $key }}-tcp + {{- if $.Values.controller.service.nodePorts.tcp }} + {{- if index $.Values.controller.service.nodePorts.tcp $key }} + nodePort: {{ index $.Values.controller.service.nodePorts.tcp $key }} + {{- end }} + {{- end }} + {{- end }} + {{- range $key, $value := .Values.udp }} + - name: {{ if $.Values.portNamePrefix }}{{ $.Values.portNamePrefix }}-{{ end }}{{ $key }}-udp + port: {{ $key }} + protocol: UDP + targetPort: {{ if $.Values.portNamePrefix }}{{ $.Values.portNamePrefix }}-{{ end }}{{ $key }}-udp + {{- if $.Values.controller.service.nodePorts.udp }} + {{- if index $.Values.controller.service.nodePorts.udp $key }} + nodePort: {{ index $.Values.controller.service.nodePorts.udp $key }} + {{- end }} + {{- end }} + {{- end }} + selector: + {{- include "ingress-nginx.selectorLabels" . | nindent 4 }} + app.kubernetes.io/component: controller +{{- end }} diff --git a/helm/sonarqube/charts/ingress-nginx/templates/controller-serviceaccount.yaml b/helm/sonarqube/charts/ingress-nginx/templates/controller-serviceaccount.yaml new file mode 100644 index 0000000..e6e776d --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/templates/controller-serviceaccount.yaml @@ -0,0 +1,18 @@ +{{- if or .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: controller + {{- with .Values.controller.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ template "ingress-nginx.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} + {{- if .Values.serviceAccount.annotations }} + annotations: + {{- toYaml .Values.serviceAccount.annotations | nindent 4 }} + {{- end }} +automountServiceAccountToken: {{ .Values.serviceAccount.automountServiceAccountToken }} +{{- end }} diff --git a/helm/sonarqube/charts/ingress-nginx/templates/controller-servicemonitor.yaml b/helm/sonarqube/charts/ingress-nginx/templates/controller-servicemonitor.yaml new file mode 100644 index 0000000..8ab16f0 --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/templates/controller-servicemonitor.yaml @@ -0,0 +1,48 @@ +{{- if and .Values.controller.metrics.enabled .Values.controller.metrics.serviceMonitor.enabled -}} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ include "ingress-nginx.controller.fullname" . }} +{{- if .Values.controller.metrics.serviceMonitor.namespace }} + namespace: {{ .Values.controller.metrics.serviceMonitor.namespace | quote }} +{{- end }} + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: controller + {{- if .Values.controller.metrics.serviceMonitor.additionalLabels }} + {{- toYaml .Values.controller.metrics.serviceMonitor.additionalLabels | nindent 4 }} + {{- end }} +spec: + endpoints: + - port: {{ .Values.controller.metrics.portName }} + interval: {{ .Values.controller.metrics.serviceMonitor.scrapeInterval }} + {{- if .Values.controller.metrics.serviceMonitor.honorLabels }} + honorLabels: true + {{- end }} + {{- if .Values.controller.metrics.serviceMonitor.relabelings }} + relabelings: {{ toYaml .Values.controller.metrics.serviceMonitor.relabelings | nindent 8 }} + {{- end }} + {{- if .Values.controller.metrics.serviceMonitor.metricRelabelings }} + metricRelabelings: {{ toYaml .Values.controller.metrics.serviceMonitor.metricRelabelings | nindent 8 }} + {{- end }} +{{- if .Values.controller.metrics.serviceMonitor.jobLabel }} + jobLabel: {{ .Values.controller.metrics.serviceMonitor.jobLabel | quote }} +{{- end }} +{{- if .Values.controller.metrics.serviceMonitor.namespaceSelector }} + namespaceSelector: {{ toYaml .Values.controller.metrics.serviceMonitor.namespaceSelector | nindent 4 }} +{{- else }} + namespaceSelector: + matchNames: + - {{ .Release.Namespace }} +{{- end }} +{{- if .Values.controller.metrics.serviceMonitor.targetLabels }} + targetLabels: + {{- range .Values.controller.metrics.serviceMonitor.targetLabels }} + - {{ . }} + {{- end }} +{{- end }} + selector: + matchLabels: + {{- include "ingress-nginx.selectorLabels" . | nindent 6 }} + app.kubernetes.io/component: controller +{{- end }} diff --git a/helm/sonarqube/charts/ingress-nginx/templates/controller-webhooks-networkpolicy.yaml b/helm/sonarqube/charts/ingress-nginx/templates/controller-webhooks-networkpolicy.yaml new file mode 100644 index 0000000..f74c2fb --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/templates/controller-webhooks-networkpolicy.yaml @@ -0,0 +1,19 @@ +{{- if .Values.controller.admissionWebhooks.enabled }} +{{- if .Values.controller.admissionWebhooks.networkPolicyEnabled }} + +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ include "ingress-nginx.fullname" . }}-webhooks-allow + namespace: {{ .Release.Namespace }} +spec: + ingress: + - {} + podSelector: + matchLabels: + app.kubernetes.io/name: {{ include "ingress-nginx.name" . }} + policyTypes: + - Ingress + +{{- end }} +{{- end }} diff --git a/helm/sonarqube/charts/ingress-nginx/templates/default-backend-deployment.yaml b/helm/sonarqube/charts/ingress-nginx/templates/default-backend-deployment.yaml new file mode 100644 index 0000000..87aced4 --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/templates/default-backend-deployment.yaml @@ -0,0 +1,123 @@ +{{- if .Values.defaultBackend.enabled -}} +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: default-backend + {{- with .Values.defaultBackend.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ include "ingress-nginx.defaultBackend.fullname" . }} + namespace: {{ .Release.Namespace }} +spec: + selector: + matchLabels: + {{- include "ingress-nginx.selectorLabels" . | nindent 6 }} + app.kubernetes.io/component: default-backend +{{- if not .Values.defaultBackend.autoscaling.enabled }} + replicas: {{ .Values.defaultBackend.replicaCount }} +{{- end }} + revisionHistoryLimit: {{ .Values.revisionHistoryLimit }} + {{- if .Values.defaultBackend.updateStrategy }} + strategy: + {{ toYaml .Values.defaultBackend.updateStrategy | nindent 4 }} + {{- end }} + minReadySeconds: {{ .Values.defaultBackend.minReadySeconds }} + template: + metadata: + {{- if .Values.defaultBackend.podAnnotations }} + annotations: {{ toYaml .Values.defaultBackend.podAnnotations | nindent 8 }} + {{- end }} + labels: + {{- include "ingress-nginx.selectorLabels" . | nindent 8 }} + app.kubernetes.io/component: default-backend + {{- with .Values.defaultBackend.labels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.defaultBackend.podLabels }} + {{- toYaml .Values.defaultBackend.podLabels | nindent 8 }} + {{- end }} + spec: + {{- if .Values.imagePullSecrets }} + imagePullSecrets: {{ toYaml .Values.imagePullSecrets | nindent 8 }} + {{- end }} + {{- if .Values.defaultBackend.priorityClassName }} + priorityClassName: {{ .Values.defaultBackend.priorityClassName }} + {{- end }} + {{- if .Values.defaultBackend.podSecurityContext }} + securityContext: {{ toYaml .Values.defaultBackend.podSecurityContext | nindent 8 }} + {{- end }} + containers: + - name: {{ template "ingress-nginx.name" . }}-default-backend + {{- with .Values.defaultBackend.image }} + image: "{{- if .repository -}}{{ .repository }}{{ else }}{{ .registry }}/{{ .image }}{{- end -}}:{{ .tag }}{{- if (.digest) -}} @{{.digest}} {{- end -}}" + {{- end }} + imagePullPolicy: {{ .Values.defaultBackend.image.pullPolicy }} + {{- if .Values.defaultBackend.extraArgs }} + args: + {{- range $key, $value := .Values.defaultBackend.extraArgs }} + {{- /* Accept keys without values or with false as value */}} + {{- if eq ($value | quote | len) 2 }} + - --{{ $key }} + {{- else }} + - --{{ $key }}={{ $value }} + {{- end }} + {{- end }} + {{- end }} + securityContext: + capabilities: + drop: + - ALL + runAsUser: {{ .Values.defaultBackend.image.runAsUser }} + runAsNonRoot: {{ .Values.defaultBackend.image.runAsNonRoot }} + allowPrivilegeEscalation: {{ .Values.defaultBackend.image.allowPrivilegeEscalation }} + readOnlyRootFilesystem: {{ .Values.defaultBackend.image.readOnlyRootFilesystem}} + {{- if .Values.defaultBackend.extraEnvs }} + env: {{ toYaml .Values.defaultBackend.extraEnvs | nindent 12 }} + {{- end }} + livenessProbe: + httpGet: + path: /healthz + port: {{ .Values.defaultBackend.port }} + scheme: HTTP + initialDelaySeconds: {{ .Values.defaultBackend.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.defaultBackend.livenessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.defaultBackend.livenessProbe.timeoutSeconds }} + successThreshold: {{ .Values.defaultBackend.livenessProbe.successThreshold }} + failureThreshold: {{ .Values.defaultBackend.livenessProbe.failureThreshold }} + readinessProbe: + httpGet: + path: /healthz + port: {{ .Values.defaultBackend.port }} + scheme: HTTP + initialDelaySeconds: {{ .Values.defaultBackend.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.defaultBackend.readinessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.defaultBackend.readinessProbe.timeoutSeconds }} + successThreshold: {{ .Values.defaultBackend.readinessProbe.successThreshold }} + failureThreshold: {{ .Values.defaultBackend.readinessProbe.failureThreshold }} + ports: + - name: http + containerPort: {{ .Values.defaultBackend.port }} + protocol: TCP + {{- if .Values.defaultBackend.extraVolumeMounts }} + volumeMounts: {{- toYaml .Values.defaultBackend.extraVolumeMounts | nindent 12 }} + {{- end }} + {{- if .Values.defaultBackend.resources }} + resources: {{ toYaml .Values.defaultBackend.resources | nindent 12 }} + {{- end }} + {{- if .Values.defaultBackend.nodeSelector }} + nodeSelector: {{ toYaml .Values.defaultBackend.nodeSelector | nindent 8 }} + {{- end }} + serviceAccountName: {{ template "ingress-nginx.defaultBackend.serviceAccountName" . }} + {{- if .Values.defaultBackend.tolerations }} + tolerations: {{ toYaml .Values.defaultBackend.tolerations | nindent 8 }} + {{- end }} + {{- if .Values.defaultBackend.affinity }} + affinity: {{ toYaml .Values.defaultBackend.affinity | nindent 8 }} + {{- end }} + terminationGracePeriodSeconds: 60 + {{- if .Values.defaultBackend.extraVolumes }} + volumes: {{ toYaml .Values.defaultBackend.extraVolumes | nindent 8 }} + {{- end }} +{{- end }} diff --git a/helm/sonarqube/charts/ingress-nginx/templates/default-backend-hpa.yaml b/helm/sonarqube/charts/ingress-nginx/templates/default-backend-hpa.yaml new file mode 100644 index 0000000..faaf4fa --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/templates/default-backend-hpa.yaml @@ -0,0 +1,40 @@ +{{- if and .Values.defaultBackend.enabled .Values.defaultBackend.autoscaling.enabled }} +apiVersion: {{ ternary "autoscaling/v2" "autoscaling/v2beta2" (.Capabilities.APIVersions.Has "autoscaling/v2") }} +kind: HorizontalPodAutoscaler +metadata: + {{- with .Values.defaultBackend.autoscaling.annotations }} + annotations: {{ toYaml . | nindent 4 }} + {{- end }} + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: default-backend + {{- with .Values.defaultBackend.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ include "ingress-nginx.defaultBackend.fullname" . }} + namespace: {{ .Release.Namespace }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "ingress-nginx.defaultBackend.fullname" . }} + minReplicas: {{ .Values.defaultBackend.autoscaling.minReplicas }} + maxReplicas: {{ .Values.defaultBackend.autoscaling.maxReplicas }} + metrics: + {{- with .Values.defaultBackend.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: {{ . }} + {{- end }} + {{- with .Values.defaultBackend.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + target: + type: Utilization + averageUtilization: {{ . }} + {{- end }} +{{- end }} diff --git a/helm/sonarqube/charts/ingress-nginx/templates/default-backend-poddisruptionbudget.yaml b/helm/sonarqube/charts/ingress-nginx/templates/default-backend-poddisruptionbudget.yaml new file mode 100644 index 0000000..00891ce --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/templates/default-backend-poddisruptionbudget.yaml @@ -0,0 +1,21 @@ +{{- if .Values.defaultBackend.enabled -}} +{{- if or (gt (.Values.defaultBackend.replicaCount | int) 1) (gt (.Values.defaultBackend.autoscaling.minReplicas | int) 1) }} +apiVersion: {{ ternary "policy/v1" "policy/v1beta1" (semverCompare ">=1.21.0-0" .Capabilities.KubeVersion.Version) }} +kind: PodDisruptionBudget +metadata: + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: default-backend + {{- with .Values.defaultBackend.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ include "ingress-nginx.defaultBackend.fullname" . }} + namespace: {{ .Release.Namespace }} +spec: + selector: + matchLabels: + {{- include "ingress-nginx.selectorLabels" . | nindent 6 }} + app.kubernetes.io/component: default-backend + minAvailable: {{ .Values.defaultBackend.minAvailable }} +{{- end }} +{{- end }} diff --git a/helm/sonarqube/charts/ingress-nginx/templates/default-backend-psp.yaml b/helm/sonarqube/charts/ingress-nginx/templates/default-backend-psp.yaml new file mode 100644 index 0000000..c144c8f --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/templates/default-backend-psp.yaml @@ -0,0 +1,38 @@ +{{- if (semverCompare "<1.25.0-0" .Capabilities.KubeVersion.Version) }} +{{- if and .Values.podSecurityPolicy.enabled .Values.defaultBackend.enabled (empty .Values.defaultBackend.existingPsp) -}} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ include "ingress-nginx.fullname" . }}-backend + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: default-backend + {{- with .Values.defaultBackend.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + allowPrivilegeEscalation: false + fsGroup: + ranges: + - max: 65535 + min: 1 + rule: MustRunAs + requiredDropCapabilities: + - ALL + runAsUser: + rule: MustRunAsNonRoot + seLinux: + rule: RunAsAny + supplementalGroups: + ranges: + - max: 65535 + min: 1 + rule: MustRunAs + volumes: + - configMap + - emptyDir + - projected + - secret + - downwardAPI +{{- end }} +{{- end }} diff --git a/helm/sonarqube/charts/ingress-nginx/templates/default-backend-role.yaml b/helm/sonarqube/charts/ingress-nginx/templates/default-backend-role.yaml new file mode 100644 index 0000000..a2b457c --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/templates/default-backend-role.yaml @@ -0,0 +1,22 @@ +{{- if and .Values.rbac.create .Values.podSecurityPolicy.enabled .Values.defaultBackend.enabled -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: default-backend + {{- with .Values.defaultBackend.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ include "ingress-nginx.fullname" . }}-backend + namespace: {{ .Release.Namespace }} +rules: + - apiGroups: [{{ template "podSecurityPolicy.apiGroup" . }}] + resources: ['podsecuritypolicies'] + verbs: ['use'] + {{- with .Values.defaultBackend.existingPsp }} + resourceNames: [{{ . }}] + {{- else }} + resourceNames: [{{ include "ingress-nginx.fullname" . }}-backend] + {{- end }} +{{- end }} diff --git a/helm/sonarqube/charts/ingress-nginx/templates/default-backend-rolebinding.yaml b/helm/sonarqube/charts/ingress-nginx/templates/default-backend-rolebinding.yaml new file mode 100644 index 0000000..dbaa516 --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/templates/default-backend-rolebinding.yaml @@ -0,0 +1,21 @@ +{{- if and .Values.rbac.create .Values.podSecurityPolicy.enabled .Values.defaultBackend.enabled -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: default-backend + {{- with .Values.defaultBackend.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ include "ingress-nginx.fullname" . }}-backend + namespace: {{ .Release.Namespace }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ include "ingress-nginx.fullname" . }}-backend +subjects: + - kind: ServiceAccount + name: {{ template "ingress-nginx.defaultBackend.serviceAccountName" . }} + namespace: {{ .Release.Namespace | quote }} +{{- end }} diff --git a/helm/sonarqube/charts/ingress-nginx/templates/default-backend-service.yaml b/helm/sonarqube/charts/ingress-nginx/templates/default-backend-service.yaml new file mode 100644 index 0000000..5f1d09a --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/templates/default-backend-service.yaml @@ -0,0 +1,41 @@ +{{- if .Values.defaultBackend.enabled -}} +apiVersion: v1 +kind: Service +metadata: +{{- if .Values.defaultBackend.service.annotations }} + annotations: {{ toYaml .Values.defaultBackend.service.annotations | nindent 4 }} +{{- end }} + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: default-backend + {{- with .Values.defaultBackend.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ include "ingress-nginx.defaultBackend.fullname" . }} + namespace: {{ .Release.Namespace }} +spec: + type: {{ .Values.defaultBackend.service.type }} +{{- if .Values.defaultBackend.service.clusterIP }} + clusterIP: {{ .Values.defaultBackend.service.clusterIP }} +{{- end }} +{{- if .Values.defaultBackend.service.externalIPs }} + externalIPs: {{ toYaml .Values.defaultBackend.service.externalIPs | nindent 4 }} +{{- end }} +{{- if .Values.defaultBackend.service.loadBalancerIP }} + loadBalancerIP: {{ .Values.defaultBackend.service.loadBalancerIP }} +{{- end }} +{{- if .Values.defaultBackend.service.loadBalancerSourceRanges }} + loadBalancerSourceRanges: {{ toYaml .Values.defaultBackend.service.loadBalancerSourceRanges | nindent 4 }} +{{- end }} + ports: + - name: http + port: {{ .Values.defaultBackend.service.servicePort }} + protocol: TCP + targetPort: http + {{- if semverCompare ">=1.20" .Capabilities.KubeVersion.Version }} + appProtocol: http + {{- end }} + selector: + {{- include "ingress-nginx.selectorLabels" . | nindent 4 }} + app.kubernetes.io/component: default-backend +{{- end }} diff --git a/helm/sonarqube/charts/ingress-nginx/templates/default-backend-serviceaccount.yaml b/helm/sonarqube/charts/ingress-nginx/templates/default-backend-serviceaccount.yaml new file mode 100644 index 0000000..b45a95a --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/templates/default-backend-serviceaccount.yaml @@ -0,0 +1,14 @@ +{{- if and .Values.defaultBackend.enabled .Values.defaultBackend.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + {{- include "ingress-nginx.labels" . | nindent 4 }} + app.kubernetes.io/component: default-backend + {{- with .Values.defaultBackend.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + name: {{ template "ingress-nginx.defaultBackend.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +automountServiceAccountToken: {{ .Values.defaultBackend.serviceAccount.automountServiceAccountToken }} +{{- end }} diff --git a/helm/sonarqube/charts/ingress-nginx/values.yaml b/helm/sonarqube/charts/ingress-nginx/values.yaml new file mode 100644 index 0000000..d091391 --- /dev/null +++ b/helm/sonarqube/charts/ingress-nginx/values.yaml @@ -0,0 +1,904 @@ +## nginx configuration +## Ref: https://github.com/kubernetes/ingress-nginx/blob/main/docs/user-guide/nginx-configuration/index.md +## + +## Overrides for generated resource names +# See templates/_helpers.tpl +# nameOverride: +# fullnameOverride: + +## Labels to apply to all resources +## +commonLabels: {} +# scmhash: abc123 +# myLabel: aakkmd + +controller: + name: controller + image: + ## Keep false as default for now! + chroot: false + registry: registry.k8s.io + image: ingress-nginx/controller + ## for backwards compatibility consider setting the full image url via the repository value below + ## use *either* current default registry/image or repository format or installing chart by providing the values.yaml will fail + ## repository: + tag: "v1.8.1" + digest: sha256:e5c4824e7375fcf2a393e1c03c293b69759af37a9ca6abdb91b13d78a93da8bd + digestChroot: sha256:e0d4121e3c5e39de9122e55e331a32d5ebf8d4d257227cb93ab54a1b912a7627 + pullPolicy: IfNotPresent + # www-data -> uid 101 + runAsUser: 101 + allowPrivilegeEscalation: true + # -- Use an existing PSP instead of creating one + existingPsp: "" + # -- Configures the controller container name + containerName: controller + # -- Configures the ports that the nginx-controller listens on + containerPort: + http: 80 + https: 443 + # -- Will add custom configuration options to Nginx https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/ + config: {} + # -- Annotations to be added to the controller config configuration configmap. + configAnnotations: {} + # -- Will add custom headers before sending traffic to backends according to https://github.com/kubernetes/ingress-nginx/tree/main/docs/examples/customization/custom-headers + proxySetHeaders: {} + # -- Will add custom headers before sending response traffic to the client according to: https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/#add-headers + addHeaders: {} + # -- Optionally customize the pod dnsConfig. + dnsConfig: {} + # -- Optionally customize the pod hostname. + hostname: {} + # -- Optionally change this to ClusterFirstWithHostNet in case you have 'hostNetwork: true'. + # By default, while using host network, name resolution uses the host's DNS. If you wish nginx-controller + # to keep resolving names inside the k8s network, use ClusterFirstWithHostNet. + dnsPolicy: ClusterFirst + # -- Bare-metal considerations via the host network https://kubernetes.github.io/ingress-nginx/deploy/baremetal/#via-the-host-network + # Ingress status was blank because there is no Service exposing the Ingress-Nginx Controller in a configuration using the host network, the default --publish-service flag used in standard cloud setups does not apply + reportNodeInternalIp: false + # -- Process Ingress objects without ingressClass annotation/ingressClassName field + # Overrides value for --watch-ingress-without-class flag of the controller binary + # Defaults to false + watchIngressWithoutClass: false + # -- Process IngressClass per name (additionally as per spec.controller). + ingressClassByName: false + # -- This configuration enables Topology Aware Routing feature, used together with service annotation service.kubernetes.io/topology-aware-hints="auto" + # Defaults to false + enableTopologyAwareRouting: false + # -- This configuration defines if Ingress Controller should allow users to set + # their own *-snippet annotations, otherwise this is forbidden / dropped + # when users add those annotations. + # Global snippets in ConfigMap are still respected + allowSnippetAnnotations: true + # -- Required for use with CNI based kubernetes installations (such as ones set up by kubeadm), + # since CNI and hostport don't mix yet. Can be deprecated once https://github.com/kubernetes/kubernetes/issues/23920 + # is merged + hostNetwork: false + ## Use host ports 80 and 443 + ## Disabled by default + hostPort: + # -- Enable 'hostPort' or not + enabled: false + ports: + # -- 'hostPort' http port + http: 80 + # -- 'hostPort' https port + https: 443 + # -- Election ID to use for status update, by default it uses the controller name combined with a suffix of 'leader' + electionID: "" + ## This section refers to the creation of the IngressClass resource + ## IngressClass resources are supported since k8s >= 1.18 and required since k8s >= 1.19 + ingressClassResource: + # -- Name of the ingressClass + name: nginx + # -- Is this ingressClass enabled or not + enabled: true + # -- Is this the default ingressClass for the cluster + default: false + # -- Controller-value of the controller that is processing this ingressClass + controllerValue: "k8s.io/ingress-nginx" + # -- Parameters is a link to a custom resource containing additional + # configuration for the controller. This is optional if the controller + # does not require extra parameters. + parameters: {} + # -- For backwards compatibility with ingress.class annotation, use ingressClass. + # Algorithm is as follows, first ingressClassName is considered, if not present, controller looks for ingress.class annotation + ingressClass: nginx + # -- Labels to add to the pod container metadata + podLabels: {} + # key: value + + # -- Security Context policies for controller pods + podSecurityContext: {} + # -- See https://kubernetes.io/docs/tasks/administer-cluster/sysctl-cluster/ for notes on enabling and using sysctls + sysctls: {} + # sysctls: + # "net.core.somaxconn": "8192" + + # -- Allows customization of the source of the IP address or FQDN to report + # in the ingress status field. By default, it reads the information provided + # by the service. If disable, the status field reports the IP address of the + # node or nodes where an ingress controller pod is running. + publishService: + # -- Enable 'publishService' or not + enabled: true + # -- Allows overriding of the publish service to bind to + # Must be / + pathOverride: "" + # Limit the scope of the controller to a specific namespace + scope: + # -- Enable 'scope' or not + enabled: false + # -- Namespace to limit the controller to; defaults to $(POD_NAMESPACE) + namespace: "" + # -- When scope.enabled == false, instead of watching all namespaces, we watching namespaces whose labels + # only match with namespaceSelector. Format like foo=bar. Defaults to empty, means watching all namespaces. + namespaceSelector: "" + # -- Allows customization of the configmap / nginx-configmap namespace; defaults to $(POD_NAMESPACE) + configMapNamespace: "" + tcp: + # -- Allows customization of the tcp-services-configmap; defaults to $(POD_NAMESPACE) + configMapNamespace: "" + # -- Annotations to be added to the tcp config configmap + annotations: {} + udp: + # -- Allows customization of the udp-services-configmap; defaults to $(POD_NAMESPACE) + configMapNamespace: "" + # -- Annotations to be added to the udp config configmap + annotations: {} + # -- Maxmind license key to download GeoLite2 Databases. + ## https://blog.maxmind.com/2019/12/18/significant-changes-to-accessing-and-using-geolite2-databases + maxmindLicenseKey: "" + # -- Additional command line arguments to pass to Ingress-Nginx Controller + # E.g. to specify the default SSL certificate you can use + extraArgs: {} + ## extraArgs: + ## default-ssl-certificate: "/" + + # -- Additional environment variables to set + extraEnvs: [] + # extraEnvs: + # - name: FOO + # valueFrom: + # secretKeyRef: + # key: FOO + # name: secret-resource + + # -- Use a `DaemonSet` or `Deployment` + kind: Deployment + # -- Annotations to be added to the controller Deployment or DaemonSet + ## + annotations: {} + # keel.sh/pollSchedule: "@every 60m" + + # -- Labels to be added to the controller Deployment or DaemonSet and other resources that do not have option to specify labels + ## + labels: {} + # keel.sh/policy: patch + # keel.sh/trigger: poll + + # -- The update strategy to apply to the Deployment or DaemonSet + ## + updateStrategy: {} + # rollingUpdate: + # maxUnavailable: 1 + # type: RollingUpdate + + # -- `minReadySeconds` to avoid killing pods before we are ready + ## + minReadySeconds: 0 + # -- Node tolerations for server scheduling to nodes with taints + ## Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ + ## + tolerations: [] + # - key: "key" + # operator: "Equal|Exists" + # value: "value" + # effect: "NoSchedule|PreferNoSchedule|NoExecute(1.6 only)" + + # -- Affinity and anti-affinity rules for server scheduling to nodes + ## Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity + ## + affinity: {} + # # An example of preferred pod anti-affinity, weight is in the range 1-100 + # podAntiAffinity: + # preferredDuringSchedulingIgnoredDuringExecution: + # - weight: 100 + # podAffinityTerm: + # labelSelector: + # matchExpressions: + # - key: app.kubernetes.io/name + # operator: In + # values: + # - ingress-nginx + # - key: app.kubernetes.io/instance + # operator: In + # values: + # - ingress-nginx + # - key: app.kubernetes.io/component + # operator: In + # values: + # - controller + # topologyKey: kubernetes.io/hostname + + # # An example of required pod anti-affinity + # podAntiAffinity: + # requiredDuringSchedulingIgnoredDuringExecution: + # - labelSelector: + # matchExpressions: + # - key: app.kubernetes.io/name + # operator: In + # values: + # - ingress-nginx + # - key: app.kubernetes.io/instance + # operator: In + # values: + # - ingress-nginx + # - key: app.kubernetes.io/component + # operator: In + # values: + # - controller + # topologyKey: "kubernetes.io/hostname" + + # -- Topology spread constraints rely on node labels to identify the topology domain(s) that each Node is in. + ## Ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ + ## + topologySpreadConstraints: [] + # - maxSkew: 1 + # topologyKey: topology.kubernetes.io/zone + # whenUnsatisfiable: DoNotSchedule + # labelSelector: + # matchLabels: + # app.kubernetes.io/instance: ingress-nginx-internal + + # -- `terminationGracePeriodSeconds` to avoid killing pods before we are ready + ## wait up to five minutes for the drain of connections + ## + terminationGracePeriodSeconds: 300 + # -- Node labels for controller pod assignment + ## Ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/ + ## + nodeSelector: + kubernetes.io/os: linux + ## Liveness and readiness probe values + ## Ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#container-probes + ## + ## startupProbe: + ## httpGet: + ## # should match container.healthCheckPath + ## path: "/healthz" + ## port: 10254 + ## scheme: HTTP + ## initialDelaySeconds: 5 + ## periodSeconds: 5 + ## timeoutSeconds: 2 + ## successThreshold: 1 + ## failureThreshold: 5 + livenessProbe: + httpGet: + # should match container.healthCheckPath + path: "/healthz" + port: 10254 + scheme: HTTP + initialDelaySeconds: 10 + periodSeconds: 10 + timeoutSeconds: 1 + successThreshold: 1 + failureThreshold: 5 + readinessProbe: + httpGet: + # should match container.healthCheckPath + path: "/healthz" + port: 10254 + scheme: HTTP + initialDelaySeconds: 10 + periodSeconds: 10 + timeoutSeconds: 1 + successThreshold: 1 + failureThreshold: 3 + # -- Path of the health check endpoint. All requests received on the port defined by + # the healthz-port parameter are forwarded internally to this path. + healthCheckPath: "/healthz" + # -- Address to bind the health check endpoint. + # It is better to set this option to the internal node address + # if the Ingress-Nginx Controller is running in the `hostNetwork: true` mode. + healthCheckHost: "" + # -- Annotations to be added to controller pods + ## + podAnnotations: {} + replicaCount: 1 + # -- Minimum available pods set in PodDisruptionBudget. + # Define either 'minAvailable' or 'maxUnavailable', never both. + minAvailable: 1 + # -- Maximum unavalaile pods set in PodDisruptionBudget. If set, 'minAvailable' is ignored. + # maxUnavailable: 1 + + ## Define requests resources to avoid probe issues due to CPU utilization in busy nodes + ## ref: https://github.com/kubernetes/ingress-nginx/issues/4735#issuecomment-551204903 + ## Ideally, there should be no limits. + ## https://engineering.indeedblog.com/blog/2019/12/cpu-throttling-regression-fix/ + resources: + ## limits: + ## cpu: 100m + ## memory: 90Mi + requests: + cpu: 100m + memory: 90Mi + # Mutually exclusive with keda autoscaling + autoscaling: + enabled: false + annotations: {} + minReplicas: 1 + maxReplicas: 11 + targetCPUUtilizationPercentage: 50 + targetMemoryUtilizationPercentage: 50 + behavior: {} + # scaleDown: + # stabilizationWindowSeconds: 300 + # policies: + # - type: Pods + # value: 1 + # periodSeconds: 180 + # scaleUp: + # stabilizationWindowSeconds: 300 + # policies: + # - type: Pods + # value: 2 + # periodSeconds: 60 + autoscalingTemplate: [] + # Custom or additional autoscaling metrics + # ref: https://kubernetes.io/docs/tasks/run-application/horizontal-pod-autoscale/#support-for-custom-metrics + # - type: Pods + # pods: + # metric: + # name: nginx_ingress_controller_nginx_process_requests_total + # target: + # type: AverageValue + # averageValue: 10000m + + # Mutually exclusive with hpa autoscaling + keda: + apiVersion: "keda.sh/v1alpha1" + ## apiVersion changes with keda 1.x vs 2.x + ## 2.x = keda.sh/v1alpha1 + ## 1.x = keda.k8s.io/v1alpha1 + enabled: false + minReplicas: 1 + maxReplicas: 11 + pollingInterval: 30 + cooldownPeriod: 300 + # fallback: + # failureThreshold: 3 + # replicas: 11 + restoreToOriginalReplicaCount: false + scaledObject: + annotations: {} + # Custom annotations for ScaledObject resource + # annotations: + # key: value + triggers: [] + # - type: prometheus + # metadata: + # serverAddress: http://:9090 + # metricName: http_requests_total + # threshold: '100' + # query: sum(rate(http_requests_total{deployment="my-deployment"}[2m])) + + behavior: {} + # scaleDown: + # stabilizationWindowSeconds: 300 + # policies: + # - type: Pods + # value: 1 + # periodSeconds: 180 + # scaleUp: + # stabilizationWindowSeconds: 300 + # policies: + # - type: Pods + # value: 2 + # periodSeconds: 60 + # -- Enable mimalloc as a drop-in replacement for malloc. + ## ref: https://github.com/microsoft/mimalloc + ## + enableMimalloc: true + ## Override NGINX template + customTemplate: + configMapName: "" + configMapKey: "" + service: + enabled: true + # -- If enabled is adding an appProtocol option for Kubernetes service. An appProtocol field replacing annotations that were + # using for setting a backend protocol. Here is an example for AWS: service.beta.kubernetes.io/aws-load-balancer-backend-protocol: http + # It allows choosing the protocol for each backend specified in the Kubernetes service. + # See the following GitHub issue for more details about the purpose: https://github.com/kubernetes/kubernetes/issues/40244 + # Will be ignored for Kubernetes versions older than 1.20 + ## + appProtocol: true + annotations: {} + labels: {} + # clusterIP: "" + + # -- List of IP addresses at which the controller services are available + ## Ref: https://kubernetes.io/docs/concepts/services-networking/service/#external-ips + ## + externalIPs: [] + # -- Used by cloud providers to connect the resulting `LoadBalancer` to a pre-existing static IP according to https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer + loadBalancerIP: "" + loadBalancerSourceRanges: [] + # -- Used by cloud providers to select a load balancer implementation other than the cloud provider default. https://kubernetes.io/docs/concepts/services-networking/service/#load-balancer-class + loadBalancerClass: "" + enableHttp: true + enableHttps: true + ## Set external traffic policy to: "Local" to preserve source IP on providers supporting it. + ## Ref: https://kubernetes.io/docs/tutorials/services/source-ip/#source-ip-for-services-with-typeloadbalancer + # externalTrafficPolicy: "" + + ## Must be either "None" or "ClientIP" if set. Kubernetes will default to "None". + ## Ref: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies + # sessionAffinity: "" + + ## Specifies the health check node port (numeric port number) for the service. If healthCheckNodePort isn’t specified, + ## the service controller allocates a port from your cluster’s NodePort range. + ## Ref: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#preserving-the-client-source-ip + # healthCheckNodePort: 0 + + # -- Represents the dual-stack-ness requested or required by this Service. Possible values are + # SingleStack, PreferDualStack or RequireDualStack. + # The ipFamilies and clusterIPs fields depend on the value of this field. + ## Ref: https://kubernetes.io/docs/concepts/services-networking/dual-stack/ + ipFamilyPolicy: "SingleStack" + # -- List of IP families (e.g. IPv4, IPv6) assigned to the service. This field is usually assigned automatically + # based on cluster configuration and the ipFamilyPolicy field. + ## Ref: https://kubernetes.io/docs/concepts/services-networking/dual-stack/ + ipFamilies: + - IPv4 + ports: + http: 80 + https: 443 + targetPorts: + http: http + https: https + type: LoadBalancer + ## type: NodePort + ## nodePorts: + ## http: 32080 + ## https: 32443 + ## tcp: + ## 8080: 32808 + nodePorts: + http: "" + https: "" + tcp: {} + udp: {} + external: + enabled: true + internal: + # -- Enables an additional internal load balancer (besides the external one). + enabled: false + # -- Annotations are mandatory for the load balancer to come up. Varies with the cloud service. + annotations: {} + # -- Used by cloud providers to connect the resulting internal LoadBalancer to a pre-existing static IP. Make sure to add to the service the needed annotation to specify the subnet which the static IP belongs to. For instance, `networking.gke.io/internal-load-balancer-subnet` for GCP and `service.beta.kubernetes.io/aws-load-balancer-subnets` for AWS. + loadBalancerIP: "" + # -- Restrict access For LoadBalancer service. Defaults to 0.0.0.0/0. + loadBalancerSourceRanges: [] + ## Set external traffic policy to: "Local" to preserve source IP on + ## providers supporting it + ## Ref: https://kubernetes.io/docs/tutorials/services/source-ip/#source-ip-for-services-with-typeloadbalancer + # externalTrafficPolicy: "" + + # -- Custom port mapping for internal service + ports: {} + # http: 80 + # https: 443 + + # -- Custom target port mapping for internal service + targetPorts: {} + # http: http + # https: https + # shareProcessNamespace enables process namespace sharing within the pod. + # This can be used for example to signal log rotation using `kill -USR1` from a sidecar. + shareProcessNamespace: false + # -- Additional containers to be added to the controller pod. + # See https://github.com/lemonldap-ng-controller/lemonldap-ng-controller as example. + extraContainers: [] + # - name: my-sidecar + # image: nginx:latest + # - name: lemonldap-ng-controller + # image: lemonldapng/lemonldap-ng-controller:0.2.0 + # args: + # - /lemonldap-ng-controller + # - --alsologtostderr + # - --configmap=$(POD_NAMESPACE)/lemonldap-ng-configuration + # env: + # - name: POD_NAME + # valueFrom: + # fieldRef: + # fieldPath: metadata.name + # - name: POD_NAMESPACE + # valueFrom: + # fieldRef: + # fieldPath: metadata.namespace + # volumeMounts: + # - name: copy-portal-skins + # mountPath: /srv/var/lib/lemonldap-ng/portal/skins + + # -- Additional volumeMounts to the controller main container. + extraVolumeMounts: [] + # - name: copy-portal-skins + # mountPath: /var/lib/lemonldap-ng/portal/skins + + # -- Additional volumes to the controller pod. + extraVolumes: [] + # - name: copy-portal-skins + # emptyDir: {} + + # -- Containers, which are run before the app containers are started. + extraInitContainers: [] + # - name: init-myservice + # image: busybox + # command: ['sh', '-c', 'until nslookup myservice; do echo waiting for myservice; sleep 2; done;'] + + # -- Modules, which are mounted into the core nginx image. See values.yaml for a sample to add opentelemetry module + extraModules: [] + # - name: mytestmodule + # image: registry.k8s.io/ingress-nginx/mytestmodule + # containerSecurityContext: + # allowPrivilegeEscalation: false + # + # The image must contain a `/usr/local/bin/init_module.sh` executable, which + # will be executed as initContainers, to move its config files within the + # mounted volume. + + opentelemetry: + enabled: false + image: registry.k8s.io/ingress-nginx/opentelemetry:v20230527@sha256:fd7ec835f31b7b37187238eb4fdad4438806e69f413a203796263131f4f02ed0 + containerSecurityContext: + allowPrivilegeEscalation: false + admissionWebhooks: + annotations: {} + # ignore-check.kube-linter.io/no-read-only-rootfs: "This deployment needs write access to root filesystem". + + ## Additional annotations to the admission webhooks. + ## These annotations will be added to the ValidatingWebhookConfiguration and + ## the Jobs Spec of the admission webhooks. + enabled: true + # -- Additional environment variables to set + extraEnvs: [] + # extraEnvs: + # - name: FOO + # valueFrom: + # secretKeyRef: + # key: FOO + # name: secret-resource + # -- Admission Webhook failure policy to use + failurePolicy: Fail + # timeoutSeconds: 10 + port: 8443 + certificate: "/usr/local/certificates/cert" + key: "/usr/local/certificates/key" + namespaceSelector: {} + objectSelector: {} + # -- Labels to be added to admission webhooks + labels: {} + # -- Use an existing PSP instead of creating one + existingPsp: "" + networkPolicyEnabled: false + service: + annotations: {} + # clusterIP: "" + externalIPs: [] + # loadBalancerIP: "" + loadBalancerSourceRanges: [] + servicePort: 443 + type: ClusterIP + createSecretJob: + securityContext: + allowPrivilegeEscalation: false + resources: {} + # limits: + # cpu: 10m + # memory: 20Mi + # requests: + # cpu: 10m + # memory: 20Mi + patchWebhookJob: + securityContext: + allowPrivilegeEscalation: false + resources: {} + patch: + enabled: true + image: + registry: registry.k8s.io + image: ingress-nginx/kube-webhook-certgen + ## for backwards compatibility consider setting the full image url via the repository value below + ## use *either* current default registry/image or repository format or installing chart by providing the values.yaml will fail + ## repository: + tag: v20230407 + digest: sha256:543c40fd093964bc9ab509d3e791f9989963021f1e9e4c9c7b6700b02bfb227b + pullPolicy: IfNotPresent + # -- Provide a priority class name to the webhook patching job + ## + priorityClassName: "" + podAnnotations: {} + nodeSelector: + kubernetes.io/os: linux + tolerations: [] + # -- Labels to be added to patch job resources + labels: {} + securityContext: + runAsNonRoot: true + runAsUser: 2000 + fsGroup: 2000 + # Use certmanager to generate webhook certs + certManager: + enabled: false + # self-signed root certificate + rootCert: + # default to be 5y + duration: "" + admissionCert: + # default to be 1y + duration: "" + # issuerRef: + # name: "issuer" + # kind: "ClusterIssuer" + metrics: + port: 10254 + portName: metrics + # if this port is changed, change healthz-port: in extraArgs: accordingly + enabled: false + service: + annotations: {} + # prometheus.io/scrape: "true" + # prometheus.io/port: "10254" + # -- Labels to be added to the metrics service resource + labels: {} + # clusterIP: "" + + # -- List of IP addresses at which the stats-exporter service is available + ## Ref: https://kubernetes.io/docs/concepts/services-networking/service/#external-ips + ## + externalIPs: [] + # loadBalancerIP: "" + loadBalancerSourceRanges: [] + servicePort: 10254 + type: ClusterIP + # externalTrafficPolicy: "" + # nodePort: "" + serviceMonitor: + enabled: false + additionalLabels: {} + ## The label to use to retrieve the job name from. + ## jobLabel: "app.kubernetes.io/name" + namespace: "" + namespaceSelector: {} + ## Default: scrape .Release.Namespace only + ## To scrape all, use the following: + ## namespaceSelector: + ## any: true + scrapeInterval: 30s + # honorLabels: true + targetLabels: [] + relabelings: [] + metricRelabelings: [] + prometheusRule: + enabled: false + additionalLabels: {} + # namespace: "" + rules: [] + # # These are just examples rules, please adapt them to your needs + # - alert: NGINXConfigFailed + # expr: count(nginx_ingress_controller_config_last_reload_successful == 0) > 0 + # for: 1s + # labels: + # severity: critical + # annotations: + # description: bad ingress config - nginx config test failed + # summary: uninstall the latest ingress changes to allow config reloads to resume + # - alert: NGINXCertificateExpiry + # expr: (avg(nginx_ingress_controller_ssl_expire_time_seconds) by (host) - time()) < 604800 + # for: 1s + # labels: + # severity: critical + # annotations: + # description: ssl certificate(s) will expire in less then a week + # summary: renew expiring certificates to avoid downtime + # - alert: NGINXTooMany500s + # expr: 100 * ( sum( nginx_ingress_controller_requests{status=~"5.+"} ) / sum(nginx_ingress_controller_requests) ) > 5 + # for: 1m + # labels: + # severity: warning + # annotations: + # description: Too many 5XXs + # summary: More than 5% of all requests returned 5XX, this requires your attention + # - alert: NGINXTooMany400s + # expr: 100 * ( sum( nginx_ingress_controller_requests{status=~"4.+"} ) / sum(nginx_ingress_controller_requests) ) > 5 + # for: 1m + # labels: + # severity: warning + # annotations: + # description: Too many 4XXs + # summary: More than 5% of all requests returned 4XX, this requires your attention + # -- Improve connection draining when ingress controller pod is deleted using a lifecycle hook: + # With this new hook, we increased the default terminationGracePeriodSeconds from 30 seconds + # to 300, allowing the draining of connections up to five minutes. + # If the active connections end before that, the pod will terminate gracefully at that time. + # To effectively take advantage of this feature, the Configmap feature + # worker-shutdown-timeout new value is 240s instead of 10s. + ## + lifecycle: + preStop: + exec: + command: + - /wait-shutdown + priorityClassName: "" +# -- Rollback limit +## +revisionHistoryLimit: 10 +## Default 404 backend +## +defaultBackend: + ## + enabled: false + name: defaultbackend + image: + registry: registry.k8s.io + image: defaultbackend-amd64 + ## for backwards compatibility consider setting the full image url via the repository value below + ## use *either* current default registry/image or repository format or installing chart by providing the values.yaml will fail + ## repository: + tag: "1.5" + pullPolicy: IfNotPresent + # nobody user -> uid 65534 + runAsUser: 65534 + runAsNonRoot: true + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + # -- Use an existing PSP instead of creating one + existingPsp: "" + extraArgs: {} + serviceAccount: + create: true + name: "" + automountServiceAccountToken: true + # -- Additional environment variables to set for defaultBackend pods + extraEnvs: [] + port: 8080 + ## Readiness and liveness probes for default backend + ## Ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/ + ## + livenessProbe: + failureThreshold: 3 + initialDelaySeconds: 30 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 5 + readinessProbe: + failureThreshold: 6 + initialDelaySeconds: 0 + periodSeconds: 5 + successThreshold: 1 + timeoutSeconds: 5 + # -- The update strategy to apply to the Deployment or DaemonSet + ## + updateStrategy: {} + # rollingUpdate: + # maxUnavailable: 1 + # type: RollingUpdate + + # -- `minReadySeconds` to avoid killing pods before we are ready + ## + minReadySeconds: 0 + # -- Node tolerations for server scheduling to nodes with taints + ## Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ + ## + tolerations: [] + # - key: "key" + # operator: "Equal|Exists" + # value: "value" + # effect: "NoSchedule|PreferNoSchedule|NoExecute(1.6 only)" + + affinity: {} + # -- Security Context policies for controller pods + # See https://kubernetes.io/docs/tasks/administer-cluster/sysctl-cluster/ for + # notes on enabling and using sysctls + ## + podSecurityContext: {} + # -- Security Context policies for controller main container. + # See https://kubernetes.io/docs/tasks/administer-cluster/sysctl-cluster/ for + # notes on enabling and using sysctls + ## + containerSecurityContext: {} + # -- Labels to add to the pod container metadata + podLabels: {} + # key: value + + # -- Node labels for default backend pod assignment + ## Ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/ + ## + nodeSelector: + kubernetes.io/os: linux + # -- Annotations to be added to default backend pods + ## + podAnnotations: {} + replicaCount: 1 + minAvailable: 1 + resources: {} + # limits: + # cpu: 10m + # memory: 20Mi + # requests: + # cpu: 10m + # memory: 20Mi + + extraVolumeMounts: [] + ## Additional volumeMounts to the default backend container. + # - name: copy-portal-skins + # mountPath: /var/lib/lemonldap-ng/portal/skins + + extraVolumes: [] + ## Additional volumes to the default backend pod. + # - name: copy-portal-skins + # emptyDir: {} + + autoscaling: + annotations: {} + enabled: false + minReplicas: 1 + maxReplicas: 2 + targetCPUUtilizationPercentage: 50 + targetMemoryUtilizationPercentage: 50 + service: + annotations: {} + # clusterIP: "" + + # -- List of IP addresses at which the default backend service is available + ## Ref: https://kubernetes.io/docs/concepts/services-networking/service/#external-ips + ## + externalIPs: [] + # loadBalancerIP: "" + loadBalancerSourceRanges: [] + servicePort: 80 + type: ClusterIP + priorityClassName: "" + # -- Labels to be added to the default backend resources + labels: {} +## Enable RBAC as per https://github.com/kubernetes/ingress-nginx/blob/main/docs/deploy/rbac.md and https://github.com/kubernetes/ingress-nginx/issues/266 +rbac: + create: true + scope: false +## If true, create & use Pod Security Policy resources +## https://kubernetes.io/docs/concepts/policy/pod-security-policy/ +podSecurityPolicy: + enabled: false +serviceAccount: + create: true + name: "" + automountServiceAccountToken: true + # -- Annotations for the controller service account + annotations: {} +# -- Optional array of imagePullSecrets containing private registry credentials +## Ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ +imagePullSecrets: [] +# - name: secretName + +# -- TCP service key-value pairs +## Ref: https://github.com/kubernetes/ingress-nginx/blob/main/docs/user-guide/exposing-tcp-udp-services.md +## +tcp: {} +# 8080: "default/example-tcp-svc:9000" + +# -- UDP service key-value pairs +## Ref: https://github.com/kubernetes/ingress-nginx/blob/main/docs/user-guide/exposing-tcp-udp-services.md +## +udp: {} +# 53: "kube-system/kube-dns:53" + +# -- Prefix for TCP and UDP ports names in ingress controller service +## Some cloud providers, like Yandex Cloud may have a requirements for a port name regex to support cloud load balancer integration +portNamePrefix: "" +# -- (string) A base64-encoded Diffie-Hellman parameter. +# This can be generated with: `openssl dhparam 4096 2> /dev/null | base64` +## Ref: https://github.com/kubernetes/ingress-nginx/tree/main/docs/examples/customization/ssl-dh-param +dhParam: "" diff --git a/helm/sonarqube/charts/postgresql/.helmignore b/helm/sonarqube/charts/postgresql/.helmignore new file mode 100644 index 0000000..f0c1319 --- /dev/null +++ b/helm/sonarqube/charts/postgresql/.helmignore @@ -0,0 +1,21 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*~ +# Various IDEs +.project +.idea/ +*.tmproj diff --git a/helm/sonarqube/charts/postgresql/Chart.lock b/helm/sonarqube/charts/postgresql/Chart.lock new file mode 100644 index 0000000..830fa8c --- /dev/null +++ b/helm/sonarqube/charts/postgresql/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: common + repository: https://charts.bitnami.com/bitnami + version: 1.10.3 +digest: sha256:e8f1d59ae8150ae6099f2d72a9e3ac2fdc0c8fd869b210226edf7c71eef11263 +generated: "2021-12-31T20:02:44.936728424Z" diff --git a/helm/sonarqube/charts/postgresql/Chart.yaml b/helm/sonarqube/charts/postgresql/Chart.yaml new file mode 100644 index 0000000..3e76bd2 --- /dev/null +++ b/helm/sonarqube/charts/postgresql/Chart.yaml @@ -0,0 +1,29 @@ +annotations: + category: Database +apiVersion: v2 +appVersion: 11.14.0 +dependencies: +- name: common + repository: https://charts.bitnami.com/bitnami + version: 1.x.x +description: Chart for PostgreSQL, an object-relational database management system + (ORDBMS) with an emphasis on extensibility and on standards-compliance. +home: https://github.com/bitnami/charts/tree/master/bitnami/postgresql +icon: https://bitnami.com/assets/stacks/postgresql/img/postgresql-stack-220x234.png +keywords: +- postgresql +- postgres +- database +- sql +- replication +- cluster +maintainers: +- email: containers@bitnami.com + name: Bitnami +- email: cedric@desaintmartin.fr + name: desaintmartin +name: postgresql +sources: +- https://github.com/bitnami/bitnami-docker-postgresql +- https://www.postgresql.org/ +version: 10.15.0 diff --git a/helm/sonarqube/charts/postgresql/README.md b/helm/sonarqube/charts/postgresql/README.md new file mode 100644 index 0000000..0f04032 --- /dev/null +++ b/helm/sonarqube/charts/postgresql/README.md @@ -0,0 +1,816 @@ +# PostgreSQL + +[PostgreSQL](https://www.postgresql.org/) is an object-relational database management system (ORDBMS) with an emphasis on extensibility and on standards-compliance. + +For HA, please see [this repo](https://github.com/bitnami/charts/tree/master/bitnami/postgresql-ha) + +## TL;DR + +```console +$ helm repo add bitnami https://charts.bitnami.com/bitnami +$ helm install my-release bitnami/postgresql +``` + +## Introduction + +This chart bootstraps a [PostgreSQL](https://github.com/bitnami/bitnami-docker-postgresql) deployment on a [Kubernetes](https://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager. + +Bitnami charts can be used with [Kubeapps](https://kubeapps.com/) for deployment and management of Helm Charts in clusters. This chart has been tested to work with NGINX Ingress, cert-manager, fluentd and Prometheus on top of the [BKPR](https://kubeprod.io/). + +## Prerequisites + +- Kubernetes 1.12+ +- Helm 3.1.0 +- PV provisioner support in the underlying infrastructure + +## Installing the Chart +To install the chart with the release name `my-release`: + +```console +$ helm install my-release bitnami/postgresql +``` + +The command deploys PostgreSQL on the Kubernetes cluster in the default configuration. The [Parameters](#parameters) section lists the parameters that can be configured during installation. + +> **Tip**: List all releases using `helm list` + +## Uninstalling the Chart + +To uninstall/delete the `my-release` deployment: + +```console +$ helm delete my-release +``` + +The command removes all the Kubernetes components but PVC's associated with the chart and deletes the release. + +To delete the PVC's associated with `my-release`: + +```console +$ kubectl delete pvc -l release=my-release +``` + +> **Note**: Deleting the PVC's will delete postgresql data as well. Please be cautious before doing it. + +## Parameters + +### Global parameters + +| Name | Description | Value | +| --------------------------------------- | ------------------------------------------------------------------------------------ | ----- | +| `global.imageRegistry` | Global Docker image registry | `""` | +| `global.imagePullSecrets` | Global Docker registry secret names as an array | `[]` | +| `global.storageClass` | Global StorageClass for Persistent Volume(s) | `""` | +| `global.postgresql.postgresqlDatabase` | PostgreSQL database (overrides `postgresqlDatabase`) | `""` | +| `global.postgresql.postgresqlUsername` | PostgreSQL username (overrides `postgresqlUsername`) | `""` | +| `global.postgresql.existingSecret` | Name of existing secret to use for PostgreSQL passwords (overrides `existingSecret`) | `""` | +| `global.postgresql.postgresqlPassword` | PostgreSQL admin password (overrides `postgresqlPassword`) | `""` | +| `global.postgresql.servicePort` | PostgreSQL port (overrides `service.port` | `""` | +| `global.postgresql.replicationPassword` | Replication user password (overrides `replication.password`) | `""` | + + +### Common parameters + +| Name | Description | Value | +| ------------------------ | -------------------------------------------------------------------------------------------- | -------------- | +| `nameOverride` | String to partially override common.names.fullname template (will maintain the release name) | `""` | +| `fullnameOverride` | String to fully override common.names.fullname template | `""` | +| `extraDeploy` | Array of extra objects to deploy with the release (evaluated as a template) | `[]` | +| `commonLabels` | Add labels to all the deployed resources | `{}` | +| `commonAnnotations` | Add annotations to all the deployed resources | `{}` | +| `diagnosticMode.enabled` | Enable diagnostic mode (all probes will be disabled and the command will be overridden) | `false` | +| `diagnosticMode.command` | Command to override all containers in the deployment | `["sleep"]` | +| `diagnosticMode.args` | Args to override all containers in the deployment | `["infinity"]` | + + +### PostgreSQL parameters + +| Name | Description | Value | +| --------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- | +| `image.registry` | PostgreSQL image registry | `docker.io` | +| `image.repository` | PostgreSQL image repository | `bitnami/postgresql` | +| `image.tag` | PostgreSQL image tag (immutable tags are recommended) | `11.14.0-debian-10-r17` | +| `image.pullPolicy` | PostgreSQL image pull policy | `IfNotPresent` | +| `image.pullSecrets` | Specify image pull secrets | `[]` | +| `image.debug` | Specify if debug values should be set | `false` | +| `volumePermissions.enabled` | Enable init container that changes volume permissions in the data directory (for cases where the default k8s `runAsUser` and `fsUser` values do not work) | `false` | +| `volumePermissions.image.registry` | Init container volume-permissions image registry | `docker.io` | +| `volumePermissions.image.repository` | Init container volume-permissions image repository | `bitnami/bitnami-shell` | +| `volumePermissions.image.tag` | Init container volume-permissions image tag (immutable tags are recommended) | `10-debian-10-r265` | +| `volumePermissions.image.pullPolicy` | Init container volume-permissions image pull policy | `IfNotPresent` | +| `volumePermissions.image.pullSecrets` | Init container volume-permissions image pull secrets | `[]` | +| `volumePermissions.securityContext.runAsUser` | User ID for the init container | `0` | +| `schedulerName` | Use an alternate scheduler, e.g. "stork". | `""` | +| `lifecycleHooks` | for the PostgreSQL container to automate configuration before or after startup | `{}` | +| `securityContext.enabled` | Enable security context | `true` | +| `securityContext.fsGroup` | Group ID for the pod | `1001` | +| `containerSecurityContext.enabled` | Enable container security context | `true` | +| `containerSecurityContext.runAsUser` | User ID for the container | `1001` | +| `serviceAccount.enabled` | Enable service account (Note: Service Account will only be automatically created if `serviceAccount.name` is not set) | `false` | +| `serviceAccount.name` | Name of an already existing service account. Setting this value disables the automatic service account creation | `""` | +| `serviceAccount.autoMount` | Auto-mount the service account token in the pod | `false` | +| `psp.create` | Whether to create a PodSecurityPolicy. WARNING: PodSecurityPolicy is deprecated in Kubernetes v1.21 or later, unavailable in v1.25 or later | `false` | +| `rbac.create` | Create Role and RoleBinding (required for PSP to work) | `false` | +| `replication.enabled` | Enable replication | `false` | +| `replication.user` | Replication user | `repl_user` | +| `replication.password` | Replication user password | `repl_password` | +| `replication.readReplicas` | Number of read replicas replicas | `1` | +| `replication.synchronousCommit` | Set synchronous commit mode. Allowed values: `on`, `remote_apply`, `remote_write`, `local` and `off` | `off` | +| `replication.numSynchronousReplicas` | Number of replicas that will have synchronous replication. Note: Cannot be greater than `replication.readReplicas`. | `0` | +| `replication.applicationName` | Cluster application name. Useful for advanced replication settings | `my_application` | +| `replication.singleService` | Create one service connecting to all read-replicas | `true` | +| `replication.uniqueServices` | Create a unique service for each independent read-replica | `false` | +| `postgresqlPostgresPassword` | PostgreSQL admin password (used when `postgresqlUsername` is not `postgres`, in which case`postgres` is the admin username) | `""` | +| `postgresqlUsername` | PostgreSQL user (has superuser privileges if username is `postgres`) | `postgres` | +| `postgresqlPassword` | PostgreSQL user password | `""` | +| `existingSecret` | Name of existing secret to use for PostgreSQL passwords | `""` | +| `usePasswordFile` | Mount PostgreSQL secret as a file instead of passing environment variable | `false` | +| `postgresqlDatabase` | PostgreSQL database | `""` | +| `postgresqlDataDir` | PostgreSQL data dir folder | `/bitnami/postgresql/data` | +| `extraEnv` | An array to add extra environment variables | `[]` | +| `extraEnvVarsCM` | Name of a Config Map containing extra environment variables | `""` | +| `postgresqlInitdbArgs` | PostgreSQL initdb extra arguments | `""` | +| `postgresqlInitdbWalDir` | Specify a custom location for the PostgreSQL transaction log | `""` | +| `postgresqlConfiguration` | PostgreSQL configuration | `{}` | +| `postgresqlExtendedConf` | Extended Runtime Config Parameters (appended to main or default configuration) | `{}` | +| `primaryAsStandBy.enabled` | Whether to enable current cluster's primary as standby server of another cluster or not | `false` | +| `primaryAsStandBy.primaryHost` | The Host of replication primary in the other cluster | `""` | +| `primaryAsStandBy.primaryPort` | The Port of replication primary in the other cluster | `""` | +| `pgHbaConfiguration` | PostgreSQL client authentication configuration | `""` | +| `configurationConfigMap` | ConfigMap with PostgreSQL configuration | `""` | +| `extendedConfConfigMap` | ConfigMap with PostgreSQL extended configuration | `""` | +| `initdbScripts` | Dictionary of initdb scripts | `{}` | +| `initdbScriptsConfigMap` | ConfigMap with scripts to be run at first boot | `""` | +| `initdbScriptsSecret` | Secret with scripts to be run at first boot (in case it contains sensitive information) | `""` | +| `initdbUser` | Specify the PostgreSQL username to execute the initdb scripts | `""` | +| `initdbPassword` | Specify the PostgreSQL password to execute the initdb scripts | `""` | +| `containerPorts.postgresql` | PostgreSQL container port | `5432` | +| `audit.logHostname` | Log client hostnames | `false` | +| `audit.logConnections` | Add client log-in operations to the log file | `false` | +| `audit.logDisconnections` | Add client log-outs operations to the log file | `false` | +| `audit.pgAuditLog` | Add operations to log using the pgAudit extension | `""` | +| `audit.pgAuditLogCatalog` | Log catalog using pgAudit | `off` | +| `audit.clientMinMessages` | Message log level to share with the user | `error` | +| `audit.logLinePrefix` | Template for log line prefix (default if not set) | `""` | +| `audit.logTimezone` | Timezone for the log timestamps | `""` | +| `postgresqlSharedPreloadLibraries` | Shared preload libraries (comma-separated list) | `pgaudit` | +| `postgresqlMaxConnections` | Maximum total connections | `""` | +| `postgresqlPostgresConnectionLimit` | Maximum connections for the postgres user | `""` | +| `postgresqlDbUserConnectionLimit` | Maximum connections for the non-admin user | `""` | +| `postgresqlTcpKeepalivesInterval` | TCP keepalives interval | `""` | +| `postgresqlTcpKeepalivesIdle` | TCP keepalives idle | `""` | +| `postgresqlTcpKeepalivesCount` | TCP keepalives count | `""` | +| `postgresqlStatementTimeout` | Statement timeout | `""` | +| `postgresqlPghbaRemoveFilters` | Comma-separated list of patterns to remove from the pg_hba.conf file | `""` | +| `terminationGracePeriodSeconds` | Seconds the pod needs to terminate gracefully | `""` | +| `ldap.enabled` | Enable LDAP support | `false` | +| `ldap.url` | LDAP URL beginning in the form `ldap[s]://host[:port]/basedn` | `""` | +| `ldap.server` | IP address or name of the LDAP server. | `""` | +| `ldap.port` | Port number on the LDAP server to connect to | `""` | +| `ldap.prefix` | String to prepend to the user name when forming the DN to bind | `""` | +| `ldap.suffix` | String to append to the user name when forming the DN to bind | `""` | +| `ldap.baseDN` | Root DN to begin the search for the user in | `""` | +| `ldap.bindDN` | DN of user to bind to LDAP | `""` | +| `ldap.bind_password` | Password for the user to bind to LDAP | `""` | +| `ldap.search_attr` | Attribute to match against the user name in the search | `""` | +| `ldap.search_filter` | The search filter to use when doing search+bind authentication | `""` | +| `ldap.scheme` | Set to `ldaps` to use LDAPS | `""` | +| `ldap.tls` | Set to `1` to use TLS encryption | `""` | +| `service.type` | Kubernetes Service type | `ClusterIP` | +| `service.clusterIP` | Static clusterIP or None for headless services | `""` | +| `service.port` | PostgreSQL port | `5432` | +| `service.nodePort` | Specify the nodePort value for the LoadBalancer and NodePort service types | `""` | +| `service.annotations` | Annotations for PostgreSQL service | `{}` | +| `service.loadBalancerIP` | Load balancer IP if service type is `LoadBalancer` | `""` | +| `service.externalTrafficPolicy` | Enable client source IP preservation | `Cluster` | +| `service.loadBalancerSourceRanges` | Addresses that are allowed when service is LoadBalancer | `[]` | +| `shmVolume.enabled` | Enable emptyDir volume for /dev/shm for primary and read replica(s) Pod(s) | `true` | +| `shmVolume.chmod.enabled` | Set to `true` to `chmod 777 /dev/shm` on a initContainer (ignored if `volumePermissions.enabled` is `false`) | `true` | +| `shmVolume.sizeLimit` | Set this to enable a size limit on the shm tmpfs. Note that the size of the tmpfs counts against container's memory limit | `""` | +| `persistence.enabled` | Enable persistence using PVC | `true` | +| `persistence.existingClaim` | Provide an existing `PersistentVolumeClaim`, the value is evaluated as a template. | `""` | +| `persistence.mountPath` | The path the volume will be mounted at, useful when using different | `/bitnami/postgresql` | +| `persistence.subPath` | The subdirectory of the volume to mount to | `""` | +| `persistence.storageClass` | PVC Storage Class for PostgreSQL volume | `""` | +| `persistence.accessModes` | PVC Access Mode for PostgreSQL volume | `["ReadWriteOnce"]` | +| `persistence.size` | PVC Storage Request for PostgreSQL volume | `8Gi` | +| `persistence.annotations` | Annotations for the PVC | `{}` | +| `persistence.selector` | Selector to match an existing Persistent Volume (this value is evaluated as a template) | `{}` | +| `updateStrategy.type` | updateStrategy for PostgreSQL StatefulSet and its reads StatefulSets | `RollingUpdate` | +| `primary.podAffinityPreset` | PostgreSQL primary pod affinity preset. Ignored if `primary.affinity` is set. Allowed values: `soft` or `hard` | `""` | +| `primary.podAntiAffinityPreset` | PostgreSQL primary pod anti-affinity preset. Ignored if `primary.affinity` is set. Allowed values: `soft` or `hard` | `soft` | +| `primary.nodeAffinityPreset.type` | PostgreSQL primary node affinity preset type. Ignored if `primary.affinity` is set. Allowed values: `soft` or `hard` | `""` | +| `primary.nodeAffinityPreset.key` | PostgreSQL primary node label key to match Ignored if `primary.affinity` is set. | `""` | +| `primary.nodeAffinityPreset.values` | PostgreSQL primary node label values to match. Ignored if `primary.affinity` is set. | `[]` | +| `primary.affinity` | Affinity for PostgreSQL primary pods assignment | `{}` | +| `primary.nodeSelector` | Node labels for PostgreSQL primary pods assignment | `{}` | +| `primary.tolerations` | Tolerations for PostgreSQL primary pods assignment | `[]` | +| `primary.extraPodSpec` | Optionally specify extra PodSpec | `{}` | +| `primary.labels` | Map of labels to add to the statefulset (postgresql primary) | `{}` | +| `primary.annotations` | Annotations for PostgreSQL primary pods | `{}` | +| `primary.podLabels` | Map of labels to add to the pods (postgresql primary) | `{}` | +| `primary.podAnnotations` | Map of annotations to add to the pods (postgresql primary) | `{}` | +| `primary.priorityClassName` | Priority Class to use for each pod (postgresql primary) | `""` | +| `primary.extraInitContainers` | Extra init containers to add to the pods (postgresql primary) | `[]` | +| `primary.extraVolumeMounts` | Extra volume mounts to add to the pods (postgresql primary) | `[]` | +| `primary.extraVolumes` | Extra volumes to add to the pods (postgresql primary) | `[]` | +| `primary.sidecars` | Extra containers to the pod | `[]` | +| `primary.service.type` | Allows using a different service type for primary | `""` | +| `primary.service.nodePort` | Allows using a different nodePort for primary | `""` | +| `primary.service.clusterIP` | Allows using a different clusterIP for primary | `""` | +| `readReplicas.podAffinityPreset` | PostgreSQL read only pod affinity preset. Ignored if `primary.affinity` is set. Allowed values: `soft` or `hard` | `""` | +| `readReplicas.podAntiAffinityPreset` | PostgreSQL read only pod anti-affinity preset. Ignored if `primary.affinity` is set. Allowed values: `soft` or `hard` | `soft` | +| `readReplicas.nodeAffinityPreset.type` | PostgreSQL read only node affinity preset type. Ignored if `primary.affinity` is set. Allowed values: `soft` or `hard` | `""` | +| `readReplicas.nodeAffinityPreset.key` | PostgreSQL read only node label key to match Ignored if `primary.affinity` is set. | `""` | +| `readReplicas.nodeAffinityPreset.values` | PostgreSQL read only node label values to match. Ignored if `primary.affinity` is set. | `[]` | +| `readReplicas.affinity` | Affinity for PostgreSQL read only pods assignment | `{}` | +| `readReplicas.nodeSelector` | Node labels for PostgreSQL read only pods assignment | `{}` | +| `readReplicas.tolerations` | Tolerations for PostgreSQL read only pods assignment | `[]` | +| `readReplicas.topologySpreadConstraints` | Topology Spread Constraints for pod assignment spread across your cluster among failure-domains. Evaluated as a template | `[]` | +| `readReplicas.extraPodSpec` | Optionally specify extra PodSpec | `{}` | +| `readReplicas.labels` | Map of labels to add to the statefulsets (postgresql readReplicas) | `{}` | +| `readReplicas.annotations` | Annotations for PostgreSQL read only pods | `{}` | +| `readReplicas.podLabels` | Map of labels to add to the pods (postgresql readReplicas) | `{}` | +| `readReplicas.podAnnotations` | Map of annotations to add to the pods (postgresql readReplicas) | `{}` | +| `readReplicas.priorityClassName` | Priority Class to use for each pod (postgresql readReplicas) | `""` | +| `readReplicas.extraInitContainers` | Extra init containers to add to the pods (postgresql readReplicas) | `[]` | +| `readReplicas.extraVolumeMounts` | Extra volume mounts to add to the pods (postgresql readReplicas) | `[]` | +| `readReplicas.extraVolumes` | Extra volumes to add to the pods (postgresql readReplicas) | `[]` | +| `readReplicas.sidecars` | Extra containers to the pod | `[]` | +| `readReplicas.service.type` | Allows using a different service type for readReplicas | `""` | +| `readReplicas.service.nodePort` | Allows using a different nodePort for readReplicas | `""` | +| `readReplicas.service.clusterIP` | Allows using a different clusterIP for readReplicas | `""` | +| `readReplicas.persistence.enabled` | Whether to enable PostgreSQL read replicas replicas persistence | `true` | +| `readReplicas.resources` | CPU/Memory resource requests/limits override for readReplicass. Will fallback to `values.resources` if not defined. | `{}` | +| `resources.requests` | The requested resources for the container | `{}` | +| `networkPolicy.enabled` | Enable creation of NetworkPolicy resources. Only Ingress traffic is filtered for now. | `false` | +| `networkPolicy.allowExternal` | Don't require client label for connections | `true` | +| `networkPolicy.explicitNamespacesSelector` | A Kubernetes LabelSelector to explicitly select namespaces from which ingress traffic could be allowed | `{}` | +| `startupProbe.enabled` | Enable startupProbe | `false` | +| `startupProbe.initialDelaySeconds` | Initial delay seconds for startupProbe | `30` | +| `startupProbe.periodSeconds` | Period seconds for startupProbe | `15` | +| `startupProbe.timeoutSeconds` | Timeout seconds for startupProbe | `5` | +| `startupProbe.failureThreshold` | Failure threshold for startupProbe | `10` | +| `startupProbe.successThreshold` | Success threshold for startupProbe | `1` | +| `livenessProbe.enabled` | Enable livenessProbe | `true` | +| `livenessProbe.initialDelaySeconds` | Initial delay seconds for livenessProbe | `30` | +| `livenessProbe.periodSeconds` | Period seconds for livenessProbe | `10` | +| `livenessProbe.timeoutSeconds` | Timeout seconds for livenessProbe | `5` | +| `livenessProbe.failureThreshold` | Failure threshold for livenessProbe | `6` | +| `livenessProbe.successThreshold` | Success threshold for livenessProbe | `1` | +| `readinessProbe.enabled` | Enable readinessProbe | `true` | +| `readinessProbe.initialDelaySeconds` | Initial delay seconds for readinessProbe | `5` | +| `readinessProbe.periodSeconds` | Period seconds for readinessProbe | `10` | +| `readinessProbe.timeoutSeconds` | Timeout seconds for readinessProbe | `5` | +| `readinessProbe.failureThreshold` | Failure threshold for readinessProbe | `6` | +| `readinessProbe.successThreshold` | Success threshold for readinessProbe | `1` | +| `customStartupProbe` | Override default startup probe | `{}` | +| `customLivenessProbe` | Override default liveness probe | `{}` | +| `customReadinessProbe` | Override default readiness probe | `{}` | +| `tls.enabled` | Enable TLS traffic support | `false` | +| `tls.autoGenerated` | Generate automatically self-signed TLS certificates | `false` | +| `tls.preferServerCiphers` | Whether to use the server's TLS cipher preferences rather than the client's | `true` | +| `tls.certificatesSecret` | Name of an existing secret that contains the certificates | `""` | +| `tls.certFilename` | Certificate filename | `""` | +| `tls.certKeyFilename` | Certificate key filename | `""` | +| `tls.certCAFilename` | CA Certificate filename | `""` | +| `tls.crlFilename` | File containing a Certificate Revocation List | `""` | +| `metrics.enabled` | Start a prometheus exporter | `false` | +| `metrics.resources` | Prometheus exporter container resources | `{}` | +| `metrics.service.type` | Kubernetes Service type | `ClusterIP` | +| `metrics.service.annotations` | Additional annotations for metrics exporter pod | `{}` | +| `metrics.service.loadBalancerIP` | loadBalancerIP if redis metrics service type is `LoadBalancer` | `""` | +| `metrics.serviceMonitor.enabled` | Set this to `true` to create ServiceMonitor for Prometheus operator | `false` | +| `metrics.serviceMonitor.additionalLabels` | Additional labels that can be used so ServiceMonitor will be discovered by Prometheus | `{}` | +| `metrics.serviceMonitor.namespace` | Optional namespace in which to create ServiceMonitor | `""` | +| `metrics.serviceMonitor.interval` | Scrape interval. If not set, the Prometheus default scrape interval is used | `""` | +| `metrics.serviceMonitor.scrapeTimeout` | Scrape timeout. If not set, the Prometheus default scrape timeout is used | `""` | +| `metrics.serviceMonitor.relabelings` | RelabelConfigs to apply to samples before scraping | `[]` | +| `metrics.serviceMonitor.metricRelabelings` | MetricRelabelConfigs to apply to samples before ingestion | `[]` | +| `metrics.prometheusRule.enabled` | Set this to true to create prometheusRules for Prometheus operator | `false` | +| `metrics.prometheusRule.additionalLabels` | Additional labels that can be used so prometheusRules will be discovered by Prometheus | `{}` | +| `metrics.prometheusRule.namespace` | namespace where prometheusRules resource should be created | `""` | +| `metrics.prometheusRule.rules` | Create specified [Rules](https://prometheus.io/docs/prometheus/latest/configuration/alerting_rules/) | `[]` | +| `metrics.image.registry` | PostgreSQL Exporter image registry | `docker.io` | +| `metrics.image.repository` | PostgreSQL Exporter image repository | `bitnami/postgres-exporter` | +| `metrics.image.tag` | PostgreSQL Exporter image tag (immutable tags are recommended) | `0.10.0-debian-10-r133` | +| `metrics.image.pullPolicy` | PostgreSQL Exporter image pull policy | `IfNotPresent` | +| `metrics.image.pullSecrets` | Specify image pull secrets | `[]` | +| `metrics.customMetrics` | Define additional custom metrics | `{}` | +| `metrics.extraEnvVars` | Extra environment variables to add to postgres-exporter | `[]` | +| `metrics.securityContext.enabled` | Enable security context for metrics | `false` | +| `metrics.securityContext.runAsUser` | User ID for the container for metrics | `1001` | +| `metrics.livenessProbe.enabled` | Enable livenessProbe | `true` | +| `metrics.livenessProbe.initialDelaySeconds` | Initial delay seconds for livenessProbe | `5` | +| `metrics.livenessProbe.periodSeconds` | Period seconds for livenessProbe | `10` | +| `metrics.livenessProbe.timeoutSeconds` | Timeout seconds for livenessProbe | `5` | +| `metrics.livenessProbe.failureThreshold` | Failure threshold for livenessProbe | `6` | +| `metrics.livenessProbe.successThreshold` | Success threshold for livenessProbe | `1` | +| `metrics.readinessProbe.enabled` | Enable readinessProbe | `true` | +| `metrics.readinessProbe.initialDelaySeconds` | Initial delay seconds for readinessProbe | `5` | +| `metrics.readinessProbe.periodSeconds` | Period seconds for readinessProbe | `10` | +| `metrics.readinessProbe.timeoutSeconds` | Timeout seconds for readinessProbe | `5` | +| `metrics.readinessProbe.failureThreshold` | Failure threshold for readinessProbe | `6` | +| `metrics.readinessProbe.successThreshold` | Success threshold for readinessProbe | `1` | + + +Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example, + +```console +$ helm install my-release \ + --set postgresqlPassword=secretpassword,postgresqlDatabase=my-database \ + bitnami/postgresql +``` + +The above command sets the PostgreSQL `postgres` account password to `secretpassword`. Additionally it creates a database named `my-database`. + +> NOTE: Once this chart is deployed, it is not possible to change the application's access credentials, such as usernames or passwords, using Helm. To change these application credentials after deployment, delete any persistent volumes (PVs) used by the chart and re-deploy it, or use the application's built-in administrative tools if available. + +Alternatively, a YAML file that specifies the values for the parameters can be provided while installing the chart. For example, + +```console +$ helm install my-release -f values.yaml bitnami/postgresql +``` + +> **Tip**: You can use the default [values.yaml](values.yaml) + +## Configuration and installation details + +### [Rolling VS Immutable tags](https://docs.bitnami.com/containers/how-to/understand-rolling-tags-containers/) + +It is strongly recommended to use immutable tags in a production environment. This ensures your deployment does not change automatically if the same tag is updated with a different image. + +Bitnami will release a new chart updating its containers if a new version of the main container, significant changes, or critical vulnerabilities exist. + +### Customizing primary and read replica services in a replicated configuration + +At the top level, there is a service object which defines the services for both primary and readReplicas. For deeper customization, there are service objects for both the primary and read types individually. This allows you to override the values in the top level service object so that the primary and read can be of different service types and with different clusterIPs / nodePorts. Also in the case you want the primary and read to be of type nodePort, you will need to set the nodePorts to different values to prevent a collision. The values that are deeper in the primary.service or readReplicas.service objects will take precedence over the top level service object. + +### Use a different PostgreSQL version + +To modify the application version used in this chart, specify a different version of the image using the `image.tag` parameter and/or a different repository using the `image.repository` parameter. Refer to the [chart documentation for more information on these parameters and how to use them with images from a private registry](https://docs.bitnami.com/kubernetes/infrastructure/postgresql/configuration/change-image-version/). + +### postgresql.conf / pg_hba.conf files as configMap + +This helm chart also supports to customize the whole configuration file. + +Add your custom file to "files/postgresql.conf" in your working directory. This file will be mounted as configMap to the containers and it will be used for configuring the PostgreSQL server. + +Alternatively, you can add additional PostgreSQL configuration parameters using the `postgresqlExtendedConf` parameter as a dict, using camelCase, e.g. {"sharedBuffers": "500MB"}. Alternatively, to replace the entire default configuration use `postgresqlConfiguration`. + +In addition to these options, you can also set an external ConfigMap with all the configuration files. This is done by setting the `configurationConfigMap` parameter. Note that this will override the two previous options. + +### Allow settings to be loaded from files other than the default `postgresql.conf` + +If you don't want to provide the whole PostgreSQL configuration file and only specify certain parameters, you can add your extended `.conf` files to "files/conf.d/" in your working directory. +Those files will be mounted as configMap to the containers adding/overwriting the default configuration using the `include_dir` directive that allows settings to be loaded from files other than the default `postgresql.conf`. + +Alternatively, you can also set an external ConfigMap with all the extra configuration files. This is done by setting the `extendedConfConfigMap` parameter. Note that this will override the previous option. + +### Initialize a fresh instance + +The [Bitnami PostgreSQL](https://github.com/bitnami/bitnami-docker-postgresql) image allows you to use your custom scripts to initialize a fresh instance. In order to execute the scripts, they must be located inside the chart folder `files/docker-entrypoint-initdb.d` so they can be consumed as a ConfigMap. + +Alternatively, you can specify custom scripts using the `initdbScripts` parameter as dict. + +In addition to these options, you can also set an external ConfigMap with all the initialization scripts. This is done by setting the `initdbScriptsConfigMap` parameter. Note that this will override the two previous options. If your initialization scripts contain sensitive information such as credentials or passwords, you can use the `initdbScriptsSecret` parameter. + +The allowed extensions are `.sh`, `.sql` and `.sql.gz`. + +### Securing traffic using TLS + +TLS support can be enabled in the chart by specifying the `tls.` parameters while creating a release. The following parameters should be configured to properly enable the TLS support in the chart: + +- `tls.enabled`: Enable TLS support. Defaults to `false` +- `tls.certificatesSecret`: Name of an existing secret that contains the certificates. No defaults. +- `tls.certFilename`: Certificate filename. No defaults. +- `tls.certKeyFilename`: Certificate key filename. No defaults. + +For example: + +* First, create the secret with the cetificates files: + + ```console + kubectl create secret generic certificates-tls-secret --from-file=./cert.crt --from-file=./cert.key --from-file=./ca.crt + ``` + +* Then, use the following parameters: + + ```console + volumePermissions.enabled=true + tls.enabled=true + tls.certificatesSecret="certificates-tls-secret" + tls.certFilename="cert.crt" + tls.certKeyFilename="cert.key" + ``` + + > Note TLS and VolumePermissions: PostgreSQL requires certain permissions on sensitive files (such as certificate keys) to start up. Due to an on-going [issue](https://github.com/kubernetes/kubernetes/issues/57923) regarding kubernetes permissions and the use of `containerSecurityContext.runAsUser`, you must enable `volumePermissions` to ensure everything works as expected. + +### Sidecars + +If you need additional containers to run within the same pod as PostgreSQL (e.g. an additional metrics or logging exporter), you can do so via the `sidecars` config parameter. Simply define your container according to the Kubernetes container spec. + +```yaml +# For the PostgreSQL primary +primary: + sidecars: + - name: your-image-name + image: your-image + imagePullPolicy: Always + ports: + - name: portname + containerPort: 1234 +# For the PostgreSQL replicas +readReplicas: + sidecars: + - name: your-image-name + image: your-image + imagePullPolicy: Always + ports: + - name: portname + containerPort: 1234 +``` + +### Metrics + +The chart optionally can start a metrics exporter for [prometheus](https://prometheus.io). The metrics endpoint (port 9187) is not exposed and it is expected that the metrics are collected from inside the k8s cluster using something similar as the described in the [example Prometheus scrape configuration](https://github.com/prometheus/prometheus/blob/master/documentation/examples/prometheus-kubernetes.yml). + +The exporter allows to create custom metrics from additional SQL queries. See the Chart's `values.yaml` for an example and consult the [exporters documentation](https://github.com/wrouesnel/postgres_exporter#adding-new-metrics-via-a-config-file) for more details. + +### Use of global variables + +In more complex scenarios, we may have the following tree of dependencies + +``` + +--------------+ + | | + +------------+ Chart 1 +-----------+ + | | | | + | --------+------+ | + | | | + | | | + | | | + | | | + v v v ++-------+------+ +--------+------+ +--------+------+ +| | | | | | +| PostgreSQL | | Sub-chart 1 | | Sub-chart 2 | +| | | | | | ++--------------+ +---------------+ +---------------+ +``` + +The three charts below depend on the parent chart Chart 1. However, subcharts 1 and 2 may need to connect to PostgreSQL as well. In order to do so, subcharts 1 and 2 need to know the PostgreSQL credentials, so one option for deploying could be deploy Chart 1 with the following parameters: + +``` +postgresql.postgresqlPassword=testtest +subchart1.postgresql.postgresqlPassword=testtest +subchart2.postgresql.postgresqlPassword=testtest +postgresql.postgresqlDatabase=db1 +subchart1.postgresql.postgresqlDatabase=db1 +subchart2.postgresql.postgresqlDatabase=db1 +``` + +If the number of dependent sub-charts increases, installing the chart with parameters can become increasingly difficult. An alternative would be to set the credentials using global variables as follows: + +``` +global.postgresql.postgresqlPassword=testtest +global.postgresql.postgresqlDatabase=db1 +``` + +This way, the credentials will be available in all of the subcharts. + +## Persistence + +The [Bitnami PostgreSQL](https://github.com/bitnami/bitnami-docker-postgresql) image stores the PostgreSQL data and configurations at the `/bitnami/postgresql` path of the container. + +Persistent Volume Claims are used to keep the data across deployments. This is known to work in GCE, AWS, and minikube. +See the [Parameters](#parameters) section to configure the PVC or to disable persistence. + +If you already have data in it, you will fail to sync to standby nodes for all commits, details can refer to [code](https://github.com/bitnami/bitnami-docker-postgresql/blob/8725fe1d7d30ebe8d9a16e9175d05f7ad9260c93/9.6/debian-9/rootfs/libpostgresql.sh#L518-L556). If you need to use those data, please covert them to sql and import after `helm install` finished. + +## NetworkPolicy + +To enable network policy for PostgreSQL, install [a networking plugin that implements the Kubernetes NetworkPolicy spec](https://kubernetes.io/docs/tasks/administer-cluster/declare-network-policy#before-you-begin), and set `networkPolicy.enabled` to `true`. + +For Kubernetes v1.5 & v1.6, you must also turn on NetworkPolicy by setting the DefaultDeny namespace annotation. Note: this will enforce policy for _all_ pods in the namespace: + +```console +$ kubectl annotate namespace default "net.beta.kubernetes.io/network-policy={\"ingress\":{\"isolation\":\"DefaultDeny\"}}" +``` + +With NetworkPolicy enabled, traffic will be limited to just port 5432. + +For more precise policy, set `networkPolicy.allowExternal=false`. This will only allow pods with the generated client label to connect to PostgreSQL. +This label will be displayed in the output of a successful install. + +## Differences between Bitnami PostgreSQL image and [Docker Official](https://hub.docker.com/_/postgres) image + +- The Docker Official PostgreSQL image does not support replication. If you pass any replication environment variable, this would be ignored. The only environment variables supported by the Docker Official image are POSTGRES_USER, POSTGRES_DB, POSTGRES_PASSWORD, POSTGRES_INITDB_ARGS, POSTGRES_INITDB_WALDIR and PGDATA. All the remaining environment variables are specific to the Bitnami PostgreSQL image. +- The Bitnami PostgreSQL image is non-root by default. This requires that you run the pod with `securityContext` and updates the permissions of the volume with an `initContainer`. A key benefit of this configuration is that the pod follows security best practices and is prepared to run on Kubernetes distributions with hard security constraints like OpenShift. +- For OpenShift, one may either define the runAsUser and fsGroup accordingly, or try this more dynamic option: volumePermissions.securityContext.runAsUser="auto",securityContext.enabled=false,containerSecurityContext.enabled=false,shmVolume.chmod.enabled=false + +### Deploy chart using Docker Official PostgreSQL Image + +From chart version 4.0.0, it is possible to use this chart with the Docker Official PostgreSQL image. +Besides specifying the new Docker repository and tag, it is important to modify the PostgreSQL data directory and volume mount point. Basically, the PostgreSQL data dir cannot be the mount point directly, it has to be a subdirectory. + +``` +image.repository=postgres +image.tag=10.6 +postgresqlDataDir=/data/pgdata +persistence.mountPath=/data/ +``` + +### Setting Pod's affinity + +This chart allows you to set your custom affinity using the `XXX.affinity` paremeter(s). Find more infomation about Pod's affinity in the [kubernetes documentation](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity). + +As an alternative, you can use of the preset configurations for pod affinity, pod anti-affinity, and node affinity available at the [bitnami/common](https://github.com/bitnami/charts/tree/master/bitnami/common#affinities) chart. To do so, set the `XXX.podAffinityPreset`, `XXX.podAntiAffinityPreset`, or `XXX.nodeAffinityPreset` parameters. + +## Troubleshooting + +Find more information about how to deal with common errors related to Bitnami’s Helm charts in [this troubleshooting guide](https://docs.bitnami.com/general/how-to/troubleshoot-helm-chart-issues). + +## Upgrading + +It's necessary to specify the existing passwords while performing an upgrade to ensure the secrets are not updated with invalid randomly generated passwords. Remember to specify the existing values of the `postgresqlPassword` and `replication.password` parameters when upgrading the chart: + +```bash +$ helm upgrade my-release bitnami/postgresql \ + --set postgresqlPassword=[POSTGRESQL_PASSWORD] \ + --set replication.password=[REPLICATION_PASSWORD] +``` + +> Note: you need to substitute the placeholders _[POSTGRESQL_PASSWORD]_, and _[REPLICATION_PASSWORD]_ with the values obtained from instructions in the installation notes. + +### To 10.0.0 + +[On November 13, 2020, Helm v2 support was formally finished](https://github.com/helm/charts#status-of-the-project), this major version is the result of the required changes applied to the Helm Chart to be able to incorporate the different features added in Helm v3 and to be consistent with the Helm project itself regarding the Helm v2 EOL. + +**What changes were introduced in this major version?** + +- Previous versions of this Helm Chart use `apiVersion: v1` (installable by both Helm 2 and 3), this Helm Chart was updated to `apiVersion: v2` (installable by Helm 3 only). [Here](https://helm.sh/docs/topics/charts/#the-apiversion-field) you can find more information about the `apiVersion` field. +- Move dependency information from the *requirements.yaml* to the *Chart.yaml* +- After running `helm dependency update`, a *Chart.lock* file is generated containing the same structure used in the previous *requirements.lock* +- The different fields present in the *Chart.yaml* file has been ordered alphabetically in a homogeneous way for all the Bitnami Helm Chart. + +**Considerations when upgrading to this version** + +- If you want to upgrade to this version using Helm v2, this scenario is not supported as this version doesn't support Helm v2 anymore +- If you installed the previous version with Helm v2 and wants to upgrade to this version with Helm v3, please refer to the [official Helm documentation](https://helm.sh/docs/topics/v2_v3_migration/#migration-use-cases) about migrating from Helm v2 to v3 + +**Useful links** + +- https://docs.bitnami.com/tutorials/resolve-helm2-helm3-post-migration-issues/ +- https://helm.sh/docs/topics/v2_v3_migration/ +- https://helm.sh/blog/migrate-from-helm-v2-to-helm-v3/ + +#### Breaking changes + +- The term `master` has been replaced with `primary` and `slave` with `readReplicas` throughout the chart. Role names have changed from `master` and `slave` to `primary` and `read`. + +To upgrade to `10.0.0`, it should be done reusing the PVCs used to hold the PostgreSQL data on your previous release. To do so, follow the instructions below (the following example assumes that the release name is `postgresql`): + +> NOTE: Please, create a backup of your database before running any of those actions. + +Obtain the credentials and the names of the PVCs used to hold the PostgreSQL data on your current release: + +```console +$ export POSTGRESQL_PASSWORD=$(kubectl get secret --namespace default postgresql -o jsonpath="{.data.postgresql-password}" | base64 --decode) +$ export POSTGRESQL_PVC=$(kubectl get pvc -l app.kubernetes.io/instance=postgresql,role=master -o jsonpath="{.items[0].metadata.name}") +``` + +Delete the PostgreSQL statefulset. Notice the option `--cascade=false`: + +```console +$ kubectl delete statefulsets.apps postgresql-postgresql --cascade=false +``` + +Now the upgrade works: + +```console +$ helm upgrade postgresql bitnami/postgresql --set postgresqlPassword=$POSTGRESQL_PASSWORD --set persistence.existingClaim=$POSTGRESQL_PVC +``` + +You will have to delete the existing PostgreSQL pod and the new statefulset is going to create a new one + +```console +$ kubectl delete pod postgresql-postgresql-0 +``` + +Finally, you should see the lines below in PostgreSQL container logs: + +```console +$ kubectl logs $(kubectl get pods -l app.kubernetes.io/instance=postgresql,app.kubernetes.io/name=postgresql,role=primary -o jsonpath="{.items[0].metadata.name}") +... +postgresql 08:05:12.59 INFO ==> Deploying PostgreSQL with persisted data... +... +``` + +### To 9.0.0 + +In this version the chart was adapted to follow the Helm label best practices, see [PR 3021](https://github.com/bitnami/charts/pull/3021). That means the backward compatibility is not guarantee when upgrading the chart to this major version. + +As a workaround, you can delete the existing statefulset (using the `--cascade=false` flag pods are not deleted) before upgrade the chart. For example, this can be a valid workflow: + +- Deploy an old version (8.X.X) + +```console +$ helm install postgresql bitnami/postgresql --version 8.10.14 +``` + +- Old version is up and running + +```console +$ helm ls +NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION +postgresql default 1 2020-08-04 13:39:54.783480286 +0000 UTC deployed postgresql-8.10.14 11.8.0 + +$ kubectl get pods +NAME READY STATUS RESTARTS AGE +postgresql-postgresql-0 1/1 Running 0 76s +``` + +- The upgrade to the latest one (9.X.X) is going to fail + +```console +$ helm upgrade postgresql bitnami/postgresql +Error: UPGRADE FAILED: cannot patch "postgresql-postgresql" with kind StatefulSet: StatefulSet.apps "postgresql-postgresql" is invalid: spec: Forbidden: updates to statefulset spec for fields other than 'replicas', 'template', and 'updateStrategy' are forbidden +``` + +- Delete the statefulset + +```console +$ kubectl delete statefulsets.apps --cascade=false postgresql-postgresql +statefulset.apps "postgresql-postgresql" deleted +``` + +- Now the upgrade works + +```console +$ helm upgrade postgresql bitnami/postgresql +$ helm ls +NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION +postgresql default 3 2020-08-04 13:42:08.020385884 +0000 UTC deployed postgresql-9.1.2 11.8.0 +``` + +- We can kill the existing pod and the new statefulset is going to create a new one: + +```console +$ kubectl delete pod postgresql-postgresql-0 +pod "postgresql-postgresql-0" deleted + +$ kubectl get pods +NAME READY STATUS RESTARTS AGE +postgresql-postgresql-0 1/1 Running 0 19s +``` + +Please, note that without the `--cascade=false` both objects (statefulset and pod) are going to be removed and both objects will be deployed again with the `helm upgrade` command + +### To 8.0.0 + +Prefixes the port names with their protocols to comply with Istio conventions. + +If you depend on the port names in your setup, make sure to update them to reflect this change. + +### To 7.1.0 + +Adds support for LDAP configuration. + +### To 7.0.0 + +Helm performs a lookup for the object based on its group (apps), version (v1), and kind (Deployment). Also known as its GroupVersionKind, or GVK. Changing the GVK is considered a compatibility breaker from Kubernetes' point of view, so you cannot "upgrade" those objects to the new GVK in-place. Earlier versions of Helm 3 did not perform the lookup correctly which has since been fixed to match the spec. + +In https://github.com/helm/charts/pull/17281 the `apiVersion` of the statefulset resources was updated to `apps/v1` in tune with the api's deprecated, resulting in compatibility breakage. + +This major version bump signifies this change. + +### To 6.5.7 + +In this version, the chart will use PostgreSQL with the Postgis extension included. The version used with Postgresql version 10, 11 and 12 is Postgis 2.5. It has been compiled with the following dependencies: + +- protobuf +- protobuf-c +- json-c +- geos +- proj + +### To 5.0.0 + +In this version, the **chart is using PostgreSQL 11 instead of PostgreSQL 10**. You can find the main difference and notable changes in the following links: [https://www.postgresql.org/about/news/1894/](https://www.postgresql.org/about/news/1894/) and [https://www.postgresql.org/about/featurematrix/](https://www.postgresql.org/about/featurematrix/). + +For major releases of PostgreSQL, the internal data storage format is subject to change, thus complicating upgrades, you can see some errors like the following one in the logs: + +```console +Welcome to the Bitnami postgresql container +Subscribe to project updates by watching https://github.com/bitnami/bitnami-docker-postgresql +Submit issues and feature requests at https://github.com/bitnami/bitnami-docker-postgresql/issues +Send us your feedback at containers@bitnami.com + +INFO ==> ** Starting PostgreSQL setup ** +NFO ==> Validating settings in POSTGRESQL_* env vars.. +INFO ==> Initializing PostgreSQL database... +INFO ==> postgresql.conf file not detected. Generating it... +INFO ==> pg_hba.conf file not detected. Generating it... +INFO ==> Deploying PostgreSQL with persisted data... +INFO ==> Configuring replication parameters +INFO ==> Loading custom scripts... +INFO ==> Enabling remote connections +INFO ==> Stopping PostgreSQL... +INFO ==> ** PostgreSQL setup finished! ** + +INFO ==> ** Starting PostgreSQL ** + [1] FATAL: database files are incompatible with server + [1] DETAIL: The data directory was initialized by PostgreSQL version 10, which is not compatible with this version 11.3. +``` + +In this case, you should migrate the data from the old chart to the new one following an approach similar to that described in [this section](https://www.postgresql.org/docs/current/upgrading.html#UPGRADING-VIA-PGDUMPALL) from the official documentation. Basically, create a database dump in the old chart, move and restore it in the new one. + +### To 4.0.0 + +This chart will use by default the Bitnami PostgreSQL container starting from version `10.7.0-r68`. This version moves the initialization logic from node.js to bash. This new version of the chart requires setting the `POSTGRES_PASSWORD` in the slaves as well, in order to properly configure the `pg_hba.conf` file. Users from previous versions of the chart are advised to upgrade immediately. + +IMPORTANT: If you do not want to upgrade the chart version then make sure you use the `10.7.0-r68` version of the container. Otherwise, you will get this error + +``` +The POSTGRESQL_PASSWORD environment variable is empty or not set. Set the environment variable ALLOW_EMPTY_PASSWORD=yes to allow the container to be started with blank passwords. This is recommended only for development +``` + +### To 3.0.0 + +This releases make it possible to specify different nodeSelector, affinity and tolerations for master and slave pods. +It also fixes an issue with `postgresql.master.fullname` helper template not obeying fullnameOverride. + +#### Breaking changes + +- `affinty` has been renamed to `master.affinity` and `slave.affinity`. +- `tolerations` has been renamed to `master.tolerations` and `slave.tolerations`. +- `nodeSelector` has been renamed to `master.nodeSelector` and `slave.nodeSelector`. + +### To 2.0.0 + +In order to upgrade from the `0.X.X` branch to `1.X.X`, you should follow the below steps: + +- Obtain the service name (`SERVICE_NAME`) and password (`OLD_PASSWORD`) of the existing postgresql chart. You can find the instructions to obtain the password in the NOTES.txt, the service name can be obtained by running + +```console +$ kubectl get svc +``` + +- Install (not upgrade) the new version + +```console +$ helm repo update +$ helm install my-release bitnami/postgresql +``` + +- Connect to the new pod (you can obtain the name by running `kubectl get pods`): + +```console +$ kubectl exec -it NAME bash +``` + +- Once logged in, create a dump file from the previous database using `pg_dump`, for that we should connect to the previous postgresql chart: + +```console +$ pg_dump -h SERVICE_NAME -U postgres DATABASE_NAME > /tmp/backup.sql +``` + +After run above command you should be prompted for a password, this password is the previous chart password (`OLD_PASSWORD`). +This operation could take some time depending on the database size. + +- Once you have the backup file, you can restore it with a command like the one below: + +```console +$ psql -U postgres DATABASE_NAME < /tmp/backup.sql +``` + +In this case, you are accessing to the local postgresql, so the password should be the new one (you can find it in NOTES.txt). + +If you want to restore the database and the database schema does not exist, it is necessary to first follow the steps described below. + +```console +$ psql -U postgres +postgres=# drop database DATABASE_NAME; +postgres=# create database DATABASE_NAME; +postgres=# create user USER_NAME; +postgres=# alter role USER_NAME with password 'BITNAMI_USER_PASSWORD'; +postgres=# grant all privileges on database DATABASE_NAME to USER_NAME; +postgres=# alter database DATABASE_NAME owner to USER_NAME; +``` + +## License + +Copyright © 2022 Bitnami + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/helm/sonarqube/charts/postgresql/charts/common/.helmignore b/helm/sonarqube/charts/postgresql/charts/common/.helmignore new file mode 100644 index 0000000..50af031 --- /dev/null +++ b/helm/sonarqube/charts/postgresql/charts/common/.helmignore @@ -0,0 +1,22 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/helm/sonarqube/charts/postgresql/charts/common/Chart.yaml b/helm/sonarqube/charts/postgresql/charts/common/Chart.yaml new file mode 100644 index 0000000..cf934aa --- /dev/null +++ b/helm/sonarqube/charts/postgresql/charts/common/Chart.yaml @@ -0,0 +1,23 @@ +annotations: + category: Infrastructure +apiVersion: v2 +appVersion: 1.10.0 +description: A Library Helm Chart for grouping common logic between bitnami charts. + This chart is not deployable by itself. +home: https://github.com/bitnami/charts/tree/master/bitnami/common +icon: https://bitnami.com/downloads/logos/bitnami-mark.png +keywords: +- common +- helper +- template +- function +- bitnami +maintainers: +- email: containers@bitnami.com + name: Bitnami +name: common +sources: +- https://github.com/bitnami/charts +- https://www.bitnami.com/ +type: library +version: 1.10.3 diff --git a/helm/sonarqube/charts/postgresql/charts/common/README.md b/helm/sonarqube/charts/postgresql/charts/common/README.md new file mode 100644 index 0000000..cbbc31d --- /dev/null +++ b/helm/sonarqube/charts/postgresql/charts/common/README.md @@ -0,0 +1,328 @@ +# Bitnami Common Library Chart + +A [Helm Library Chart](https://helm.sh/docs/topics/library_charts/#helm) for grouping common logic between bitnami charts. + +## TL;DR + +```yaml +dependencies: + - name: common + version: 0.x.x + repository: https://charts.bitnami.com/bitnami +``` + +```bash +$ helm dependency update +``` + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "common.names.fullname" . }} +data: + myvalue: "Hello World" +``` + +## Introduction + +This chart provides a common template helpers which can be used to develop new charts using [Helm](https://helm.sh) package manager. + +Bitnami charts can be used with [Kubeapps](https://kubeapps.com/) for deployment and management of Helm Charts in clusters. This Helm chart has been tested on top of [Bitnami Kubernetes Production Runtime](https://kubeprod.io/) (BKPR). Deploy BKPR to get automated TLS certificates, logging and monitoring for your applications. + +## Prerequisites + +- Kubernetes 1.12+ +- Helm 3.1.0 + +## Parameters + +The following table lists the helpers available in the library which are scoped in different sections. + +### Affinities + +| Helper identifier | Description | Expected Input | +|-------------------------------|------------------------------------------------------|------------------------------------------------| +| `common.affinities.node.soft` | Return a soft nodeAffinity definition | `dict "key" "FOO" "values" (list "BAR" "BAZ")` | +| `common.affinities.node.hard` | Return a hard nodeAffinity definition | `dict "key" "FOO" "values" (list "BAR" "BAZ")` | +| `common.affinities.pod.soft` | Return a soft podAffinity/podAntiAffinity definition | `dict "component" "FOO" "context" $` | +| `common.affinities.pod.hard` | Return a hard podAffinity/podAntiAffinity definition | `dict "component" "FOO" "context" $` | + +### Capabilities + +| Helper identifier | Description | Expected Input | +|------------------------------------------------|------------------------------------------------------------------------------------------------|-------------------| +| `common.capabilities.kubeVersion` | Return the target Kubernetes version (using client default if .Values.kubeVersion is not set). | `.` Chart context | +| `common.capabilities.cronjob.apiVersion` | Return the appropriate apiVersion for cronjob. | `.` Chart context | +| `common.capabilities.deployment.apiVersion` | Return the appropriate apiVersion for deployment. | `.` Chart context | +| `common.capabilities.statefulset.apiVersion` | Return the appropriate apiVersion for statefulset. | `.` Chart context | +| `common.capabilities.ingress.apiVersion` | Return the appropriate apiVersion for ingress. | `.` Chart context | +| `common.capabilities.rbac.apiVersion` | Return the appropriate apiVersion for RBAC resources. | `.` Chart context | +| `common.capabilities.crd.apiVersion` | Return the appropriate apiVersion for CRDs. | `.` Chart context | +| `common.capabilities.policy.apiVersion` | Return the appropriate apiVersion for podsecuritypolicy. | `.` Chart context | +| `common.capabilities.networkPolicy.apiVersion` | Return the appropriate apiVersion for networkpolicy. | `.` Chart context | +| `common.capabilities.supportsHelmVersion` | Returns true if the used Helm version is 3.3+ | `.` Chart context | + +### Errors + +| Helper identifier | Description | Expected Input | +|-----------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------| +| `common.errors.upgrade.passwords.empty` | It will ensure required passwords are given when we are upgrading a chart. If `validationErrors` is not empty it will throw an error and will stop the upgrade action. | `dict "validationErrors" (list $validationError00 $validationError01) "context" $` | + +### Images + +| Helper identifier | Description | Expected Input | +|-----------------------------|------------------------------------------------------|---------------------------------------------------------------------------------------------------------| +| `common.images.image` | Return the proper and full image name | `dict "imageRoot" .Values.path.to.the.image "global" $`, see [ImageRoot](#imageroot) for the structure. | +| `common.images.pullSecrets` | Return the proper Docker Image Registry Secret Names (deprecated: use common.images.renderPullSecrets instead) | `dict "images" (list .Values.path.to.the.image1, .Values.path.to.the.image2) "global" .Values.global` | +| `common.images.renderPullSecrets` | Return the proper Docker Image Registry Secret Names (evaluates values as templates) | `dict "images" (list .Values.path.to.the.image1, .Values.path.to.the.image2) "context" $` | + +### Ingress + +| Helper identifier | Description | Expected Input | +|-------------------------------------------|----------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `common.ingress.backend` | Generate a proper Ingress backend entry depending on the API version | `dict "serviceName" "foo" "servicePort" "bar"`, see the [Ingress deprecation notice](https://kubernetes.io/blog/2019/07/18/api-deprecations-in-1-16/) for the syntax differences | +| `common.ingress.supportsPathType` | Prints "true" if the pathType field is supported | `.` Chart context | +| `common.ingress.supportsIngressClassname` | Prints "true" if the ingressClassname field is supported | `.` Chart context | + +### Labels + +| Helper identifier | Description | Expected Input | +|-----------------------------|------------------------------------------------------|-------------------| +| `common.labels.standard` | Return Kubernetes standard labels | `.` Chart context | +| `common.labels.matchLabels` | Return the proper Docker Image Registry Secret Names | `.` Chart context | + +### Names + +| Helper identifier | Description | Expected Input | +|-------------------------|------------------------------------------------------------|-------------------| +| `common.names.name` | Expand the name of the chart or use `.Values.nameOverride` | `.` Chart context | +| `common.names.fullname` | Create a default fully qualified app name. | `.` Chart context | +| `common.names.chart` | Chart name plus version | `.` Chart context | + +### Secrets + +| Helper identifier | Description | Expected Input | +|---------------------------|--------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `common.secrets.name` | Generate the name of the secret. | `dict "existingSecret" .Values.path.to.the.existingSecret "defaultNameSuffix" "mySuffix" "context" $` see [ExistingSecret](#existingsecret) for the structure. | +| `common.secrets.key` | Generate secret key. | `dict "existingSecret" .Values.path.to.the.existingSecret "key" "keyName"` see [ExistingSecret](#existingsecret) for the structure. | +| `common.passwords.manage` | Generate secret password or retrieve one if already created. | `dict "secret" "secret-name" "key" "keyName" "providedValues" (list "path.to.password1" "path.to.password2") "length" 10 "strong" false "chartName" "chartName" "context" $`, length, strong and chartNAme fields are optional. | +| `common.secrets.exists` | Returns whether a previous generated secret already exists. | `dict "secret" "secret-name" "context" $` | + +### Storage + +| Helper identifier | Description | Expected Input | +|-------------------------------|---------------------------------------|---------------------------------------------------------------------------------------------------------------------| +| `common.storage.class` | Return the proper Storage Class | `dict "persistence" .Values.path.to.the.persistence "global" $`, see [Persistence](#persistence) for the structure. | + +### TplValues + +| Helper identifier | Description | Expected Input | +|---------------------------|----------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------| +| `common.tplvalues.render` | Renders a value that contains template | `dict "value" .Values.path.to.the.Value "context" $`, value is the value should rendered as template, context frequently is the chart context `$` or `.` | + +### Utils + +| Helper identifier | Description | Expected Input | +|--------------------------------|------------------------------------------------------------------------------------------|------------------------------------------------------------------------| +| `common.utils.fieldToEnvVar` | Build environment variable name given a field. | `dict "field" "my-password"` | +| `common.utils.secret.getvalue` | Print instructions to get a secret value. | `dict "secret" "secret-name" "field" "secret-value-field" "context" $` | +| `common.utils.getValueFromKey` | Gets a value from `.Values` object given its key path | `dict "key" "path.to.key" "context" $` | +| `common.utils.getKeyFromList` | Returns first `.Values` key with a defined value or first of the list if all non-defined | `dict "keys" (list "path.to.key1" "path.to.key2") "context" $` | + +### Validations + +| Helper identifier | Description | Expected Input | +|--------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `common.validations.values.single.empty` | Validate a value must not be empty. | `dict "valueKey" "path.to.value" "secret" "secret.name" "field" "my-password" "subchart" "subchart" "context" $` secret, field and subchart are optional. In case they are given, the helper will generate a how to get instruction. See [ValidateValue](#validatevalue) | +| `common.validations.values.multiple.empty` | Validate a multiple values must not be empty. It returns a shared error for all the values. | `dict "required" (list $validateValueConf00 $validateValueConf01) "context" $`. See [ValidateValue](#validatevalue) | +| `common.validations.values.mariadb.passwords` | This helper will ensure required password for MariaDB are not empty. It returns a shared error for all the values. | `dict "secret" "mariadb-secret" "subchart" "true" "context" $` subchart field is optional and could be true or false it depends on where you will use mariadb chart and the helper. | +| `common.validations.values.postgresql.passwords` | This helper will ensure required password for PostgreSQL are not empty. It returns a shared error for all the values. | `dict "secret" "postgresql-secret" "subchart" "true" "context" $` subchart field is optional and could be true or false it depends on where you will use postgresql chart and the helper. | +| `common.validations.values.redis.passwords` | This helper will ensure required password for Redis™ are not empty. It returns a shared error for all the values. | `dict "secret" "redis-secret" "subchart" "true" "context" $` subchart field is optional and could be true or false it depends on where you will use redis chart and the helper. | +| `common.validations.values.cassandra.passwords` | This helper will ensure required password for Cassandra are not empty. It returns a shared error for all the values. | `dict "secret" "cassandra-secret" "subchart" "true" "context" $` subchart field is optional and could be true or false it depends on where you will use cassandra chart and the helper. | +| `common.validations.values.mongodb.passwords` | This helper will ensure required password for MongoDB® are not empty. It returns a shared error for all the values. | `dict "secret" "mongodb-secret" "subchart" "true" "context" $` subchart field is optional and could be true or false it depends on where you will use mongodb chart and the helper. | + +### Warnings + +| Helper identifier | Description | Expected Input | +|------------------------------|----------------------------------|------------------------------------------------------------| +| `common.warnings.rollingTag` | Warning about using rolling tag. | `ImageRoot` see [ImageRoot](#imageroot) for the structure. | + +## Special input schemas + +### ImageRoot + +```yaml +registry: + type: string + description: Docker registry where the image is located + example: docker.io + +repository: + type: string + description: Repository and image name + example: bitnami/nginx + +tag: + type: string + description: image tag + example: 1.16.1-debian-10-r63 + +pullPolicy: + type: string + description: Specify a imagePullPolicy. Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' + +pullSecrets: + type: array + items: + type: string + description: Optionally specify an array of imagePullSecrets (evaluated as templates). + +debug: + type: boolean + description: Set to true if you would like to see extra information on logs + example: false + +## An instance would be: +# registry: docker.io +# repository: bitnami/nginx +# tag: 1.16.1-debian-10-r63 +# pullPolicy: IfNotPresent +# debug: false +``` + +### Persistence + +```yaml +enabled: + type: boolean + description: Whether enable persistence. + example: true + +storageClass: + type: string + description: Ghost data Persistent Volume Storage Class, If set to "-", storageClassName: "" which disables dynamic provisioning. + example: "-" + +accessMode: + type: string + description: Access mode for the Persistent Volume Storage. + example: ReadWriteOnce + +size: + type: string + description: Size the Persistent Volume Storage. + example: 8Gi + +path: + type: string + description: Path to be persisted. + example: /bitnami + +## An instance would be: +# enabled: true +# storageClass: "-" +# accessMode: ReadWriteOnce +# size: 8Gi +# path: /bitnami +``` + +### ExistingSecret + +```yaml +name: + type: string + description: Name of the existing secret. + example: mySecret +keyMapping: + description: Mapping between the expected key name and the name of the key in the existing secret. + type: object + +## An instance would be: +# name: mySecret +# keyMapping: +# password: myPasswordKey +``` + +#### Example of use + +When we store sensitive data for a deployment in a secret, some times we want to give to users the possibility of using theirs existing secrets. + +```yaml +# templates/secret.yaml +--- +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "common.names.fullname" . }} + labels: + app: {{ include "common.names.fullname" . }} +type: Opaque +data: + password: {{ .Values.password | b64enc | quote }} + +# templates/dpl.yaml +--- +... + env: + - name: PASSWORD + valueFrom: + secretKeyRef: + name: {{ include "common.secrets.name" (dict "existingSecret" .Values.existingSecret "context" $) }} + key: {{ include "common.secrets.key" (dict "existingSecret" .Values.existingSecret "key" "password") }} +... + +# values.yaml +--- +name: mySecret +keyMapping: + password: myPasswordKey +``` + +### ValidateValue + +#### NOTES.txt + +```console +{{- $validateValueConf00 := (dict "valueKey" "path.to.value00" "secret" "secretName" "field" "password-00") -}} +{{- $validateValueConf01 := (dict "valueKey" "path.to.value01" "secret" "secretName" "field" "password-01") -}} + +{{ include "common.validations.values.multiple.empty" (dict "required" (list $validateValueConf00 $validateValueConf01) "context" $) }} +``` + +If we force those values to be empty we will see some alerts + +```console +$ helm install test mychart --set path.to.value00="",path.to.value01="" + 'path.to.value00' must not be empty, please add '--set path.to.value00=$PASSWORD_00' to the command. To get the current value: + + export PASSWORD_00=$(kubectl get secret --namespace default secretName -o jsonpath="{.data.password-00}" | base64 --decode) + + 'path.to.value01' must not be empty, please add '--set path.to.value01=$PASSWORD_01' to the command. To get the current value: + + export PASSWORD_01=$(kubectl get secret --namespace default secretName -o jsonpath="{.data.password-01}" | base64 --decode) +``` + +## Upgrading + +### To 1.0.0 + +[On November 13, 2020, Helm v2 support was formally finished](https://github.com/helm/charts#status-of-the-project), this major version is the result of the required changes applied to the Helm Chart to be able to incorporate the different features added in Helm v3 and to be consistent with the Helm project itself regarding the Helm v2 EOL. + +**What changes were introduced in this major version?** + +- Previous versions of this Helm Chart use `apiVersion: v1` (installable by both Helm 2 and 3), this Helm Chart was updated to `apiVersion: v2` (installable by Helm 3 only). [Here](https://helm.sh/docs/topics/charts/#the-apiversion-field) you can find more information about the `apiVersion` field. +- Use `type: library`. [Here](https://v3.helm.sh/docs/faq/#library-chart-support) you can find more information. +- The different fields present in the *Chart.yaml* file has been ordered alphabetically in a homogeneous way for all the Bitnami Helm Charts + +**Considerations when upgrading to this version** + +- If you want to upgrade to this version from a previous one installed with Helm v3, you shouldn't face any issues +- If you want to upgrade to this version using Helm v2, this scenario is not supported as this version doesn't support Helm v2 anymore +- If you installed the previous version with Helm v2 and wants to upgrade to this version with Helm v3, please refer to the [official Helm documentation](https://helm.sh/docs/topics/v2_v3_migration/#migration-use-cases) about migrating from Helm v2 to v3 + +**Useful links** + +- https://docs.bitnami.com/tutorials/resolve-helm2-helm3-post-migration-issues/ +- https://helm.sh/docs/topics/v2_v3_migration/ +- https://helm.sh/blog/migrate-from-helm-v2-to-helm-v3/ diff --git a/helm/sonarqube/charts/postgresql/charts/common/templates/_affinities.tpl b/helm/sonarqube/charts/postgresql/charts/common/templates/_affinities.tpl new file mode 100644 index 0000000..189ea40 --- /dev/null +++ b/helm/sonarqube/charts/postgresql/charts/common/templates/_affinities.tpl @@ -0,0 +1,102 @@ +{{/* vim: set filetype=mustache: */}} + +{{/* +Return a soft nodeAffinity definition +{{ include "common.affinities.nodes.soft" (dict "key" "FOO" "values" (list "BAR" "BAZ")) -}} +*/}} +{{- define "common.affinities.nodes.soft" -}} +preferredDuringSchedulingIgnoredDuringExecution: + - preference: + matchExpressions: + - key: {{ .key }} + operator: In + values: + {{- range .values }} + - {{ . | quote }} + {{- end }} + weight: 1 +{{- end -}} + +{{/* +Return a hard nodeAffinity definition +{{ include "common.affinities.nodes.hard" (dict "key" "FOO" "values" (list "BAR" "BAZ")) -}} +*/}} +{{- define "common.affinities.nodes.hard" -}} +requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: {{ .key }} + operator: In + values: + {{- range .values }} + - {{ . | quote }} + {{- end }} +{{- end -}} + +{{/* +Return a nodeAffinity definition +{{ include "common.affinities.nodes" (dict "type" "soft" "key" "FOO" "values" (list "BAR" "BAZ")) -}} +*/}} +{{- define "common.affinities.nodes" -}} + {{- if eq .type "soft" }} + {{- include "common.affinities.nodes.soft" . -}} + {{- else if eq .type "hard" }} + {{- include "common.affinities.nodes.hard" . -}} + {{- end -}} +{{- end -}} + +{{/* +Return a soft podAffinity/podAntiAffinity definition +{{ include "common.affinities.pods.soft" (dict "component" "FOO" "extraMatchLabels" .Values.extraMatchLabels "context" $) -}} +*/}} +{{- define "common.affinities.pods.soft" -}} +{{- $component := default "" .component -}} +{{- $extraMatchLabels := default (dict) .extraMatchLabels -}} +preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchLabels: {{- (include "common.labels.matchLabels" .context) | nindent 10 }} + {{- if not (empty $component) }} + {{ printf "app.kubernetes.io/component: %s" $component }} + {{- end }} + {{- range $key, $value := $extraMatchLabels }} + {{ $key }}: {{ $value | quote }} + {{- end }} + namespaces: + - {{ .context.Release.Namespace | quote }} + topologyKey: kubernetes.io/hostname + weight: 1 +{{- end -}} + +{{/* +Return a hard podAffinity/podAntiAffinity definition +{{ include "common.affinities.pods.hard" (dict "component" "FOO" "extraMatchLabels" .Values.extraMatchLabels "context" $) -}} +*/}} +{{- define "common.affinities.pods.hard" -}} +{{- $component := default "" .component -}} +{{- $extraMatchLabels := default (dict) .extraMatchLabels -}} +requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: {{- (include "common.labels.matchLabels" .context) | nindent 8 }} + {{- if not (empty $component) }} + {{ printf "app.kubernetes.io/component: %s" $component }} + {{- end }} + {{- range $key, $value := $extraMatchLabels }} + {{ $key }}: {{ $value | quote }} + {{- end }} + namespaces: + - {{ .context.Release.Namespace | quote }} + topologyKey: kubernetes.io/hostname +{{- end -}} + +{{/* +Return a podAffinity/podAntiAffinity definition +{{ include "common.affinities.pods" (dict "type" "soft" "key" "FOO" "values" (list "BAR" "BAZ")) -}} +*/}} +{{- define "common.affinities.pods" -}} + {{- if eq .type "soft" }} + {{- include "common.affinities.pods.soft" . -}} + {{- else if eq .type "hard" }} + {{- include "common.affinities.pods.hard" . -}} + {{- end -}} +{{- end -}} diff --git a/helm/sonarqube/charts/postgresql/charts/common/templates/_capabilities.tpl b/helm/sonarqube/charts/postgresql/charts/common/templates/_capabilities.tpl new file mode 100644 index 0000000..b94212b --- /dev/null +++ b/helm/sonarqube/charts/postgresql/charts/common/templates/_capabilities.tpl @@ -0,0 +1,128 @@ +{{/* vim: set filetype=mustache: */}} + +{{/* +Return the target Kubernetes version +*/}} +{{- define "common.capabilities.kubeVersion" -}} +{{- if .Values.global }} + {{- if .Values.global.kubeVersion }} + {{- .Values.global.kubeVersion -}} + {{- else }} + {{- default .Capabilities.KubeVersion.Version .Values.kubeVersion -}} + {{- end -}} +{{- else }} +{{- default .Capabilities.KubeVersion.Version .Values.kubeVersion -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for poddisruptionbudget. +*/}} +{{- define "common.capabilities.policy.apiVersion" -}} +{{- if semverCompare "<1.21-0" (include "common.capabilities.kubeVersion" .) -}} +{{- print "policy/v1beta1" -}} +{{- else -}} +{{- print "policy/v1" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for networkpolicy. +*/}} +{{- define "common.capabilities.networkPolicy.apiVersion" -}} +{{- if semverCompare "<1.7-0" (include "common.capabilities.kubeVersion" .) -}} +{{- print "extensions/v1beta1" -}} +{{- else -}} +{{- print "networking.k8s.io/v1" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for cronjob. +*/}} +{{- define "common.capabilities.cronjob.apiVersion" -}} +{{- if semverCompare "<1.21-0" (include "common.capabilities.kubeVersion" .) -}} +{{- print "batch/v1beta1" -}} +{{- else -}} +{{- print "batch/v1" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for deployment. +*/}} +{{- define "common.capabilities.deployment.apiVersion" -}} +{{- if semverCompare "<1.14-0" (include "common.capabilities.kubeVersion" .) -}} +{{- print "extensions/v1beta1" -}} +{{- else -}} +{{- print "apps/v1" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for statefulset. +*/}} +{{- define "common.capabilities.statefulset.apiVersion" -}} +{{- if semverCompare "<1.14-0" (include "common.capabilities.kubeVersion" .) -}} +{{- print "apps/v1beta1" -}} +{{- else -}} +{{- print "apps/v1" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for ingress. +*/}} +{{- define "common.capabilities.ingress.apiVersion" -}} +{{- if .Values.ingress -}} +{{- if .Values.ingress.apiVersion -}} +{{- .Values.ingress.apiVersion -}} +{{- else if semverCompare "<1.14-0" (include "common.capabilities.kubeVersion" .) -}} +{{- print "extensions/v1beta1" -}} +{{- else if semverCompare "<1.19-0" (include "common.capabilities.kubeVersion" .) -}} +{{- print "networking.k8s.io/v1beta1" -}} +{{- else -}} +{{- print "networking.k8s.io/v1" -}} +{{- end }} +{{- else if semverCompare "<1.14-0" (include "common.capabilities.kubeVersion" .) -}} +{{- print "extensions/v1beta1" -}} +{{- else if semverCompare "<1.19-0" (include "common.capabilities.kubeVersion" .) -}} +{{- print "networking.k8s.io/v1beta1" -}} +{{- else -}} +{{- print "networking.k8s.io/v1" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for RBAC resources. +*/}} +{{- define "common.capabilities.rbac.apiVersion" -}} +{{- if semverCompare "<1.17-0" (include "common.capabilities.kubeVersion" .) -}} +{{- print "rbac.authorization.k8s.io/v1beta1" -}} +{{- else -}} +{{- print "rbac.authorization.k8s.io/v1" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the appropriate apiVersion for CRDs. +*/}} +{{- define "common.capabilities.crd.apiVersion" -}} +{{- if semverCompare "<1.19-0" (include "common.capabilities.kubeVersion" .) -}} +{{- print "apiextensions.k8s.io/v1beta1" -}} +{{- else -}} +{{- print "apiextensions.k8s.io/v1" -}} +{{- end -}} +{{- end -}} + +{{/* +Returns true if the used Helm version is 3.3+. +A way to check the used Helm version was not introduced until version 3.3.0 with .Capabilities.HelmVersion, which contains an additional "{}}" structure. +This check is introduced as a regexMatch instead of {{ if .Capabilities.HelmVersion }} because checking for the key HelmVersion in <3.3 results in a "interface not found" error. +**To be removed when the catalog's minimun Helm version is 3.3** +*/}} +{{- define "common.capabilities.supportsHelmVersion" -}} +{{- if regexMatch "{(v[0-9])*[^}]*}}$" (.Capabilities | toString ) }} + {{- true -}} +{{- end -}} +{{- end -}} diff --git a/helm/sonarqube/charts/postgresql/charts/common/templates/_errors.tpl b/helm/sonarqube/charts/postgresql/charts/common/templates/_errors.tpl new file mode 100644 index 0000000..a79cc2e --- /dev/null +++ b/helm/sonarqube/charts/postgresql/charts/common/templates/_errors.tpl @@ -0,0 +1,23 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Through error when upgrading using empty passwords values that must not be empty. + +Usage: +{{- $validationError00 := include "common.validations.values.single.empty" (dict "valueKey" "path.to.password00" "secret" "secretName" "field" "password-00") -}} +{{- $validationError01 := include "common.validations.values.single.empty" (dict "valueKey" "path.to.password01" "secret" "secretName" "field" "password-01") -}} +{{ include "common.errors.upgrade.passwords.empty" (dict "validationErrors" (list $validationError00 $validationError01) "context" $) }} + +Required password params: + - validationErrors - String - Required. List of validation strings to be return, if it is empty it won't throw error. + - context - Context - Required. Parent context. +*/}} +{{- define "common.errors.upgrade.passwords.empty" -}} + {{- $validationErrors := join "" .validationErrors -}} + {{- if and $validationErrors .context.Release.IsUpgrade -}} + {{- $errorString := "\nPASSWORDS ERROR: You must provide your current passwords when upgrading the release." -}} + {{- $errorString = print $errorString "\n Note that even after reinstallation, old credentials may be needed as they may be kept in persistent volume claims." -}} + {{- $errorString = print $errorString "\n Further information can be obtained at https://docs.bitnami.com/general/how-to/troubleshoot-helm-chart-issues/#credential-errors-while-upgrading-chart-releases" -}} + {{- $errorString = print $errorString "\n%s" -}} + {{- printf $errorString $validationErrors | fail -}} + {{- end -}} +{{- end -}} diff --git a/helm/sonarqube/charts/postgresql/charts/common/templates/_images.tpl b/helm/sonarqube/charts/postgresql/charts/common/templates/_images.tpl new file mode 100644 index 0000000..42ffbc7 --- /dev/null +++ b/helm/sonarqube/charts/postgresql/charts/common/templates/_images.tpl @@ -0,0 +1,75 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Return the proper image name +{{ include "common.images.image" ( dict "imageRoot" .Values.path.to.the.image "global" $) }} +*/}} +{{- define "common.images.image" -}} +{{- $registryName := .imageRoot.registry -}} +{{- $repositoryName := .imageRoot.repository -}} +{{- $tag := .imageRoot.tag | toString -}} +{{- if .global }} + {{- if .global.imageRegistry }} + {{- $registryName = .global.imageRegistry -}} + {{- end -}} +{{- end -}} +{{- if $registryName }} +{{- printf "%s/%s:%s" $registryName $repositoryName $tag -}} +{{- else -}} +{{- printf "%s:%s" $repositoryName $tag -}} +{{- end -}} +{{- end -}} + +{{/* +Return the proper Docker Image Registry Secret Names (deprecated: use common.images.renderPullSecrets instead) +{{ include "common.images.pullSecrets" ( dict "images" (list .Values.path.to.the.image1, .Values.path.to.the.image2) "global" .Values.global) }} +*/}} +{{- define "common.images.pullSecrets" -}} + {{- $pullSecrets := list }} + + {{- if .global }} + {{- range .global.imagePullSecrets -}} + {{- $pullSecrets = append $pullSecrets . -}} + {{- end -}} + {{- end -}} + + {{- range .images -}} + {{- range .pullSecrets -}} + {{- $pullSecrets = append $pullSecrets . -}} + {{- end -}} + {{- end -}} + + {{- if (not (empty $pullSecrets)) }} +imagePullSecrets: + {{- range $pullSecrets }} + - name: {{ . }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +Return the proper Docker Image Registry Secret Names evaluating values as templates +{{ include "common.images.renderPullSecrets" ( dict "images" (list .Values.path.to.the.image1, .Values.path.to.the.image2) "context" $) }} +*/}} +{{- define "common.images.renderPullSecrets" -}} + {{- $pullSecrets := list }} + {{- $context := .context }} + + {{- if $context.Values.global }} + {{- range $context.Values.global.imagePullSecrets -}} + {{- $pullSecrets = append $pullSecrets (include "common.tplvalues.render" (dict "value" . "context" $context)) -}} + {{- end -}} + {{- end -}} + + {{- range .images -}} + {{- range .pullSecrets -}} + {{- $pullSecrets = append $pullSecrets (include "common.tplvalues.render" (dict "value" . "context" $context)) -}} + {{- end -}} + {{- end -}} + + {{- if (not (empty $pullSecrets)) }} +imagePullSecrets: + {{- range $pullSecrets }} + - name: {{ . }} + {{- end }} + {{- end }} +{{- end -}} diff --git a/helm/sonarqube/charts/postgresql/charts/common/templates/_ingress.tpl b/helm/sonarqube/charts/postgresql/charts/common/templates/_ingress.tpl new file mode 100644 index 0000000..f905f20 --- /dev/null +++ b/helm/sonarqube/charts/postgresql/charts/common/templates/_ingress.tpl @@ -0,0 +1,55 @@ +{{/* vim: set filetype=mustache: */}} + +{{/* +Generate backend entry that is compatible with all Kubernetes API versions. + +Usage: +{{ include "common.ingress.backend" (dict "serviceName" "backendName" "servicePort" "backendPort" "context" $) }} + +Params: + - serviceName - String. Name of an existing service backend + - servicePort - String/Int. Port name (or number) of the service. It will be translated to different yaml depending if it is a string or an integer. + - context - Dict - Required. The context for the template evaluation. +*/}} +{{- define "common.ingress.backend" -}} +{{- $apiVersion := (include "common.capabilities.ingress.apiVersion" .context) -}} +{{- if or (eq $apiVersion "extensions/v1beta1") (eq $apiVersion "networking.k8s.io/v1beta1") -}} +serviceName: {{ .serviceName }} +servicePort: {{ .servicePort }} +{{- else -}} +service: + name: {{ .serviceName }} + port: + {{- if typeIs "string" .servicePort }} + name: {{ .servicePort }} + {{- else if or (typeIs "int" .servicePort) (typeIs "float64" .servicePort) }} + number: {{ .servicePort | int }} + {{- end }} +{{- end -}} +{{- end -}} + +{{/* +Print "true" if the API pathType field is supported +Usage: +{{ include "common.ingress.supportsPathType" . }} +*/}} +{{- define "common.ingress.supportsPathType" -}} +{{- if (semverCompare "<1.18-0" (include "common.capabilities.kubeVersion" .)) -}} +{{- print "false" -}} +{{- else -}} +{{- print "true" -}} +{{- end -}} +{{- end -}} + +{{/* +Returns true if the ingressClassname field is supported +Usage: +{{ include "common.ingress.supportsIngressClassname" . }} +*/}} +{{- define "common.ingress.supportsIngressClassname" -}} +{{- if semverCompare "<1.18-0" (include "common.capabilities.kubeVersion" .) -}} +{{- print "false" -}} +{{- else -}} +{{- print "true" -}} +{{- end -}} +{{- end -}} diff --git a/helm/sonarqube/charts/postgresql/charts/common/templates/_labels.tpl b/helm/sonarqube/charts/postgresql/charts/common/templates/_labels.tpl new file mode 100644 index 0000000..252066c --- /dev/null +++ b/helm/sonarqube/charts/postgresql/charts/common/templates/_labels.tpl @@ -0,0 +1,18 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Kubernetes standard labels +*/}} +{{- define "common.labels.standard" -}} +app.kubernetes.io/name: {{ include "common.names.name" . }} +helm.sh/chart: {{ include "common.names.chart" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end -}} + +{{/* +Labels to use on deploy.spec.selector.matchLabels and svc.spec.selector +*/}} +{{- define "common.labels.matchLabels" -}} +app.kubernetes.io/name: {{ include "common.names.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end -}} diff --git a/helm/sonarqube/charts/postgresql/charts/common/templates/_names.tpl b/helm/sonarqube/charts/postgresql/charts/common/templates/_names.tpl new file mode 100644 index 0000000..cf03231 --- /dev/null +++ b/helm/sonarqube/charts/postgresql/charts/common/templates/_names.tpl @@ -0,0 +1,52 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "common.names.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "common.names.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "common.names.fullname" -}} +{{- if .Values.fullnameOverride -}} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Create a default fully qualified dependency name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +Usage: +{{ include "common.names.dependency.fullname" (dict "chartName" "dependency-chart-name" "chartValues" .Values.dependency-chart "context" $) }} +*/}} +{{- define "common.names.dependency.fullname" -}} +{{- if .chartValues.fullnameOverride -}} +{{- .chartValues.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .chartName .chartValues.nameOverride -}} +{{- if contains $name .context.Release.Name -}} +{{- .context.Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .context.Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} diff --git a/helm/sonarqube/charts/postgresql/charts/common/templates/_secrets.tpl b/helm/sonarqube/charts/postgresql/charts/common/templates/_secrets.tpl new file mode 100644 index 0000000..60b84a7 --- /dev/null +++ b/helm/sonarqube/charts/postgresql/charts/common/templates/_secrets.tpl @@ -0,0 +1,129 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Generate secret name. + +Usage: +{{ include "common.secrets.name" (dict "existingSecret" .Values.path.to.the.existingSecret "defaultNameSuffix" "mySuffix" "context" $) }} + +Params: + - existingSecret - ExistingSecret/String - Optional. The path to the existing secrets in the values.yaml given by the user + to be used instead of the default one. Allows for it to be of type String (just the secret name) for backwards compatibility. + +info: https://github.com/bitnami/charts/tree/master/bitnami/common#existingsecret + - defaultNameSuffix - String - Optional. It is used only if we have several secrets in the same deployment. + - context - Dict - Required. The context for the template evaluation. +*/}} +{{- define "common.secrets.name" -}} +{{- $name := (include "common.names.fullname" .context) -}} + +{{- if .defaultNameSuffix -}} +{{- $name = printf "%s-%s" $name .defaultNameSuffix | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{- with .existingSecret -}} +{{- if not (typeIs "string" .) -}} +{{- with .name -}} +{{- $name = . -}} +{{- end -}} +{{- else -}} +{{- $name = . -}} +{{- end -}} +{{- end -}} + +{{- printf "%s" $name -}} +{{- end -}} + +{{/* +Generate secret key. + +Usage: +{{ include "common.secrets.key" (dict "existingSecret" .Values.path.to.the.existingSecret "key" "keyName") }} + +Params: + - existingSecret - ExistingSecret/String - Optional. The path to the existing secrets in the values.yaml given by the user + to be used instead of the default one. Allows for it to be of type String (just the secret name) for backwards compatibility. + +info: https://github.com/bitnami/charts/tree/master/bitnami/common#existingsecret + - key - String - Required. Name of the key in the secret. +*/}} +{{- define "common.secrets.key" -}} +{{- $key := .key -}} + +{{- if .existingSecret -}} + {{- if not (typeIs "string" .existingSecret) -}} + {{- if .existingSecret.keyMapping -}} + {{- $key = index .existingSecret.keyMapping $.key -}} + {{- end -}} + {{- end }} +{{- end -}} + +{{- printf "%s" $key -}} +{{- end -}} + +{{/* +Generate secret password or retrieve one if already created. + +Usage: +{{ include "common.secrets.passwords.manage" (dict "secret" "secret-name" "key" "keyName" "providedValues" (list "path.to.password1" "path.to.password2") "length" 10 "strong" false "chartName" "chartName" "context" $) }} + +Params: + - secret - String - Required - Name of the 'Secret' resource where the password is stored. + - key - String - Required - Name of the key in the secret. + - providedValues - List - Required - The path to the validating value in the values.yaml, e.g: "mysql.password". Will pick first parameter with a defined value. + - length - int - Optional - Length of the generated random password. + - strong - Boolean - Optional - Whether to add symbols to the generated random password. + - chartName - String - Optional - Name of the chart used when said chart is deployed as a subchart. + - context - Context - Required - Parent context. +*/}} +{{- define "common.secrets.passwords.manage" -}} + +{{- $password := "" }} +{{- $subchart := "" }} +{{- $chartName := default "" .chartName }} +{{- $passwordLength := default 10 .length }} +{{- $providedPasswordKey := include "common.utils.getKeyFromList" (dict "keys" .providedValues "context" $.context) }} +{{- $providedPasswordValue := include "common.utils.getValueFromKey" (dict "key" $providedPasswordKey "context" $.context) }} +{{- $secret := (lookup "v1" "Secret" $.context.Release.Namespace .secret) }} +{{- if $secret }} + {{- if index $secret.data .key }} + {{- $password = index $secret.data .key }} + {{- end -}} +{{- else if $providedPasswordValue }} + {{- $password = $providedPasswordValue | toString | b64enc | quote }} +{{- else }} + + {{- if .context.Values.enabled }} + {{- $subchart = $chartName }} + {{- end -}} + + {{- $requiredPassword := dict "valueKey" $providedPasswordKey "secret" .secret "field" .key "subchart" $subchart "context" $.context -}} + {{- $requiredPasswordError := include "common.validations.values.single.empty" $requiredPassword -}} + {{- $passwordValidationErrors := list $requiredPasswordError -}} + {{- include "common.errors.upgrade.passwords.empty" (dict "validationErrors" $passwordValidationErrors "context" $.context) -}} + + {{- if .strong }} + {{- $subStr := list (lower (randAlpha 1)) (randNumeric 1) (upper (randAlpha 1)) | join "_" }} + {{- $password = randAscii $passwordLength }} + {{- $password = regexReplaceAllLiteral "\\W" $password "@" | substr 5 $passwordLength }} + {{- $password = printf "%s%s" $subStr $password | toString | shuffle | b64enc | quote }} + {{- else }} + {{- $password = randAlphaNum $passwordLength | b64enc | quote }} + {{- end }} +{{- end -}} +{{- printf "%s" $password -}} +{{- end -}} + +{{/* +Returns whether a previous generated secret already exists + +Usage: +{{ include "common.secrets.exists" (dict "secret" "secret-name" "context" $) }} + +Params: + - secret - String - Required - Name of the 'Secret' resource where the password is stored. + - context - Context - Required - Parent context. +*/}} +{{- define "common.secrets.exists" -}} +{{- $secret := (lookup "v1" "Secret" $.context.Release.Namespace .secret) }} +{{- if $secret }} + {{- true -}} +{{- end -}} +{{- end -}} diff --git a/helm/sonarqube/charts/postgresql/charts/common/templates/_storage.tpl b/helm/sonarqube/charts/postgresql/charts/common/templates/_storage.tpl new file mode 100644 index 0000000..60e2a84 --- /dev/null +++ b/helm/sonarqube/charts/postgresql/charts/common/templates/_storage.tpl @@ -0,0 +1,23 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Return the proper Storage Class +{{ include "common.storage.class" ( dict "persistence" .Values.path.to.the.persistence "global" $) }} +*/}} +{{- define "common.storage.class" -}} + +{{- $storageClass := .persistence.storageClass -}} +{{- if .global -}} + {{- if .global.storageClass -}} + {{- $storageClass = .global.storageClass -}} + {{- end -}} +{{- end -}} + +{{- if $storageClass -}} + {{- if (eq "-" $storageClass) -}} + {{- printf "storageClassName: \"\"" -}} + {{- else }} + {{- printf "storageClassName: %s" $storageClass -}} + {{- end -}} +{{- end -}} + +{{- end -}} diff --git a/helm/sonarqube/charts/postgresql/charts/common/templates/_tplvalues.tpl b/helm/sonarqube/charts/postgresql/charts/common/templates/_tplvalues.tpl new file mode 100644 index 0000000..2db1668 --- /dev/null +++ b/helm/sonarqube/charts/postgresql/charts/common/templates/_tplvalues.tpl @@ -0,0 +1,13 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Renders a value that contains template. +Usage: +{{ include "common.tplvalues.render" ( dict "value" .Values.path.to.the.Value "context" $) }} +*/}} +{{- define "common.tplvalues.render" -}} + {{- if typeIs "string" .value }} + {{- tpl .value .context }} + {{- else }} + {{- tpl (.value | toYaml) .context }} + {{- end }} +{{- end -}} diff --git a/helm/sonarqube/charts/postgresql/charts/common/templates/_utils.tpl b/helm/sonarqube/charts/postgresql/charts/common/templates/_utils.tpl new file mode 100644 index 0000000..ea083a2 --- /dev/null +++ b/helm/sonarqube/charts/postgresql/charts/common/templates/_utils.tpl @@ -0,0 +1,62 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Print instructions to get a secret value. +Usage: +{{ include "common.utils.secret.getvalue" (dict "secret" "secret-name" "field" "secret-value-field" "context" $) }} +*/}} +{{- define "common.utils.secret.getvalue" -}} +{{- $varname := include "common.utils.fieldToEnvVar" . -}} +export {{ $varname }}=$(kubectl get secret --namespace {{ .context.Release.Namespace | quote }} {{ .secret }} -o jsonpath="{.data.{{ .field }}}" | base64 --decode) +{{- end -}} + +{{/* +Build env var name given a field +Usage: +{{ include "common.utils.fieldToEnvVar" dict "field" "my-password" }} +*/}} +{{- define "common.utils.fieldToEnvVar" -}} + {{- $fieldNameSplit := splitList "-" .field -}} + {{- $upperCaseFieldNameSplit := list -}} + + {{- range $fieldNameSplit -}} + {{- $upperCaseFieldNameSplit = append $upperCaseFieldNameSplit ( upper . ) -}} + {{- end -}} + + {{ join "_" $upperCaseFieldNameSplit }} +{{- end -}} + +{{/* +Gets a value from .Values given +Usage: +{{ include "common.utils.getValueFromKey" (dict "key" "path.to.key" "context" $) }} +*/}} +{{- define "common.utils.getValueFromKey" -}} +{{- $splitKey := splitList "." .key -}} +{{- $value := "" -}} +{{- $latestObj := $.context.Values -}} +{{- range $splitKey -}} + {{- if not $latestObj -}} + {{- printf "please review the entire path of '%s' exists in values" $.key | fail -}} + {{- end -}} + {{- $value = ( index $latestObj . ) -}} + {{- $latestObj = $value -}} +{{- end -}} +{{- printf "%v" (default "" $value) -}} +{{- end -}} + +{{/* +Returns first .Values key with a defined value or first of the list if all non-defined +Usage: +{{ include "common.utils.getKeyFromList" (dict "keys" (list "path.to.key1" "path.to.key2") "context" $) }} +*/}} +{{- define "common.utils.getKeyFromList" -}} +{{- $key := first .keys -}} +{{- $reverseKeys := reverse .keys }} +{{- range $reverseKeys }} + {{- $value := include "common.utils.getValueFromKey" (dict "key" . "context" $.context ) }} + {{- if $value -}} + {{- $key = . }} + {{- end -}} +{{- end -}} +{{- printf "%s" $key -}} +{{- end -}} diff --git a/helm/sonarqube/charts/postgresql/charts/common/templates/_warnings.tpl b/helm/sonarqube/charts/postgresql/charts/common/templates/_warnings.tpl new file mode 100644 index 0000000..ae10fa4 --- /dev/null +++ b/helm/sonarqube/charts/postgresql/charts/common/templates/_warnings.tpl @@ -0,0 +1,14 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Warning about using rolling tag. +Usage: +{{ include "common.warnings.rollingTag" .Values.path.to.the.imageRoot }} +*/}} +{{- define "common.warnings.rollingTag" -}} + +{{- if and (contains "bitnami/" .repository) (not (.tag | toString | regexFind "-r\\d+$|sha256:")) }} +WARNING: Rolling tag detected ({{ .repository }}:{{ .tag }}), please note that it is strongly recommended to avoid using rolling tags in a production environment. ++info https://docs.bitnami.com/containers/how-to/understand-rolling-tags-containers/ +{{- end }} + +{{- end -}} diff --git a/helm/sonarqube/charts/postgresql/charts/common/templates/validations/_cassandra.tpl b/helm/sonarqube/charts/postgresql/charts/common/templates/validations/_cassandra.tpl new file mode 100644 index 0000000..ded1ae3 --- /dev/null +++ b/helm/sonarqube/charts/postgresql/charts/common/templates/validations/_cassandra.tpl @@ -0,0 +1,72 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Validate Cassandra required passwords are not empty. + +Usage: +{{ include "common.validations.values.cassandra.passwords" (dict "secret" "secretName" "subchart" false "context" $) }} +Params: + - secret - String - Required. Name of the secret where Cassandra values are stored, e.g: "cassandra-passwords-secret" + - subchart - Boolean - Optional. Whether Cassandra is used as subchart or not. Default: false +*/}} +{{- define "common.validations.values.cassandra.passwords" -}} + {{- $existingSecret := include "common.cassandra.values.existingSecret" . -}} + {{- $enabled := include "common.cassandra.values.enabled" . -}} + {{- $dbUserPrefix := include "common.cassandra.values.key.dbUser" . -}} + {{- $valueKeyPassword := printf "%s.password" $dbUserPrefix -}} + + {{- if and (or (not $existingSecret) (eq $existingSecret "\"\"")) (eq $enabled "true") -}} + {{- $requiredPasswords := list -}} + + {{- $requiredPassword := dict "valueKey" $valueKeyPassword "secret" .secret "field" "cassandra-password" -}} + {{- $requiredPasswords = append $requiredPasswords $requiredPassword -}} + + {{- include "common.validations.values.multiple.empty" (dict "required" $requiredPasswords "context" .context) -}} + + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for existingSecret. + +Usage: +{{ include "common.cassandra.values.existingSecret" (dict "context" $) }} +Params: + - subchart - Boolean - Optional. Whether Cassandra is used as subchart or not. Default: false +*/}} +{{- define "common.cassandra.values.existingSecret" -}} + {{- if .subchart -}} + {{- .context.Values.cassandra.dbUser.existingSecret | quote -}} + {{- else -}} + {{- .context.Values.dbUser.existingSecret | quote -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for enabled cassandra. + +Usage: +{{ include "common.cassandra.values.enabled" (dict "context" $) }} +*/}} +{{- define "common.cassandra.values.enabled" -}} + {{- if .subchart -}} + {{- printf "%v" .context.Values.cassandra.enabled -}} + {{- else -}} + {{- printf "%v" (not .context.Values.enabled) -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for the key dbUser + +Usage: +{{ include "common.cassandra.values.key.dbUser" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether Cassandra is used as subchart or not. Default: false +*/}} +{{- define "common.cassandra.values.key.dbUser" -}} + {{- if .subchart -}} + cassandra.dbUser + {{- else -}} + dbUser + {{- end -}} +{{- end -}} diff --git a/helm/sonarqube/charts/postgresql/charts/common/templates/validations/_mariadb.tpl b/helm/sonarqube/charts/postgresql/charts/common/templates/validations/_mariadb.tpl new file mode 100644 index 0000000..b6906ff --- /dev/null +++ b/helm/sonarqube/charts/postgresql/charts/common/templates/validations/_mariadb.tpl @@ -0,0 +1,103 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Validate MariaDB required passwords are not empty. + +Usage: +{{ include "common.validations.values.mariadb.passwords" (dict "secret" "secretName" "subchart" false "context" $) }} +Params: + - secret - String - Required. Name of the secret where MariaDB values are stored, e.g: "mysql-passwords-secret" + - subchart - Boolean - Optional. Whether MariaDB is used as subchart or not. Default: false +*/}} +{{- define "common.validations.values.mariadb.passwords" -}} + {{- $existingSecret := include "common.mariadb.values.auth.existingSecret" . -}} + {{- $enabled := include "common.mariadb.values.enabled" . -}} + {{- $architecture := include "common.mariadb.values.architecture" . -}} + {{- $authPrefix := include "common.mariadb.values.key.auth" . -}} + {{- $valueKeyRootPassword := printf "%s.rootPassword" $authPrefix -}} + {{- $valueKeyUsername := printf "%s.username" $authPrefix -}} + {{- $valueKeyPassword := printf "%s.password" $authPrefix -}} + {{- $valueKeyReplicationPassword := printf "%s.replicationPassword" $authPrefix -}} + + {{- if and (or (not $existingSecret) (eq $existingSecret "\"\"")) (eq $enabled "true") -}} + {{- $requiredPasswords := list -}} + + {{- $requiredRootPassword := dict "valueKey" $valueKeyRootPassword "secret" .secret "field" "mariadb-root-password" -}} + {{- $requiredPasswords = append $requiredPasswords $requiredRootPassword -}} + + {{- $valueUsername := include "common.utils.getValueFromKey" (dict "key" $valueKeyUsername "context" .context) }} + {{- if not (empty $valueUsername) -}} + {{- $requiredPassword := dict "valueKey" $valueKeyPassword "secret" .secret "field" "mariadb-password" -}} + {{- $requiredPasswords = append $requiredPasswords $requiredPassword -}} + {{- end -}} + + {{- if (eq $architecture "replication") -}} + {{- $requiredReplicationPassword := dict "valueKey" $valueKeyReplicationPassword "secret" .secret "field" "mariadb-replication-password" -}} + {{- $requiredPasswords = append $requiredPasswords $requiredReplicationPassword -}} + {{- end -}} + + {{- include "common.validations.values.multiple.empty" (dict "required" $requiredPasswords "context" .context) -}} + + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for existingSecret. + +Usage: +{{ include "common.mariadb.values.auth.existingSecret" (dict "context" $) }} +Params: + - subchart - Boolean - Optional. Whether MariaDB is used as subchart or not. Default: false +*/}} +{{- define "common.mariadb.values.auth.existingSecret" -}} + {{- if .subchart -}} + {{- .context.Values.mariadb.auth.existingSecret | quote -}} + {{- else -}} + {{- .context.Values.auth.existingSecret | quote -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for enabled mariadb. + +Usage: +{{ include "common.mariadb.values.enabled" (dict "context" $) }} +*/}} +{{- define "common.mariadb.values.enabled" -}} + {{- if .subchart -}} + {{- printf "%v" .context.Values.mariadb.enabled -}} + {{- else -}} + {{- printf "%v" (not .context.Values.enabled) -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for architecture + +Usage: +{{ include "common.mariadb.values.architecture" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether MariaDB is used as subchart or not. Default: false +*/}} +{{- define "common.mariadb.values.architecture" -}} + {{- if .subchart -}} + {{- .context.Values.mariadb.architecture -}} + {{- else -}} + {{- .context.Values.architecture -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for the key auth + +Usage: +{{ include "common.mariadb.values.key.auth" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether MariaDB is used as subchart or not. Default: false +*/}} +{{- define "common.mariadb.values.key.auth" -}} + {{- if .subchart -}} + mariadb.auth + {{- else -}} + auth + {{- end -}} +{{- end -}} diff --git a/helm/sonarqube/charts/postgresql/charts/common/templates/validations/_mongodb.tpl b/helm/sonarqube/charts/postgresql/charts/common/templates/validations/_mongodb.tpl new file mode 100644 index 0000000..a071ea4 --- /dev/null +++ b/helm/sonarqube/charts/postgresql/charts/common/templates/validations/_mongodb.tpl @@ -0,0 +1,108 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Validate MongoDB® required passwords are not empty. + +Usage: +{{ include "common.validations.values.mongodb.passwords" (dict "secret" "secretName" "subchart" false "context" $) }} +Params: + - secret - String - Required. Name of the secret where MongoDB® values are stored, e.g: "mongodb-passwords-secret" + - subchart - Boolean - Optional. Whether MongoDB® is used as subchart or not. Default: false +*/}} +{{- define "common.validations.values.mongodb.passwords" -}} + {{- $existingSecret := include "common.mongodb.values.auth.existingSecret" . -}} + {{- $enabled := include "common.mongodb.values.enabled" . -}} + {{- $authPrefix := include "common.mongodb.values.key.auth" . -}} + {{- $architecture := include "common.mongodb.values.architecture" . -}} + {{- $valueKeyRootPassword := printf "%s.rootPassword" $authPrefix -}} + {{- $valueKeyUsername := printf "%s.username" $authPrefix -}} + {{- $valueKeyDatabase := printf "%s.database" $authPrefix -}} + {{- $valueKeyPassword := printf "%s.password" $authPrefix -}} + {{- $valueKeyReplicaSetKey := printf "%s.replicaSetKey" $authPrefix -}} + {{- $valueKeyAuthEnabled := printf "%s.enabled" $authPrefix -}} + + {{- $authEnabled := include "common.utils.getValueFromKey" (dict "key" $valueKeyAuthEnabled "context" .context) -}} + + {{- if and (or (not $existingSecret) (eq $existingSecret "\"\"")) (eq $enabled "true") (eq $authEnabled "true") -}} + {{- $requiredPasswords := list -}} + + {{- $requiredRootPassword := dict "valueKey" $valueKeyRootPassword "secret" .secret "field" "mongodb-root-password" -}} + {{- $requiredPasswords = append $requiredPasswords $requiredRootPassword -}} + + {{- $valueUsername := include "common.utils.getValueFromKey" (dict "key" $valueKeyUsername "context" .context) }} + {{- $valueDatabase := include "common.utils.getValueFromKey" (dict "key" $valueKeyDatabase "context" .context) }} + {{- if and $valueUsername $valueDatabase -}} + {{- $requiredPassword := dict "valueKey" $valueKeyPassword "secret" .secret "field" "mongodb-password" -}} + {{- $requiredPasswords = append $requiredPasswords $requiredPassword -}} + {{- end -}} + + {{- if (eq $architecture "replicaset") -}} + {{- $requiredReplicaSetKey := dict "valueKey" $valueKeyReplicaSetKey "secret" .secret "field" "mongodb-replica-set-key" -}} + {{- $requiredPasswords = append $requiredPasswords $requiredReplicaSetKey -}} + {{- end -}} + + {{- include "common.validations.values.multiple.empty" (dict "required" $requiredPasswords "context" .context) -}} + + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for existingSecret. + +Usage: +{{ include "common.mongodb.values.auth.existingSecret" (dict "context" $) }} +Params: + - subchart - Boolean - Optional. Whether MongoDb is used as subchart or not. Default: false +*/}} +{{- define "common.mongodb.values.auth.existingSecret" -}} + {{- if .subchart -}} + {{- .context.Values.mongodb.auth.existingSecret | quote -}} + {{- else -}} + {{- .context.Values.auth.existingSecret | quote -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for enabled mongodb. + +Usage: +{{ include "common.mongodb.values.enabled" (dict "context" $) }} +*/}} +{{- define "common.mongodb.values.enabled" -}} + {{- if .subchart -}} + {{- printf "%v" .context.Values.mongodb.enabled -}} + {{- else -}} + {{- printf "%v" (not .context.Values.enabled) -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for the key auth + +Usage: +{{ include "common.mongodb.values.key.auth" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether MongoDB® is used as subchart or not. Default: false +*/}} +{{- define "common.mongodb.values.key.auth" -}} + {{- if .subchart -}} + mongodb.auth + {{- else -}} + auth + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for architecture + +Usage: +{{ include "common.mongodb.values.architecture" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether MariaDB is used as subchart or not. Default: false +*/}} +{{- define "common.mongodb.values.architecture" -}} + {{- if .subchart -}} + {{- .context.Values.mongodb.architecture -}} + {{- else -}} + {{- .context.Values.architecture -}} + {{- end -}} +{{- end -}} diff --git a/helm/sonarqube/charts/postgresql/charts/common/templates/validations/_postgresql.tpl b/helm/sonarqube/charts/postgresql/charts/common/templates/validations/_postgresql.tpl new file mode 100644 index 0000000..164ec0d --- /dev/null +++ b/helm/sonarqube/charts/postgresql/charts/common/templates/validations/_postgresql.tpl @@ -0,0 +1,129 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Validate PostgreSQL required passwords are not empty. + +Usage: +{{ include "common.validations.values.postgresql.passwords" (dict "secret" "secretName" "subchart" false "context" $) }} +Params: + - secret - String - Required. Name of the secret where postgresql values are stored, e.g: "postgresql-passwords-secret" + - subchart - Boolean - Optional. Whether postgresql is used as subchart or not. Default: false +*/}} +{{- define "common.validations.values.postgresql.passwords" -}} + {{- $existingSecret := include "common.postgresql.values.existingSecret" . -}} + {{- $enabled := include "common.postgresql.values.enabled" . -}} + {{- $valueKeyPostgresqlPassword := include "common.postgresql.values.key.postgressPassword" . -}} + {{- $valueKeyPostgresqlReplicationEnabled := include "common.postgresql.values.key.replicationPassword" . -}} + {{- if and (or (not $existingSecret) (eq $existingSecret "\"\"")) (eq $enabled "true") -}} + {{- $requiredPasswords := list -}} + {{- $requiredPostgresqlPassword := dict "valueKey" $valueKeyPostgresqlPassword "secret" .secret "field" "postgresql-password" -}} + {{- $requiredPasswords = append $requiredPasswords $requiredPostgresqlPassword -}} + + {{- $enabledReplication := include "common.postgresql.values.enabled.replication" . -}} + {{- if (eq $enabledReplication "true") -}} + {{- $requiredPostgresqlReplicationPassword := dict "valueKey" $valueKeyPostgresqlReplicationEnabled "secret" .secret "field" "postgresql-replication-password" -}} + {{- $requiredPasswords = append $requiredPasswords $requiredPostgresqlReplicationPassword -}} + {{- end -}} + + {{- include "common.validations.values.multiple.empty" (dict "required" $requiredPasswords "context" .context) -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to decide whether evaluate global values. + +Usage: +{{ include "common.postgresql.values.use.global" (dict "key" "key-of-global" "context" $) }} +Params: + - key - String - Required. Field to be evaluated within global, e.g: "existingSecret" +*/}} +{{- define "common.postgresql.values.use.global" -}} + {{- if .context.Values.global -}} + {{- if .context.Values.global.postgresql -}} + {{- index .context.Values.global.postgresql .key | quote -}} + {{- end -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for existingSecret. + +Usage: +{{ include "common.postgresql.values.existingSecret" (dict "context" $) }} +*/}} +{{- define "common.postgresql.values.existingSecret" -}} + {{- $globalValue := include "common.postgresql.values.use.global" (dict "key" "existingSecret" "context" .context) -}} + + {{- if .subchart -}} + {{- default (.context.Values.postgresql.existingSecret | quote) $globalValue -}} + {{- else -}} + {{- default (.context.Values.existingSecret | quote) $globalValue -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for enabled postgresql. + +Usage: +{{ include "common.postgresql.values.enabled" (dict "context" $) }} +*/}} +{{- define "common.postgresql.values.enabled" -}} + {{- if .subchart -}} + {{- printf "%v" .context.Values.postgresql.enabled -}} + {{- else -}} + {{- printf "%v" (not .context.Values.enabled) -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for the key postgressPassword. + +Usage: +{{ include "common.postgresql.values.key.postgressPassword" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether postgresql is used as subchart or not. Default: false +*/}} +{{- define "common.postgresql.values.key.postgressPassword" -}} + {{- $globalValue := include "common.postgresql.values.use.global" (dict "key" "postgresqlUsername" "context" .context) -}} + + {{- if not $globalValue -}} + {{- if .subchart -}} + postgresql.postgresqlPassword + {{- else -}} + postgresqlPassword + {{- end -}} + {{- else -}} + global.postgresql.postgresqlPassword + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for enabled.replication. + +Usage: +{{ include "common.postgresql.values.enabled.replication" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether postgresql is used as subchart or not. Default: false +*/}} +{{- define "common.postgresql.values.enabled.replication" -}} + {{- if .subchart -}} + {{- printf "%v" .context.Values.postgresql.replication.enabled -}} + {{- else -}} + {{- printf "%v" .context.Values.replication.enabled -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for the key replication.password. + +Usage: +{{ include "common.postgresql.values.key.replicationPassword" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether postgresql is used as subchart or not. Default: false +*/}} +{{- define "common.postgresql.values.key.replicationPassword" -}} + {{- if .subchart -}} + postgresql.replication.password + {{- else -}} + replication.password + {{- end -}} +{{- end -}} diff --git a/helm/sonarqube/charts/postgresql/charts/common/templates/validations/_redis.tpl b/helm/sonarqube/charts/postgresql/charts/common/templates/validations/_redis.tpl new file mode 100644 index 0000000..5d72959 --- /dev/null +++ b/helm/sonarqube/charts/postgresql/charts/common/templates/validations/_redis.tpl @@ -0,0 +1,76 @@ + +{{/* vim: set filetype=mustache: */}} +{{/* +Validate Redis™ required passwords are not empty. + +Usage: +{{ include "common.validations.values.redis.passwords" (dict "secret" "secretName" "subchart" false "context" $) }} +Params: + - secret - String - Required. Name of the secret where redis values are stored, e.g: "redis-passwords-secret" + - subchart - Boolean - Optional. Whether redis is used as subchart or not. Default: false +*/}} +{{- define "common.validations.values.redis.passwords" -}} + {{- $enabled := include "common.redis.values.enabled" . -}} + {{- $valueKeyPrefix := include "common.redis.values.keys.prefix" . -}} + {{- $standarizedVersion := include "common.redis.values.standarized.version" . }} + + {{- $existingSecret := ternary (printf "%s%s" $valueKeyPrefix "auth.existingSecret") (printf "%s%s" $valueKeyPrefix "existingSecret") (eq $standarizedVersion "true") }} + {{- $existingSecretValue := include "common.utils.getValueFromKey" (dict "key" $existingSecret "context" .context) }} + + {{- $valueKeyRedisPassword := ternary (printf "%s%s" $valueKeyPrefix "auth.password") (printf "%s%s" $valueKeyPrefix "password") (eq $standarizedVersion "true") }} + {{- $valueKeyRedisUseAuth := ternary (printf "%s%s" $valueKeyPrefix "auth.enabled") (printf "%s%s" $valueKeyPrefix "usePassword") (eq $standarizedVersion "true") }} + + {{- if and (or (not $existingSecret) (eq $existingSecret "\"\"")) (eq $enabled "true") -}} + {{- $requiredPasswords := list -}} + + {{- $useAuth := include "common.utils.getValueFromKey" (dict "key" $valueKeyRedisUseAuth "context" .context) -}} + {{- if eq $useAuth "true" -}} + {{- $requiredRedisPassword := dict "valueKey" $valueKeyRedisPassword "secret" .secret "field" "redis-password" -}} + {{- $requiredPasswords = append $requiredPasswords $requiredRedisPassword -}} + {{- end -}} + + {{- include "common.validations.values.multiple.empty" (dict "required" $requiredPasswords "context" .context) -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right value for enabled redis. + +Usage: +{{ include "common.redis.values.enabled" (dict "context" $) }} +*/}} +{{- define "common.redis.values.enabled" -}} + {{- if .subchart -}} + {{- printf "%v" .context.Values.redis.enabled -}} + {{- else -}} + {{- printf "%v" (not .context.Values.enabled) -}} + {{- end -}} +{{- end -}} + +{{/* +Auxiliary function to get the right prefix path for the values + +Usage: +{{ include "common.redis.values.key.prefix" (dict "subchart" "true" "context" $) }} +Params: + - subchart - Boolean - Optional. Whether redis is used as subchart or not. Default: false +*/}} +{{- define "common.redis.values.keys.prefix" -}} + {{- if .subchart -}}redis.{{- else -}}{{- end -}} +{{- end -}} + +{{/* +Checks whether the redis chart's includes the standarizations (version >= 14) + +Usage: +{{ include "common.redis.values.standarized.version" (dict "context" $) }} +*/}} +{{- define "common.redis.values.standarized.version" -}} + + {{- $standarizedAuth := printf "%s%s" (include "common.redis.values.keys.prefix" .) "auth" -}} + {{- $standarizedAuthValues := include "common.utils.getValueFromKey" (dict "key" $standarizedAuth "context" .context) }} + + {{- if $standarizedAuthValues -}} + {{- true -}} + {{- end -}} +{{- end -}} diff --git a/helm/sonarqube/charts/postgresql/charts/common/templates/validations/_validations.tpl b/helm/sonarqube/charts/postgresql/charts/common/templates/validations/_validations.tpl new file mode 100644 index 0000000..9a814cf --- /dev/null +++ b/helm/sonarqube/charts/postgresql/charts/common/templates/validations/_validations.tpl @@ -0,0 +1,46 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Validate values must not be empty. + +Usage: +{{- $validateValueConf00 := (dict "valueKey" "path.to.value" "secret" "secretName" "field" "password-00") -}} +{{- $validateValueConf01 := (dict "valueKey" "path.to.value" "secret" "secretName" "field" "password-01") -}} +{{ include "common.validations.values.empty" (dict "required" (list $validateValueConf00 $validateValueConf01) "context" $) }} + +Validate value params: + - valueKey - String - Required. The path to the validating value in the values.yaml, e.g: "mysql.password" + - secret - String - Optional. Name of the secret where the validating value is generated/stored, e.g: "mysql-passwords-secret" + - field - String - Optional. Name of the field in the secret data, e.g: "mysql-password" +*/}} +{{- define "common.validations.values.multiple.empty" -}} + {{- range .required -}} + {{- include "common.validations.values.single.empty" (dict "valueKey" .valueKey "secret" .secret "field" .field "context" $.context) -}} + {{- end -}} +{{- end -}} + +{{/* +Validate a value must not be empty. + +Usage: +{{ include "common.validations.value.empty" (dict "valueKey" "mariadb.password" "secret" "secretName" "field" "my-password" "subchart" "subchart" "context" $) }} + +Validate value params: + - valueKey - String - Required. The path to the validating value in the values.yaml, e.g: "mysql.password" + - secret - String - Optional. Name of the secret where the validating value is generated/stored, e.g: "mysql-passwords-secret" + - field - String - Optional. Name of the field in the secret data, e.g: "mysql-password" + - subchart - String - Optional - Name of the subchart that the validated password is part of. +*/}} +{{- define "common.validations.values.single.empty" -}} + {{- $value := include "common.utils.getValueFromKey" (dict "key" .valueKey "context" .context) }} + {{- $subchart := ternary "" (printf "%s." .subchart) (empty .subchart) }} + + {{- if not $value -}} + {{- $varname := "my-value" -}} + {{- $getCurrentValue := "" -}} + {{- if and .secret .field -}} + {{- $varname = include "common.utils.fieldToEnvVar" . -}} + {{- $getCurrentValue = printf " To get the current value:\n\n %s\n" (include "common.utils.secret.getvalue" .) -}} + {{- end -}} + {{- printf "\n '%s' must not be empty, please add '--set %s%s=$%s' to the command.%s" .valueKey $subchart .valueKey $varname $getCurrentValue -}} + {{- end -}} +{{- end -}} diff --git a/helm/sonarqube/charts/postgresql/charts/common/values.yaml b/helm/sonarqube/charts/postgresql/charts/common/values.yaml new file mode 100644 index 0000000..f2df68e --- /dev/null +++ b/helm/sonarqube/charts/postgresql/charts/common/values.yaml @@ -0,0 +1,5 @@ +## bitnami/common +## It is required by CI/CD tools and processes. +## @skip exampleValue +## +exampleValue: common-chart diff --git a/helm/sonarqube/charts/postgresql/ci/commonAnnotations.yaml b/helm/sonarqube/charts/postgresql/ci/commonAnnotations.yaml new file mode 100644 index 0000000..97e18a4 --- /dev/null +++ b/helm/sonarqube/charts/postgresql/ci/commonAnnotations.yaml @@ -0,0 +1,3 @@ +commonAnnotations: + helm.sh/hook: "\"pre-install, pre-upgrade\"" + helm.sh/hook-weight: "-1" diff --git a/helm/sonarqube/charts/postgresql/ci/default-values.yaml b/helm/sonarqube/charts/postgresql/ci/default-values.yaml new file mode 100644 index 0000000..fc2ba60 --- /dev/null +++ b/helm/sonarqube/charts/postgresql/ci/default-values.yaml @@ -0,0 +1 @@ +# Leave this file empty to ensure that CI runs builds against the default configuration in values.yaml. diff --git a/helm/sonarqube/charts/postgresql/ci/shmvolume-disabled-values.yaml b/helm/sonarqube/charts/postgresql/ci/shmvolume-disabled-values.yaml new file mode 100644 index 0000000..347d3b4 --- /dev/null +++ b/helm/sonarqube/charts/postgresql/ci/shmvolume-disabled-values.yaml @@ -0,0 +1,2 @@ +shmVolume: + enabled: false diff --git a/helm/sonarqube/charts/postgresql/files/README.md b/helm/sonarqube/charts/postgresql/files/README.md new file mode 100644 index 0000000..1813a2f --- /dev/null +++ b/helm/sonarqube/charts/postgresql/files/README.md @@ -0,0 +1 @@ +Copy here your postgresql.conf and/or pg_hba.conf files to use it as a config map. diff --git a/helm/sonarqube/charts/postgresql/files/conf.d/README.md b/helm/sonarqube/charts/postgresql/files/conf.d/README.md new file mode 100644 index 0000000..184c187 --- /dev/null +++ b/helm/sonarqube/charts/postgresql/files/conf.d/README.md @@ -0,0 +1,4 @@ +If you don't want to provide the whole configuration file and only specify certain parameters, you can copy here your extended `.conf` files. +These files will be injected as a config maps and add/overwrite the default configuration using the `include_dir` directive that allows settings to be loaded from files other than the default `postgresql.conf`. + +More info in the [bitnami-docker-postgresql README](https://github.com/bitnami/bitnami-docker-postgresql#configuration-file). diff --git a/helm/sonarqube/charts/postgresql/files/docker-entrypoint-initdb.d/README.md b/helm/sonarqube/charts/postgresql/files/docker-entrypoint-initdb.d/README.md new file mode 100644 index 0000000..cba3809 --- /dev/null +++ b/helm/sonarqube/charts/postgresql/files/docker-entrypoint-initdb.d/README.md @@ -0,0 +1,3 @@ +You can copy here your custom `.sh`, `.sql` or `.sql.gz` file so they are executed during the first boot of the image. + +More info in the [bitnami-docker-postgresql](https://github.com/bitnami/bitnami-docker-postgresql#initializing-a-new-instance) repository. \ No newline at end of file diff --git a/helm/sonarqube/charts/postgresql/templates/NOTES.txt b/helm/sonarqube/charts/postgresql/templates/NOTES.txt new file mode 100644 index 0000000..ccb581d --- /dev/null +++ b/helm/sonarqube/charts/postgresql/templates/NOTES.txt @@ -0,0 +1,89 @@ +CHART NAME: {{ .Chart.Name }} +CHART VERSION: {{ .Chart.Version }} +APP VERSION: {{ .Chart.AppVersion }} + +** Please be patient while the chart is being deployed ** + +{{- if .Values.diagnosticMode.enabled }} +The chart has been deployed in diagnostic mode. All probes have been disabled and the command has been overwritten with: + + command: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.command "context" $) | nindent 4 }} + args: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.args "context" $) | nindent 4 }} + +Get the list of pods by executing: + + kubectl get pods --namespace {{ .Release.Namespace }} -l app.kubernetes.io/instance={{ .Release.Name }} + +Access the pod you want to debug by executing + + kubectl exec --namespace {{ .Release.Namespace }} -ti -- bash + +In order to replicate the container startup scripts execute this command: + + /opt/bitnami/scripts/postgresql/entrypoint.sh /opt/bitnami/scripts/postgresql/run.sh + +{{- else }} + +PostgreSQL can be accessed via port {{ template "postgresql.servicePort" . }} on the following DNS names from within your cluster: + + {{ template "common.names.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local - Read/Write connection +{{- if .Values.replication.enabled }} +{{- if .Values.replication.singleService }} + {{ template "common.names.fullname" . }}-read.{{ .Release.Namespace }}.svc.cluster.local - Read only connection +{{- end }} +{{- if .Values.replication.uniqueServices }} +{{- $replicaCount := .Values.replication.readReplicas | int }} +{{- $root := . }} +{{- range $i, $e := until $replicaCount }} + {{ template "common.names.fullname" $root }}-read-{{ $i }}.{{ $root.Release.Namespace }}.svc.cluster.local - Read only connection to replica {{ $i }} +{{- end }} +{{- end }} +{{- end }} + +{{- if not (eq (include "postgresql.username" .) "postgres") }} + +To get the password for "postgres" run: + + export POSTGRES_ADMIN_PASSWORD=$(kubectl get secret --namespace {{ .Release.Namespace }} {{ template "postgresql.secretName" . }} -o jsonpath="{.data.postgresql-postgres-password}" | base64 --decode) +{{- end }} + +To get the password for "{{ template "postgresql.username" . }}" run: + + export POSTGRES_PASSWORD=$(kubectl get secret --namespace {{ .Release.Namespace }} {{ template "postgresql.secretName" . }} -o jsonpath="{.data.postgresql-password}" | base64 --decode) + +To connect to your database run the following command: + + kubectl run {{ template "common.names.fullname" . }}-client --rm --tty -i --restart='Never' --namespace {{ .Release.Namespace }} --image {{ template "postgresql.image" . }} --env="PGPASSWORD=$POSTGRES_PASSWORD" {{- if and (.Values.networkPolicy.enabled) (not .Values.networkPolicy.allowExternal) }} + --labels="{{ template "common.names.fullname" . }}-client=true" {{- end }} --command -- psql --host {{ template "common.names.fullname" . }} -U {{ .Values.postgresqlUsername }} -d {{- if .Values.postgresqlDatabase }} {{ .Values.postgresqlDatabase }}{{- else }} postgres{{- end }} -p {{ template "postgresql.servicePort" . }} + +{{ if and (.Values.networkPolicy.enabled) (not .Values.networkPolicy.allowExternal) }} +Note: Since NetworkPolicy is enabled, only pods with label {{ template "common.names.fullname" . }}-client=true" will be able to connect to this PostgreSQL cluster. +{{- end }} + +To connect to your database from outside the cluster execute the following commands: + +{{- if contains "NodePort" .Values.service.type }} + + export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") + export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "common.names.fullname" . }}) + {{ if (include "postgresql.password" . ) }}PGPASSWORD="$POSTGRES_PASSWORD" {{ end }}psql --host $NODE_IP --port $NODE_PORT -U {{ .Values.postgresqlUsername }} -d {{- if .Values.postgresqlDatabase }} {{ .Values.postgresqlDatabase }}{{- else }} postgres{{- end }} + +{{- else if contains "LoadBalancer" .Values.service.type }} + + NOTE: It may take a few minutes for the LoadBalancer IP to be available. + Watch the status with: 'kubectl get svc --namespace {{ .Release.Namespace }} -w {{ template "common.names.fullname" . }}' + + export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "common.names.fullname" . }} --template "{{ "{{ range (index .status.loadBalancer.ingress 0) }}{{ . }}{{ end }}" }}") + {{ if (include "postgresql.password" . ) }}PGPASSWORD="$POSTGRES_PASSWORD" {{ end }}psql --host $SERVICE_IP --port {{ template "postgresql.servicePort" . }} -U {{ .Values.postgresqlUsername }} -d {{- if .Values.postgresqlDatabase }} {{ .Values.postgresqlDatabase }}{{- else }} postgres{{- end }} + +{{- else if contains "ClusterIP" .Values.service.type }} + + kubectl port-forward --namespace {{ .Release.Namespace }} svc/{{ template "common.names.fullname" . }} {{ template "postgresql.servicePort" . }}:{{ template "postgresql.servicePort" . }} & + {{ if (include "postgresql.password" . ) }}PGPASSWORD="$POSTGRES_PASSWORD" {{ end }}psql --host 127.0.0.1 -U {{ .Values.postgresqlUsername }} -d {{- if .Values.postgresqlDatabase }} {{ .Values.postgresqlDatabase }}{{- else }} postgres{{- end }} -p {{ template "postgresql.servicePort" . }} + +{{- end }} +{{- end }} + +{{- include "postgresql.validateValues" . -}} +{{- include "common.warnings.rollingTag" .Values.image -}} +{{- include "common.warnings.rollingTag" .Values.volumePermissions.image }} diff --git a/helm/sonarqube/charts/postgresql/templates/_helpers.tpl b/helm/sonarqube/charts/postgresql/templates/_helpers.tpl new file mode 100644 index 0000000..16e4456 --- /dev/null +++ b/helm/sonarqube/charts/postgresql/templates/_helpers.tpl @@ -0,0 +1,361 @@ +{{/* vim: set filetype=mustache: */}} + +{{/* +Expand the name of the chart. +*/}} +{{- define "postgresql.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +*/}} +{{- define "postgresql.primary.fullname" -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- $fullname := default (printf "%s-%s" .Release.Name $name) .Values.fullnameOverride -}} +{{- if .Values.replication.enabled -}} +{{- printf "%s-%s" $fullname "primary" | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s" $fullname | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the proper PostgreSQL image name +*/}} +{{- define "postgresql.image" -}} +{{ include "common.images.image" (dict "imageRoot" .Values.image "global" .Values.global) }} +{{- end -}} + +{{/* +Return the proper PostgreSQL metrics image name +*/}} +{{- define "postgresql.metrics.image" -}} +{{ include "common.images.image" (dict "imageRoot" .Values.metrics.image "global" .Values.global) }} +{{- end -}} + +{{/* +Return the proper image name (for the init container volume-permissions image) +*/}} +{{- define "postgresql.volumePermissions.image" -}} +{{ include "common.images.image" (dict "imageRoot" .Values.volumePermissions.image "global" .Values.global) }} +{{- end -}} + +{{/* +Return the proper Docker Image Registry Secret Names +*/}} +{{- define "postgresql.imagePullSecrets" -}} +{{ include "common.images.pullSecrets" (dict "images" (list .Values.image .Values.metrics.image .Values.volumePermissions.image) "global" .Values.global) }} +{{- end -}} + +{{/* +Returns the available value for certain key in an existing secret (if it exists), +otherwise it generates a random value. +*/}} +{{- define "getValueFromSecret" }} +{{- $len := (default 16 .Length) | int -}} +{{- $obj := (lookup "v1" "Secret" .Namespace .Name).data -}} +{{- if $obj }} +{{- index $obj .Key | b64dec -}} +{{- else -}} +{{- randAlphaNum $len -}} +{{- end -}} +{{- end }} + +{{/* +Return PostgreSQL postgres user password +*/}} +{{- define "postgresql.postgres.password" -}} +{{- if .Values.global.postgresql.postgresqlPostgresPassword }} + {{- .Values.global.postgresql.postgresqlPostgresPassword -}} +{{- else if .Values.postgresqlPostgresPassword -}} + {{- .Values.postgresqlPostgresPassword -}} +{{- else -}} + {{- include "getValueFromSecret" (dict "Namespace" .Release.Namespace "Name" (include "common.names.fullname" .) "Length" 10 "Key" "postgresql-postgres-password") -}} +{{- end -}} +{{- end -}} + +{{/* +Return PostgreSQL password +*/}} +{{- define "postgresql.password" -}} +{{- if .Values.global.postgresql.postgresqlPassword }} + {{- .Values.global.postgresql.postgresqlPassword -}} +{{- else if .Values.postgresqlPassword -}} + {{- .Values.postgresqlPassword -}} +{{- else -}} + {{- include "getValueFromSecret" (dict "Namespace" .Release.Namespace "Name" (include "common.names.fullname" .) "Length" 10 "Key" "postgresql-password") -}} +{{- end -}} +{{- end -}} + +{{/* +Return PostgreSQL replication password +*/}} +{{- define "postgresql.replication.password" -}} +{{- if .Values.global.postgresql.replicationPassword }} + {{- .Values.global.postgresql.replicationPassword -}} +{{- else if .Values.replication.password -}} + {{- .Values.replication.password -}} +{{- else -}} + {{- include "getValueFromSecret" (dict "Namespace" .Release.Namespace "Name" (include "common.names.fullname" .) "Length" 10 "Key" "postgresql-replication-password") -}} +{{- end -}} +{{- end -}} + +{{/* +Return PostgreSQL username +*/}} +{{- define "postgresql.username" -}} +{{- if .Values.global.postgresql.postgresqlUsername }} + {{- .Values.global.postgresql.postgresqlUsername -}} +{{- else -}} + {{- .Values.postgresqlUsername -}} +{{- end -}} +{{- end -}} + +{{/* +Return PostgreSQL replication username +*/}} +{{- define "postgresql.replication.username" -}} +{{- if .Values.global.postgresql.replicationUser }} + {{- .Values.global.postgresql.replicationUser -}} +{{- else -}} + {{- .Values.replication.user -}} +{{- end -}} +{{- end -}} + +{{/* +Return PostgreSQL port +*/}} +{{- define "postgresql.servicePort" -}} +{{- if .Values.global.postgresql.servicePort }} + {{- .Values.global.postgresql.servicePort -}} +{{- else -}} + {{- .Values.service.port -}} +{{- end -}} +{{- end -}} + +{{/* +Return PostgreSQL created database +*/}} +{{- define "postgresql.database" -}} +{{- if .Values.global.postgresql.postgresqlDatabase }} + {{- .Values.global.postgresql.postgresqlDatabase -}} +{{- else if .Values.postgresqlDatabase -}} + {{- .Values.postgresqlDatabase -}} +{{- end -}} +{{- end -}} + +{{/* +Get the password secret. +*/}} +{{- define "postgresql.secretName" -}} +{{- if .Values.global.postgresql.existingSecret }} + {{- printf "%s" (tpl .Values.global.postgresql.existingSecret $) -}} +{{- else if .Values.existingSecret -}} + {{- printf "%s" (tpl .Values.existingSecret $) -}} +{{- else -}} + {{- printf "%s" (include "common.names.fullname" .) -}} +{{- end -}} +{{- end -}} + +{{/* +Return true if we should use an existingSecret. +*/}} +{{- define "postgresql.useExistingSecret" -}} +{{- if or .Values.global.postgresql.existingSecret .Values.existingSecret -}} + {{- true -}} +{{- end -}} +{{- end -}} + +{{/* +Return true if a secret object should be created +*/}} +{{- define "postgresql.createSecret" -}} +{{- if not (include "postgresql.useExistingSecret" .) -}} + {{- true -}} +{{- end -}} +{{- end -}} + +{{/* +Get the configuration ConfigMap name. +*/}} +{{- define "postgresql.configurationCM" -}} +{{- if .Values.configurationConfigMap -}} +{{- printf "%s" (tpl .Values.configurationConfigMap $) -}} +{{- else -}} +{{- printf "%s-configuration" (include "common.names.fullname" .) -}} +{{- end -}} +{{- end -}} + +{{/* +Get the extended configuration ConfigMap name. +*/}} +{{- define "postgresql.extendedConfigurationCM" -}} +{{- if .Values.extendedConfConfigMap -}} +{{- printf "%s" (tpl .Values.extendedConfConfigMap $) -}} +{{- else -}} +{{- printf "%s-extended-configuration" (include "common.names.fullname" .) -}} +{{- end -}} +{{- end -}} + +{{/* +Return true if a configmap should be mounted with PostgreSQL configuration +*/}} +{{- define "postgresql.mountConfigurationCM" -}} +{{- if or (.Files.Glob "files/postgresql.conf") (.Files.Glob "files/pg_hba.conf") .Values.postgresqlConfiguration .Values.pgHbaConfiguration .Values.configurationConfigMap }} + {{- true -}} +{{- end -}} +{{- end -}} + +{{/* +Get the initialization scripts ConfigMap name. +*/}} +{{- define "postgresql.initdbScriptsCM" -}} +{{- if .Values.initdbScriptsConfigMap -}} +{{- printf "%s" (tpl .Values.initdbScriptsConfigMap $) -}} +{{- else -}} +{{- printf "%s-init-scripts" (include "common.names.fullname" .) -}} +{{- end -}} +{{- end -}} + +{{/* +Get the initialization scripts Secret name. +*/}} +{{- define "postgresql.initdbScriptsSecret" -}} +{{- printf "%s" (tpl .Values.initdbScriptsSecret $) -}} +{{- end -}} + +{{/* +Get the metrics ConfigMap name. +*/}} +{{- define "postgresql.metricsCM" -}} +{{- printf "%s-metrics" (include "common.names.fullname" .) -}} +{{- end -}} + +{{/* +Get the readiness probe command +*/}} +{{- define "postgresql.readinessProbeCommand" -}} +- | +{{- if (include "postgresql.database" .) }} + exec pg_isready -U {{ include "postgresql.username" . | quote }} -d "dbname={{ include "postgresql.database" . }} {{- if .Values.tls.enabled }} sslcert={{ include "postgresql.tlsCert" . }} sslkey={{ include "postgresql.tlsCertKey" . }}{{- end }}" -h 127.0.0.1 -p {{ .Values.containerPorts.postgresql }} +{{- else }} + exec pg_isready -U {{ include "postgresql.username" . | quote }} {{- if .Values.tls.enabled }} -d "sslcert={{ include "postgresql.tlsCert" . }} sslkey={{ include "postgresql.tlsCertKey" . }}"{{- end }} -h 127.0.0.1 -p {{ .Values.containerPorts.postgresql }} +{{- end }} +{{- if contains "bitnami/" .Values.image.repository }} + [ -f /opt/bitnami/postgresql/tmp/.initialized ] || [ -f /bitnami/postgresql/.initialized ] +{{- end -}} +{{- end -}} + +{{/* +Compile all warnings into a single message, and call fail. +*/}} +{{- define "postgresql.validateValues" -}} +{{- $messages := list -}} +{{- $messages := append $messages (include "postgresql.validateValues.ldapConfigurationMethod" .) -}} +{{- $messages := append $messages (include "postgresql.validateValues.psp" .) -}} +{{- $messages := append $messages (include "postgresql.validateValues.tls" .) -}} +{{- $messages := without $messages "" -}} +{{- $message := join "\n" $messages -}} + +{{- if $message -}} +{{- printf "\nVALUES VALIDATION:\n%s" $message | fail -}} +{{- end -}} +{{- end -}} + +{{/* +Validate values of Postgresql - If ldap.url is used then you don't need the other settings for ldap +*/}} +{{- define "postgresql.validateValues.ldapConfigurationMethod" -}} +{{- if and .Values.ldap.enabled (and (not (empty .Values.ldap.url)) (not (empty .Values.ldap.server))) }} +postgresql: ldap.url, ldap.server + You cannot set both `ldap.url` and `ldap.server` at the same time. + Please provide a unique way to configure LDAP. + More info at https://www.postgresql.org/docs/current/auth-ldap.html +{{- end -}} +{{- end -}} + +{{/* +Validate values of Postgresql - If PSP is enabled RBAC should be enabled too +*/}} +{{- define "postgresql.validateValues.psp" -}} +{{- if and .Values.psp.create (not .Values.rbac.create) }} +postgresql: psp.create, rbac.create + RBAC should be enabled if PSP is enabled in order for PSP to work. + More info at https://kubernetes.io/docs/concepts/policy/pod-security-policy/#authorizing-policies +{{- end -}} +{{- end -}} + +{{/* +Validate values of Postgresql TLS - When TLS is enabled, so must be VolumePermissions +*/}} +{{- define "postgresql.validateValues.tls" -}} +{{- if and .Values.tls.enabled (not .Values.volumePermissions.enabled) }} +postgresql: tls.enabled, volumePermissions.enabled + When TLS is enabled you must enable volumePermissions as well to ensure certificates files have + the right permissions. +{{- end -}} +{{- end -}} + +{{/* +Return the path to the cert file. +*/}} +{{- define "postgresql.tlsCert" -}} +{{- if .Values.tls.autoGenerated }} + {{- printf "/opt/bitnami/postgresql/certs/tls.crt" -}} +{{- else -}} + {{- required "Certificate filename is required when TLS in enabled" .Values.tls.certFilename | printf "/opt/bitnami/postgresql/certs/%s" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the path to the cert key file. +*/}} +{{- define "postgresql.tlsCertKey" -}} +{{- if .Values.tls.autoGenerated }} + {{- printf "/opt/bitnami/postgresql/certs/tls.key" -}} +{{- else -}} +{{- required "Certificate Key filename is required when TLS in enabled" .Values.tls.certKeyFilename | printf "/opt/bitnami/postgresql/certs/%s" -}} +{{- end -}} +{{- end -}} + +{{/* +Return the path to the CA cert file. +*/}} +{{- define "postgresql.tlsCACert" -}} +{{- if .Values.tls.autoGenerated }} + {{- printf "/opt/bitnami/postgresql/certs/ca.crt" -}} +{{- else -}} + {{- printf "/opt/bitnami/postgresql/certs/%s" .Values.tls.certCAFilename -}} +{{- end -}} +{{- end -}} + +{{/* +Return the path to the CRL file. +*/}} +{{- define "postgresql.tlsCRL" -}} +{{- if .Values.tls.crlFilename -}} +{{- printf "/opt/bitnami/postgresql/certs/%s" .Values.tls.crlFilename -}} +{{- end -}} +{{- end -}} + +{{/* +Return true if a TLS credentials secret object should be created +*/}} +{{- define "postgresql.createTlsSecret" -}} +{{- if and .Values.tls.autoGenerated (not .Values.tls.certificatesSecret) }} + {{- true -}} +{{- end -}} +{{- end -}} + +{{/* +Return the path to the CA cert file. +*/}} +{{- define "postgresql.tlsSecretName" -}} +{{- if .Values.tls.autoGenerated }} + {{- printf "%s-crt" (include "common.names.fullname" .) -}} +{{- else -}} + {{ required "A secret containing TLS certificates is required when TLS is enabled" .Values.tls.certificatesSecret }} +{{- end -}} +{{- end -}} diff --git a/helm/sonarqube/charts/postgresql/templates/configmap.yaml b/helm/sonarqube/charts/postgresql/templates/configmap.yaml new file mode 100644 index 0000000..0ff4dfe --- /dev/null +++ b/helm/sonarqube/charts/postgresql/templates/configmap.yaml @@ -0,0 +1,34 @@ +{{ if and (or (.Files.Glob "files/postgresql.conf") (.Files.Glob "files/pg_hba.conf") .Values.postgresqlConfiguration .Values.pgHbaConfiguration) (not .Values.configurationConfigMap) }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "common.names.fullname" . }}-configuration + labels: + {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} + namespace: {{ .Release.Namespace }} +data: +{{- if (.Files.Glob "files/postgresql.conf") }} +{{ (.Files.Glob "files/postgresql.conf").AsConfig | indent 2 }} +{{- else if .Values.postgresqlConfiguration }} + postgresql.conf: | +{{- range $key, $value := default dict .Values.postgresqlConfiguration }} + {{- if kindIs "string" $value }} + {{ $key | snakecase }} = '{{ $value }}' + {{- else }} + {{ $key | snakecase }} = {{ $value }} + {{- end }} +{{- end }} +{{- end }} +{{- if (.Files.Glob "files/pg_hba.conf") }} +{{ (.Files.Glob "files/pg_hba.conf").AsConfig | indent 2 }} +{{- else if .Values.pgHbaConfiguration }} + pg_hba.conf: | +{{ .Values.pgHbaConfiguration | indent 4 }} +{{- end }} +{{ end }} diff --git a/helm/sonarqube/charts/postgresql/templates/extended-config-configmap.yaml b/helm/sonarqube/charts/postgresql/templates/extended-config-configmap.yaml new file mode 100644 index 0000000..a94e06f --- /dev/null +++ b/helm/sonarqube/charts/postgresql/templates/extended-config-configmap.yaml @@ -0,0 +1,29 @@ +{{- if and (or (.Files.Glob "files/conf.d/*.conf") .Values.postgresqlExtendedConf) (not .Values.extendedConfConfigMap) }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "common.names.fullname" . }}-extended-configuration + labels: + {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} + namespace: {{ .Release.Namespace }} +data: +{{- with .Files.Glob "files/conf.d/*.conf" }} +{{ .AsConfig | indent 2 }} +{{- end }} +{{ with .Values.postgresqlExtendedConf }} + override.conf: | +{{- range $key, $value := . }} + {{- if kindIs "string" $value }} + {{ $key | snakecase }} = '{{ $value }}' + {{- else }} + {{ $key | snakecase }} = {{ $value }} + {{- end }} +{{- end }} +{{- end }} +{{- end }} diff --git a/helm/sonarqube/charts/postgresql/templates/extra-list.yaml b/helm/sonarqube/charts/postgresql/templates/extra-list.yaml new file mode 100644 index 0000000..9ac65f9 --- /dev/null +++ b/helm/sonarqube/charts/postgresql/templates/extra-list.yaml @@ -0,0 +1,4 @@ +{{- range .Values.extraDeploy }} +--- +{{ include "common.tplvalues.render" (dict "value" . "context" $) }} +{{- end }} diff --git a/helm/sonarqube/charts/postgresql/templates/initialization-configmap.yaml b/helm/sonarqube/charts/postgresql/templates/initialization-configmap.yaml new file mode 100644 index 0000000..c681e5c --- /dev/null +++ b/helm/sonarqube/charts/postgresql/templates/initialization-configmap.yaml @@ -0,0 +1,26 @@ +{{- if and (or (.Files.Glob "files/docker-entrypoint-initdb.d/*.{sh,sql,sql.gz}") .Values.initdbScripts) (not .Values.initdbScriptsConfigMap) }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "common.names.fullname" . }}-init-scripts + labels: + {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} + namespace: {{ .Release.Namespace }} +{{- with .Files.Glob "files/docker-entrypoint-initdb.d/*.sql.gz" }} +binaryData: +{{- range $path, $bytes := . }} + {{ base $path }}: {{ $.Files.Get $path | b64enc | quote }} +{{- end }} +{{- end }} +data: +{{- with .Files.Glob "files/docker-entrypoint-initdb.d/*.{sh,sql}" }} +{{ .AsConfig | indent 2 }} +{{- end }} +{{- include "common.tplvalues.render" (dict "value" .Values.initdbScripts "context" .) | nindent 2 }} +{{- end }} diff --git a/helm/sonarqube/charts/postgresql/templates/metrics-configmap.yaml b/helm/sonarqube/charts/postgresql/templates/metrics-configmap.yaml new file mode 100644 index 0000000..b6411f3 --- /dev/null +++ b/helm/sonarqube/charts/postgresql/templates/metrics-configmap.yaml @@ -0,0 +1,17 @@ +{{- if and .Values.metrics.enabled .Values.metrics.customMetrics }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "postgresql.metricsCM" . }} + labels: + {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} + namespace: {{ .Release.Namespace }} +data: + custom-metrics.yaml: {{ toYaml .Values.metrics.customMetrics | quote }} +{{- end }} diff --git a/helm/sonarqube/charts/postgresql/templates/metrics-svc.yaml b/helm/sonarqube/charts/postgresql/templates/metrics-svc.yaml new file mode 100644 index 0000000..06c52fd --- /dev/null +++ b/helm/sonarqube/charts/postgresql/templates/metrics-svc.yaml @@ -0,0 +1,29 @@ +{{- if .Values.metrics.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "common.names.fullname" . }}-metrics + labels: + {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + annotations: + {{- if .Values.commonAnnotations }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} + {{- toYaml .Values.metrics.service.annotations | nindent 4 }} + namespace: {{ .Release.Namespace }} +spec: + type: {{ .Values.metrics.service.type }} + {{- if and (eq .Values.metrics.service.type "LoadBalancer") .Values.metrics.service.loadBalancerIP }} + loadBalancerIP: {{ .Values.metrics.service.loadBalancerIP }} + {{- end }} + ports: + - name: http-metrics + port: 9187 + targetPort: http-metrics + selector: + {{- include "common.labels.matchLabels" . | nindent 4 }} + role: primary +{{- end }} diff --git a/helm/sonarqube/charts/postgresql/templates/networkpolicy.yaml b/helm/sonarqube/charts/postgresql/templates/networkpolicy.yaml new file mode 100644 index 0000000..c51f678 --- /dev/null +++ b/helm/sonarqube/charts/postgresql/templates/networkpolicy.yaml @@ -0,0 +1,42 @@ +{{- if .Values.networkPolicy.enabled }} +kind: NetworkPolicy +apiVersion: {{ include "common.capabilities.networkPolicy.apiVersion" . }} +metadata: + name: {{ template "common.names.fullname" . }} + labels: + {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} + namespace: {{ .Release.Namespace }} +spec: + podSelector: + matchLabels: + {{- include "common.labels.matchLabels" . | nindent 6 }} + ingress: + # Allow inbound connections + - ports: + - port: {{ template "postgresql.servicePort" . }} + {{- if not .Values.networkPolicy.allowExternal }} + from: + - podSelector: + matchLabels: + {{ template "common.names.fullname" . }}-client: "true" + {{- if .Values.networkPolicy.explicitNamespacesSelector }} + namespaceSelector: +{{ toYaml .Values.networkPolicy.explicitNamespacesSelector | indent 12 }} + {{- end }} + - podSelector: + matchLabels: + {{- include "common.labels.matchLabels" . | nindent 14 }} + role: read + {{- end }} + {{- if .Values.metrics.enabled }} + # Allow prometheus scrapes + - ports: + - port: 9187 + {{- end }} +{{- end }} diff --git a/helm/sonarqube/charts/postgresql/templates/podsecuritypolicy.yaml b/helm/sonarqube/charts/postgresql/templates/podsecuritypolicy.yaml new file mode 100644 index 0000000..0eefb3b --- /dev/null +++ b/helm/sonarqube/charts/postgresql/templates/podsecuritypolicy.yaml @@ -0,0 +1,42 @@ +{{- $pspAvailable := (semverCompare "<1.25-0" (include "common.capabilities.kubeVersion" .)) -}} +{{- if and $pspAvailable .Values.psp.create }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "common.names.fullname" . }} + labels: + {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} + namespace: {{ .Release.Namespace }} +spec: + privileged: false + volumes: + - 'configMap' + - 'secret' + - 'persistentVolumeClaim' + - 'emptyDir' + - 'projected' + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + rule: 'RunAsAny' + seLinux: + rule: 'RunAsAny' + supplementalGroups: + rule: 'MustRunAs' + ranges: + - min: 1 + max: 65535 + fsGroup: + rule: 'MustRunAs' + ranges: + - min: 1 + max: 65535 + readOnlyRootFilesystem: false +{{- end }} diff --git a/helm/sonarqube/charts/postgresql/templates/prometheusrule.yaml b/helm/sonarqube/charts/postgresql/templates/prometheusrule.yaml new file mode 100644 index 0000000..727a6b7 --- /dev/null +++ b/helm/sonarqube/charts/postgresql/templates/prometheusrule.yaml @@ -0,0 +1,26 @@ +{{- if and .Values.metrics.enabled .Values.metrics.prometheusRule.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: {{ template "common.names.fullname" . }} +{{- with .Values.metrics.prometheusRule.namespace }} + namespace: {{ . }} +{{- end }} + labels: + {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- with .Values.metrics.prometheusRule.additionalLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +spec: +{{- with .Values.metrics.prometheusRule.rules }} + groups: + - name: {{ template "postgresql.name" $ }} + rules: {{ tpl (toYaml .) $ | nindent 8 }} +{{- end }} +{{- end }} diff --git a/helm/sonarqube/charts/postgresql/templates/role.yaml b/helm/sonarqube/charts/postgresql/templates/role.yaml new file mode 100644 index 0000000..1366eda --- /dev/null +++ b/helm/sonarqube/charts/postgresql/templates/role.yaml @@ -0,0 +1,24 @@ +{{- if .Values.rbac.create }} +kind: Role +apiVersion: {{ include "common.capabilities.rbac.apiVersion" . }} +metadata: + name: {{ template "common.names.fullname" . }} + labels: + {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} + namespace: {{ .Release.Namespace }} +rules: + {{- $pspAvailable := (semverCompare "<1.25-0" (include "common.capabilities.kubeVersion" .)) -}} + {{- if and $pspAvailable .Values.psp.create }} + - apiGroups: ["extensions"] + resources: ["podsecuritypolicies"] + verbs: ["use"] + resourceNames: + - {{ template "common.names.fullname" . }} + {{- end }} +{{- end }} diff --git a/helm/sonarqube/charts/postgresql/templates/rolebinding.yaml b/helm/sonarqube/charts/postgresql/templates/rolebinding.yaml new file mode 100644 index 0000000..988cb73 --- /dev/null +++ b/helm/sonarqube/charts/postgresql/templates/rolebinding.yaml @@ -0,0 +1,23 @@ +{{- if .Values.rbac.create }} +kind: RoleBinding +apiVersion: {{ include "common.capabilities.rbac.apiVersion" . }} +metadata: + name: {{ template "common.names.fullname" . }} + labels: + {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} + namespace: {{ .Release.Namespace }} +roleRef: + kind: Role + name: {{ template "common.names.fullname" . }} + apiGroup: rbac.authorization.k8s.io +subjects: + - kind: ServiceAccount + name: {{ default (include "common.names.fullname" . ) .Values.serviceAccount.name }} + namespace: {{ .Release.Namespace }} +{{- end }} diff --git a/helm/sonarqube/charts/postgresql/templates/secrets.yaml b/helm/sonarqube/charts/postgresql/templates/secrets.yaml new file mode 100644 index 0000000..6bab462 --- /dev/null +++ b/helm/sonarqube/charts/postgresql/templates/secrets.yaml @@ -0,0 +1,27 @@ +{{- if (include "postgresql.createSecret" .) }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "common.names.fullname" . }} + labels: + {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} + namespace: {{ .Release.Namespace }} +type: Opaque +data: + {{- if not (eq (include "postgresql.username" .) "postgres") }} + postgresql-postgres-password: {{ include "postgresql.postgres.password" . | b64enc | quote }} + {{- end }} + postgresql-password: {{ include "postgresql.password" . | b64enc | quote }} + {{- if .Values.replication.enabled }} + postgresql-replication-password: {{ include "postgresql.replication.password" . | b64enc | quote }} + {{- end }} + {{- if (and .Values.ldap.enabled .Values.ldap.bind_password) }} + postgresql-ldap-password: {{ .Values.ldap.bind_password | b64enc | quote }} + {{- end }} +{{- end -}} diff --git a/helm/sonarqube/charts/postgresql/templates/serviceaccount.yaml b/helm/sonarqube/charts/postgresql/templates/serviceaccount.yaml new file mode 100644 index 0000000..8e951b8 --- /dev/null +++ b/helm/sonarqube/charts/postgresql/templates/serviceaccount.yaml @@ -0,0 +1,15 @@ +{{- if and (.Values.serviceAccount.enabled) (not .Values.serviceAccount.name) }} +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + name: {{ template "common.names.fullname" . }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} + namespace: {{ .Release.Namespace }} +{{- end }} diff --git a/helm/sonarqube/charts/postgresql/templates/servicemonitor.yaml b/helm/sonarqube/charts/postgresql/templates/servicemonitor.yaml new file mode 100644 index 0000000..6cd6a1d --- /dev/null +++ b/helm/sonarqube/charts/postgresql/templates/servicemonitor.yaml @@ -0,0 +1,42 @@ +{{- if and .Values.metrics.enabled .Values.metrics.serviceMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ include "common.names.fullname" . }} + {{- if .Values.metrics.serviceMonitor.namespace }} + namespace: {{ .Values.metrics.serviceMonitor.namespace }} + {{- end }} + labels: + {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.metrics.serviceMonitor.additionalLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.metrics.serviceMonitor.additionalLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} + +spec: + endpoints: + - port: http-metrics + {{- if .Values.metrics.serviceMonitor.interval }} + interval: {{ .Values.metrics.serviceMonitor.interval }} + {{- end }} + {{- if .Values.metrics.serviceMonitor.scrapeTimeout }} + scrapeTimeout: {{ .Values.metrics.serviceMonitor.scrapeTimeout }} + {{- end }} + {{- if .Values.metrics.serviceMonitor.relabelings }} + relabelings: {{- include "common.tplvalues.render" ( dict "value" .Values.metrics.serviceMonitor.relabelings "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.metrics.serviceMonitor.metricRelabelings }} + metricRelabelings: {{- include "common.tplvalues.render" ( dict "value" .Values.metrics.serviceMonitor.metricRelabelings "context" $) | nindent 8 }} + {{- end }} + namespaceSelector: + matchNames: + - {{ .Release.Namespace }} + selector: + matchLabels: + {{- include "common.labels.matchLabels" . | nindent 6 }} +{{- end }} diff --git a/helm/sonarqube/charts/postgresql/templates/statefulset-readreplicas.yaml b/helm/sonarqube/charts/postgresql/templates/statefulset-readreplicas.yaml new file mode 100644 index 0000000..505093a --- /dev/null +++ b/helm/sonarqube/charts/postgresql/templates/statefulset-readreplicas.yaml @@ -0,0 +1,430 @@ +{{- if .Values.replication.enabled }} +{{- $readReplicasResources := coalesce .Values.readReplicas.resources .Values.resources -}} +apiVersion: {{ include "common.capabilities.statefulset.apiVersion" . }} +kind: StatefulSet +metadata: + name: "{{ template "common.names.fullname" . }}-read" + labels: {{- include "common.labels.standard" . | nindent 4 }} + app.kubernetes.io/component: read + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.readReplicas.labels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.readReplicas.labels "context" $ ) | nindent 4 }} + {{- end }} + annotations: + {{- if .Values.commonAnnotations }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} + {{- with .Values.readReplicas.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + namespace: {{ .Release.Namespace }} +spec: + serviceName: {{ template "common.names.fullname" . }}-headless + replicas: {{ .Values.replication.readReplicas }} + selector: + matchLabels: + {{- include "common.labels.matchLabels" . | nindent 6 }} + role: read + template: + metadata: + name: {{ template "common.names.fullname" . }} + labels: + {{- include "common.labels.standard" . | nindent 8 }} + app.kubernetes.io/component: read + role: read + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 8 }} + {{- end }} + {{- if .Values.readReplicas.podLabels }} + {{- include "common.tplvalues.render" (dict "value" .Values.readReplicas.podLabels "context" $) | nindent 8 }} + {{- end }} +{{- with .Values.readReplicas.podAnnotations }} + annotations: +{{ toYaml . | indent 8 }} +{{- end }} + spec: + {{- if .Values.schedulerName }} + schedulerName: "{{ .Values.schedulerName }}" + {{- end }} +{{- include "postgresql.imagePullSecrets" . | indent 6 }} + {{- if .Values.readReplicas.affinity }} + affinity: {{- include "common.tplvalues.render" (dict "value" .Values.readReplicas.affinity "context" $) | nindent 8 }} + {{- else }} + affinity: + podAffinity: {{- include "common.affinities.pods" (dict "type" .Values.readReplicas.podAffinityPreset "component" "read" "context" $) | nindent 10 }} + podAntiAffinity: {{- include "common.affinities.pods" (dict "type" .Values.readReplicas.podAntiAffinityPreset "component" "read" "context" $) | nindent 10 }} + nodeAffinity: {{- include "common.affinities.nodes" (dict "type" .Values.readReplicas.nodeAffinityPreset.type "key" .Values.readReplicas.nodeAffinityPreset.key "values" .Values.readReplicas.nodeAffinityPreset.values) | nindent 10 }} + {{- end }} + {{- if .Values.readReplicas.nodeSelector }} + nodeSelector: {{- include "common.tplvalues.render" (dict "value" .Values.readReplicas.nodeSelector "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.readReplicas.tolerations }} + tolerations: {{- include "common.tplvalues.render" (dict "value" .Values.readReplicas.tolerations "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.readReplicas.topologySpreadConstraints }} + topologySpreadConstraints: {{- include "common.tplvalues.render" (dict "value" .Values.readReplicas.topologySpreadConstraints "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.terminationGracePeriodSeconds }} + terminationGracePeriodSeconds: {{ .Values.terminationGracePeriodSeconds }} + {{- end }} + {{- if .Values.securityContext.enabled }} + securityContext: {{- omit .Values.securityContext "enabled" | toYaml | nindent 8 }} + {{- end }} + automountServiceAccountToken: {{ .Values.serviceAccount.autoMount }} + {{- if .Values.serviceAccount.enabled }} + serviceAccountName: {{ default (include "common.names.fullname" . ) .Values.serviceAccount.name }} + {{- end }} + {{- if or .Values.readReplicas.extraInitContainers (and .Values.volumePermissions.enabled (or .Values.persistence.enabled (and .Values.shmVolume.enabled .Values.shmVolume.chmod.enabled))) }} + initContainers: + {{- if and .Values.volumePermissions.enabled (or .Values.persistence.enabled (and .Values.shmVolume.enabled .Values.shmVolume.chmod.enabled) .Values.tls.enabled) }} + - name: init-chmod-data + image: {{ template "postgresql.volumePermissions.image" . }} + imagePullPolicy: {{ .Values.volumePermissions.image.pullPolicy | quote }} + {{- if .Values.resources }} + resources: {{- toYaml .Values.resources | nindent 12 }} + {{- end }} + command: + - /bin/sh + - -cx + - | + {{- if .Values.persistence.enabled }} + {{- if eq ( toString ( .Values.volumePermissions.securityContext.runAsUser )) "auto" }} + chown `id -u`:`id -G | cut -d " " -f2` {{ .Values.persistence.mountPath }} + {{- else }} + chown {{ .Values.containerSecurityContext.runAsUser }}:{{ .Values.securityContext.fsGroup }} {{ .Values.persistence.mountPath }} + {{- end }} + mkdir -p {{ .Values.persistence.mountPath }}/data {{- if (include "postgresql.mountConfigurationCM" .) }} {{ .Values.persistence.mountPath }}/conf {{- end }} + chmod 700 {{ .Values.persistence.mountPath }}/data {{- if (include "postgresql.mountConfigurationCM" .) }} {{ .Values.persistence.mountPath }}/conf {{- end }} + find {{ .Values.persistence.mountPath }} -mindepth 1 -maxdepth 1 {{- if not (include "postgresql.mountConfigurationCM" .) }} -not -name "conf" {{- end }} -not -name ".snapshot" -not -name "lost+found" | \ + {{- if eq ( toString ( .Values.volumePermissions.securityContext.runAsUser )) "auto" }} + xargs chown -R `id -u`:`id -G | cut -d " " -f2` + {{- else }} + xargs chown -R {{ .Values.containerSecurityContext.runAsUser }}:{{ .Values.securityContext.fsGroup }} + {{- end }} + {{- end }} + {{- if and .Values.shmVolume.enabled .Values.shmVolume.chmod.enabled }} + chmod -R 777 /dev/shm + {{- end }} + {{- if .Values.tls.enabled }} + cp /tmp/certs/* /opt/bitnami/postgresql/certs/ + {{- if eq ( toString ( .Values.volumePermissions.securityContext.runAsUser )) "auto" }} + chown -R `id -u`:`id -G | cut -d " " -f2` /opt/bitnami/postgresql/certs/ + {{- else }} + chown -R {{ .Values.containerSecurityContext.runAsUser }}:{{ .Values.securityContext.fsGroup }} /opt/bitnami/postgresql/certs/ + {{- end }} + chmod 600 {{ template "postgresql.tlsCertKey" . }} + {{- end }} + {{- if eq ( toString ( .Values.volumePermissions.securityContext.runAsUser )) "auto" }} + securityContext: {{- omit .Values.volumePermissions.securityContext "runAsUser" | toYaml | nindent 12 }} + {{- else }} + securityContext: {{- .Values.volumePermissions.securityContext | toYaml | nindent 12 }} + {{- end }} + volumeMounts: + {{ if .Values.persistence.enabled }} + - name: data + mountPath: {{ .Values.persistence.mountPath }} + subPath: {{ .Values.persistence.subPath }} + {{- end }} + {{- if .Values.shmVolume.enabled }} + - name: dshm + mountPath: /dev/shm + {{- end }} + {{- if .Values.tls.enabled }} + - name: raw-certificates + mountPath: /tmp/certs + - name: postgresql-certificates + mountPath: /opt/bitnami/postgresql/certs + {{- end }} + {{- end }} + {{- if .Values.readReplicas.extraInitContainers }} + {{- include "common.tplvalues.render" ( dict "value" .Values.readReplicas.extraInitContainers "context" $ ) | nindent 8 }} + {{- end }} + {{- end }} + {{- if .Values.readReplicas.priorityClassName }} + priorityClassName: {{ .Values.readReplicas.priorityClassName }} + {{- end }} + containers: + - name: {{ template "common.names.fullname" . }} + image: {{ template "postgresql.image" . }} + imagePullPolicy: "{{ .Values.image.pullPolicy }}" + {{- if $readReplicasResources }} + resources: {{- toYaml $readReplicasResources | nindent 12 }} + {{- end }} + {{- if .Values.containerSecurityContext.enabled }} + securityContext: {{- omit .Values.containerSecurityContext "enabled" | toYaml | nindent 12 }} + {{- end }} + {{- if .Values.diagnosticMode.enabled }} + command: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.command "context" $) | nindent 12 }} + args: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.args "context" $) | nindent 12 }} + {{- end }} + env: + - name: BITNAMI_DEBUG + value: {{ ternary "true" "false" (or .Values.image.debug .Values.diagnosticMode.enabled) | quote }} + - name: POSTGRESQL_VOLUME_DIR + value: "{{ .Values.persistence.mountPath }}" + - name: POSTGRESQL_PORT_NUMBER + value: {{ .Values.containerPorts.postgresql | quote }} + {{- if .Values.persistence.mountPath }} + - name: PGDATA + value: {{ .Values.postgresqlDataDir | quote }} + {{- end }} + - name: POSTGRES_REPLICATION_MODE + value: "slave" + - name: POSTGRES_REPLICATION_USER + value: {{ include "postgresql.replication.username" . | quote }} + {{- if .Values.usePasswordFile }} + - name: POSTGRES_REPLICATION_PASSWORD_FILE + value: "/opt/bitnami/postgresql/secrets/postgresql-replication-password" + {{- else }} + - name: POSTGRES_REPLICATION_PASSWORD + valueFrom: + secretKeyRef: + name: {{ template "postgresql.secretName" . }} + key: postgresql-replication-password + {{- end }} + - name: POSTGRES_CLUSTER_APP_NAME + value: {{ .Values.replication.applicationName }} + - name: POSTGRES_MASTER_HOST + value: {{ template "common.names.fullname" . }} + - name: POSTGRES_MASTER_PORT_NUMBER + value: {{ include "postgresql.servicePort" . | quote }} + {{- if not (eq (include "postgresql.username" .) "postgres") }} + {{- if .Values.usePasswordFile }} + - name: POSTGRES_POSTGRES_PASSWORD_FILE + value: "/opt/bitnami/postgresql/secrets/postgresql-postgres-password" + {{- else }} + - name: POSTGRES_POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + name: {{ template "postgresql.secretName" . }} + key: postgresql-postgres-password + {{- end }} + {{- end }} + {{- if .Values.usePasswordFile }} + - name: POSTGRES_PASSWORD_FILE + value: "/opt/bitnami/postgresql/secrets/postgresql-password" + {{- else }} + - name: POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + name: {{ template "postgresql.secretName" . }} + key: postgresql-password + {{- end }} + - name: POSTGRESQL_ENABLE_TLS + value: {{ ternary "yes" "no" .Values.tls.enabled | quote }} + {{- if .Values.tls.enabled }} + - name: POSTGRESQL_TLS_PREFER_SERVER_CIPHERS + value: {{ ternary "yes" "no" .Values.tls.preferServerCiphers | quote }} + - name: POSTGRESQL_TLS_CERT_FILE + value: {{ template "postgresql.tlsCert" . }} + - name: POSTGRESQL_TLS_KEY_FILE + value: {{ template "postgresql.tlsCertKey" . }} + {{- if .Values.tls.certCAFilename }} + - name: POSTGRESQL_TLS_CA_FILE + value: {{ template "postgresql.tlsCACert" . }} + {{- end }} + {{- if .Values.tls.crlFilename }} + - name: POSTGRESQL_TLS_CRL_FILE + value: {{ template "postgresql.tlsCRL" . }} + {{- end }} + {{- end }} + - name: POSTGRESQL_LOG_HOSTNAME + value: {{ .Values.audit.logHostname | quote }} + - name: POSTGRESQL_LOG_CONNECTIONS + value: {{ .Values.audit.logConnections | quote }} + - name: POSTGRESQL_LOG_DISCONNECTIONS + value: {{ .Values.audit.logDisconnections | quote }} + {{- if .Values.audit.logLinePrefix }} + - name: POSTGRESQL_LOG_LINE_PREFIX + value: {{ .Values.audit.logLinePrefix | quote }} + {{- end }} + {{- if .Values.audit.logTimezone }} + - name: POSTGRESQL_LOG_TIMEZONE + value: {{ .Values.audit.logTimezone | quote }} + {{- end }} + {{- if .Values.audit.pgAuditLog }} + - name: POSTGRESQL_PGAUDIT_LOG + value: {{ .Values.audit.pgAuditLog | quote }} + {{- end }} + - name: POSTGRESQL_PGAUDIT_LOG_CATALOG + value: {{ .Values.audit.pgAuditLogCatalog | quote }} + - name: POSTGRESQL_CLIENT_MIN_MESSAGES + value: {{ .Values.audit.clientMinMessages | quote }} + - name: POSTGRESQL_SHARED_PRELOAD_LIBRARIES + value: {{ .Values.postgresqlSharedPreloadLibraries | quote }} + {{- if .Values.postgresqlMaxConnections }} + - name: POSTGRESQL_MAX_CONNECTIONS + value: {{ .Values.postgresqlMaxConnections | quote }} + {{- end }} + {{- if .Values.postgresqlPostgresConnectionLimit }} + - name: POSTGRESQL_POSTGRES_CONNECTION_LIMIT + value: {{ .Values.postgresqlPostgresConnectionLimit | quote }} + {{- end }} + {{- if .Values.postgresqlDbUserConnectionLimit }} + - name: POSTGRESQL_USERNAME_CONNECTION_LIMIT + value: {{ .Values.postgresqlDbUserConnectionLimit | quote }} + {{- end }} + {{- if .Values.postgresqlTcpKeepalivesInterval }} + - name: POSTGRESQL_TCP_KEEPALIVES_INTERVAL + value: {{ .Values.postgresqlTcpKeepalivesInterval | quote }} + {{- end }} + {{- if .Values.postgresqlTcpKeepalivesIdle }} + - name: POSTGRESQL_TCP_KEEPALIVES_IDLE + value: {{ .Values.postgresqlTcpKeepalivesIdle | quote }} + {{- end }} + {{- if .Values.postgresqlStatementTimeout }} + - name: POSTGRESQL_STATEMENT_TIMEOUT + value: {{ .Values.postgresqlStatementTimeout | quote }} + {{- end }} + {{- if .Values.postgresqlTcpKeepalivesCount }} + - name: POSTGRESQL_TCP_KEEPALIVES_COUNT + value: {{ .Values.postgresqlTcpKeepalivesCount | quote }} + {{- end }} + {{- if .Values.postgresqlPghbaRemoveFilters }} + - name: POSTGRESQL_PGHBA_REMOVE_FILTERS + value: {{ .Values.postgresqlPghbaRemoveFilters | quote }} + {{- end }} + ports: + - name: tcp-postgresql + containerPort: {{ .Values.containerPorts.postgresql }} + {{- if not .Values.diagnosticMode.enabled }} + {{- if .Values.livenessProbe.enabled }} + livenessProbe: + exec: + command: + - /bin/sh + - -c + {{- if (include "postgresql.database" .) }} + - exec pg_isready -U {{ include "postgresql.username" . | quote }} -d "dbname={{ include "postgresql.database" . }} {{- if and .Values.tls.enabled .Values.tls.certCAFilename }} sslcert={{ include "postgresql.tlsCert" . }} sslkey={{ include "postgresql.tlsCertKey" . }}{{- end }}" -h 127.0.0.1 -p {{ .Values.containerPorts.postgresql }} + {{- else }} + - exec pg_isready -U {{ include "postgresql.username" . | quote }} {{- if and .Values.tls.enabled .Values.tls.certCAFilename }} -d "sslcert={{ include "postgresql.tlsCert" . }} sslkey={{ include "postgresql.tlsCertKey" . }}"{{- end }} -h 127.0.0.1 -p {{ .Values.containerPorts.postgresql }} + {{- end }} + initialDelaySeconds: {{ .Values.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.livenessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.livenessProbe.timeoutSeconds }} + successThreshold: {{ .Values.livenessProbe.successThreshold }} + failureThreshold: {{ .Values.livenessProbe.failureThreshold }} + {{- else if .Values.customLivenessProbe }} + livenessProbe: {{- include "common.tplvalues.render" (dict "value" .Values.customLivenessProbe "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.readinessProbe.enabled }} + readinessProbe: + exec: + command: + - /bin/sh + - -c + - -e + {{- include "postgresql.readinessProbeCommand" . | nindent 16 }} + initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.readinessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.readinessProbe.timeoutSeconds }} + successThreshold: {{ .Values.readinessProbe.successThreshold }} + failureThreshold: {{ .Values.readinessProbe.failureThreshold }} + {{- else if .Values.customReadinessProbe }} + readinessProbe: {{- include "common.tplvalues.render" (dict "value" .Values.customReadinessProbe "context" $) | nindent 12 }} + {{- end }} + {{- end }} + volumeMounts: + {{- if .Values.usePasswordFile }} + - name: postgresql-password + mountPath: /opt/bitnami/postgresql/secrets/ + {{- end }} + {{- if .Values.shmVolume.enabled }} + - name: dshm + mountPath: /dev/shm + {{- end }} + {{- if .Values.persistence.enabled }} + - name: data + mountPath: {{ .Values.persistence.mountPath }} + subPath: {{ .Values.persistence.subPath }} + {{ end }} + {{- if or (.Files.Glob "files/conf.d/*.conf") .Values.postgresqlExtendedConf .Values.extendedConfConfigMap }} + - name: postgresql-extended-config + mountPath: /bitnami/postgresql/conf/conf.d/ + {{- end }} + {{- if or (.Files.Glob "files/postgresql.conf") (.Files.Glob "files/pg_hba.conf") .Values.postgresqlConfiguration .Values.pgHbaConfiguration .Values.configurationConfigMap }} + - name: postgresql-config + mountPath: /bitnami/postgresql/conf + {{- end }} + {{- if .Values.tls.enabled }} + - name: postgresql-certificates + mountPath: /opt/bitnami/postgresql/certs + readOnly: true + {{- end }} + {{- if .Values.readReplicas.extraVolumeMounts }} + {{- include "common.tplvalues.render" (dict "value" .Values.readReplicas.extraVolumeMounts "context" $) | nindent 12 }} + {{- end }} +{{- if .Values.readReplicas.sidecars }} +{{- include "common.tplvalues.render" ( dict "value" .Values.readReplicas.sidecars "context" $ ) | nindent 8 }} +{{- end }} + volumes: + {{- if .Values.usePasswordFile }} + - name: postgresql-password + secret: + secretName: {{ template "postgresql.secretName" . }} + {{- end }} + {{- if or (.Files.Glob "files/postgresql.conf") (.Files.Glob "files/pg_hba.conf") .Values.postgresqlConfiguration .Values.pgHbaConfiguration .Values.configurationConfigMap }} + - name: postgresql-config + configMap: + name: {{ template "postgresql.configurationCM" . }} + {{- end }} + {{- if or (.Files.Glob "files/conf.d/*.conf") .Values.postgresqlExtendedConf .Values.extendedConfConfigMap }} + - name: postgresql-extended-config + configMap: + name: {{ template "postgresql.extendedConfigurationCM" . }} + {{- end }} + {{- if .Values.tls.enabled }} + - name: raw-certificates + secret: + secretName: {{ template "postgresql.tlsSecretName" . }} + - name: postgresql-certificates + emptyDir: {} + {{- end }} + {{- if .Values.shmVolume.enabled }} + - name: dshm + emptyDir: + medium: Memory + sizeLimit: 1Gi + {{- end }} + {{- if or (not .Values.persistence.enabled) (not .Values.readReplicas.persistence.enabled) }} + - name: data + emptyDir: {} + {{- end }} + {{- if .Values.readReplicas.extraVolumes }} + {{- include "common.tplvalues.render" ( dict "value" .Values.readReplicas.extraVolumes "context" $ ) | nindent 8 }} + {{- end }} + {{- if .Values.readReplicas.extraPodSpec }} + {{- include "common.tplvalues.render" (dict "value" .Values.readReplicas.extraPodSpec "context" $) | nindent 6 }} + {{- end }} + updateStrategy: + type: {{ .Values.updateStrategy.type }} + {{- if (eq "Recreate" .Values.updateStrategy.type) }} + rollingUpdate: null + {{- end }} +{{- if and .Values.persistence.enabled .Values.readReplicas.persistence.enabled }} + volumeClaimTemplates: + - metadata: + name: data + {{- with .Values.persistence.annotations }} + annotations: + {{- range $key, $value := . }} + {{ $key }}: {{ $value }} + {{- end }} + {{- end }} + spec: + accessModes: + {{- range .Values.persistence.accessModes }} + - {{ . | quote }} + {{- end }} + resources: + requests: + storage: {{ .Values.persistence.size | quote }} + {{ include "common.storage.class" (dict "persistence" .Values.persistence "global" .Values.global) }} + + {{- if .Values.persistence.selector }} + selector: {{- include "common.tplvalues.render" (dict "value" .Values.persistence.selector "context" $) | nindent 10 }} + {{- end -}} +{{- end }} +{{- end }} diff --git a/helm/sonarqube/charts/postgresql/templates/statefulset.yaml b/helm/sonarqube/charts/postgresql/templates/statefulset.yaml new file mode 100644 index 0000000..6f9d587 --- /dev/null +++ b/helm/sonarqube/charts/postgresql/templates/statefulset.yaml @@ -0,0 +1,636 @@ +apiVersion: {{ include "common.capabilities.statefulset.apiVersion" . }} +kind: StatefulSet +metadata: + name: {{ template "postgresql.primary.fullname" . }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + app.kubernetes.io/component: primary + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.primary.labels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.primary.labels "context" $ ) | nindent 4 }} + {{- end }} + annotations: + {{- if .Values.commonAnnotations }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} + {{- with .Values.primary.annotations }} + {{- toYaml . | nindent 4 }} + {{- end }} + namespace: {{ .Release.Namespace }} +spec: + serviceName: {{ template "common.names.fullname" . }}-headless + replicas: 1 + updateStrategy: + type: {{ .Values.updateStrategy.type }} + {{- if (eq "Recreate" .Values.updateStrategy.type) }} + rollingUpdate: null + {{- end }} + selector: + matchLabels: + {{- include "common.labels.matchLabels" . | nindent 6 }} + role: primary + template: + metadata: + name: {{ template "common.names.fullname" . }} + labels: + {{- include "common.labels.standard" . | nindent 8 }} + role: primary + app.kubernetes.io/component: primary + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 8 }} + {{- end }} + {{- if .Values.primary.podLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.primary.podLabels "context" $ ) | nindent 8 }} + {{- end }} + {{- with .Values.primary.podAnnotations }} + annotations: {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- if .Values.schedulerName }} + schedulerName: "{{ .Values.schedulerName }}" + {{- end }} +{{- include "postgresql.imagePullSecrets" . | indent 6 }} + {{- if .Values.primary.affinity }} + affinity: {{- include "common.tplvalues.render" (dict "value" .Values.primary.affinity "context" $) | nindent 8 }} + {{- else }} + affinity: + podAffinity: {{- include "common.affinities.pods" (dict "type" .Values.primary.podAffinityPreset "component" "primary" "context" $) | nindent 10 }} + podAntiAffinity: {{- include "common.affinities.pods" (dict "type" .Values.primary.podAntiAffinityPreset "component" "primary" "context" $) | nindent 10 }} + nodeAffinity: {{- include "common.affinities.nodes" (dict "type" .Values.primary.nodeAffinityPreset.type "key" .Values.primary.nodeAffinityPreset.key "values" .Values.primary.nodeAffinityPreset.values) | nindent 10 }} + {{- end }} + {{- if .Values.primary.nodeSelector }} + nodeSelector: {{- include "common.tplvalues.render" (dict "value" .Values.primary.nodeSelector "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.primary.tolerations }} + tolerations: {{- include "common.tplvalues.render" (dict "value" .Values.primary.tolerations "context" $) | nindent 8 }} + {{- end }} + {{- if .Values.terminationGracePeriodSeconds }} + terminationGracePeriodSeconds: {{ .Values.terminationGracePeriodSeconds }} + {{- end }} + {{- if .Values.securityContext.enabled }} + securityContext: {{- omit .Values.securityContext "enabled" | toYaml | nindent 8 }} + {{- end }} + automountServiceAccountToken: {{ .Values.serviceAccount.autoMount }} + {{- if .Values.serviceAccount.enabled }} + serviceAccountName: {{ default (include "common.names.fullname" . ) .Values.serviceAccount.name }} + {{- end }} + {{- if or .Values.primary.extraInitContainers (and .Values.volumePermissions.enabled (or .Values.persistence.enabled (and .Values.shmVolume.enabled .Values.shmVolume.chmod.enabled))) }} + initContainers: + {{- if and .Values.volumePermissions.enabled (or .Values.persistence.enabled (and .Values.shmVolume.enabled .Values.shmVolume.chmod.enabled) .Values.tls.enabled) }} + - name: init-chmod-data + image: {{ template "postgresql.volumePermissions.image" . }} + imagePullPolicy: {{ .Values.volumePermissions.image.pullPolicy | quote }} + {{- if .Values.resources }} + resources: {{- toYaml .Values.resources | nindent 12 }} + {{- end }} + command: + - /bin/sh + - -cx + - | + {{- if .Values.persistence.enabled }} + {{- if eq ( toString ( .Values.volumePermissions.securityContext.runAsUser )) "auto" }} + chown `id -u`:`id -G | cut -d " " -f2` {{ .Values.persistence.mountPath }} + {{- else }} + chown {{ .Values.containerSecurityContext.runAsUser }}:{{ .Values.securityContext.fsGroup }} {{ .Values.persistence.mountPath }} + {{- end }} + mkdir -p {{ .Values.persistence.mountPath }}/data {{- if (include "postgresql.mountConfigurationCM" .) }} {{ .Values.persistence.mountPath }}/conf {{- end }} + chmod 700 {{ .Values.persistence.mountPath }}/data {{- if (include "postgresql.mountConfigurationCM" .) }} {{ .Values.persistence.mountPath }}/conf {{- end }} + find {{ .Values.persistence.mountPath }} -mindepth 1 -maxdepth 1 {{- if not (include "postgresql.mountConfigurationCM" .) }} -not -name "conf" {{- end }} -not -name ".snapshot" -not -name "lost+found" | \ + {{- if eq ( toString ( .Values.volumePermissions.securityContext.runAsUser )) "auto" }} + xargs chown -R `id -u`:`id -G | cut -d " " -f2` + {{- else }} + xargs chown -R {{ .Values.containerSecurityContext.runAsUser }}:{{ .Values.securityContext.fsGroup }} + {{- end }} + {{- end }} + {{- if and .Values.shmVolume.enabled .Values.shmVolume.chmod.enabled }} + chmod -R 777 /dev/shm + {{- end }} + {{- if .Values.tls.enabled }} + cp /tmp/certs/* /opt/bitnami/postgresql/certs/ + {{- if eq ( toString ( .Values.volumePermissions.securityContext.runAsUser )) "auto" }} + chown -R `id -u`:`id -G | cut -d " " -f2` /opt/bitnami/postgresql/certs/ + {{- else }} + chown -R {{ .Values.containerSecurityContext.runAsUser }}:{{ .Values.securityContext.fsGroup }} /opt/bitnami/postgresql/certs/ + {{- end }} + chmod 600 {{ template "postgresql.tlsCertKey" . }} + {{- end }} + {{- if eq ( toString ( .Values.volumePermissions.securityContext.runAsUser )) "auto" }} + securityContext: {{- omit .Values.volumePermissions.securityContext "runAsUser" | toYaml | nindent 12 }} + {{- else }} + securityContext: {{- .Values.volumePermissions.securityContext | toYaml | nindent 12 }} + {{- end }} + volumeMounts: + {{- if .Values.persistence.enabled }} + - name: data + mountPath: {{ .Values.persistence.mountPath }} + subPath: {{ .Values.persistence.subPath }} + {{- end }} + {{- if .Values.shmVolume.enabled }} + - name: dshm + mountPath: /dev/shm + {{- end }} + {{- if .Values.tls.enabled }} + - name: raw-certificates + mountPath: /tmp/certs + - name: postgresql-certificates + mountPath: /opt/bitnami/postgresql/certs + {{- end }} + {{- end }} + {{- if .Values.primary.extraInitContainers }} + {{- include "common.tplvalues.render" ( dict "value" .Values.primary.extraInitContainers "context" $ ) | nindent 8 }} + {{- end }} + {{- end }} + {{- if .Values.primary.priorityClassName }} + priorityClassName: {{ .Values.primary.priorityClassName }} + {{- end }} + containers: + - name: {{ template "common.names.fullname" . }} + image: {{ template "postgresql.image" . }} + imagePullPolicy: "{{ .Values.image.pullPolicy }}" + {{- if .Values.resources }} + resources: {{- toYaml .Values.resources | nindent 12 }} + {{- end }} + {{- if .Values.lifecycleHooks }} + lifecycle: {{- include "common.tplvalues.render" (dict "value" .Values.lifecycleHooks "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.containerSecurityContext.enabled }} + securityContext: {{- omit .Values.containerSecurityContext "enabled" | toYaml | nindent 12 }} + {{- end }} + {{- if .Values.diagnosticMode.enabled }} + command: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.command "context" $) | nindent 12 }} + args: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.args "context" $) | nindent 12 }} + {{- end }} + env: + - name: BITNAMI_DEBUG + value: {{ ternary "true" "false" (or .Values.image.debug .Values.diagnosticMode.enabled) | quote }} + - name: POSTGRESQL_PORT_NUMBER + value: {{ .Values.containerPorts.postgresql | quote }} + - name: POSTGRESQL_VOLUME_DIR + value: "{{ .Values.persistence.mountPath }}" + {{- if .Values.postgresqlInitdbArgs }} + - name: POSTGRES_INITDB_ARGS + value: {{ .Values.postgresqlInitdbArgs | quote }} + {{- end }} + {{- if .Values.postgresqlInitdbWalDir }} + - name: POSTGRES_INITDB_WALDIR + value: {{ .Values.postgresqlInitdbWalDir | quote }} + {{- end }} + {{- if .Values.initdbUser }} + - name: POSTGRESQL_INITSCRIPTS_USERNAME + value: {{ .Values.initdbUser }} + {{- end }} + {{- if .Values.initdbPassword }} + - name: POSTGRESQL_INITSCRIPTS_PASSWORD + value: {{ .Values.initdbPassword }} + {{- end }} + {{- if .Values.persistence.mountPath }} + - name: PGDATA + value: {{ .Values.postgresqlDataDir | quote }} + {{- end }} + {{- if .Values.primaryAsStandBy.enabled }} + - name: POSTGRES_MASTER_HOST + value: {{ .Values.primaryAsStandBy.primaryHost }} + - name: POSTGRES_MASTER_PORT_NUMBER + value: {{ .Values.primaryAsStandBy.primaryPort | quote }} + {{- end }} + {{- if or .Values.replication.enabled .Values.primaryAsStandBy.enabled }} + - name: POSTGRES_REPLICATION_MODE + {{- if .Values.primaryAsStandBy.enabled }} + value: "slave" + {{- else }} + value: "master" + {{- end }} + - name: POSTGRES_REPLICATION_USER + value: {{ include "postgresql.replication.username" . | quote }} + {{- if .Values.usePasswordFile }} + - name: POSTGRES_REPLICATION_PASSWORD_FILE + value: "/opt/bitnami/postgresql/secrets/postgresql-replication-password" + {{- else }} + - name: POSTGRES_REPLICATION_PASSWORD + valueFrom: + secretKeyRef: + name: {{ template "postgresql.secretName" . }} + key: postgresql-replication-password + {{- end }} + {{- if not (eq .Values.replication.synchronousCommit "off") }} + - name: POSTGRES_SYNCHRONOUS_COMMIT_MODE + value: {{ .Values.replication.synchronousCommit | quote }} + - name: POSTGRES_NUM_SYNCHRONOUS_REPLICAS + value: {{ .Values.replication.numSynchronousReplicas | quote }} + {{- end }} + - name: POSTGRES_CLUSTER_APP_NAME + value: {{ .Values.replication.applicationName }} + {{- end }} + {{- if not (eq (include "postgresql.username" .) "postgres") }} + {{- if .Values.usePasswordFile }} + - name: POSTGRES_POSTGRES_PASSWORD_FILE + value: "/opt/bitnami/postgresql/secrets/postgresql-postgres-password" + {{- else }} + - name: POSTGRES_POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + name: {{ template "postgresql.secretName" . }} + key: postgresql-postgres-password + {{- end }} + {{- end }} + - name: POSTGRES_USER + value: {{ include "postgresql.username" . | quote }} + {{- if .Values.usePasswordFile }} + - name: POSTGRES_PASSWORD_FILE + value: "/opt/bitnami/postgresql/secrets/postgresql-password" + {{- else }} + - name: POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + name: {{ template "postgresql.secretName" . }} + key: postgresql-password + {{- end }} + {{- if (include "postgresql.database" .) }} + - name: POSTGRES_DB + value: {{ (include "postgresql.database" .) | quote }} + {{- end }} + {{- if .Values.extraEnv }} + {{- include "common.tplvalues.render" (dict "value" .Values.extraEnv "context" $) | nindent 12 }} + {{- end }} + - name: POSTGRESQL_ENABLE_LDAP + value: {{ ternary "yes" "no" .Values.ldap.enabled | quote }} + {{- if .Values.ldap.enabled }} + - name: POSTGRESQL_LDAP_SERVER + value: {{ .Values.ldap.server }} + - name: POSTGRESQL_LDAP_PORT + value: {{ .Values.ldap.port | quote }} + - name: POSTGRESQL_LDAP_SCHEME + value: {{ .Values.ldap.scheme }} + {{- if .Values.ldap.tls }} + - name: POSTGRESQL_LDAP_TLS + value: "1" + {{- end }} + - name: POSTGRESQL_LDAP_PREFIX + value: {{ .Values.ldap.prefix | quote }} + - name: POSTGRESQL_LDAP_SUFFIX + value: {{ .Values.ldap.suffix | quote }} + - name: POSTGRESQL_LDAP_BASE_DN + value: {{ .Values.ldap.baseDN }} + - name: POSTGRESQL_LDAP_BIND_DN + value: {{ .Values.ldap.bindDN }} + {{- if (not (empty .Values.ldap.bind_password)) }} + - name: POSTGRESQL_LDAP_BIND_PASSWORD + valueFrom: + secretKeyRef: + name: {{ template "postgresql.secretName" . }} + key: postgresql-ldap-password + {{- end }} + - name: POSTGRESQL_LDAP_SEARCH_ATTR + value: {{ .Values.ldap.search_attr }} + - name: POSTGRESQL_LDAP_SEARCH_FILTER + value: {{ .Values.ldap.search_filter }} + - name: POSTGRESQL_LDAP_URL + value: {{ .Values.ldap.url }} + {{- end }} + - name: POSTGRESQL_ENABLE_TLS + value: {{ ternary "yes" "no" .Values.tls.enabled | quote }} + {{- if .Values.tls.enabled }} + - name: POSTGRESQL_TLS_PREFER_SERVER_CIPHERS + value: {{ ternary "yes" "no" .Values.tls.preferServerCiphers | quote }} + - name: POSTGRESQL_TLS_CERT_FILE + value: {{ template "postgresql.tlsCert" . }} + - name: POSTGRESQL_TLS_KEY_FILE + value: {{ template "postgresql.tlsCertKey" . }} + {{- if .Values.tls.certCAFilename }} + - name: POSTGRESQL_TLS_CA_FILE + value: {{ template "postgresql.tlsCACert" . }} + {{- end }} + {{- if .Values.tls.crlFilename }} + - name: POSTGRESQL_TLS_CRL_FILE + value: {{ template "postgresql.tlsCRL" . }} + {{- end }} + {{- end }} + - name: POSTGRESQL_LOG_HOSTNAME + value: {{ .Values.audit.logHostname | quote }} + - name: POSTGRESQL_LOG_CONNECTIONS + value: {{ .Values.audit.logConnections | quote }} + - name: POSTGRESQL_LOG_DISCONNECTIONS + value: {{ .Values.audit.logDisconnections | quote }} + {{- if .Values.audit.logLinePrefix }} + - name: POSTGRESQL_LOG_LINE_PREFIX + value: {{ .Values.audit.logLinePrefix | quote }} + {{- end }} + {{- if .Values.audit.logTimezone }} + - name: POSTGRESQL_LOG_TIMEZONE + value: {{ .Values.audit.logTimezone | quote }} + {{- end }} + {{- if .Values.audit.pgAuditLog }} + - name: POSTGRESQL_PGAUDIT_LOG + value: {{ .Values.audit.pgAuditLog | quote }} + {{- end }} + - name: POSTGRESQL_PGAUDIT_LOG_CATALOG + value: {{ .Values.audit.pgAuditLogCatalog | quote }} + - name: POSTGRESQL_CLIENT_MIN_MESSAGES + value: {{ .Values.audit.clientMinMessages | quote }} + - name: POSTGRESQL_SHARED_PRELOAD_LIBRARIES + value: {{ .Values.postgresqlSharedPreloadLibraries | quote }} + {{- if .Values.postgresqlMaxConnections }} + - name: POSTGRESQL_MAX_CONNECTIONS + value: {{ .Values.postgresqlMaxConnections | quote }} + {{- end }} + {{- if .Values.postgresqlPostgresConnectionLimit }} + - name: POSTGRESQL_POSTGRES_CONNECTION_LIMIT + value: {{ .Values.postgresqlPostgresConnectionLimit | quote }} + {{- end }} + {{- if .Values.postgresqlDbUserConnectionLimit }} + - name: POSTGRESQL_USERNAME_CONNECTION_LIMIT + value: {{ .Values.postgresqlDbUserConnectionLimit | quote }} + {{- end }} + {{- if .Values.postgresqlTcpKeepalivesInterval }} + - name: POSTGRESQL_TCP_KEEPALIVES_INTERVAL + value: {{ .Values.postgresqlTcpKeepalivesInterval | quote }} + {{- end }} + {{- if .Values.postgresqlTcpKeepalivesIdle }} + - name: POSTGRESQL_TCP_KEEPALIVES_IDLE + value: {{ .Values.postgresqlTcpKeepalivesIdle | quote }} + {{- end }} + {{- if .Values.postgresqlStatementTimeout }} + - name: POSTGRESQL_STATEMENT_TIMEOUT + value: {{ .Values.postgresqlStatementTimeout | quote }} + {{- end }} + {{- if .Values.postgresqlTcpKeepalivesCount }} + - name: POSTGRESQL_TCP_KEEPALIVES_COUNT + value: {{ .Values.postgresqlTcpKeepalivesCount | quote }} + {{- end }} + {{- if .Values.postgresqlPghbaRemoveFilters }} + - name: POSTGRESQL_PGHBA_REMOVE_FILTERS + value: {{ .Values.postgresqlPghbaRemoveFilters | quote }} + {{- end }} + {{- if .Values.extraEnvVarsCM }} + envFrom: + - configMapRef: + name: {{ tpl .Values.extraEnvVarsCM . }} + {{- end }} + ports: + - name: tcp-postgresql + containerPort: {{ .Values.containerPorts.postgresql }} + {{- if not .Values.diagnosticMode.enabled }} + {{- if .Values.startupProbe.enabled }} + startupProbe: + exec: + command: + - /bin/sh + - -c + {{- if (include "postgresql.database" .) }} + - exec pg_isready -U {{ include "postgresql.username" . | quote }} -d "dbname={{ include "postgresql.database" . }} {{- if and .Values.tls.enabled .Values.tls.certCAFilename }} sslcert={{ include "postgresql.tlsCert" . }} sslkey={{ include "postgresql.tlsCertKey" . }}{{- end }}" -h 127.0.0.1 -p {{ .Values.containerPorts.postgresql }} + {{- else }} + - exec pg_isready -U {{ include "postgresql.username" . | quote }} {{- if and .Values.tls.enabled .Values.tls.certCAFilename }} -d "sslcert={{ include "postgresql.tlsCert" . }} sslkey={{ include "postgresql.tlsCertKey" . }}"{{- end }} -h 127.0.0.1 -p {{ .Values.containerPorts.postgresql }} + {{- end }} + initialDelaySeconds: {{ .Values.startupProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.startupProbe.periodSeconds }} + timeoutSeconds: {{ .Values.startupProbe.timeoutSeconds }} + successThreshold: {{ .Values.startupProbe.successThreshold }} + failureThreshold: {{ .Values.startupProbe.failureThreshold }} + {{- else if .Values.customStartupProbe }} + startupProbe: {{- include "common.tplvalues.render" (dict "value" .Values.customStartupProbe "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.livenessProbe.enabled }} + livenessProbe: + exec: + command: + - /bin/sh + - -c + {{- if (include "postgresql.database" .) }} + - exec pg_isready -U {{ include "postgresql.username" . | quote }} -d "dbname={{ include "postgresql.database" . }} {{- if and .Values.tls.enabled .Values.tls.certCAFilename }} sslcert={{ include "postgresql.tlsCert" . }} sslkey={{ include "postgresql.tlsCertKey" . }}{{- end }}" -h 127.0.0.1 -p {{ .Values.containerPorts.postgresql }} + {{- else }} + - exec pg_isready -U {{ include "postgresql.username" . | quote }} {{- if and .Values.tls.enabled .Values.tls.certCAFilename }} -d "sslcert={{ include "postgresql.tlsCert" . }} sslkey={{ include "postgresql.tlsCertKey" . }}"{{- end }} -h 127.0.0.1 -p {{ .Values.containerPorts.postgresql }} + {{- end }} + initialDelaySeconds: {{ .Values.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.livenessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.livenessProbe.timeoutSeconds }} + successThreshold: {{ .Values.livenessProbe.successThreshold }} + failureThreshold: {{ .Values.livenessProbe.failureThreshold }} + {{- else if .Values.customLivenessProbe }} + livenessProbe: {{- include "common.tplvalues.render" (dict "value" .Values.customLivenessProbe "context" $) | nindent 12 }} + {{- end }} + {{- if .Values.readinessProbe.enabled }} + readinessProbe: + exec: + command: + - /bin/sh + - -c + - -e + {{- include "postgresql.readinessProbeCommand" . | nindent 16 }} + initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.readinessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.readinessProbe.timeoutSeconds }} + successThreshold: {{ .Values.readinessProbe.successThreshold }} + failureThreshold: {{ .Values.readinessProbe.failureThreshold }} + {{- else if .Values.customReadinessProbe }} + readinessProbe: {{- include "common.tplvalues.render" (dict "value" .Values.customReadinessProbe "context" $) | nindent 12 }} + {{- end }} + {{- end }} + volumeMounts: + {{- if or (.Files.Glob "files/docker-entrypoint-initdb.d/*.{sh,sql,sql.gz}") .Values.initdbScriptsConfigMap .Values.initdbScripts }} + - name: custom-init-scripts + mountPath: /docker-entrypoint-initdb.d/ + {{- end }} + {{- if .Values.initdbScriptsSecret }} + - name: custom-init-scripts-secret + mountPath: /docker-entrypoint-initdb.d/secret + {{- end }} + {{- if or (.Files.Glob "files/conf.d/*.conf") .Values.postgresqlExtendedConf .Values.extendedConfConfigMap }} + - name: postgresql-extended-config + mountPath: /bitnami/postgresql/conf/conf.d/ + {{- end }} + {{- if .Values.usePasswordFile }} + - name: postgresql-password + mountPath: /opt/bitnami/postgresql/secrets/ + {{- end }} + {{- if .Values.tls.enabled }} + - name: postgresql-certificates + mountPath: /opt/bitnami/postgresql/certs + readOnly: true + {{- end }} + {{- if .Values.shmVolume.enabled }} + - name: dshm + mountPath: /dev/shm + {{- end }} + {{- if .Values.persistence.enabled }} + - name: data + mountPath: {{ .Values.persistence.mountPath }} + subPath: {{ .Values.persistence.subPath }} + {{- end }} + {{- if or (.Files.Glob "files/postgresql.conf") (.Files.Glob "files/pg_hba.conf") .Values.postgresqlConfiguration .Values.pgHbaConfiguration .Values.configurationConfigMap }} + - name: postgresql-config + mountPath: /bitnami/postgresql/conf + {{- end }} + {{- if .Values.primary.extraVolumeMounts }} + {{- include "common.tplvalues.render" (dict "value" .Values.primary.extraVolumeMounts "context" $) | nindent 12 }} + {{- end }} +{{- if .Values.primary.sidecars }} +{{- include "common.tplvalues.render" ( dict "value" .Values.primary.sidecars "context" $ ) | nindent 8 }} +{{- end }} +{{- if .Values.metrics.enabled }} + - name: metrics + image: {{ template "postgresql.metrics.image" . }} + imagePullPolicy: {{ .Values.metrics.image.pullPolicy | quote }} + {{- if .Values.metrics.securityContext.enabled }} + securityContext: {{- omit .Values.metrics.securityContext "enabled" | toYaml | nindent 12 }} + {{- end }} + {{- if .Values.diagnosticMode.enabled }} + command: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.command "context" $) | nindent 12 }} + args: {{- include "common.tplvalues.render" (dict "value" .Values.diagnosticMode.args "context" $) | nindent 12 }} + {{- end }} + env: + {{- $database := required "In order to enable metrics you need to specify a database (.Values.postgresqlDatabase or .Values.global.postgresql.postgresqlDatabase)" (include "postgresql.database" .) }} + {{- $sslmode := ternary "require" "disable" .Values.tls.enabled }} + {{- if and .Values.tls.enabled .Values.tls.certCAFilename }} + - name: DATA_SOURCE_NAME + value: {{ printf "host=127.0.0.1 port=%d user=%s sslmode=%s sslcert=%s sslkey=%s" (int (include "postgresql.servicePort" .)) (include "postgresql.username" .) $sslmode (include "postgresql.tlsCert" .) (include "postgresql.tlsCertKey" .) }} + {{- else }} + - name: DATA_SOURCE_URI + value: {{ printf "127.0.0.1:%d/%s?sslmode=%s" (int (include "postgresql.servicePort" .)) $database $sslmode }} + {{- end }} + {{- if .Values.usePasswordFile }} + - name: DATA_SOURCE_PASS_FILE + value: "/opt/bitnami/postgresql/secrets/postgresql-password" + {{- else }} + - name: DATA_SOURCE_PASS + valueFrom: + secretKeyRef: + name: {{ template "postgresql.secretName" . }} + key: postgresql-password + {{- end }} + - name: DATA_SOURCE_USER + value: {{ template "postgresql.username" . }} + {{- if .Values.metrics.extraEnvVars }} + {{- include "common.tplvalues.render" (dict "value" .Values.metrics.extraEnvVars "context" $) | nindent 12 }} + {{- end }} + {{- if not .Values.diagnosticMode.enabled }} + {{- if .Values.livenessProbe.enabled }} + livenessProbe: + httpGet: + path: / + port: http-metrics + initialDelaySeconds: {{ .Values.metrics.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.metrics.livenessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.metrics.livenessProbe.timeoutSeconds }} + successThreshold: {{ .Values.metrics.livenessProbe.successThreshold }} + failureThreshold: {{ .Values.metrics.livenessProbe.failureThreshold }} + {{- end }} + {{- if .Values.readinessProbe.enabled }} + readinessProbe: + httpGet: + path: / + port: http-metrics + initialDelaySeconds: {{ .Values.metrics.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.metrics.readinessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.metrics.readinessProbe.timeoutSeconds }} + successThreshold: {{ .Values.metrics.readinessProbe.successThreshold }} + failureThreshold: {{ .Values.metrics.readinessProbe.failureThreshold }} + {{- end }} + {{- end }} + volumeMounts: + {{- if .Values.usePasswordFile }} + - name: postgresql-password + mountPath: /opt/bitnami/postgresql/secrets/ + {{- end }} + {{- if .Values.tls.enabled }} + - name: postgresql-certificates + mountPath: /opt/bitnami/postgresql/certs + readOnly: true + {{- end }} + {{- if .Values.metrics.customMetrics }} + - name: custom-metrics + mountPath: /conf + readOnly: true + args: ["--extend.query-path", "/conf/custom-metrics.yaml"] + {{- end }} + ports: + - name: http-metrics + containerPort: 9187 + {{- if .Values.metrics.resources }} + resources: {{- toYaml .Values.metrics.resources | nindent 12 }} + {{- end }} +{{- end }} + volumes: + {{- if or (.Files.Glob "files/postgresql.conf") (.Files.Glob "files/pg_hba.conf") .Values.postgresqlConfiguration .Values.pgHbaConfiguration .Values.configurationConfigMap }} + - name: postgresql-config + configMap: + name: {{ template "postgresql.configurationCM" . }} + {{- end }} + {{- if or (.Files.Glob "files/conf.d/*.conf") .Values.postgresqlExtendedConf .Values.extendedConfConfigMap }} + - name: postgresql-extended-config + configMap: + name: {{ template "postgresql.extendedConfigurationCM" . }} + {{- end }} + {{- if .Values.usePasswordFile }} + - name: postgresql-password + secret: + secretName: {{ template "postgresql.secretName" . }} + {{- end }} + {{- if or (.Files.Glob "files/docker-entrypoint-initdb.d/*.{sh,sql,sql.gz}") .Values.initdbScriptsConfigMap .Values.initdbScripts }} + - name: custom-init-scripts + configMap: + name: {{ template "postgresql.initdbScriptsCM" . }} + {{- end }} + {{- if .Values.initdbScriptsSecret }} + - name: custom-init-scripts-secret + secret: + secretName: {{ template "postgresql.initdbScriptsSecret" . }} + {{- end }} + {{- if .Values.tls.enabled }} + - name: raw-certificates + secret: + secretName: {{ template "postgresql.tlsSecretName" . }} + - name: postgresql-certificates + emptyDir: {} + {{- end }} + {{- if .Values.primary.extraVolumes }} + {{- include "common.tplvalues.render" ( dict "value" .Values.primary.extraVolumes "context" $ ) | nindent 8 }} + {{- end }} + {{- if and .Values.metrics.enabled .Values.metrics.customMetrics }} + - name: custom-metrics + configMap: + name: {{ template "postgresql.metricsCM" . }} + {{- end }} + {{- if .Values.shmVolume.enabled }} + - name: dshm + emptyDir: + medium: Memory +{{- with .Values.shmVolume.sizeLimit }} + sizeLimit: {{ . }} +{{- end }} + {{- end }} +{{- if and .Values.persistence.enabled .Values.persistence.existingClaim }} + - name: data + persistentVolumeClaim: +{{- with .Values.persistence.existingClaim }} + claimName: {{ tpl . $ }} +{{- end }} +{{- else if not .Values.persistence.enabled }} + - name: data + emptyDir: {} + {{- if .Values.primary.extraPodSpec }} + {{- include "common.tplvalues.render" (dict "value" .Values.primary.extraPodSpec "context" $) | nindent 6 }} + {{- end }} +{{- else if and .Values.persistence.enabled (not .Values.persistence.existingClaim) }} + volumeClaimTemplates: + - metadata: + name: data + {{- with .Values.persistence.annotations }} + annotations: + {{- range $key, $value := . }} + {{ $key }}: {{ $value }} + {{- end }} + {{- end }} + spec: + accessModes: + {{- range .Values.persistence.accessModes }} + - {{ . | quote }} + {{- end }} + resources: + requests: + storage: {{ .Values.persistence.size | quote }} + {{ include "common.storage.class" (dict "persistence" .Values.persistence "global" .Values.global) }} + {{- if .Values.persistence.selector }} + selector: {{- include "common.tplvalues.render" (dict "value" .Values.persistence.selector "context" $) | nindent 10 }} + {{- end -}} +{{- end }} diff --git a/helm/sonarqube/charts/postgresql/templates/svc-headless.yaml b/helm/sonarqube/charts/postgresql/templates/svc-headless.yaml new file mode 100644 index 0000000..fbbfd40 --- /dev/null +++ b/helm/sonarqube/charts/postgresql/templates/svc-headless.yaml @@ -0,0 +1,31 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ template "common.names.fullname" . }}-headless + labels: + {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} + # Use this annotation in addition to the actual publishNotReadyAddresses + # field below because the annotation will stop being respected soon but the + # field is broken in some versions of Kubernetes: + # https://github.com/kubernetes/kubernetes/issues/58662 + service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" + namespace: {{ .Release.Namespace }} +spec: + type: ClusterIP + clusterIP: None + # We want all pods in the StatefulSet to have their addresses published for + # the sake of the other Postgresql pods even before they're ready, since they + # have to be able to talk to each other in order to become ready. + publishNotReadyAddresses: true + ports: + - name: tcp-postgresql + port: {{ template "postgresql.servicePort" . }} + targetPort: tcp-postgresql + selector: + {{- include "common.labels.matchLabels" . | nindent 4 }} diff --git a/helm/sonarqube/charts/postgresql/templates/svc-read-set.yaml b/helm/sonarqube/charts/postgresql/templates/svc-read-set.yaml new file mode 100644 index 0000000..08d8049 --- /dev/null +++ b/helm/sonarqube/charts/postgresql/templates/svc-read-set.yaml @@ -0,0 +1,42 @@ +{{- if and .Values.replication.enabled .Values.replication.uniqueServices }} +{{- $serviceAnnotations := coalesce .Values.readReplicas.service.annotations .Values.service.annotations -}} + +{{- $fullName := include "common.names.fullname" . }} +{{- $replicaCount := .Values.replication.readReplicas | int }} +{{- $root := . }} + +{{- range $i, $e := until $replicaCount }} +{{- $targetPod := printf "%s-read-%d" (printf "%s" $fullName) $i }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ $fullName }}-read-{{ $i }} + labels: + pod: {{ $targetPod }} + {{- include "common.labels.standard" $root | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + annotations: + + {{- if $root.Values.commonAnnotations }} + {{- include "common.tplvalues.render" ( dict "value" $root.Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} + {{- if $serviceAnnotations }} + {{- include "common.tplvalues.render" (dict "value" $serviceAnnotations "context" $) | nindent 4 }} + {{- end }} + namespace: {{ $root.Release.Namespace }} +spec: + type: ClusterIP + ports: + - name: tcp-postgresql + port: {{ template "postgresql.servicePort" $root }} + targetPort: tcp-postgresql + selector: + {{- include "common.labels.matchLabels" $root | nindent 4 }} + role: read + statefulset.kubernetes.io/pod-name: {{ $targetPod }} + +{{- end }} +{{- end }} diff --git a/helm/sonarqube/charts/postgresql/templates/svc-read.yaml b/helm/sonarqube/charts/postgresql/templates/svc-read.yaml new file mode 100644 index 0000000..ed1005f --- /dev/null +++ b/helm/sonarqube/charts/postgresql/templates/svc-read.yaml @@ -0,0 +1,47 @@ +{{- if and .Values.replication.enabled .Values.replication.singleService }} +{{- $serviceAnnotations := coalesce .Values.readReplicas.service.annotations .Values.service.annotations -}} +{{- $serviceType := coalesce .Values.readReplicas.service.type .Values.service.type -}} +{{- $serviceLoadBalancerIP := coalesce .Values.readReplicas.service.loadBalancerIP .Values.service.loadBalancerIP -}} +{{- $serviceLoadBalancerSourceRanges := coalesce .Values.readReplicas.service.loadBalancerSourceRanges .Values.service.loadBalancerSourceRanges -}} +{{- $serviceClusterIP := coalesce .Values.readReplicas.service.clusterIP .Values.service.clusterIP -}} +{{- $serviceNodePort := coalesce .Values.readReplicas.service.nodePort .Values.service.nodePort -}} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "common.names.fullname" . }}-read + labels: + {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + annotations: + {{- if .Values.commonAnnotations }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} + {{- if $serviceAnnotations }} + {{- include "common.tplvalues.render" (dict "value" $serviceAnnotations "context" $) | nindent 4 }} + {{- end }} + namespace: {{ .Release.Namespace }} +spec: + type: {{ $serviceType }} + {{- if and $serviceLoadBalancerIP (eq $serviceType "LoadBalancer") }} + loadBalancerIP: {{ $serviceLoadBalancerIP }} + externalTrafficPolicy: {{ .Values.service.externalTrafficPolicy | quote }} + {{- end }} + {{- if and (eq $serviceType "LoadBalancer") $serviceLoadBalancerSourceRanges }} + loadBalancerSourceRanges: {{- include "common.tplvalues.render" (dict "value" $serviceLoadBalancerSourceRanges "context" $) | nindent 4 }} + {{- end }} + {{- if and (eq $serviceType "ClusterIP") $serviceClusterIP }} + clusterIP: {{ $serviceClusterIP }} + {{- end }} + ports: + - name: tcp-postgresql + port: {{ template "postgresql.servicePort" . }} + targetPort: tcp-postgresql + {{- if $serviceNodePort }} + nodePort: {{ $serviceNodePort }} + {{- end }} + selector: + {{- include "common.labels.matchLabels" . | nindent 4 }} + role: read +{{- end }} diff --git a/helm/sonarqube/charts/postgresql/templates/svc.yaml b/helm/sonarqube/charts/postgresql/templates/svc.yaml new file mode 100644 index 0000000..a47efb9 --- /dev/null +++ b/helm/sonarqube/charts/postgresql/templates/svc.yaml @@ -0,0 +1,45 @@ +{{- $serviceAnnotations := coalesce .Values.primary.service.annotations .Values.service.annotations -}} +{{- $serviceType := coalesce .Values.primary.service.type .Values.service.type -}} +{{- $serviceLoadBalancerIP := coalesce .Values.primary.service.loadBalancerIP .Values.service.loadBalancerIP -}} +{{- $serviceLoadBalancerSourceRanges := coalesce .Values.primary.service.loadBalancerSourceRanges .Values.service.loadBalancerSourceRanges -}} +{{- $serviceClusterIP := coalesce .Values.primary.service.clusterIP .Values.service.clusterIP -}} +{{- $serviceNodePort := coalesce .Values.primary.service.nodePort .Values.service.nodePort -}} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "common.names.fullname" . }} + labels: + {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + annotations: + {{- if .Values.commonAnnotations }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} + {{- if $serviceAnnotations }} + {{- include "common.tplvalues.render" (dict "value" $serviceAnnotations "context" $) | nindent 4 }} + {{- end }} + namespace: {{ .Release.Namespace }} +spec: + type: {{ $serviceType }} + {{- if and $serviceLoadBalancerIP (eq $serviceType "LoadBalancer") }} + loadBalancerIP: {{ $serviceLoadBalancerIP }} + externalTrafficPolicy: {{ .Values.service.externalTrafficPolicy | quote }} + {{- end }} + {{- if and (eq $serviceType "LoadBalancer") $serviceLoadBalancerSourceRanges }} + loadBalancerSourceRanges: {{- include "common.tplvalues.render" (dict "value" $serviceLoadBalancerSourceRanges "context" $) | nindent 4 }} + {{- end }} + {{- if and (eq $serviceType "ClusterIP") $serviceClusterIP }} + clusterIP: {{ $serviceClusterIP }} + {{- end }} + ports: + - name: tcp-postgresql + port: {{ template "postgresql.servicePort" . }} + targetPort: tcp-postgresql + {{- if $serviceNodePort }} + nodePort: {{ $serviceNodePort }} + {{- end }} + selector: + {{- include "common.labels.matchLabels" . | nindent 4 }} + role: primary diff --git a/helm/sonarqube/charts/postgresql/templates/tls-secrets.yaml b/helm/sonarqube/charts/postgresql/templates/tls-secrets.yaml new file mode 100644 index 0000000..a5944fc --- /dev/null +++ b/helm/sonarqube/charts/postgresql/templates/tls-secrets.yaml @@ -0,0 +1,25 @@ +{{- if (include "postgresql.createTlsSecret" . ) }} +{{- $ca := genCA "postgresql-ca" 365 }} +{{- $fullname := include "common.names.fullname" . }} +{{- $releaseNamespace := .Release.Namespace }} +{{- $clusterDomain := .Values.clusterDomain }} +{{- $headlessServiceName := printf "%s-headless" (include "common.names.fullname" .) }} +{{- $altNames := list (printf "*.%s.%s.svc.%s" $fullname $releaseNamespace $clusterDomain) (printf "%s.%s.svc.%s" $fullname $releaseNamespace $clusterDomain) (printf "*.%s.%s.svc.%s" $headlessServiceName $releaseNamespace $clusterDomain) (printf "%s.%s.svc.%s" $headlessServiceName $releaseNamespace $clusterDomain) $fullname }} +{{- $crt := genSignedCert $fullname nil $altNames 365 $ca }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ printf "%s-crt" (include "common.names.fullname" .) }} + labels: {{- include "common.labels.standard" . | nindent 4 }} + {{- if .Values.commonLabels }} + {{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} +type: kubernetes.io/tls +data: + ca.crt: {{ $ca.Cert | b64enc | quote }} + tls.crt: {{ $crt.Cert | b64enc | quote }} + tls.key: {{ $crt.Key | b64enc | quote }} +{{- end }} diff --git a/helm/sonarqube/charts/postgresql/values.schema.json b/helm/sonarqube/charts/postgresql/values.schema.json new file mode 100644 index 0000000..66a2a9d --- /dev/null +++ b/helm/sonarqube/charts/postgresql/values.schema.json @@ -0,0 +1,103 @@ +{ + "$schema": "http://json-schema.org/schema#", + "type": "object", + "properties": { + "postgresqlUsername": { + "type": "string", + "title": "Admin user", + "form": true + }, + "postgresqlPassword": { + "type": "string", + "title": "Password", + "form": true + }, + "persistence": { + "type": "object", + "properties": { + "size": { + "type": "string", + "title": "Persistent Volume Size", + "form": true, + "render": "slider", + "sliderMin": 1, + "sliderMax": 100, + "sliderUnit": "Gi" + } + } + }, + "resources": { + "type": "object", + "title": "Required Resources", + "description": "Configure resource requests", + "form": true, + "properties": { + "requests": { + "type": "object", + "properties": { + "memory": { + "type": "string", + "form": true, + "render": "slider", + "title": "Memory Request", + "sliderMin": 10, + "sliderMax": 2048, + "sliderUnit": "Mi" + }, + "cpu": { + "type": "string", + "form": true, + "render": "slider", + "title": "CPU Request", + "sliderMin": 10, + "sliderMax": 2000, + "sliderUnit": "m" + } + } + } + } + }, + "replication": { + "type": "object", + "form": true, + "title": "Replication Details", + "properties": { + "enabled": { + "type": "boolean", + "title": "Enable Replication", + "form": true + }, + "readReplicas": { + "type": "integer", + "title": "read Replicas", + "form": true, + "hidden": { + "value": false, + "path": "replication/enabled" + } + } + } + }, + "volumePermissions": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "form": true, + "title": "Enable Init Containers", + "description": "Change the owner of the persist volume mountpoint to RunAsUser:fsGroup" + } + } + }, + "metrics": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "title": "Configure metrics exporter", + "form": true + } + } + } + } +} diff --git a/helm/sonarqube/charts/postgresql/values.yaml b/helm/sonarqube/charts/postgresql/values.yaml new file mode 100644 index 0000000..d874fdd --- /dev/null +++ b/helm/sonarqube/charts/postgresql/values.yaml @@ -0,0 +1,996 @@ +## @section Global parameters +## Global Docker image parameters +## Please, note that this will override the image parameters, including dependencies, configured to use the global value +## Current available global Docker image parameters: imageRegistry, imagePullSecrets and storageClass +## + +## @param global.imageRegistry Global Docker image registry +## @param global.imagePullSecrets Global Docker registry secret names as an array +## @param global.storageClass Global StorageClass for Persistent Volume(s) +## +global: + imageRegistry: "" + ## E.g. + ## imagePullSecrets: + ## - myRegistryKeySecretName + ## + imagePullSecrets: [] + storageClass: "" + ## @param global.postgresql.postgresqlDatabase PostgreSQL database (overrides `postgresqlDatabase`) + ## @param global.postgresql.postgresqlUsername PostgreSQL username (overrides `postgresqlUsername`) + ## @param global.postgresql.existingSecret Name of existing secret to use for PostgreSQL passwords (overrides `existingSecret`) + ## @param global.postgresql.postgresqlPassword PostgreSQL admin password (overrides `postgresqlPassword`) + ## @param global.postgresql.servicePort PostgreSQL port (overrides `service.port` + ## @param global.postgresql.replicationPassword Replication user password (overrides `replication.password`) + ## + postgresql: + postgresqlDatabase: "" + postgresqlUsername: "" + existingSecret: "" + postgresqlPassword: "" + servicePort: "" + replicationPassword: "" + +## @section Common parameters +## + +## @param nameOverride String to partially override common.names.fullname template (will maintain the release name) +## +nameOverride: "" +## @param fullnameOverride String to fully override common.names.fullname template +## +fullnameOverride: "" +## @param extraDeploy Array of extra objects to deploy with the release (evaluated as a template) +## +extraDeploy: [] +## @param commonLabels Add labels to all the deployed resources +## +commonLabels: {} +## @param commonAnnotations Add annotations to all the deployed resources +## +commonAnnotations: {} + +## Enable diagnostic mode in the deployment +## +diagnosticMode: + ## @param diagnosticMode.enabled Enable diagnostic mode (all probes will be disabled and the command will be overridden) + ## + enabled: false + ## @param diagnosticMode.command Command to override all containers in the deployment + ## + command: + - sleep + ## @param diagnosticMode.args Args to override all containers in the deployment + ## + args: + - infinity + +## @section PostgreSQL parameters +## + +## Bitnami PostgreSQL image version +## ref: https://hub.docker.com/r/bitnami/postgresql/tags/ +## @param image.registry PostgreSQL image registry +## @param image.repository PostgreSQL image repository +## @param image.tag PostgreSQL image tag (immutable tags are recommended) +## @param image.pullPolicy PostgreSQL image pull policy +## @param image.pullSecrets Specify image pull secrets +## @param image.debug Specify if debug values should be set +## +image: + registry: docker.io + repository: bitnami/postgresql + tag: 11.14.0-debian-10-r22 + ## Specify a imagePullPolicy + ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' + ## ref: https://kubernetes.io/docs/user-guide/images/#pre-pulling-images + ## + pullPolicy: IfNotPresent + ## Optionally specify an array of imagePullSecrets. + ## Secrets must be manually created in the namespace. + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ + ## Example: + ## pullSecrets: + ## - myRegistryKeySecretName + ## + pullSecrets: [] + ## Set to true if you would like to see extra information on logs + ## It turns BASH and/or NAMI debugging in the image + ## + debug: false +## Init containers parameters: +## volumePermissions: Change the owner of the persist volume mountpoint to RunAsUser:fsGroup +## +volumePermissions: + ## @param volumePermissions.enabled Enable init container that changes volume permissions in the data directory (for cases where the default k8s `runAsUser` and `fsUser` values do not work) + ## + enabled: false + ## @param volumePermissions.image.registry Init container volume-permissions image registry + ## @param volumePermissions.image.repository Init container volume-permissions image repository + ## @param volumePermissions.image.tag Init container volume-permissions image tag (immutable tags are recommended) + ## @param volumePermissions.image.pullPolicy Init container volume-permissions image pull policy + ## @param volumePermissions.image.pullSecrets Init container volume-permissions image pull secrets + ## + image: + registry: docker.io + repository: bitnami/bitnami-shell + tag: 10-debian-10-r299 + ## Specify a imagePullPolicy + ## Defaults to 'Always' if image tag is 'latest', else set to 'IfNotPresent' + ## ref: https://kubernetes.io/docs/user-guide/images/#pre-pulling-images + ## + pullPolicy: IfNotPresent + ## Optionally specify an array of imagePullSecrets. + ## Secrets must be manually created in the namespace. + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ + ## Example: + ## pullSecrets: + ## - myRegistryKeySecretName + ## + pullSecrets: [] + ## Init container Security Context + ## @param volumePermissions.securityContext.runAsUser User ID for the init container + ## Note: the chown of the data folder is done to securityContext.runAsUser + ## and not the below volumePermissions.securityContext.runAsUser + ## When runAsUser is set to special value "auto", init container will try to chwon the + ## data folder to autodetermined user&group, using commands: `id -u`:`id -G | cut -d" " -f2` + ## "auto" is especially useful for OpenShift which has scc with dynamic userids (and 0 is not allowed). + ## You may want to use this volumePermissions.securityContext.runAsUser="auto" in combination with + ## pod securityContext.enabled=false and shmVolume.chmod.enabled=false + ## + securityContext: + runAsUser: 0 +## @param schedulerName Use an alternate scheduler, e.g. "stork". +## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ +## +schedulerName: "" +## @param lifecycleHooks for the PostgreSQL container to automate configuration before or after startup +## +lifecycleHooks: {} +## Pod Security Context +## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ +## @param securityContext.enabled Enable security context +## @param securityContext.fsGroup Group ID for the pod +## +securityContext: + enabled: true + fsGroup: 1001 +## Container Security Context +## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ +## @param containerSecurityContext.enabled Enable container security context +## @param containerSecurityContext.runAsUser User ID for the container +## +containerSecurityContext: + enabled: true + runAsUser: 1001 +## Pod Service Account +## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ +## +serviceAccount: + ## @param serviceAccount.enabled Enable service account (Note: Service Account will only be automatically created if `serviceAccount.name` is not set) + ## + enabled: false + ## @param serviceAccount.name Name of an already existing service account. Setting this value disables the automatic service account creation + ## + name: "" + ## @param serviceAccount.autoMount Auto-mount the service account token in the pod + ## + autoMount: false +## Pod Security Policy +## ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/ +## @param psp.create Whether to create a PodSecurityPolicy. WARNING: PodSecurityPolicy is deprecated in Kubernetes v1.21 or later, unavailable in v1.25 or later +## +psp: + create: false +## Creates role for ServiceAccount +## Required for PSP +## @param rbac.create Create Role and RoleBinding (required for PSP to work) +## +rbac: + create: false +## @param replication.enabled Enable replication +## @param replication.user Replication user +## @param replication.password Replication user password +## @param replication.readReplicas Number of read replicas replicas +## @param replication.synchronousCommit Set synchronous commit mode. Allowed values: `on`, `remote_apply`, `remote_write`, `local` and `off` +## @param replication.numSynchronousReplicas Number of replicas that will have synchronous replication. Note: Cannot be greater than `replication.readReplicas`. +## @param replication.applicationName Cluster application name. Useful for advanced replication settings +## @param replication.singleService Create one service connecting to all read-replicas +## @param replication.uniqueServices Create a unique service for each independent read-replica +## +replication: + enabled: false + user: repl_user + password: repl_password + readReplicas: 1 + ## ref: https://www.postgresql.org/docs/9.6/runtime-config-wal.html#GUC-WAL-LEVEL + ## + synchronousCommit: "off" + ## NOTE: It cannot be > readReplicas + ## + numSynchronousReplicas: 0 + applicationName: my_application + singleService: true + uniqueServices: false +## @param postgresqlPostgresPassword PostgreSQL admin password (used when `postgresqlUsername` is not `postgres`, in which case`postgres` is the admin username) +## ref: https://github.com/bitnami/bitnami-docker-postgresql/blob/master/README.md#creating-a-database-user-on-first-run (see note!) +## +postgresqlPostgresPassword: "" +## @param postgresqlUsername PostgreSQL user (has superuser privileges if username is `postgres`) +## ref: https://github.com/bitnami/bitnami-docker-postgresql/blob/master/README.md#setting-the-root-password-on-first-run +## +postgresqlUsername: postgres +## @param postgresqlPassword PostgreSQL user password +## ref: https://github.com/bitnami/bitnami-docker-postgresql/blob/master/README.md#setting-the-root-password-on-first-run +## +postgresqlPassword: "" +## @param existingSecret Name of existing secret to use for PostgreSQL passwords +## The secret has to contain the keys postgresql-password which is the password for postgresqlUsername when it is +## different of postgres, postgresql-postgres-password which will override postgresqlPassword, +## postgresql-replication-password which will override replication.password and postgresql-ldap-password which will be +## used to authenticate on LDAP. The value is evaluated as a template. +## e.g: +## existingSecret: secret +## +existingSecret: "" +## @param usePasswordFile Mount PostgreSQL secret as a file instead of passing environment variable +## +usePasswordFile: false +## @param postgresqlDatabase PostgreSQL database +## ref: https://github.com/bitnami/bitnami-docker-postgresql/blob/master/README.md#creating-a-database-on-first-run +## +postgresqlDatabase: "" +## @param postgresqlDataDir PostgreSQL data dir folder +## ref: https://github.com/bitnami/bitnami-docker-postgresql/blob/master/README.md +## +postgresqlDataDir: /bitnami/postgresql/data +## @param extraEnv An array to add extra environment variables +## For example: +## extraEnv: +## - name: FOO +## value: "bar" +## +extraEnv: [] +## @param extraEnvVarsCM Name of a Config Map containing extra environment variables +## +extraEnvVarsCM: "" +## @param postgresqlInitdbArgs PostgreSQL initdb extra arguments +## ref: https://github.com/bitnami/bitnami-docker-postgresql/blob/master/README.md +## +postgresqlInitdbArgs: "" +## @param postgresqlInitdbWalDir Specify a custom location for the PostgreSQL transaction log +## ref: https://github.com/bitnami/bitnami-docker-postgresql/blob/master/README.md +## +postgresqlInitdbWalDir: "" +## @param postgresqlConfiguration PostgreSQL configuration +## Specify runtime configuration parameters as a dict, using camelCase, e.g. +## {"sharedBuffers": "500MB"} +## Alternatively, you can put your postgresql.conf under the files/ directory +## ref: https://www.postgresql.org/docs/current/static/runtime-config.html +## +postgresqlConfiguration: {} +## @param postgresqlExtendedConf Extended Runtime Config Parameters (appended to main or default configuration) +## Alternatively, you can put your *.conf under the files/conf.d/ directory +## https://github.com/bitnami/bitnami-docker-postgresql#allow-settings-to-be-loaded-from-files-other-than-the-default-postgresqlconf +## +postgresqlExtendedConf: {} +## Configure current cluster's primary server to be the standby server in other cluster. +## This will allow cross cluster replication and provide cross cluster high availability. +## You will need to configure pgHbaConfiguration if you want to enable this feature with local cluster replication enabled. +## @param primaryAsStandBy.enabled Whether to enable current cluster's primary as standby server of another cluster or not +## @param primaryAsStandBy.primaryHost The Host of replication primary in the other cluster +## @param primaryAsStandBy.primaryPort The Port of replication primary in the other cluster +## +primaryAsStandBy: + enabled: false + primaryHost: "" + primaryPort: "" +## @param pgHbaConfiguration PostgreSQL client authentication configuration +## Specify content for pg_hba.conf +## Default: do not create pg_hba.conf +## Alternatively, you can put your pg_hba.conf under the files/ directory +## pgHbaConfiguration: |- +## local all all trust +## host all all localhost trust +## host mydatabase mysuser 192.168.0.0/24 md5 +## +pgHbaConfiguration: "" +## @param configurationConfigMap ConfigMap with PostgreSQL configuration +## NOTE: This will override postgresqlConfiguration and pgHbaConfiguration +## +configurationConfigMap: "" +## @param extendedConfConfigMap ConfigMap with PostgreSQL extended configuration +## +extendedConfConfigMap: "" +## @param initdbScripts Dictionary of initdb scripts +## Specify dictionary of scripts to be run at first boot +## Alternatively, you can put your scripts under the files/docker-entrypoint-initdb.d directory +## e.g: +## initdbScripts: +## my_init_script.sh: | +## #!/bin/sh +## echo "Do something." +## +initdbScripts: {} +## @param initdbScriptsConfigMap ConfigMap with scripts to be run at first boot +## NOTE: This will override initdbScripts +## +initdbScriptsConfigMap: "" +## @param initdbScriptsSecret Secret with scripts to be run at first boot (in case it contains sensitive information) +## NOTE: This can work along initdbScripts or initdbScriptsConfigMap +## +initdbScriptsSecret: "" +## @param initdbUser Specify the PostgreSQL username to execute the initdb scripts +## +initdbUser: "" +## @param initdbPassword Specify the PostgreSQL password to execute the initdb scripts +## +initdbPassword: "" + +## @param containerPorts.postgresql PostgreSQL container port +## +containerPorts: + postgresql: 5432 +## Audit settings +## https://github.com/bitnami/bitnami-docker-postgresql#auditing +## +audit: + ## @param audit.logHostname Log client hostnames + ## + logHostname: false + ## @param audit.logConnections Add client log-in operations to the log file + ## + logConnections: false + ## @param audit.logDisconnections Add client log-outs operations to the log file + ## + logDisconnections: false + ## @param audit.pgAuditLog Add operations to log using the pgAudit extension + ## + pgAuditLog: "" + ## @param audit.pgAuditLogCatalog Log catalog using pgAudit + ## + pgAuditLogCatalog: "off" + ## @param audit.clientMinMessages Message log level to share with the user + ## + clientMinMessages: error + ## @param audit.logLinePrefix Template for log line prefix (default if not set) + ## + logLinePrefix: "" + ## @param audit.logTimezone Timezone for the log timestamps + ## + logTimezone: "" +## @param postgresqlSharedPreloadLibraries Shared preload libraries (comma-separated list) +## +postgresqlSharedPreloadLibraries: "pgaudit" +## @param postgresqlMaxConnections Maximum total connections +## +postgresqlMaxConnections: "" +## @param postgresqlPostgresConnectionLimit Maximum connections for the postgres user +## +postgresqlPostgresConnectionLimit: "" +## @param postgresqlDbUserConnectionLimit Maximum connections for the non-admin user +## +postgresqlDbUserConnectionLimit: "" +## @param postgresqlTcpKeepalivesInterval TCP keepalives interval +## +postgresqlTcpKeepalivesInterval: "" +## @param postgresqlTcpKeepalivesIdle TCP keepalives idle +## +postgresqlTcpKeepalivesIdle: "" +## @param postgresqlTcpKeepalivesCount TCP keepalives count +## +postgresqlTcpKeepalivesCount: "" +## @param postgresqlStatementTimeout Statement timeout +## +postgresqlStatementTimeout: "" +## @param postgresqlPghbaRemoveFilters Comma-separated list of patterns to remove from the pg_hba.conf file +## Cannot be used with custom pg_hba.conf +## +postgresqlPghbaRemoveFilters: "" +## @param terminationGracePeriodSeconds Seconds the pod needs to terminate gracefully +## ref: https://kubernetes.io/docs/concepts/workloads/pods/pod/#termination-of-pods +## e.g: +## terminationGracePeriodSeconds: 30 +## +terminationGracePeriodSeconds: "" +## LDAP configuration +## @param ldap.enabled Enable LDAP support +## @param ldap.url LDAP URL beginning in the form `ldap[s]://host[:port]/basedn` +## @param ldap.server IP address or name of the LDAP server. +## @param ldap.port Port number on the LDAP server to connect to +## @param ldap.prefix String to prepend to the user name when forming the DN to bind +## @param ldap.suffix String to append to the user name when forming the DN to bind +## @param ldap.baseDN Root DN to begin the search for the user in +## @param ldap.bindDN DN of user to bind to LDAP +## @param ldap.bind_password Password for the user to bind to LDAP +## @param ldap.search_attr Attribute to match against the user name in the search +## @param ldap.search_filter The search filter to use when doing search+bind authentication +## @param ldap.scheme Set to `ldaps` to use LDAPS +## @param ldap.tls Set to `1` to use TLS encryption +## +ldap: + enabled: false + url: "" + server: "" + port: "" + prefix: "" + suffix: "" + baseDN: "" + bindDN: "" + bind_password: "" + search_attr: "" + search_filter: "" + scheme: "" + tls: "" +## PostgreSQL service configuration +## +service: + ## @param service.type Kubernetes Service type + ## + type: ClusterIP + ## @param service.clusterIP Static clusterIP or None for headless services + ## e.g: + ## clusterIP: None + ## + clusterIP: "" + ## @param service.port PostgreSQL port + ## + port: 5432 + ## @param service.nodePort Specify the nodePort value for the LoadBalancer and NodePort service types + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport + ## + nodePort: "" + ## @param service.annotations Annotations for PostgreSQL service + ## + annotations: {} + ## @param service.loadBalancerIP Load balancer IP if service type is `LoadBalancer` + ## Set the LoadBalancer service type to internal only + ## ref: https://kubernetes.io/docs/concepts/services-networking/service/#internal-load-balancer + ## + loadBalancerIP: "" + ## @param service.externalTrafficPolicy Enable client source IP preservation + ## ref https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#preserving-the-client-source-ip + ## + externalTrafficPolicy: Cluster + ## @param service.loadBalancerSourceRanges Addresses that are allowed when service is LoadBalancer + ## https://kubernetes.io/docs/tasks/access-application-cluster/configure-cloud-provider-firewall/#restrict-access-for-loadbalancer-service + ## + ## loadBalancerSourceRanges: + ## - 10.10.10.0/24 + ## + loadBalancerSourceRanges: [] +## Start primary and read(s) pod(s) without limitations on shm memory. +## By default docker and containerd (and possibly other container runtimes) +## limit `/dev/shm` to `64M` (see e.g. the +## [docker issue](https://github.com/docker-library/postgres/issues/416) and the +## [containerd issue](https://github.com/containerd/containerd/issues/3654), +## which could be not enough if PostgreSQL uses parallel workers heavily. +## +shmVolume: + ## @param shmVolume.enabled Enable emptyDir volume for /dev/shm for primary and read replica(s) Pod(s) + ## Set `shmVolume.enabled` to `true` to mount a new tmpfs volume to remove the above limitation. + ## + enabled: true + ## @param shmVolume.chmod.enabled Set to `true` to `chmod 777 /dev/shm` on a initContainer (ignored if `volumePermissions.enabled` is `false`) + ## + chmod: + enabled: true + ## @param shmVolume.sizeLimit Set this to enable a size limit on the shm tmpfs. Note that the size of the tmpfs counts against container's memory limit + ## e.g: + ## sizeLimit: 1Gi + ## + sizeLimit: "" +persistence: + ## @param persistence.enabled Enable persistence using PVC + ## + enabled: true + ## @param persistence.existingClaim Provide an existing `PersistentVolumeClaim`, the value is evaluated as a template. + ## If defined, PVC must be created manually before volume will be bound + ## The value is evaluated as a template, so, for example, the name can depend on .Release or .Chart + ## + existingClaim: "" + ## @param persistence.mountPath The path the volume will be mounted at, useful when using different + ## PostgreSQL images. + ## + mountPath: /bitnami/postgresql + ## @param persistence.subPath The subdirectory of the volume to mount to + ## Useful in dev environments and one PV for multiple services + ## + subPath: "" + ## @param persistence.storageClass PVC Storage Class for PostgreSQL volume + ## If defined, storageClassName: + ## If set to "-", storageClassName: "", which disables dynamic provisioning + ## If undefined (the default) or set to null, no storageClassName spec is + ## set, choosing the default provisioner. (gp2 on AWS, standard on + ## GKE, AWS & OpenStack) + ## + storageClass: "" + ## @param persistence.accessModes PVC Access Mode for PostgreSQL volume + ## + accessModes: + - ReadWriteOnce + ## @param persistence.size PVC Storage Request for PostgreSQL volume + ## + size: 8Gi + ## @param persistence.annotations Annotations for the PVC + ## + annotations: {} + ## @param persistence.selector Selector to match an existing Persistent Volume (this value is evaluated as a template) + ## selector: + ## matchLabels: + ## app: my-app + ## + selector: {} +## @param updateStrategy.type updateStrategy for PostgreSQL StatefulSet and its reads StatefulSets +## ref: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#update-strategies +## +updateStrategy: + type: RollingUpdate +## +## PostgreSQL Primary parameters +## +primary: + ## @param primary.podAffinityPreset PostgreSQL primary pod affinity preset. Ignored if `primary.affinity` is set. Allowed values: `soft` or `hard` + ## ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity + ## + podAffinityPreset: "" + ## @param primary.podAntiAffinityPreset PostgreSQL primary pod anti-affinity preset. Ignored if `primary.affinity` is set. Allowed values: `soft` or `hard` + ## ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity + ## + podAntiAffinityPreset: soft + ## PostgreSQL Primary node affinity preset + ## ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#node-affinity + ## + nodeAffinityPreset: + ## @param primary.nodeAffinityPreset.type PostgreSQL primary node affinity preset type. Ignored if `primary.affinity` is set. Allowed values: `soft` or `hard` + ## + type: "" + ## @param primary.nodeAffinityPreset.key PostgreSQL primary node label key to match Ignored if `primary.affinity` is set. + ## E.g. + ## key: "kubernetes.io/e2e-az-name" + ## + key: "" + ## @param primary.nodeAffinityPreset.values PostgreSQL primary node label values to match. Ignored if `primary.affinity` is set. + ## E.g. + ## values: + ## - e2e-az1 + ## - e2e-az2 + ## + values: [] + ## @param primary.affinity Affinity for PostgreSQL primary pods assignment + ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity + ## Note: primary.podAffinityPreset, primary.podAntiAffinityPreset, and primary.nodeAffinityPreset will be ignored when it's set + ## + affinity: {} + ## @param primary.nodeSelector Node labels for PostgreSQL primary pods assignment + ## ref: https://kubernetes.io/docs/user-guide/node-selection/ + ## + nodeSelector: {} + ## @param primary.tolerations Tolerations for PostgreSQL primary pods assignment + ## ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ + ## + tolerations: [] + ## @param primary.extraPodSpec Optionally specify extra PodSpec + ## + extraPodSpec: {} + ## @param primary.labels Map of labels to add to the statefulset (postgresql primary) + ## + labels: {} + ## @param primary.annotations Annotations for PostgreSQL primary pods + ## + annotations: {} + ## @param primary.podLabels Map of labels to add to the pods (postgresql primary) + ## + podLabels: {} + ## @param primary.podAnnotations Map of annotations to add to the pods (postgresql primary) + ## + podAnnotations: {} + ## @param primary.priorityClassName Priority Class to use for each pod (postgresql primary) + ## + priorityClassName: "" + ## @param primary.extraInitContainers Extra init containers to add to the pods (postgresql primary) + ## Example + ## + ## extraInitContainers: + ## - name: do-something + ## image: busybox + ## command: ['do', 'something'] + ## + extraInitContainers: [] + ## @param primary.extraVolumeMounts Extra volume mounts to add to the pods (postgresql primary) + ## + extraVolumeMounts: [] + ## @param primary.extraVolumes Extra volumes to add to the pods (postgresql primary) + ## + extraVolumes: [] + ## @param primary.sidecars Extra containers to the pod + ## For example: + ## sidecars: + ## - name: your-image-name + ## image: your-image + ## imagePullPolicy: Always + ## ports: + ## - name: portname + ## containerPort: 1234 + ## + sidecars: [] + ## Override the service configuration for primary + ## @param primary.service.type Allows using a different service type for primary + ## @param primary.service.nodePort Allows using a different nodePort for primary + ## @param primary.service.clusterIP Allows using a different clusterIP for primary + ## + service: + type: "" + nodePort: "" + clusterIP: "" +## PostgreSQL read only replica parameters +## +readReplicas: + ## @param readReplicas.podAffinityPreset PostgreSQL read only pod affinity preset. Ignored if `primary.affinity` is set. Allowed values: `soft` or `hard` + ## ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity + ## + podAffinityPreset: "" + ## @param readReplicas.podAntiAffinityPreset PostgreSQL read only pod anti-affinity preset. Ignored if `primary.affinity` is set. Allowed values: `soft` or `hard` + ## ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#inter-pod-affinity-and-anti-affinity + ## + podAntiAffinityPreset: soft + ## PostgreSQL read only node affinity preset + ## ref: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#node-affinity + ## + nodeAffinityPreset: + ## @param readReplicas.nodeAffinityPreset.type PostgreSQL read only node affinity preset type. Ignored if `primary.affinity` is set. Allowed values: `soft` or `hard` + ## + type: "" + ## @param readReplicas.nodeAffinityPreset.key PostgreSQL read only node label key to match Ignored if `primary.affinity` is set. + ## E.g. + ## key: "kubernetes.io/e2e-az-name" + ## + key: "" + ## @param readReplicas.nodeAffinityPreset.values PostgreSQL read only node label values to match. Ignored if `primary.affinity` is set. + ## E.g. + ## values: + ## - e2e-az1 + ## - e2e-az2 + ## + values: [] + ## @param readReplicas.affinity Affinity for PostgreSQL read only pods assignment + ## ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity + ## Note: readReplicas.podAffinityPreset, readReplicas.podAntiAffinityPreset, and readReplicas.nodeAffinityPreset will be ignored when it's set + ## + affinity: {} + ## @param readReplicas.nodeSelector Node labels for PostgreSQL read only pods assignment + ## ref: https://kubernetes.io/docs/user-guide/node-selection/ + ## + nodeSelector: {} + ## @param readReplicas.tolerations Tolerations for PostgreSQL read only pods assignment + ## ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ + ## + tolerations: [] + ## @param readReplicas.topologySpreadConstraints Topology Spread Constraints for pod assignment spread across your cluster among failure-domains. Evaluated as a template + ## Ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/#spread-constraints-for-pods + ## + topologySpreadConstraints: [] + ## @param readReplicas.extraPodSpec Optionally specify extra PodSpec + ## + extraPodSpec: {} + ## @param readReplicas.labels Map of labels to add to the statefulsets (postgresql readReplicas) + ## + labels: {} + ## @param readReplicas.annotations Annotations for PostgreSQL read only pods + ## + annotations: {} + ## @param readReplicas.podLabels Map of labels to add to the pods (postgresql readReplicas) + ## + podLabels: {} + ## @param readReplicas.podAnnotations Map of annotations to add to the pods (postgresql readReplicas) + ## + podAnnotations: {} + ## @param readReplicas.priorityClassName Priority Class to use for each pod (postgresql readReplicas) + ## + priorityClassName: "" + ## @param readReplicas.extraInitContainers Extra init containers to add to the pods (postgresql readReplicas) + ## Example + ## + ## extraInitContainers: + ## - name: do-something + ## image: busybox + ## command: ['do', 'something'] + ## + extraInitContainers: [] + ## @param readReplicas.extraVolumeMounts Extra volume mounts to add to the pods (postgresql readReplicas) + ## + extraVolumeMounts: [] + ## @param readReplicas.extraVolumes Extra volumes to add to the pods (postgresql readReplicas) + ## + extraVolumes: [] + ## @param readReplicas.sidecars Extra containers to the pod + ## + ## For example: + ## sidecars: + ## - name: your-image-name + ## image: your-image + ## imagePullPolicy: Always + ## ports: + ## - name: portname + ## containerPort: 1234 + ## + sidecars: [] + ## Override the service configuration for read + ## @param readReplicas.service.type Allows using a different service type for readReplicas + ## @param readReplicas.service.nodePort Allows using a different nodePort for readReplicas + ## @param readReplicas.service.clusterIP Allows using a different clusterIP for readReplicas + ## + service: + type: "" + nodePort: "" + clusterIP: "" + ## @param readReplicas.persistence.enabled Whether to enable PostgreSQL read replicas replicas persistence + ## + persistence: + enabled: true + ## @param readReplicas.resources CPU/Memory resource requests/limits override for readReplicass. Will fallback to `values.resources` if not defined. + ## + resources: {} +## Configure resource requests and limits +## ref: https://kubernetes.io/docs/user-guide/compute-resources/ +## @param resources.requests [object] The requested resources for the container +## +resources: + requests: + memory: 256Mi + cpu: 250m +networkPolicy: + ## @param networkPolicy.enabled Enable creation of NetworkPolicy resources. Only Ingress traffic is filtered for now. + ## + enabled: false + ## @param networkPolicy.allowExternal Don't require client label for connections + ## The Policy model to apply. When set to false, only pods with the correct + ## client label will have network access to the port PostgreSQL is listening + ## on. When true, PostgreSQL will accept connections from any source + ## (with the correct destination port). + ## + allowExternal: true + ## @param networkPolicy.explicitNamespacesSelector A Kubernetes LabelSelector to explicitly select namespaces from which ingress traffic could be allowed + ## If explicitNamespacesSelector is missing or set to {}, only client Pods that are in the networkPolicy's namespace + ## and that match other criteria, the ones that have the good label, can reach the DB. + ## But sometimes, we want the DB to be accessible to clients from other namespaces, in this case, we can use this + ## LabelSelector to select these namespaces, note that the networkPolicy's namespace should also be explicitly added. + ## + ## Example: + ## explicitNamespacesSelector: + ## matchLabels: + ## role: frontend + ## matchExpressions: + ## - {key: role, operator: In, values: [frontend]} + ## + explicitNamespacesSelector: {} +## Configure extra options for liveness probe +## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#configure-probes +## @param startupProbe.enabled Enable startupProbe +## @param startupProbe.initialDelaySeconds Initial delay seconds for startupProbe +## @param startupProbe.periodSeconds Period seconds for startupProbe +## @param startupProbe.timeoutSeconds Timeout seconds for startupProbe +## @param startupProbe.failureThreshold Failure threshold for startupProbe +## @param startupProbe.successThreshold Success threshold for startupProbe +## +startupProbe: + enabled: false + initialDelaySeconds: 30 + periodSeconds: 15 + timeoutSeconds: 5 + failureThreshold: 10 + successThreshold: 1 +## Configure extra options for liveness probe +## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#configure-probes +## @param livenessProbe.enabled Enable livenessProbe +## @param livenessProbe.initialDelaySeconds Initial delay seconds for livenessProbe +## @param livenessProbe.periodSeconds Period seconds for livenessProbe +## @param livenessProbe.timeoutSeconds Timeout seconds for livenessProbe +## @param livenessProbe.failureThreshold Failure threshold for livenessProbe +## @param livenessProbe.successThreshold Success threshold for livenessProbe +## +livenessProbe: + enabled: true + initialDelaySeconds: 30 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 6 + successThreshold: 1 +## Configure extra options for readiness probe +## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes +## @param readinessProbe.enabled Enable readinessProbe +## @param readinessProbe.initialDelaySeconds Initial delay seconds for readinessProbe +## @param readinessProbe.periodSeconds Period seconds for readinessProbe +## @param readinessProbe.timeoutSeconds Timeout seconds for readinessProbe +## @param readinessProbe.failureThreshold Failure threshold for readinessProbe +## @param readinessProbe.successThreshold Success threshold for readinessProbe +## +readinessProbe: + enabled: true + initialDelaySeconds: 5 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 6 + successThreshold: 1 +## @param customStartupProbe Override default startup probe +## +customStartupProbe: {} +## @param customLivenessProbe Override default liveness probe +## +customLivenessProbe: {} +## @param customReadinessProbe Override default readiness probe +## +customReadinessProbe: {} +## +## TLS configuration +## +tls: + ## @param tls.enabled Enable TLS traffic support + ## + enabled: false + ## @param tls.autoGenerated Generate automatically self-signed TLS certificates + ## + autoGenerated: false + ## @param tls.preferServerCiphers Whether to use the server's TLS cipher preferences rather than the client's + ## + preferServerCiphers: true + ## @param tls.certificatesSecret Name of an existing secret that contains the certificates + ## + certificatesSecret: "" + ## @param tls.certFilename Certificate filename + ## + certFilename: "" + ## @param tls.certKeyFilename Certificate key filename + ## + certKeyFilename: "" + ## @param tls.certCAFilename CA Certificate filename + ## If provided, PostgreSQL will authenticate TLS/SSL clients by requesting them a certificate + ## ref: https://www.postgresql.org/docs/9.6/auth-methods.html + ## + certCAFilename: "" + ## @param tls.crlFilename File containing a Certificate Revocation List + ## + crlFilename: "" +## Configure metrics exporter +## +metrics: + ## @param metrics.enabled Start a prometheus exporter + ## + enabled: false + ## @param metrics.resources Prometheus exporter container resources + ## + resources: {} + ## @param metrics.service.type Kubernetes Service type + ## @param metrics.service.annotations [object] Additional annotations for metrics exporter pod + ## @param metrics.service.loadBalancerIP loadBalancerIP if redis metrics service type is `LoadBalancer` + ## + service: + type: ClusterIP + annotations: + prometheus.io/scrape: "true" + prometheus.io/port: "9187" + loadBalancerIP: "" + ## @param metrics.serviceMonitor.enabled Set this to `true` to create ServiceMonitor for Prometheus operator + ## @param metrics.serviceMonitor.additionalLabels Additional labels that can be used so ServiceMonitor will be discovered by Prometheus + ## @param metrics.serviceMonitor.namespace Optional namespace in which to create ServiceMonitor + ## @param metrics.serviceMonitor.interval Scrape interval. If not set, the Prometheus default scrape interval is used + ## @param metrics.serviceMonitor.scrapeTimeout Scrape timeout. If not set, the Prometheus default scrape timeout is used + ## @param metrics.serviceMonitor.relabelings RelabelConfigs to apply to samples before scraping + ## @param metrics.serviceMonitor.metricRelabelings MetricRelabelConfigs to apply to samples before ingestion + ## + serviceMonitor: + enabled: false + additionalLabels: {} + namespace: "" + interval: "" + scrapeTimeout: "" + relabelings: [] + metricRelabelings: [] + ## Custom PrometheusRule to be defined + ## The value is evaluated as a template, so, for example, the value can depend on .Release or .Chart + ## ref: https://github.com/coreos/prometheus-operator#customresourcedefinitions + ## + prometheusRule: + ## @param metrics.prometheusRule.enabled Set this to true to create prometheusRules for Prometheus operator + ## + enabled: false + ## @param metrics.prometheusRule.additionalLabels Additional labels that can be used so prometheusRules will be discovered by Prometheus + ## + additionalLabels: {} + ## @param metrics.prometheusRule.namespace namespace where prometheusRules resource should be created + ## + namespace: "" + ## @param metrics.prometheusRule.rules Create specified [Rules](https://prometheus.io/docs/prometheus/latest/configuration/alerting_rules/) + ## Make sure to constraint the rules to the current postgresql service. + ## rules: + ## - alert: HugeReplicationLag + ## expr: pg_replication_lag{service="{{ template "common.names.fullname" . }}-metrics"} / 3600 > 1 + ## for: 1m + ## labels: + ## severity: critical + ## annotations: + ## description: replication for {{ template "common.names.fullname" . }} PostgreSQL is lagging by {{ "{{ $value }}" }} hour(s). + ## summary: PostgreSQL replication is lagging by {{ "{{ $value }}" }} hour(s). + ## + rules: [] + ## @param metrics.image.registry PostgreSQL Exporter image registry + ## @param metrics.image.repository PostgreSQL Exporter image repository + ## @param metrics.image.tag PostgreSQL Exporter image tag (immutable tags are recommended) + ## @param metrics.image.pullPolicy PostgreSQL Exporter image pull policy + ## @param metrics.image.pullSecrets Specify image pull secrets + ## + image: + registry: docker.io + repository: bitnami/postgres-exporter + tag: 0.10.0-debian-10-r167 + pullPolicy: IfNotPresent + ## Optionally specify an array of imagePullSecrets. + ## Secrets must be manually created in the namespace. + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ + ## Example: + ## pullSecrets: + ## - myRegistryKeySecretName + ## + pullSecrets: [] + ## @param metrics.customMetrics Define additional custom metrics + ## ref: https://github.com/wrouesnel/postgres_exporter#adding-new-metrics-via-a-config-file + ## customMetrics: + ## pg_database: + ## query: "SELECT d.datname AS name, CASE WHEN pg_catalog.has_database_privilege(d.datname, 'CONNECT') THEN pg_catalog.pg_database_size(d.datname) ELSE 0 END AS size_bytes FROM pg_catalog.pg_database d where datname not in ('template0', 'template1', 'postgres')" + ## metrics: + ## - name: + ## usage: "LABEL" + ## description: "Name of the database" + ## - size_bytes: + ## usage: "GAUGE" + ## description: "Size of the database in bytes" + ## + customMetrics: {} + ## @param metrics.extraEnvVars Extra environment variables to add to postgres-exporter + ## see: https://github.com/wrouesnel/postgres_exporter#environment-variables + ## For example: + ## extraEnvVars: + ## - name: PG_EXPORTER_DISABLE_DEFAULT_METRICS + ## value: "true" + ## + extraEnvVars: [] + ## Pod Security Context + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + ## @param metrics.securityContext.enabled Enable security context for metrics + ## @param metrics.securityContext.runAsUser User ID for the container for metrics + ## + securityContext: + enabled: false + runAsUser: 1001 + ## Configure extra options for liveness probe + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes + ## @param metrics.livenessProbe.enabled Enable livenessProbe + ## @param metrics.livenessProbe.initialDelaySeconds Initial delay seconds for livenessProbe + ## @param metrics.livenessProbe.periodSeconds Period seconds for livenessProbe + ## @param metrics.livenessProbe.timeoutSeconds Timeout seconds for livenessProbe + ## @param metrics.livenessProbe.failureThreshold Failure threshold for livenessProbe + ## @param metrics.livenessProbe.successThreshold Success threshold for livenessProbe + ## + livenessProbe: + enabled: true + initialDelaySeconds: 5 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 6 + successThreshold: 1 + ## Configure extra options for readiness probe + ## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#configure-probes + ## @param metrics.readinessProbe.enabled Enable readinessProbe + ## @param metrics.readinessProbe.initialDelaySeconds Initial delay seconds for readinessProbe + ## @param metrics.readinessProbe.periodSeconds Period seconds for readinessProbe + ## @param metrics.readinessProbe.timeoutSeconds Timeout seconds for readinessProbe + ## @param metrics.readinessProbe.failureThreshold Failure threshold for readinessProbe + ## @param metrics.readinessProbe.successThreshold Success threshold for readinessProbe + ## + readinessProbe: + enabled: true + initialDelaySeconds: 5 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 6 + successThreshold: 1 diff --git a/helm/sonarqube/override_values.yaml b/helm/sonarqube/override_values.yaml new file mode 100644 index 0000000..eb8fb40 --- /dev/null +++ b/helm/sonarqube/override_values.yaml @@ -0,0 +1,27 @@ +service: + type: NodePort + nodePort: 31024 + +resources: + limits: + cpu: 800m + memory: 4Gi + requests: + cpu: 400m + memory: 2Gi + +persistence: + enabled: true + storageClass: nfs-provisioner-mgmt-nas + +postgresql: + resources: + limits: + cpu: 400m + memory: 500Mi + requests: + cpu: 200m + memory: 200Mi + persistence: + enabled: true + storageClass: nfs-provisioner-mgmt-nas \ No newline at end of file diff --git a/helm/sonarqube/templates/NOTES.txt b/helm/sonarqube/templates/NOTES.txt new file mode 100644 index 0000000..5ca350c --- /dev/null +++ b/helm/sonarqube/templates/NOTES.txt @@ -0,0 +1,22 @@ +1. Get the application URL by running these commands: +{{- if .Values.ingress.enabled }} +{{- range .Values.ingress.hosts }} + http://{{ .name }} +{{- end }} +{{- else if .Values.route.enabled }} + export ROUTE_HOST=$(kubectl get route {{ template "sonarqube.name" . }} --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.host}") + echo https://$ROUTE_HOST +{{- else if contains "NodePort" .Values.service.type }} + export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ template "sonarqube.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 svc -w {{ template "sonarqube.fullname" . }}' + export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ template "sonarqube.fullname" . }} -o jsonpath='{.status.loadBalancer.ingress[0].ip}') + echo http://$SERVICE_IP:{{ .Values.service.externalPort }} +{{- else if contains "ClusterIP" .Values.service.type }} + export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app={{ template "sonarqube.name" . }},release={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") + echo "Visit http://127.0.0.1:8080 to use your application" + kubectl port-forward $POD_NAME 8080:{{ .Values.service.externalPort }} -n {{ .Release.Namespace }} +{{- end }} diff --git a/helm/sonarqube/templates/_helpers.tpl b/helm/sonarqube/templates/_helpers.tpl new file mode 100644 index 0000000..837ac98 --- /dev/null +++ b/helm/sonarqube/templates/_helpers.tpl @@ -0,0 +1,199 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "sonarqube.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +*/}} +{{- define "sonarqube.fullname" -}} +{{- if .Values.fullnameOverride -}} +{{- .Values.fullnameOverride | trunc 63 -}} +{{- else -}} +{{- printf "%s-%s" .Release.Name (include "sonarqube.name" .) | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} + +{{/* + Create a default fully qualified mysql/postgresql name. + We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +*/}} +{{- define "postgresql.fullname" -}} +{{- printf "%s-%s" .Release.Name "postgresql" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* + Determine the hostname to use for PostgreSQL/mySQL. +*/}} +{{- define "postgresql.hostname" -}} +{{- if .Values.postgresql.enabled -}} +{{- printf "%s-%s" .Release.Name "postgresql" | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s" .Values.postgresql.postgresqlServer -}} +{{- end -}} +{{- end -}} + +{{/* +Determine the k8s secret containing the JDBC credentials +*/}} +{{- define "jdbc.secret" -}} +{{- if .Values.postgresql.enabled -}} + {{- if .Values.postgresql.existingSecret -}} + {{- .Values.postgresql.existingSecret -}} + {{- else -}} + {{- template "postgresql.fullname" . -}} + {{- end -}} +{{- else if .Values.jdbcOverwrite.enable -}} + {{- if .Values.jdbcOverwrite.jdbcSecretName -}} + {{- .Values.jdbcOverwrite.jdbcSecretName -}} + {{- else -}} + {{- template "sonarqube.fullname" . -}} + {{- end -}} +{{- else -}} + {{- template "sonarqube.fullname" . -}} +{{- end -}} +{{- end -}} + +{{/* +Determine JDBC username +*/}} +{{- define "jdbc.username" -}} +{{- if and .Values.postgresql.enabled .Values.postgresql.postgresqlUsername -}} + {{- .Values.postgresql.postgresqlUsername | quote -}} +{{- else if and .Values.jdbcOverwrite.enable .Values.jdbcOverwrite.jdbcUsername -}} + {{- .Values.jdbcOverwrite.jdbcUsername | quote -}} +{{- else -}} + {{- .Values.postgresql.postgresqlUsername -}} +{{- end -}} +{{- end -}} + +{{/* +Determine the k8s secretKey contrining the JDBC password +*/}} +{{- define "jdbc.secretPasswordKey" -}} +{{- if .Values.postgresql.enabled -}} + {{- if and .Values.postgresql.existingSecret .Values.postgresql.existingSecretPasswordKey -}} + {{- .Values.postgresql.existingSecretPasswordKey -}} + {{- else -}} + {{- "postgresql-password" -}} + {{- end -}} +{{- else if .Values.jdbcOverwrite.enable -}} + {{- if and .Values.jdbcOverwrite.jdbcSecretName .Values.jdbcOverwrite.jdbcSecretPasswordKey -}} + {{- .Values.jdbcOverwrite.jdbcSecretPasswordKey -}} + {{- else -}} + {{- "jdbc-password" -}} + {{- end -}} +{{- else -}} + {{- "jdbc-password" -}} +{{- end -}} +{{- end -}} + +{{/* +Determine JDBC password if internal secret is used +*/}} +{{- define "jdbc.internalSecretPasswd" -}} +{{- if .Values.jdbcOverwrite.enable -}} + {{- .Values.jdbcOverwrite.jdbcPassword | b64enc | quote -}} +{{- else -}} + {{- .Values.postgresql.postgresqlPassword | b64enc | quote -}} +{{- end -}} +{{- end -}} + +{{/* +Set sonarqube.jvmOpts +*/}} +{{- define "sonarqube.jvmOpts" -}} +{{- $tempJvm := .Values.jvmOpts -}} +{{- if and .Values.sonarProperties (hasKey (.Values.sonarProperties) "sonar.web.javaOpts")}} +{{- $tempJvm = (get .Values.sonarProperties "sonar.web.javaOpts") -}} +{{- else if .Values.env -}} +{{- range $index, $val := .Values.env -}} +{{- if eq $val.name "SONAR_WEB_JAVAOPTS" -}} +{{- $tempJvm = $val.value -}} +{{- end -}} +{{- end -}} +{{- end -}} +{{- if and .Values.caCerts.enabled .Values.prometheusExporter.enabled -}} +{{ printf "-javaagent:%s/data/jmx_prometheus_javaagent.jar=%d:%s/conf/prometheus-config.yaml -Djavax.net.ssl.trustStore=%s/certs/cacerts %s" .Values.sonarqubeFolder (int .Values.prometheusExporter.webBeanPort) .Values.sonarqubeFolder .Values.sonarqubeFolder $tempJvm | trim | quote }} +{{- else if .Values.caCerts.enabled -}} +{{ printf "-Djavax.net.ssl.trustStore=%s/certs/cacerts %s" .Values.sonarqubeFolder $tempJvm | trim | quote }} +{{- else if .Values.prometheusExporter.enabled -}} +{{ printf "-javaagent:%s/data/jmx_prometheus_javaagent.jar=%d:%s/conf/prometheus-config.yaml %s" .Values.sonarqubeFolder (int .Values.prometheusExporter.webBeanPort) .Values.sonarqubeFolder $tempJvm | trim | quote }} +{{- else -}} +{{ printf "%s" $tempJvm }} +{{- end -}} +{{- end -}} + +{{/* +Set sonarqube.jvmCEOpts +*/}} +{{- define "sonarqube.jvmCEOpts" -}} +{{- $tempJvm := .Values.jvmCeOpts -}} +{{- if and .Values.sonarProperties (hasKey (.Values.sonarProperties) "sonar.ce.javaOpts")}} +{{- $tempJvm = (get .Values.sonarProperties "sonar.ce.javaOpts") -}} +{{- else if .Values.env -}} +{{- range $index, $val := .Values.env -}} +{{- if eq $val.name "SONAR_CE_JAVAOPTS" -}} +{{- $tempJvm = $val.value -}} +{{- end -}} +{{- end -}} +{{- end -}} +{{- if and .Values.caCerts.enabled .Values.prometheusExporter.enabled -}} +{{ printf "-javaagent:%s/data/jmx_prometheus_javaagent.jar=%d:%s/conf/prometheus-ce-config.yaml -Djavax.net.ssl.trustStore=%s/certs/cacerts %s" .Values.sonarqubeFolder (int .Values.prometheusExporter.ceBeanPort) .Values.sonarqubeFolder .Values.sonarqubeFolder $tempJvm | trim | quote }} +{{- else if .Values.caCerts.enabled -}} +{{ printf "-Djavax.net.ssl.trustStore=%s/certs/cacerts %s" .Values.sonarqubeFolder $tempJvm | trim | quote }} +{{- else if .Values.prometheusExporter.enabled -}} +{{ printf "-javaagent:%s/data/jmx_prometheus_javaagent.jar=%d:%s/conf/prometheus-ce-config.yaml %s" .Values.sonarqubeFolder (int .Values.prometheusExporter.ceBeanPort) .Values.sonarqubeFolder $tempJvm | trim | quote }} +{{- else -}} +{{ printf "%s" $tempJvm }} +{{- end -}} +{{- end -}} + +{{/* +Set prometheusExporter.downloadURL +*/}} +{{- define "prometheusExporter.downloadURL" -}} +{{- if .Values.prometheusExporter.downloadURL -}} +{{ printf "%s" .Values.prometheusExporter.downloadURL }} +{{- else -}} +{{ printf "https://repo1.maven.org/maven2/io/prometheus/jmx/jmx_prometheus_javaagent/%s/jmx_prometheus_javaagent-%s.jar" .Values.prometheusExporter.version .Values.prometheusExporter.version }} +{{- end -}} +{{- end -}} + + +{{/* +Create the name of the service account to use +*/}} +{{- define "sonarqube.serviceAccountName" -}} +{{- if .Values.serviceAccount.create -}} + {{ default (include "sonarqube.fullname" .) .Values.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +Set sonarqube.webcontext, ensuring it starts and ends with a slash, in order to ease probes url template +*/}} +{{- define "sonarqube.webcontext" -}} +{{- $tempWebcontext := .Values.sonarWebContext -}} +{{- if and .Values.sonarProperties (hasKey (.Values.sonarProperties) "sonar.web.context") -}} +{{- $tempWebcontext = (get .Values.sonarProperties "sonar.web.context") -}} +{{- end -}} +{{- range $index, $val := .Values.env -}} +{{- if eq $val.name "SONAR_WEB_CONTEXT" -}} +{{- $tempWebcontext = $val.value -}} +{{- end -}} +{{- end -}} +{{- if not (hasPrefix "/" $tempWebcontext) -}} +{{- $tempWebcontext = print "/" $tempWebcontext -}} +{{- end -}} +{{- if not (hasSuffix "/" $tempWebcontext) -}} +{{- $tempWebcontext = print $tempWebcontext "/" -}} +{{- end -}} +{{ printf "%s" $tempWebcontext }} +{{- end -}} \ No newline at end of file diff --git a/helm/sonarqube/templates/change-admin-password-hook.yml b/helm/sonarqube/templates/change-admin-password-hook.yml new file mode 100644 index 0000000..4f83977 --- /dev/null +++ b/helm/sonarqube/templates/change-admin-password-hook.yml @@ -0,0 +1,82 @@ +{{- if .Values.account }} +{{- if or .Values.account.adminPassword .Values.account.adminPasswordSecretName}} +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ template "sonarqube.fullname" . }}-change-admin-password-hook + labels: + app: {{ template "sonarqube.name" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}" + {{- range $key, $value := .Values.service.labels }} + {{ $key }}: {{ $value | quote }} + {{- end }} + annotations: + "helm.sh/hook": post-install + "helm.sh/hook-delete-policy": hook-succeeded + {{- range $key, $value := .Values.adminJobAnnotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} +spec: + template: + metadata: + name: {{ template "sonarqube.fullname" . }}-change-admin-password-hook + labels: + app: {{ template "sonarqube.name" . }} + heritage: {{ .Release.Service }} + release: {{ .Release.Name }} + {{- range $key, $value := .Values.service.labels }} + {{ $key }}: {{ $value | quote }} + {{- end }} + spec: + restartPolicy: OnFailure + {{- if or .Values.image.pullSecrets .Values.image.pullSecret }} + imagePullSecrets: + {{- if .Values.image.pullSecret }} + - name: {{ .Values.image.pullSecret }} + {{- end }} + {{- if .Values.image.pullSecrets }} +{{ toYaml .Values.image.pullSecrets | indent 8 }} + {{- end }} + {{- end }} + serviceAccountName: {{ template "sonarqube.serviceAccountName" . }} + {{- if .Values.tolerations }} + tolerations: +{{ toYaml .Values.tolerations | indent 8 }} + {{- end }} + {{- if .Values.affinity }} + affinity: +{{ toYaml .Values.affinity | indent 8 }} + {{- end }} + containers: + - name: {{ template "sonarqube.fullname" . }}-change-default-admin-password + image: {{ default "curlimages/curl:8.2.0" .Values.curlContainerImage }} + {{- if $securityContext := .Values.account.securityContext }} + securityContext: +{{ toYaml $securityContext | indent 12 }} + {{- end }} + command: ["sh", "-c", 'until curl -v --connect-timeout 100 {{ template "sonarqube.fullname" . }}:{{ default 9000 .Values.service.internalPort }}{{ .Values.account.sonarWebContext | default (include "sonarqube.webcontext" .) }}api/system/status | grep -w UP; do sleep 10; done; curl -v --connect-timeout 100 -u admin:$CURRENT_ADMIN_PASSWORD -X POST "{{ template "sonarqube.fullname" . }}:{{ default 9000 .Values.service.internalPort }}{{ .Values.account.sonarWebContext | default (include "sonarqube.webcontext" .) }}api/users/change_password?login=admin&previousPassword=$CURRENT_ADMIN_PASSWORD&password=$ADMIN_PASSWORD"'] + env: + - name: ADMIN_PASSWORD + valueFrom: + secretKeyRef: + {{- if .Values.account.adminPassword }} + name: {{ template "sonarqube.fullname" . }}-admin-password + {{- else }} + name: {{ .Values.account.adminPasswordSecretName }} + {{- end }} + key: password + - name: CURRENT_ADMIN_PASSWORD + valueFrom: + secretKeyRef: + {{- if .Values.account.adminPassword }} + name: {{ template "sonarqube.fullname" . }}-admin-password + {{- else }} + name: {{ .Values.account.adminPasswordSecretName }} + {{- end }} + key: currentPassword + resources: +{{ toYaml (default .Values.resources .Values.account.resources) | indent 10 }} +{{- end }} +{{- end }} diff --git a/helm/sonarqube/templates/config.yaml b/helm/sonarqube/templates/config.yaml new file mode 100644 index 0000000..2fc8623 --- /dev/null +++ b/helm/sonarqube/templates/config.yaml @@ -0,0 +1,20 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "sonarqube.fullname" . }}-config + labels: + app: {{ template "sonarqube.name" . }} + chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +data: + sonar.properties: | + {{- range $key, $val := .Values.sonarProperties }} + {{ $key }}={{ $val }} + {{- end }} + {{- if not .Values.elasticsearch.bootstrapChecks }} + sonar.es.bootstrap.checks.disable=true + {{- end }} + {{- if .Values.sonarSecretKey }} + sonar.secretKeyPath={{ .Values.sonarqubeFolder }}/secret/sonar-secret.txt + {{- end }} diff --git a/helm/sonarqube/templates/deployment.yaml b/helm/sonarqube/templates/deployment.yaml new file mode 100644 index 0000000..f9aa9fc --- /dev/null +++ b/helm/sonarqube/templates/deployment.yaml @@ -0,0 +1,482 @@ +{{- if eq .Values.deploymentType "Deployment"}} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "sonarqube.fullname" . }} + labels: + app: {{ template "sonarqube.name" . }} + chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + app.kubernetes.io/name: {{ template "sonarqube.name" . }}-{{ template "sonarqube.fullname" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/part-of: sonarqube + app.kubernetes.io/component: {{ template "sonarqube.fullname" . }} + app.kubernetes.io/version: {{ tpl .Values.image.tag . | quote }} +spec: + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: + app: {{ template "sonarqube.name" . }} + release: {{ .Release.Name }} +{{- if .Values.deploymentStrategy }} + strategy: +{{ toYaml .Values.deploymentStrategy | indent 4 }} +{{- end }} + template: + metadata: + labels: + app: {{ template "sonarqube.name" . }} + release: {{ .Release.Name }} +{{- with .Values.podLabels }} +{{ toYaml . | indent 8 }} +{{- end }} + annotations: + checksum/init-sysctl: {{ include (print $.Template.BasePath "/init-sysctl.yaml") . | sha256sum }} + checksum/plugins: {{ include (print $.Template.BasePath "/install-plugins.yaml") . | sha256sum }} + checksum/config: {{ include (print $.Template.BasePath "/config.yaml") . | sha256sum }} + checksum/secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }} +{{- if .Values.prometheusExporter.enabled }} + checksum/prometheus-config: {{ include (print $.Template.BasePath "/prometheus-config.yaml") . | sha256sum }} + checksum/prometheus-ce-config: {{ include (print $.Template.BasePath "/prometheus-ce-config.yaml") . | sha256sum }} +{{- end }} +{{- if .Values.annotations}} + {{- range $key, $value := .Values.annotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} +{{- end }} + spec: + {{- if .Values.schedulerName }} + schedulerName: {{ .Values.schedulerName }} + {{- end }} + securityContext: +{{ toYaml .Values.securityContext | indent 8 }} + {{- if or .Values.image.pullSecrets .Values.image.pullSecret }} + imagePullSecrets: + {{- if .Values.image.pullSecret }} + - name: {{ .Values.image.pullSecret }} + {{- end }} + {{- if .Values.image.pullSecrets}} +{{ toYaml .Values.image.pullSecrets | indent 8 }} + {{- end }} + {{- end }} + initContainers: + {{- if .Values.extraInitContainers }} +{{ toYaml .Values.extraInitContainers | indent 8 }} + {{- end }} + {{- if .Values.postgresql.enabled }} + - name: "wait-for-db" + image: {{ default "busybox:1.32" .Values.initContainers.image }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + {{- if $securityContext := .Values.initContainers.securityContext }} + securityContext: +{{ toYaml $securityContext | indent 12 }} + {{- end }} + resources: +{{ toYaml .Values.initContainers.resources | indent 12 }} + command: ["/bin/sh", "-c", "for i in $(seq 1 200); do nc -z -w3 {{ .Release.Name}}-postgresql 5432 && exit 0 || sleep 2; done; exit 1"] + {{- end }} + {{- if .Values.caCerts.enabled }} + - name: ca-certs + image: {{ default "adoptopenjdk/openjdk11:alpine" .Values.caCerts.image }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + command: ["sh"] + args: ["-c", "cp -f \"${JAVA_HOME}/lib/security/cacerts\" /tmp/certs/cacerts; if [ \"$(ls /tmp/secrets/ca-certs)\" ]; then for f in /tmp/secrets/ca-certs/*; do keytool -importcert -file \"${f}\" -alias \"$(basename \"${f}\")\" -keystore /tmp/certs/cacerts -storepass changeit -trustcacerts -noprompt; done; fi;"] + {{- if $securityContext := .Values.initContainers.securityContext }} + securityContext: +{{ toYaml $securityContext | indent 12 }} + {{- end }} + resources: +{{ toYaml .Values.initContainers.resources | indent 12 }} + volumeMounts: + - mountPath: /tmp/certs + name: sonarqube + subPath: certs + - mountPath: /tmp/secrets/ca-certs + name: ca-certs + {{- with .Values.env }} + env: + {{- . | toYaml | trim | nindent 12 }} + {{- end }} + {{- end }} + {{- if or .Values.initSysctl.enabled .Values.elasticsearch.configureNode }} + - name: init-sysctl + image: {{ default "busybox:1.32" .Values.initSysctl.image }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + {{- if $securityContext := (default .Values.initContainers.securityContext .Values.initSysctl.securityContext) }} + securityContext: +{{ toYaml $securityContext | indent 12 }} + {{- end }} + resources: +{{ toYaml (default .Values.initContainers.resources .Values.initSysctl.resources) | indent 12 }} + command: ["sh", + "-e", + "/tmp/scripts/init_sysctl.sh"] + volumeMounts: + - name: init-sysctl + mountPath: /tmp/scripts/ + {{- with .Values.env }} + env: + {{- . | toYaml | trim | nindent 12 }} + {{- end }} + {{- end }} + + {{- if or .Values.sonarProperties .Values.sonarSecretProperties .Values.sonarSecretKey (not .Values.elasticsearch.bootstrapChecks) }} + - name: concat-properties + image: {{ default "busybox:1.32" .Values.initContainers.image }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + command: + - sh + - -c + - | + #!/bin/sh + if [ -f /tmp/props/sonar.properties ]; then + cat /tmp/props/sonar.properties > /tmp/result/sonar.properties + fi + if [ -f /tmp/props/secret.properties ]; then + cat /tmp/props/secret.properties > /tmp/result/sonar.properties + fi + if [ -f /tmp/props/sonar.properties -a -f /tmp/props/secret.properties ]; then + awk 1 /tmp/props/sonar.properties /tmp/props/secret.properties > /tmp/result/sonar.properties + fi + volumeMounts: + {{- if or .Values.sonarProperties .Values.sonarSecretKey (not .Values.elasticsearch.bootstrapChecks) }} + - mountPath: /tmp/props/sonar.properties + name: config + subPath: sonar.properties + {{- end }} + {{- if .Values.sonarSecretProperties }} + - mountPath: /tmp/props/secret.properties + name: secret-config + subPath: secret.properties + {{- end }} + - mountPath: /tmp/result + name: concat-dir + {{- if $securityContext := .Values.initContainers.securityContext }} + securityContext: +{{ toYaml $securityContext | indent 12 }} + {{- end }} + resources: +{{ toYaml .Values.initContainers.resources | indent 12 }} + {{- with .Values.env }} + env: + {{- . | toYaml | trim | nindent 12 }} + {{- end }} + {{- end }} + + {{- if .Values.prometheusExporter.enabled }} + - name: inject-prometheus-exporter + image: {{ default "curlimages/curl:8.2.0" .Values.prometheusExporter.image }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + {{- if $securityContext := (default .Values.initContainers.securityContext .Values.prometheusExporter.securityContext) }} + securityContext: +{{ toYaml $securityContext | indent 12 }} + {{- end }} + resources: +{{ toYaml (default .Values.initContainers.resources .Values.prometheusExporter.resources) | indent 12 }} + command: ["/bin/sh","-c"] + args: ["curl -s '{{ template "prometheusExporter.downloadURL" . }}' {{ if $.Values.prometheusExporter.noCheckCertificate }}--insecure{{ end }} --output /data/jmx_prometheus_javaagent.jar -v"] + volumeMounts: + - mountPath: /data + name: sonarqube + subPath: data + env: + - name: http_proxy + value: {{ default "" .Values.prometheusExporter.httpProxy }} + - name: https_proxy + value: {{ default "" .Values.prometheusExporter.httpsProxy }} + - name: no_proxy + value: {{ default "" .Values.prometheusExporter.noProxy }} + {{- with .Values.env }} + {{- . | toYaml | trim | nindent 12 }} + {{- end }} + {{- end }} + {{- if .Values.plugins.install }} + - name: install-plugins + image: {{ default "curlimages/curl:8.2.0" .Values.plugins.image }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + command: ["sh", + "-e", + "/tmp/scripts/install_plugins.sh"] + volumeMounts: + - mountPath: {{ .Values.sonarqubeFolder }}/extensions/plugins + name: sonarqube + subPath: extensions/plugins + - name: install-plugins + mountPath: /tmp/scripts/ + {{- if .Values.plugins.netrcCreds }} + - name: plugins-netrc-file + mountPath: /root + {{- end }} + {{- if $securityContext := (default .Values.initContainers.securityContext .Values.plugins.securityContext) }} + securityContext: +{{ toYaml $securityContext | indent 12 }} + {{- end }} + resources: +{{ toYaml (default .Values.initContainers.resources .Values.plugins.resource) | indent 12 }} + env: + - name: http_proxy + value: {{ default "" .Values.plugins.httpProxy }} + - name: https_proxy + value: {{ default "" .Values.plugins.httpsProxy }} + - name: no_proxy + value: {{ default "" .Values.plugins.noProxy }} + {{- with .Values.env }} + {{- . | toYaml | trim | nindent 12 }} + {{- end }} + {{- end }} + containers: + {{- if .Values.extraContainers }} + {{- toYaml .Values.extraContainers | nindent 8 }} + {{- end }} + - name: {{ .Chart.Name }} + image: "{{ .Values.image.repository }}:{{ tpl .Values.image.tag . }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + ports: + - name: http + containerPort: {{ .Values.service.internalPort }} + protocol: TCP + {{- if .Values.prometheusExporter.enabled }} + - name: monitoring-web + containerPort: {{ .Values.prometheusExporter.webBeanPort }} + protocol: TCP + - name: monitoring-ce + containerPort: {{ .Values.prometheusExporter.ceBeanPort }} + protocol: TCP + {{- end }} + resources: +{{ toYaml (default .Values.resources .Values.resource) | indent 12 }} + env: + {{- with .Values.env }} + {{- . | toYaml | trim | nindent 12 }} + {{- end }} + - name: SONAR_HELM_CHART_VERSION + value: {{ .Chart.Version | replace "+" "_" }} + - name: SONAR_WEB_JAVAOPTS + value: {{ template "sonarqube.jvmOpts" . }} + - name: SONAR_CE_JAVAOPTS + value: {{ template "sonarqube.jvmCEOpts" . }} + - name: SONAR_WEB_CONTEXT + value: {{ include "sonarqube.webcontext" . }} + - name: SONAR_JDBC_PASSWORD + valueFrom: + secretKeyRef: + name: {{ template "jdbc.secret" . }} + key: {{ template "jdbc.secretPasswordKey" . }} + - name: SONAR_WEB_SYSTEMPASSCODE + valueFrom: + secretKeyRef: + {{- if and .Values.monitoringPasscodeSecretName .Values.monitoringPasscodeSecretKey }} + name: {{ .Values.monitoringPasscodeSecretName }} + key: {{ .Values.monitoringPasscodeSecretKey }} + {{- else }} + name: {{ template "sonarqube.fullname" . }}-monitoring-passcode + key: SONAR_WEB_SYSTEMPASSCODE + {{- end }} + envFrom: + - configMapRef: + name: {{ template "sonarqube.fullname" . }}-jdbc-config +{{- range .Values.extraConfig.secrets }} + - secretRef: + name: {{ . }} +{{- end }} +{{- range .Values.extraConfig.configmaps }} + - configMapRef: + name: {{ . }} +{{- end }} + livenessProbe: + exec: + command: + - sh + - -c + - | + host="$(hostname -i || echo '127.0.0.1')" + wget --no-proxy --quiet -O /dev/null --timeout={{ .Values.livenessProbe.timeoutSeconds }} --header="X-Sonar-Passcode: $SONAR_WEB_SYSTEMPASSCODE" "http://${host}:{{ .Values.service.internalPort }}{{ .Values.livenessProbe.sonarWebContext | default (include "sonarqube.webcontext" .) }}api/system/liveness" + initialDelaySeconds: {{ .Values.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.livenessProbe.periodSeconds }} + failureThreshold: {{ .Values.livenessProbe.failureThreshold }} + timeoutSeconds: {{ .Values.livenessProbe.timeoutSeconds }} + readinessProbe: + exec: + command: + - sh + - -c + - | + #!/bin/bash + # A Sonarqube container is considered ready if the status is UP, DB_MIGRATION_NEEDED or DB_MIGRATION_RUNNING + # status about migration are added to prevent the node to be kill while sonarqube is upgrading the database. + host="$(hostname -i || echo '127.0.0.1')" + if wget --no-proxy -qO- http://${host}:{{ .Values.service.internalPort }}{{ .Values.readinessProbe.sonarWebContext | default (include "sonarqube.webcontext" .) }}api/system/status | grep -q -e '"status":"UP"' -e '"status":"DB_MIGRATION_NEEDED"' -e '"status":"DB_MIGRATION_RUNNING"'; then + exit 0 + fi + exit 1 + initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.readinessProbe.periodSeconds }} + failureThreshold: {{ .Values.readinessProbe.failureThreshold }} + timeoutSeconds: {{ .Values.readinessProbe.timeoutSeconds }} + startupProbe: + httpGet: + scheme: HTTP + path: {{ .Values.startupProbe.sonarWebContext | default (include "sonarqube.webcontext" .) }}api/system/status + port: http + initialDelaySeconds: {{ .Values.startupProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.startupProbe.periodSeconds }} + failureThreshold: {{ .Values.startupProbe.failureThreshold }} + timeoutSeconds: {{ .Values.startupProbe.timeoutSeconds }} + {{- if .Values.containerSecurityContext }} + securityContext: +{{- toYaml .Values.containerSecurityContext | nindent 12 }} + {{- end }} + volumeMounts: +{{- if .Values.persistence.mounts }} +{{ toYaml .Values.persistence.mounts | indent 12 }} +{{- end }} +{{- if .Values.extraVolumeMounts }} +{{- .Values.extraVolumeMounts | toYaml | nindent 12 }} +{{- end }} + {{- if or .Values.sonarProperties .Values.sonarSecretProperties .Values.sonarSecretKey (not .Values.elasticsearch.bootstrapChecks) }} + - mountPath: {{ .Values.sonarqubeFolder }}/conf/ + name: concat-dir + {{- end }} + {{- if .Values.sonarSecretKey }} + - mountPath: {{ .Values.sonarqubeFolder }}/secret/ + name: secret + {{- end }} + {{- if .Values.caCerts.enabled }} + - mountPath: {{ .Values.sonarqubeFolder }}/certs + name: sonarqube + subPath: certs + {{- end }} + - mountPath: {{ .Values.sonarqubeFolder }}/data + name: sonarqube + subPath: data + {{- if .Values.persistence.enabled }} + - mountPath: {{ .Values.sonarqubeFolder }}/extensions + name: sonarqube + subPath: extensions + {{- else if .Values.plugins.install }} + - mountPath: {{ .Values.sonarqubeFolder }}/extensions/plugins + name: sonarqube + subPath: extensions/plugins + {{- end }} + - mountPath: {{ .Values.sonarqubeFolder }}/temp + name: sonarqube + subPath: temp + - mountPath: {{ .Values.sonarqubeFolder }}/logs + name: sonarqube + subPath: logs + - mountPath: /tmp + name: tmp-dir + {{- if .Values.prometheusExporter.enabled }} + - mountPath: {{ .Values.sonarqubeFolder }}/conf/prometheus-config.yaml + subPath: prometheus-config.yaml + name: prometheus-config + - mountPath: {{ .Values.sonarqubeFolder }}/conf/prometheus-ce-config.yaml + subPath: prometheus-ce-config.yaml + name: prometheus-ce-config + {{- end }} + {{- if .Values.priorityClassName }} + priorityClassName: {{ .Values.priorityClassName }} + {{- end }} + {{- if .Values.nodeSelector }} + nodeSelector: +{{ toYaml .Values.nodeSelector | indent 8 }} + {{- end }} + {{- if .Values.hostAliases }} + hostAliases: +{{ toYaml .Values.hostAliases | indent 8 }} + {{- end }} + {{- if .Values.tolerations }} + tolerations: +{{ toYaml .Values.tolerations | indent 8 }} + {{- end }} + {{- if .Values.affinity }} + affinity: +{{ toYaml .Values.affinity | indent 8 }} + {{- end }} + serviceAccountName: {{ template "sonarqube.serviceAccountName" . }} + volumes: +{{- if .Values.extraVolumes }} +{{- .Values.extraVolumes | toYaml | nindent 6 }} +{{- end }} +{{- if .Values.persistence.volumes }} +{{ tpl (toYaml .Values.persistence.volumes | indent 6) . }} +{{- end }} + {{- if or .Values.sonarProperties .Values.sonarSecretKey ( not .Values.elasticsearch.bootstrapChecks) }} + - name: config + configMap: + name: {{ template "sonarqube.fullname" . }}-config + items: + - key: sonar.properties + path: sonar.properties + {{- end }} + {{- if .Values.sonarSecretProperties }} + - name: secret-config + secret: + secretName: {{ .Values.sonarSecretProperties }} + items: + - key: secret.properties + path: secret.properties + {{- end }} + {{- if .Values.sonarSecretKey }} + - name: secret + secret: + secretName: {{ .Values.sonarSecretKey }} + items: + - key: sonar-secret.txt + path: sonar-secret.txt + {{- end }} + {{- if .Values.caCerts.enabled }} + - name: ca-certs + secret: + secretName: {{ .Values.caCerts.secret }} + {{- end }} + {{- if .Values.plugins.netrcCreds }} + - name: plugins-netrc-file + secret: + secretName: {{ .Values.plugins.netrcCreds }} + items: + - key: netrc + path: .netrc + {{- end }} + - name: init-sysctl + configMap: + name: {{ template "sonarqube.fullname" . }}-init-sysctl + items: + - key: init_sysctl.sh + path: init_sysctl.sh + - name: install-plugins + configMap: + name: {{ template "sonarqube.fullname" . }}-install-plugins + items: + - key: install_plugins.sh + path: install_plugins.sh + {{- if .Values.prometheusExporter.enabled }} + - name: prometheus-config + configMap: + name: {{ template "sonarqube.fullname" . }}-prometheus-config + items: + - key: prometheus-config.yaml + path: prometheus-config.yaml + - name: prometheus-ce-config + configMap: + name: {{ template "sonarqube.fullname" . }}-prometheus-ce-config + items: + - key: prometheus-ce-config.yaml + path: prometheus-ce-config.yaml + {{- end }} + - name: sonarqube + {{- if .Values.persistence.enabled }} + persistentVolumeClaim: + claimName: {{ if .Values.persistence.existingClaim }}{{ .Values.persistence.existingClaim }}{{- else }}{{ template "sonarqube.fullname" . }}{{- end }} + {{- else }} + emptyDir: {{- toYaml .Values.emptyDir | nindent 10 }} + {{- end }} + - name : tmp-dir + emptyDir: {{- toYaml .Values.emptyDir | nindent 10 }} + {{- if or .Values.sonarProperties .Values.sonarSecretProperties .Values.sonarSecretKey ( not .Values.elasticsearch.bootstrapChecks) }} + - name : concat-dir + emptyDir: {{- toYaml .Values.emptyDir | nindent 10 -}} + {{- end }} +{{- end }} diff --git a/helm/sonarqube/templates/ingress.yaml b/helm/sonarqube/templates/ingress.yaml new file mode 100644 index 0000000..438c346 --- /dev/null +++ b/helm/sonarqube/templates/ingress.yaml @@ -0,0 +1,43 @@ +{{- if .Values.ingress.enabled -}} +{{- $serviceName := include "sonarqube.fullname" . -}} +{{- $servicePort := .Values.service.externalPort -}} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ template "sonarqube.fullname" . }} + labels: + app: {{ template "sonarqube.name" . }} + chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +{{- if .Values.ingress.labels }} +{{ .Values.ingress.labels | toYaml | trimSuffix "\n"| indent 4 -}} +{{- end}} +{{- if .Values.ingress.annotations}} + annotations: + {{- range $key, $value := .Values.ingress.annotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} +{{- end }} +spec: + {{- if .Values.ingress.ingressClassName }} + ingressClassName: {{ .Values.ingress.ingressClassName }} + {{- end }} + rules: + {{- range .Values.ingress.hosts }} + - host: {{ printf "%s" .name }} + http: + paths: + - backend: + service: + name: {{ default $serviceName .serviceName }} + port: + number: {{ default $servicePort .servicePort }} + path: {{ .path | default (include "sonarqube.webcontext" $) }} + pathType: {{ default "ImplementationSpecific" .pathType }} + {{- end }} + {{- if .Values.ingress.tls }} + tls: +{{ toYaml .Values.ingress.tls | indent 4 }} + {{- end -}} +{{- end }} \ No newline at end of file diff --git a/helm/sonarqube/templates/init-fs.yaml b/helm/sonarqube/templates/init-fs.yaml new file mode 100644 index 0000000..bb5026f --- /dev/null +++ b/helm/sonarqube/templates/init-fs.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "sonarqube.fullname" . }}-init-fs + labels: + app: {{ template "sonarqube.name" . }} + chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +data: + init_fs.sh: |- + {{- if .Values.persistence.enabled }} + chown -R {{ .Values.persistence.uid }}: {{ .Values.sonarqubeFolder }} + {{- end }} diff --git a/helm/sonarqube/templates/init-sysctl.yaml b/helm/sonarqube/templates/init-sysctl.yaml new file mode 100644 index 0000000..b400ab4 --- /dev/null +++ b/helm/sonarqube/templates/init-sysctl.yaml @@ -0,0 +1,37 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "sonarqube.fullname" . }}-init-sysctl + labels: + app: {{ template "sonarqube.name" . }} + chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +data: + init_sysctl.sh: |- + {{- if .Values.initSysctl.vmMaxMapCount }} + if [[ "$(sysctl -n vm.max_map_count)" -lt {{ .Values.initSysctl.vmMaxMapCount }} ]]; then + sysctl -w vm.max_map_count={{ .Values.initSysctl.vmMaxMapCount }} + fi + {{- end }} + {{- if .Values.initSysctl.fsFileMax }} + if [[ "$(sysctl -n fs.file-max)" -lt {{ .Values.initSysctl.fsFileMax }} ]]; then + sysctl -w fs.file-max={{ .Values.initSysctl.fsFileMax }} + fi + {{- end }} + {{- if .Values.initSysctl.nofile }} + if [[ "$(ulimit -n)" != "unlimited" ]]; then + if [[ "$(ulimit -n)" -lt {{ .Values.initSysctl.nofile }} ]]; then + echo "ulimit -n {{ .Values.initSysctl.nofile }}" + ulimit -n {{ .Values.initSysctl.nofile }} + fi + fi + {{- end }} + {{- if .Values.initSysctl.nproc }} + if [[ "$(ulimit -u)" != "unlimited" ]]; then + if [[ "$(ulimit -u)" -lt {{ .Values.initSysctl.nproc }} ]]; then + echo "ulimit -u {{ .Values.initSysctl.nproc }}" + ulimit -u {{ .Values.initSysctl.nproc }} + fi + fi + {{- end }} diff --git a/helm/sonarqube/templates/install-plugins.yaml b/helm/sonarqube/templates/install-plugins.yaml new file mode 100644 index 0000000..073646c --- /dev/null +++ b/helm/sonarqube/templates/install-plugins.yaml @@ -0,0 +1,18 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "sonarqube.fullname" . }}-install-plugins + labels: + app: {{ template "sonarqube.name" . }} + chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +data: + install_plugins.sh: |- + {{- if .Values.plugins.install }} + rm -f {{ .Values.sonarqubeFolder }}/extensions/plugins/* + cd {{ .Values.sonarqubeFolder }}/extensions/plugins + {{- range $index, $val := .Values.plugins.install }} + curl {{ if $.Values.plugins.noCheckCertificate }}--insecure{{ end }} {{ if $.Values.plugins.netrcCreds }}--netrc-file /root/.netrc{{ end }} -fsSLO {{ $val | quote }} + {{- end }} + {{- end }} diff --git a/helm/sonarqube/templates/jdbc-config.yaml b/helm/sonarqube/templates/jdbc-config.yaml new file mode 100644 index 0000000..9c4f350 --- /dev/null +++ b/helm/sonarqube/templates/jdbc-config.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "sonarqube.fullname" . }}-jdbc-config + labels: + app: {{ template "sonarqube.name" . }} + chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +data: + SONAR_JDBC_USERNAME: {{ template "jdbc.username" . }} +{{- if .Values.jdbcOverwrite.enable }} + SONAR_JDBC_URL: {{ .Values.jdbcOverwrite.jdbcUrl | trim | quote }} +{{- else if and .Values.postgresql.service.port .Values.postgresql.postgresqlDatabase }} + SONAR_JDBC_URL: "jdbc:postgresql://{{ template "postgresql.hostname" . }}:{{- .Values.postgresql.service.port -}}/{{- .Values.postgresql.postgresqlDatabase -}}" +{{- end }} diff --git a/helm/sonarqube/templates/networkpolicy.yaml b/helm/sonarqube/templates/networkpolicy.yaml new file mode 100644 index 0000000..c9952ef --- /dev/null +++ b/helm/sonarqube/templates/networkpolicy.yaml @@ -0,0 +1,114 @@ +{{- if .Values.networkPolicy.enabled }} +--- +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ template "sonarqube.fullname" . }}-network-policy + labels: + app: {{ template "sonarqube.name" . }} + chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +spec: + podSelector: + matchLabels: + app: {{ template "sonarqube.name" . }} + policyTypes: + - Ingress + - Egress + ingress: + - from: + - podSelector: + matchLabels: + app: {{ template "sonarqube.name" . }} + release: {{ .Release.Name }} + ports: + - port: {{ .Values.service.internalPort }} +{{ if .Values.prometheusExporter.enabled }} + - from: + - namespaceSelector: + matchLabels: + networking/namespace: {{ .Values.networkPolicy.prometheusNamespace }} + ports: + - port: {{ .Values.prometheusExporter.ceBeanPort }} + protocol: TCP + - port: {{ .Values.prometheusExporter.webBeanPort }} + protocol: TCP +{{ end }} + egress: + - to: + - namespaceSelector: + matchLabels: + networking/namespace: kube-system + podSelector: + matchLabels: + k8s-app: kube-dns + ports: + - port: 53 + protocol: UDP +{{- if .Values.postgresql.enabled }} + - to: + - podSelector: + matchLabels: + app.kubernetes.io/name: postgresql + ports: + - port: 5432 + protocol: TCP +{{- end }} + - to: + - ipBlock: + cidr: 0.0.0.0/0 +{{- end -}} + +{{ if and .Values.postgresql.enabled .Values.networkPolicy.enabled }} +--- +kind: NetworkPolicy +apiVersion: networking.k8s.io/v1 +metadata: + name: {{ template "sonarqube.fullname" . }}-database + labels: + app: {{ template "sonarqube.name" . }} + chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +spec: + podSelector: + matchLabels: + app.kubernetes.io/name: postgresql + policyTypes: + - Ingress + - Egress + ingress: + - from: + - podSelector: + matchLabels: + app: {{ template "sonarqube.name" . }} + ports: + - port: 5432 + egress: + - to: + - namespaceSelector: {} + podSelector: + matchLabels: + k8s-app: kube-dns + ports: + - port: 53 + protocol: UDP +{{- end }} + +{{- if and .Values.networkPolicy.enabled .Values.networkPolicy.additionalNetworkPolicys }} +--- +kind: NetworkPolicy +apiVersion: networking.k8s.io/v1 +metadata: + name: {{ template "sonarqube.fullname" . }}-additional-network-policy + labels: + app: {{ template "sonarqube.name" . }} + chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +spec: +{{- with .Values.networkPolicy.additionalNetworkPolicys -}} +{{ toYaml . | nindent 2 }} +{{- end }} +{{- end -}} diff --git a/helm/sonarqube/templates/prometheus-ce-config.yaml b/helm/sonarqube/templates/prometheus-ce-config.yaml new file mode 100644 index 0000000..4427323 --- /dev/null +++ b/helm/sonarqube/templates/prometheus-ce-config.yaml @@ -0,0 +1,14 @@ +{{- if .Values.prometheusExporter.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "sonarqube.fullname" . }}-prometheus-ce-config + labels: + app: {{ template "sonarqube.name" . }} + chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +data: + prometheus-ce-config.yaml: |- +{{ .Values.prometheusExporter.ceConfig | default .Values.prometheusExporter.config | toYaml | indent 8 }} +{{- end }} \ No newline at end of file diff --git a/helm/sonarqube/templates/prometheus-config.yaml b/helm/sonarqube/templates/prometheus-config.yaml new file mode 100644 index 0000000..84481d5 --- /dev/null +++ b/helm/sonarqube/templates/prometheus-config.yaml @@ -0,0 +1,14 @@ +{{- if .Values.prometheusExporter.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "sonarqube.fullname" . }}-prometheus-config + labels: + app: {{ template "sonarqube.name" . }} + chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +data: + prometheus-config.yaml: |- +{{ toYaml .Values.prometheusExporter.config | indent 8 }} +{{- end }} \ No newline at end of file diff --git a/helm/sonarqube/templates/prometheus-podmonitor.yaml b/helm/sonarqube/templates/prometheus-podmonitor.yaml new file mode 100644 index 0000000..f76c43b --- /dev/null +++ b/helm/sonarqube/templates/prometheus-podmonitor.yaml @@ -0,0 +1,37 @@ +{{- if .Values.prometheusMonitoring.podMonitor.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: PodMonitor +metadata: + name: {{ template "sonarqube.name" . }} + namespace: {{ .Values.prometheusMonitoring.podMonitor.namespace | quote }} + labels: + app: {{ template "sonarqube.name" . }} +spec: + {{- if .Values.prometheusMonitoring.podMonitor.jobLabel }} + jobLabel: {{ .Values.prometheusMonitoring.podMonitor.jobLabel | quote }} + {{- end }} + namespaceSelector: + matchNames: + - {{ .Release.Namespace }} + selector: + matchLabels: + app: {{ template "sonarqube.name" . }} + podMetricsEndpoints: + - port: http + path: /api/monitoring/metrics + scheme: http + {{- if .Values.prometheusMonitoring.podMonitor.interval }} + interval: {{ .Values.prometheusMonitoring.podMonitor.interval }} + {{- end }} + {{- if .Values.prometheusMonitoring.podMonitor.scrapeTimeout }} + scrapeTimeout: {{ .Values.prometheusMonitoring.podMonitor.scrapeTimeout }} + {{- end }} + bearerTokenSecret: + {{- if and .Values.monitoringPasscodeSecretName .Values.monitoringPasscodeSecretKey }} + name: {{ .Values.monitoringPasscodeSecretName }} + key: {{ .Values.monitoringPasscodeSecretKey }} + {{- else }} + name: {{ template "sonarqube.fullname" . }}-monitoring-passcode + key: SONAR_WEB_SYSTEMPASSCODE + {{- end }} +{{- end }} \ No newline at end of file diff --git a/helm/sonarqube/templates/pvc.yaml b/helm/sonarqube/templates/pvc.yaml new file mode 100644 index 0000000..554df93 --- /dev/null +++ b/helm/sonarqube/templates/pvc.yaml @@ -0,0 +1,30 @@ +{{- if and .Values.persistence.enabled (not .Values.persistence.existingClaim) }} +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: + name: {{ template "sonarqube.fullname" . }} + labels: + app: {{ template "sonarqube.name" . }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}" + release: "{{ .Release.Name }}" + heritage: "{{ .Release.Service }}" +{{ if .Values.persistence.annotations}} + annotations: + {{- range $key, $value := .Values.persistence.annotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} +{{- end }} +spec: + accessModes: + - {{ .Values.persistence.accessMode | quote }} + resources: + requests: + storage: {{ .Values.persistence.size | quote }} +{{- if .Values.persistence.storageClass }} +{{- if (eq "-" .Values.persistence.storageClass) }} + storageClassName: "" +{{- else }} + storageClassName: "{{ .Values.persistence.storageClass }}" +{{- end }} +{{- end }} +{{- end }} diff --git a/helm/sonarqube/templates/route.yaml b/helm/sonarqube/templates/route.yaml new file mode 100644 index 0000000..93d5065 --- /dev/null +++ b/helm/sonarqube/templates/route.yaml @@ -0,0 +1,34 @@ +{{- if .Values.route.enabled -}} +{{- $serviceName := include "sonarqube.fullname" . -}} +kind: Route +apiVersion: route.openshift.io/v1 +metadata: + name: {{ template "sonarqube.fullname" . }} + labels: + app: {{ template "sonarqube.name" . }} + chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +{{- if .Values.route.labels }} +{{ .Values.route.labels | toYaml | trimSuffix "\n"| indent 4 -}} +{{- end}} +{{- if .Values.route.annotations}} + annotations: + {{- range $key, $value := .Values.route.annotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} +{{- end }} +spec: +{{- if .Values.route.host }} + host: {{ .Values.route.host }} +{{- end }} + to: + kind: Service + name: {{ default $serviceName .serviceName }} + port: + targetPort: http + {{- if .Values.route.tls }} + tls: +{{ toYaml .Values.route.tls | indent 4 }} + {{- end -}} +{{- end -}} diff --git a/helm/sonarqube/templates/secret.yaml b/helm/sonarqube/templates/secret.yaml new file mode 100644 index 0000000..9ac2a2d --- /dev/null +++ b/helm/sonarqube/templates/secret.yaml @@ -0,0 +1,64 @@ +--- +{{- if not (or .Values.postgresql.enabled .Values.postgresql.existingSecret .Values.jdbcOverwrite.jdbcSecretName)}} +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "sonarqube.fullname" . }} + labels: + app: {{ template "sonarqube.name" . }} + chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +type: Opaque +data: + {{ template "jdbc.secretPasswordKey" . }}: {{ template "jdbc.internalSecretPasswd" . }} +{{- end }} +--- +{{- if .Values.monitoringPasscode}} +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "sonarqube.fullname" . }}-monitoring-passcode + labels: + app: {{ template "sonarqube.name" . }} + chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +type: Opaque +data: + SONAR_WEB_SYSTEMPASSCODE: {{ .Values.monitoringPasscode | b64enc | quote }} +{{- end }} +--- +{{- if and .Values.monitoringPasscode .Values.prometheusMonitoring.podMonitor.enabled}} +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "sonarqube.fullname" . }}-monitoring-passcode + namespace: {{.Values.prometheusMonitoring.podMonitor.namespace}} + labels: + app: {{ template "sonarqube.name" . }} + chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +type: Opaque +data: + SONAR_WEB_SYSTEMPASSCODE: {{ .Values.monitoringPasscode | b64enc | quote }} +{{- end }} +--- +{{- if .Values.account }} +{{- if .Values.account.adminPassword }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "sonarqube.fullname" . }}-admin-password + labels: + app: {{ template "sonarqube.name" . }} + chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +type: Opaque +stringData: + password: {{ .Values.account.adminPassword | urlquery | quote }} + currentPassword: {{ default "admin" .Values.account.currentAdminPassword | urlquery | quote }} +{{- end }} +{{- end }} diff --git a/helm/sonarqube/templates/service.yaml b/helm/sonarqube/templates/service.yaml new file mode 100644 index 0000000..3824edf --- /dev/null +++ b/helm/sonarqube/templates/service.yaml @@ -0,0 +1,42 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ template "sonarqube.fullname" . }} + labels: + app: {{ template "sonarqube.name" . }} + chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + {{- range $key, $value := .Values.service.labels }} + {{ $key }}: {{ $value | quote }} + {{- end }} +{{ if .Values.service.annotations}} + annotations: + {{- range $key, $value := .Values.service.annotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} +{{- end }} +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.externalPort }} + targetPort: http + protocol: TCP + name: http + {{- if .Values.service.nodePort }} + nodePort: {{ .Values.service.nodePort }} + {{- end }} + selector: + app: {{ template "sonarqube.name" . }} + release: {{ .Release.Name }} + {{- if eq .Values.service.type "LoadBalancer"}} + {{- if .Values.service.loadBalancerSourceRanges }} + loadBalancerSourceRanges: + {{- range .Values.service.loadBalancerSourceRanges }} + - {{ . }} + {{- end }} + {{- end -}} + {{- if .Values.service.loadBalancerIP}} + loadBalancerIP: {{.Values.service.loadBalancerIP}} + {{- end }} + {{- end }} diff --git a/helm/sonarqube/templates/serviceaccount.yaml b/helm/sonarqube/templates/serviceaccount.yaml new file mode 100644 index 0000000..2e05ebe --- /dev/null +++ b/helm/sonarqube/templates/serviceaccount.yaml @@ -0,0 +1,16 @@ +{{- if .Values.serviceAccount.create -}} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: +{{- if .Values.serviceAccount.name }} + name: {{ .Values.serviceAccount.name }} +{{- else }} + name: {{ include "sonarqube.fullname" . }} +{{- end }} +{{- if .Values.serviceAccount.annotations }} + annotations: +{{ toYaml .Values.serviceAccount.annotations | indent 4 }} +{{- end }} +automountServiceAccountToken: {{ .Values.serviceAccount.automountToken | default "false" }} +{{- end -}} diff --git a/helm/sonarqube/templates/sonarqube-scc.yaml b/helm/sonarqube/templates/sonarqube-scc.yaml new file mode 100644 index 0000000..966a440 --- /dev/null +++ b/helm/sonarqube/templates/sonarqube-scc.yaml @@ -0,0 +1,63 @@ +{{- if and (.Values.OpenShift.enabled) (.Values.OpenShift.createSCC) }} + +# This SCC allows any user ID but restricts capabilties and host access +apiVersion: security.openshift.io/v1 +kind: SecurityContextConstraints +metadata: + annotations: + kubernetes.io/description: "allows pod to run as root, privileged and run sysctl" + "helm.sh/hook": pre-install + name: {{ .Release.Name }}-privileged-scc +allowHostDirVolumePlugin: false +allowHostIPC: false +allowHostNetwork: false +allowHostPID: false +allowHostPorts: false +allowPrivilegedContainer: true +allowPrivilegeEscalation: true +allowedCapabilities: [] +allowedFlexVolumes: [] +allowedUnsafeSysctls: [] +defaultAddCapabilities: [] +defaultAllowPrivilegeEscalation: true +fsGroup: + type: RunAsAny +readOnlyRootFilesystem: false +requiredDropCapabilities: +- KILL +- MKNOD +- SETUID +- SETGID +runAsUser: + type: RunAsAny +# This can be customized for your host machine +seLinuxContext: + type: MustRunAs +# seLinuxOptions: +# level: +# user: +# role: +# type: +supplementalGroups: + type: RunAsAny +# This can be customized for your host machine +volumes: +- configMap +- downwardAPI +- emptyDir +- persistentVolumeClaim +- projected +- secret +# If you want a priority on your SCC -- set for a value more than 0 +priority: 11 +users: +{{- if .Values.serviceAccount.name }} +- system:serviceaccount:{{ .Release.Namespace }}:{{ .Values.serviceAccount.name }} +{{- else }} +- system:serviceaccount:{{ .Release.Namespace }}:{{ .Release.Name }}-sonarqube +{{- end }} +{{- if .Values.postgresql.securityContext.enabled }} +- system:serviceaccount:{{ .Release.Namespace }}:{{ .Release.Name }}-postgresql +{{- end }} + +{{- end }} diff --git a/helm/sonarqube/templates/sonarqube-sts.yaml b/helm/sonarqube/templates/sonarqube-sts.yaml new file mode 100644 index 0000000..e62d917 --- /dev/null +++ b/helm/sonarqube/templates/sonarqube-sts.yaml @@ -0,0 +1,531 @@ +{{- if eq .Values.deploymentType "StatefulSet"}} +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ template "sonarqube.fullname" . }} + labels: + app: {{ template "sonarqube.name" . }} + chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + app.kubernetes.io/name: {{ template "sonarqube.name" . }}-{{ template "sonarqube.fullname" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/part-of: sonarqube + app.kubernetes.io/component: {{ template "sonarqube.fullname" . }} + app.kubernetes.io/version: {{ tpl .Values.image.tag . | quote }} +spec: + replicas: {{ .Values.replicaCount }} + serviceName: {{ template "sonarqube.fullname" . }} + selector: + matchLabels: + app: {{ template "sonarqube.name" . }} + release: {{ .Release.Name }} + template: + metadata: + labels: + app: {{ template "sonarqube.name" . }} + release: {{ .Release.Name }} +{{- with .Values.podLabels }} +{{ toYaml . | indent 8 }} +{{- end }} + annotations: + checksum/init-sysctl: {{ include (print $.Template.BasePath "/init-sysctl.yaml") . | sha256sum }} + checksum/init-fs: {{ include (print $.Template.BasePath "/init-fs.yaml") . | sha256sum }} + checksum/plugins: {{ include (print $.Template.BasePath "/install-plugins.yaml") . | sha256sum }} + checksum/config: {{ include (print $.Template.BasePath "/config.yaml") . | sha256sum }} + checksum/secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }} +{{- if .Values.prometheusExporter.enabled }} + checksum/prometheus-config: {{ include (print $.Template.BasePath "/prometheus-config.yaml") . | sha256sum }} + checksum/prometheus-ce-config: {{ include (print $.Template.BasePath "/prometheus-ce-config.yaml") . | sha256sum }} +{{- end }} +{{- if .Values.annotations}} + {{- range $key, $value := .Values.annotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} +{{- end }} + spec: + {{- if .Values.schedulerName }} + schedulerName: {{ .Values.schedulerName }} + {{- end }} + securityContext: +{{ toYaml .Values.securityContext | indent 8 }} + {{- if or .Values.image.pullSecrets .Values.image.pullSecret }} + imagePullSecrets: + {{- if .Values.image.pullSecret }} + - name: {{ .Values.image.pullSecret }} + {{- end }} + {{- if .Values.image.pullSecrets}} +{{ toYaml .Values.image.pullSecrets | indent 8 }} + {{- end }} + {{- end }} + initContainers: + {{- if .Values.extraInitContainers }} +{{ toYaml .Values.extraInitContainers | indent 8 }} + {{- end }} + {{- if .Values.postgresql.enabled }} + - name: "wait-for-db" + image: {{ default "busybox:1.32" .Values.initContainers.image }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + {{- if $securityContext := .Values.initContainers.securityContext }} + securityContext: +{{ toYaml $securityContext | indent 12 }} + {{- end }} + resources: +{{ toYaml .Values.initContainers.resources | indent 12 }} + command: ["/bin/sh", "-c", "for i in $(seq 1 200); do nc -z -w3 {{ .Release.Name}}-postgresql 5432 && exit 0 || sleep 2; done; exit 1"] + {{- end }} + {{- if .Values.caCerts.enabled }} + - name: ca-certs + image: {{ default "adoptopenjdk/openjdk11:alpine" .Values.caCerts.image }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + command: ["sh"] + args: ["-c", "cp -f \"${JAVA_HOME}/lib/security/cacerts\" /tmp/certs/cacerts; if [ \"$(ls /tmp/secrets/ca-certs)\" ]; then for f in /tmp/secrets/ca-certs/*; do keytool -importcert -file \"${f}\" -alias \"$(basename \"${f}\")\" -keystore /tmp/certs/cacerts -storepass changeit -trustcacerts -noprompt; done; fi;"] + {{- if $securityContext := .Values.initContainers.securityContext }} + securityContext: +{{ toYaml $securityContext | indent 12 }} + {{- end }} + resources: +{{ toYaml .Values.initContainers.resources | indent 12 }} + volumeMounts: + - mountPath: /tmp/certs + name: sonarqube + subPath: certs + - mountPath: /tmp/secrets/ca-certs + name: ca-certs + {{- with .Values.env }} + env: + {{- . | toYaml | trim | nindent 12 }} + {{- end }} + {{- end }} + {{- if or .Values.initSysctl.enabled .Values.elasticsearch.configureNode }} + - name: init-sysctl + image: {{ default "busybox:1.32" .Values.initSysctl.image }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + {{- if $securityContext := (default .Values.initContainers.securityContext .Values.initSysctl.securityContext) }} + securityContext: +{{ toYaml $securityContext | indent 12 }} + {{- end }} + resources: +{{ toYaml (default .Values.initContainers.resources .Values.initSysctl.resources) | indent 12 }} + command: ["sh", + "-e", + "/tmp/scripts/init_sysctl.sh"] + volumeMounts: + - name: init-sysctl + mountPath: /tmp/scripts/ + {{- with .Values.env }} + env: + {{- . | toYaml | trim | nindent 12 }} + {{- end }} + {{- end }} + + {{- if or .Values.sonarProperties .Values.sonarSecretProperties .Values.sonarSecretKey (not .Values.elasticsearch.bootstrapChecks) }} + - name: concat-properties + image: {{ default "busybox:1.32" .Values.initContainers.image }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + command: + - sh + - -c + - | + #!/bin/sh + if [ -f /tmp/props/sonar.properties ]; then + cat /tmp/props/sonar.properties > /tmp/result/sonar.properties + fi + if [ -f /tmp/props/secret.properties ]; then + cat /tmp/props/secret.properties > /tmp/result/sonar.properties + fi + if [ -f /tmp/props/sonar.properties -a -f /tmp/props/secret.properties ]; then + awk 1 /tmp/props/sonar.properties /tmp/props/secret.properties > /tmp/result/sonar.properties + fi + volumeMounts: + {{- if or .Values.sonarProperties .Values.sonarSecretKey (not .Values.elasticsearch.bootstrapChecks) }} + - mountPath: /tmp/props/sonar.properties + name: config + subPath: sonar.properties + {{- end }} + {{- if .Values.sonarSecretProperties }} + - mountPath: /tmp/props/secret.properties + name: secret-config + subPath: secret.properties + {{- end }} + - mountPath: /tmp/result + name: concat-dir + {{- if $securityContext := .Values.initContainers.securityContext }} + securityContext: +{{ toYaml $securityContext | indent 12 }} + {{- end }} + resources: +{{ toYaml .Values.initContainers.resources | indent 12 }} + {{- with .Values.env }} + env: + {{- . | toYaml | trim | nindent 12 }} + {{- end }} + {{- end }} + + {{- if .Values.prometheusExporter.enabled }} + - name: inject-prometheus-exporter + image: {{ default "curlimages/curl:8.2.0" .Values.prometheusExporter.image }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + {{- if $securityContext := (default .Values.initContainers.securityContext .Values.prometheusExporter.securityContext) }} + securityContext: +{{ toYaml $securityContext | indent 12 }} + {{- end }} + resources: +{{ toYaml (default .Values.initContainers.resources .Values.prometheusExporter.resources) | indent 12 }} + command: ["/bin/sh","-c"] + args: ["curl -s '{{ template "prometheusExporter.downloadURL" . }}' {{ if $.Values.prometheusExporter.noCheckCertificate }}--insecure{{ end }} --output /data/jmx_prometheus_javaagent.jar -v"] + volumeMounts: + - mountPath: /data + name: sonarqube + subPath: data + env: + - name: http_proxy + value: {{ default "" .Values.prometheusExporter.httpProxy }} + - name: https_proxy + value: {{ default "" .Values.prometheusExporter.httpsProxy }} + - name: no_proxy + value: {{ default "" .Values.prometheusExporter.noProxy }} + {{- with .Values.env }} + {{- . | toYaml | trim | nindent 12 }} + {{- end }} + {{- end }} + {{- if and .Values.persistence.enabled .Values.initFs.enabled }} + - name: init-fs + image: {{ default "busybox:1.32" .Values.initFs.image }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + {{- if $securityContext := (default .Values.initContainers.securityContext .Values.initFs.securityContext) }} + securityContext: +{{ toYaml $securityContext | indent 12 }} + {{- end }} + resources: +{{ toYaml (default .Values.initContainers.resources .Values.initFs.resources) | indent 12 }} + command: ["sh", + "-e", + "/tmp/scripts/init_fs.sh"] + volumeMounts: + - name: init-fs + mountPath: /tmp/scripts/ +{{- if .Values.persistence.mounts }} +{{ toYaml .Values.persistence.mounts | indent 12 }} +{{- end }} + {{- if .Values.caCerts.enabled }} + - mountPath: {{ .Values.sonarqubeFolder }}/certs + name: sonarqube + subPath: certs + {{- end }} + - mountPath: {{ .Values.sonarqubeFolder }}/data + name: sonarqube + subPath: data + {{- if .Values.persistence.enabled }} + - mountPath: {{ .Values.sonarqubeFolder }}/extensions + name: sonarqube + subPath: extensions + {{- else if .Values.plugins.install }} + - mountPath: {{ .Values.sonarqubeFolder }}/extensions/plugins + name: sonarqube + subPath: extensions/plugins + {{- end }} + - mountPath: {{ .Values.sonarqubeFolder }}/temp + name: sonarqube + subPath: temp + - mountPath: {{ .Values.sonarqubeFolder }}/logs + name: sonarqube + subPath: logs + - mountPath: /tmp + name: tmp-dir + {{- end }} + {{- if .Values.plugins.install }} + - name: install-plugins + image: {{ default "curlimages/curl:8.2.0" .Values.plugins.image }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + command: ["sh", + "-e", + "/tmp/scripts/install_plugins.sh"] + volumeMounts: + - mountPath: {{ .Values.sonarqubeFolder }}/extensions/plugins + name: sonarqube + subPath: extensions/plugins + - name: install-plugins + mountPath: /tmp/scripts/ + {{- if .Values.plugins.netrcCreds }} + - name: plugins-netrc-file + mountPath: /root + {{- end }} + {{- if $securityContext := (default .Values.initContainers.securityContext .Values.plugins.securityContext) }} + securityContext: +{{ toYaml $securityContext | indent 12 }} + {{- end }} + resources: +{{ toYaml (default .Values.initContainers.resources .Values.plugins.resource) | indent 12 }} + env: + - name: http_proxy + value: {{ default "" .Values.plugins.httpProxy }} + - name: https_proxy + value: {{ default "" .Values.plugins.httpsProxy }} + - name: no_proxy + value: {{ default "" .Values.plugins.noProxy }} + {{- with .Values.env }} + {{- . | toYaml | trim | nindent 12 }} + {{- end }} + {{- end }} + containers: + {{- if .Values.extraContainers }} + {{- toYaml .Values.extraContainers | nindent 8 }} + {{- end }} + - name: {{ .Chart.Name }} + image: "{{ .Values.image.repository }}:{{ tpl .Values.image.tag . }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + ports: + - name: http + containerPort: {{ .Values.service.internalPort }} + protocol: TCP + {{- if .Values.prometheusExporter.enabled }} + - name: monitoring-web + containerPort: {{ .Values.prometheusExporter.webBeanPort }} + protocol: TCP + - name: monitoring-ce + containerPort: {{ .Values.prometheusExporter.ceBeanPort }} + protocol: TCP + {{- end }} + resources: +{{ toYaml (default .Values.resources .Values.resource) | indent 12 }} + env: + {{- with .Values.env }} + {{- . | toYaml | trim | nindent 12 }} + {{- end }} + - name: SONAR_HELM_CHART_VERSION + value: {{ .Chart.Version | replace "+" "_" }} + - name: SONAR_WEB_JAVAOPTS + value: {{ template "sonarqube.jvmOpts" . }} + - name: SONAR_WEB_CONTEXT + value: {{ include "sonarqube.webcontext" . }} + - name: SONAR_CE_JAVAOPTS + value: {{ template "sonarqube.jvmCEOpts" . }} + - name: SONAR_JDBC_PASSWORD + valueFrom: + secretKeyRef: + name: {{ template "jdbc.secret" . }} + key: {{ template "jdbc.secretPasswordKey" . }} + - name: SONAR_WEB_SYSTEMPASSCODE + valueFrom: + secretKeyRef: + {{- if and .Values.monitoringPasscodeSecretName .Values.monitoringPasscodeSecretKey }} + name: {{ .Values.monitoringPasscodeSecretName }} + key: {{ .Values.monitoringPasscodeSecretKey }} + {{- else }} + name: {{ template "sonarqube.fullname" . }}-monitoring-passcode + key: SONAR_WEB_SYSTEMPASSCODE + {{- end }} + envFrom: + - configMapRef: + name: {{ template "sonarqube.fullname" . }}-jdbc-config +{{- range .Values.extraConfig.secrets }} + - secretRef: + name: {{ . }} +{{- end }} +{{- range .Values.extraConfig.configmaps }} + - configMapRef: + name: {{ . }} +{{- end }} + livenessProbe: + exec: + command: + - sh + - -c + - | + host="$(hostname -i || echo '127.0.0.1')" + wget --no-proxy --quiet -O /dev/null --timeout={{ .Values.livenessProbe.timeoutSeconds }} --header="X-Sonar-Passcode: $SONAR_WEB_SYSTEMPASSCODE" "http://${host}:{{ .Values.service.internalPort }}{{ .Values.livenessProbe.sonarWebContext | default (include "sonarqube.webcontext" .) }}api/system/liveness" + initialDelaySeconds: {{ .Values.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.livenessProbe.periodSeconds }} + failureThreshold: {{ .Values.livenessProbe.failureThreshold }} + timeoutSeconds: {{ .Values.livenessProbe.timeoutSeconds }} + readinessProbe: + exec: + command: + - sh + - -c + - | + #!/bin/bash + # A Sonarqube container is considered ready if the status is UP, DB_MIGRATION_NEEDED or DB_MIGRATION_RUNNING + # status about migration are added to prevent the node to be kill while sonarqube is upgrading the database. + host="$(hostname -i || echo '127.0.0.1')" + if wget --no-proxy -qO- http://${host}:{{ .Values.service.internalPort }}{{ .Values.readinessProbe.sonarWebContext | default (include "sonarqube.webcontext" .) }}api/system/status | grep -q -e '"status":"UP"' -e '"status":"DB_MIGRATION_NEEDED"' -e '"status":"DB_MIGRATION_RUNNING"'; then + exit 0 + fi + exit 1 + initialDelaySeconds: {{ .Values.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.readinessProbe.periodSeconds }} + failureThreshold: {{ .Values.readinessProbe.failureThreshold }} + timeoutSeconds: {{ .Values.readinessProbe.timeoutSeconds }} + startupProbe: + httpGet: + scheme: HTTP + path: {{ .Values.startupProbe.sonarWebContext | default (include "sonarqube.webcontext" .) }}api/system/status + port: http + initialDelaySeconds: {{ .Values.startupProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.startupProbe.periodSeconds }} + failureThreshold: {{ .Values.startupProbe.failureThreshold }} + timeoutSeconds: {{ .Values.startupProbe.timeoutSeconds }} + {{- if .Values.containerSecurityContext }} + securityContext: +{{- toYaml .Values.containerSecurityContext | nindent 12 }} + {{- end }} + volumeMounts: +{{- if .Values.persistence.mounts }} +{{ toYaml .Values.persistence.mounts | indent 12 }} +{{- end }} +{{- if .Values.extraVolumeMounts }} +{{- .Values.extraVolumeMounts | toYaml | nindent 12 }} +{{- end }} + {{- if or .Values.sonarProperties .Values.sonarSecretProperties .Values.sonarSecretKey (not .Values.elasticsearch.bootstrapChecks) }} + - mountPath: {{ .Values.sonarqubeFolder }}/conf/ + name: concat-dir + {{- end }} + {{- if .Values.sonarSecretKey }} + - mountPath: {{ .Values.sonarqubeFolder }}/secret/ + name: secret + {{- end }} + {{- if .Values.caCerts.enabled }} + - mountPath: {{ .Values.sonarqubeFolder }}/certs + name: sonarqube + subPath: certs + {{- end }} + - mountPath: {{ .Values.sonarqubeFolder }}/data + name: sonarqube + subPath: data + {{- if .Values.persistence.enabled }} + - mountPath: {{ .Values.sonarqubeFolder }}/extensions + name: sonarqube + subPath: extensions + {{- else if .Values.plugins.install }} + - mountPath: {{ .Values.sonarqubeFolder }}/extensions/plugins + name: sonarqube + subPath: extensions/plugins + {{- end }} + - mountPath: {{ .Values.sonarqubeFolder }}/temp + name: sonarqube + subPath: temp + - mountPath: {{ .Values.sonarqubeFolder }}/logs + name: sonarqube + subPath: logs + - mountPath: /tmp + name: tmp-dir + {{- if .Values.prometheusExporter.enabled }} + - mountPath: {{ .Values.sonarqubeFolder }}/conf/prometheus-config.yaml + subPath: prometheus-config.yaml + name: prometheus-config + - mountPath: {{ .Values.sonarqubeFolder }}/conf/prometheus-ce-config.yaml + subPath: prometheus-ce-config.yaml + name: prometheus-ce-config + {{- end }} + {{- if .Values.priorityClassName }} + priorityClassName: {{ .Values.priorityClassName }} + {{- end }} + {{- if .Values.nodeSelector }} + nodeSelector: +{{ toYaml .Values.nodeSelector | indent 8 }} + {{- end }} + {{- if .Values.hostAliases }} + hostAliases: +{{ toYaml .Values.hostAliases | indent 8 }} + {{- end }} + {{- if .Values.tolerations }} + tolerations: +{{ toYaml .Values.tolerations | indent 8 }} + {{- end }} + {{- if .Values.affinity }} + affinity: +{{ toYaml .Values.affinity | indent 8 }} + {{- end }} + serviceAccountName: {{ template "sonarqube.serviceAccountName" . }} + volumes: +{{- if .Values.persistence.volumes }} +{{ tpl (toYaml .Values.persistence.volumes | indent 6) . }} +{{- end }} +{{- if .Values.extraVolumes }} +{{- .Values.extraVolumes | toYaml | nindent 6 }} +{{- end }} + {{- if or .Values.sonarProperties .Values.sonarSecretKey ( not .Values.elasticsearch.bootstrapChecks) }} + - name: config + configMap: + name: {{ template "sonarqube.fullname" . }}-config + items: + - key: sonar.properties + path: sonar.properties + {{- end }} + {{- if .Values.sonarSecretProperties }} + - name: secret-config + secret: + secretName: {{ .Values.sonarSecretProperties }} + items: + - key: secret.properties + path: secret.properties + {{- end }} + {{- if .Values.sonarSecretKey }} + - name: secret + secret: + secretName: {{ .Values.sonarSecretKey }} + items: + - key: sonar-secret.txt + path: sonar-secret.txt + {{- end }} + {{- if .Values.caCerts.enabled }} + - name: ca-certs + secret: + secretName: {{ .Values.caCerts.secret }} + {{- end }} + {{- if .Values.plugins.netrcCreds }} + - name: plugins-netrc-file + secret: + secretName: {{ .Values.plugins.netrcCreds }} + items: + - key: netrc + path: .netrc + {{- end }} + - name: init-sysctl + configMap: + name: {{ template "sonarqube.fullname" . }}-init-sysctl + items: + - key: init_sysctl.sh + path: init_sysctl.sh + - name: init-fs + configMap: + name: {{ template "sonarqube.fullname" . }}-init-fs + items: + - key: init_fs.sh + path: init_fs.sh + - name: install-plugins + configMap: + name: {{ template "sonarqube.fullname" . }}-install-plugins + items: + - key: install_plugins.sh + path: install_plugins.sh + {{- if .Values.prometheusExporter.enabled }} + - name: prometheus-config + configMap: + name: {{ template "sonarqube.fullname" . }}-prometheus-config + items: + - key: prometheus-config.yaml + path: prometheus-config.yaml + - name: prometheus-ce-config + configMap: + name: {{ template "sonarqube.fullname" . }}-prometheus-ce-config + items: + - key: prometheus-ce-config.yaml + path: prometheus-ce-config.yaml + {{- end }} + - name: sonarqube + {{- if .Values.persistence.enabled }} + persistentVolumeClaim: + claimName: {{ if .Values.persistence.existingClaim }}{{ .Values.persistence.existingClaim }}{{- else }}{{ template "sonarqube.fullname" . }}{{- end }} + {{- else }} + emptyDir: {{- toYaml .Values.emptyDir | nindent 10 }} + {{- end }} + - name : tmp-dir + emptyDir: {{- toYaml .Values.emptyDir | nindent 10 }} + {{- if or .Values.sonarProperties .Values.sonarSecretProperties .Values.sonarSecretKey ( not .Values.elasticsearch.bootstrapChecks) }} + - name : concat-dir + emptyDir: {{- toYaml .Values.emptyDir | nindent 10 -}} + {{- end }} +{{- end }} diff --git a/helm/sonarqube/templates/tests/sonarqube-test.yaml b/helm/sonarqube/templates/tests/sonarqube-test.yaml new file mode 100644 index 0000000..654f4cf --- /dev/null +++ b/helm/sonarqube/templates/tests/sonarqube-test.yaml @@ -0,0 +1,40 @@ +{{- if .Values.tests.enabled -}} +apiVersion: v1 +kind: Pod +metadata: + name: "{{ .Release.Name }}-ui-test" + annotations: + "helm.sh/hook": test-success + labels: + app: {{ template "sonarqube.name" . }} + chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +spec: + {{- if or .Values.image.pullSecrets .Values.image.pullSecret }} + imagePullSecrets: + {{- if .Values.image.pullSecret }} + - name: {{ .Values.image.pullSecret }} + {{- end}} + {{- if .Values.image.pullSecrets}} +{{ toYaml .Values.image.pullSecrets | indent 4 }} + {{- end}} + {{- end }} + containers: + - name: {{ .Release.Name }}-ui-test + image: {{ .Values.tests.image | default (printf "%s:%s" .Values.image.repository (tpl .Values.image.tag .)) | quote }} + imagePullPolicy: {{ .Values.image.pullPolicy }} + command: ['wget'] + args: [ + '--retry-connrefused', + '--waitretry=1', + '--timeout=5', + '-t', + '12', + '-qO-', + '{{ template "sonarqube.fullname" . }}:{{ .Values.service.internalPort }}/api/system/status' + ] + resources: +{{ toYaml .Values.tests.resources | indent 8 }} + restartPolicy: Never +{{- end -}} diff --git a/helm/sonarqube/values.schema.json b/helm/sonarqube/values.schema.json new file mode 100644 index 0000000..cedf4eb --- /dev/null +++ b/helm/sonarqube/values.schema.json @@ -0,0 +1,62 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "required": [ + "replicaCount" + ], + "properties": { + "replicaCount": { + "type": "integer", + "enum": [0, 1] + }, + "jvmOpts": { + "type": "string", + "deprecated": true, + "$comment": "(DEPRECATED) Please use SONAR_WEB_JAVAOPTS or sonar.web.javaOpts" + }, + "jvmCeOpts": { + "type": "string", + "deprecated": true, + "$comment": "(DEPRECATED) Please use SONAR_CE_JAVAOPTS or sonar.ce.javaOpts" + }, + "livenessProbe": { + "type": "object", + "properties": { + "sonarWebContext": { + "type": "string", + "deprecated": true, + "$comment": "(DEPRECATED) please use sonarWebContext at the value top level" + } + } + }, + "startupProbe": { + "type": "object", + "properties": { + "sonarWebContext": { + "type": "string", + "deprecated": true, + "$comment": "(DEPRECATED) please use sonarWebContext at the value top level" + } + } + }, + "readinessProbe": { + "type": "object", + "properties": { + "sonarWebContext": { + "type": "string", + "deprecated": true, + "$comment": "(DEPRECATED) please use sonarWebContext at the value top level" + } + } + }, + "account": { + "type": "object", + "properties": { + "sonarWebContext": { + "type": "string", + "deprecated": true, + "$comment": "(DEPRECATED) please use sonarWebContext at the value top level" + } + } + } + } + } \ No newline at end of file diff --git a/helm/sonarqube/values.yaml b/helm/sonarqube/values.yaml new file mode 100644 index 0000000..3037fff --- /dev/null +++ b/helm/sonarqube/values.yaml @@ -0,0 +1,542 @@ +# Default values for sonarqube. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +# If the deployment Type is set to Deployment sonarqube is deployed as a replica set. +deploymentType: "StatefulSet" + +# There should not be more than 1 sonarqube instance connected to the same database. Please set this value to 1 or 0 (in case you need to scale down programmatically). +replicaCount: 1 + +# This will use the default deployment strategy unless it is overriden +deploymentStrategy: {} +# Uncomment this to scheduler pods on priority +# priorityClassName: "high-priority" + +## Use an alternate scheduler, e.g. "stork". +## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ +## +# schedulerName: + +## Is this deployment for OpenShift? If so, we help with SCCs +OpenShift: + enabled: false + createSCC: true + +edition: "community" + +image: + repository: sonarqube + tag: 10.2.1-{{ .Values.edition }} + pullPolicy: IfNotPresent + # If using a private repository, the imagePullSecrets to use + # pullSecrets: + # - name: my-repo-secret + +# Set security context for sonarqube pod +securityContext: + fsGroup: 1000 + +# Set security context for sonarqube container +containerSecurityContext: + # Sonarqube dockerfile creates sonarqube user as UID and GID 1000 + runAsUser: 1000 + +# Settings to configure elasticsearch host requirements +elasticsearch: + # DEPRECATED: Use initSysctl.enabled instead + configureNode: true + bootstrapChecks: true + +service: + type: ClusterIP + externalPort: 9000 + internalPort: 9000 + labels: + annotations: {} + # May be used in example for internal load balancing in GCP: + # cloud.google.com/load-balancer-type: Internal + # loadBalancerSourceRanges: + # - 0.0.0.0/0 + # loadBalancerIP: 1.2.3.4 + +# Optionally create Network Policies +networkPolicy: + enabled: false + + # If you plan on using the jmx exporter, you need to define where the traffic is coming from + prometheusNamespace: "monitoring" + + # If you are using a external database and enable network Policies to be created + # you will need to explicitly allow egress traffic to your database + # expects https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.21/#networkpolicyspec-v1-networking-k8s-io + # additionalNetworkPolicys: + +# will be used as default for ingress path and probes path, will be injected in .Values.env as SONAR_WEB_CONTEXT +# if .Values.env.SONAR_WEB_CONTEXT is set, this value will be ignored +sonarWebContext: "" + +# also install the nginx ingress helm chart +nginx: + enabled: false + +ingress: + enabled: false + # Used to create an Ingress record. + hosts: + - name: sonarqube.your-org.com + # Different clouds or configurations might need /* as the default path + # path: / + # For additional control over serviceName and servicePort + # serviceName: someService + # servicePort: somePort + # the pathType can be one of the following values: Exact|Prefix|ImplementationSpecific(default) + # pathType: ImplementationSpecific + annotations: + # kubernetes.io/tls-acme: "true" + # This property allows for reports up to a certain size to be uploaded to SonarQube + nginx.ingress.kubernetes.io/proxy-body-size: "64m" + + # Set the ingressClassName on the ingress record + # ingressClassName: nginx + +# Additional labels for Ingress manifest file + # labels: + # traffic-type: external + # traffic-type: internal + tls: [] + # Secrets must be manually created in the namespace. To generate a self-signed certificate (and private key) and then create the secret in the cluster please refer to official documentation available at https://kubernetes.github.io/ingress-nginx/user-guide/tls/#tls-secrets + # - secretName: chart-example-tls + # hosts: + # - chart-example.local + +route: + enabled: false + host: "" + # Add tls section to secure traffic. TODO: extend this section with other secure route settings + # Comment this out if you want plain http route created. + tls: + termination: edge + + annotations: {} + # See Openshift/OKD route annotation + # https://docs.openshift.com/container-platform/4.10/networking/routes/route-configuration.html#nw-route-specific-annotations_route-configuration + # haproxy.router.openshift.io/timeout: 1m + + # Additional labels for Route manifest file + # labels: + # external: 'true' + +# Affinity for pod assignment +# Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity +affinity: {} + +# Tolerations for pod assignment +# Ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ +# taint a node with the following command to mark it as not schedulable for new pods +# kubectl taint nodes sonarqube=true:NoSchedule +# The following statement will tolerate this taint and as such reverse a node for sonarqube +tolerations: [] +# - key: "sonarqube" +# operator: "Equal" +# value: "true" +# effect: "NoSchedule" + +# Node labels for pod assignment +# Ref: https://kubernetes.io/docs/user-guide/node-selection/ +# add a label to a node with the following command +# kubectl label node sonarqube=true +nodeSelector: {} +# sonarqube: "true" + +# hostAliases allows the modification of the hosts file inside a container +hostAliases: [] +# - ip: "192.168.1.10" +# hostnames: +# - "example.com" +# - "www.example.com" + +readinessProbe: + initialDelaySeconds: 60 + periodSeconds: 30 + failureThreshold: 6 + # Note that timeoutSeconds was not respected before Kubernetes 1.20 for exec probes + timeoutSeconds: 1 + # If an ingress *path* other than the root (/) is defined, it should be reflected here + # A trailing "/" must be included + # deprecated please use sonarWebContext at the value top level + # sonarWebContext: / + +livenessProbe: + initialDelaySeconds: 60 + periodSeconds: 30 + failureThreshold: 6 + # Note that timeoutSeconds was not respected before Kubernetes 1.20 for exec probes + timeoutSeconds: 1 + # If an ingress *path* other than the root (/) is defined, it should be reflected here + # A trailing "/" must be included + # deprecated please use sonarWebContext at the value top level + # sonarWebContext: / + +startupProbe: + initialDelaySeconds: 30 + periodSeconds: 10 + failureThreshold: 24 + # Note that timeoutSeconds was not respected before Kubernetes 1.20 for exec probes + timeoutSeconds: 1 + # If an ingress *path* other than the root (/) is defined, it should be reflected here + # A trailing "/" must be included + # deprecated please use sonarWebContext at the value top level + # sonarWebContext: / + +initContainers: + # image: busybox:1.32 + # We allow the init containers to have a separate security context declaration because + # the initContainer may not require the same as SonarQube. + # securityContext: {} + # We allow the init containers to have a separate resources declaration because + # the initContainer does not take as much resources. + resources: {} + +# Extra init containers to e.g. download required artifacts +extraInitContainers: {} + +## Array of extra containers to run alongside the sonarqube container +## +## Example: +## - name: myapp-container +## image: busybox +## command: ['sh', '-c', 'echo Hello && sleep 3600'] +## +extraContainers: [] + +## Provide a secret containing one or more certificate files in the keys that will be added to cacerts +## The cacerts file will be set via SONARQUBE_WEB_JVM_OPTS and SONAR_CE_JAVAOPTS +## +caCerts: + enabled: false + image: adoptopenjdk/openjdk11:alpine + secret: your-secret + +initSysctl: + enabled: true + vmMaxMapCount: 524288 + fsFileMax: 131072 + nofile: 131072 + nproc: 8192 + # image: busybox:1.32 + securityContext: + privileged: true + # resources: {} + +initFs: + enabled: true + # image: busybox:1.32 + securityContext: + privileged: true + +prometheusExporter: + enabled: false + # jmx_prometheus_javaagent version to download from Maven Central + version: "0.17.2" + # Alternative full download URL for the jmx_prometheus_javaagent.jar (overrides prometheusExporter.version) + # downloadURL: "" + # if you need to ignore TLS certificates for whatever reason enable the following flag + noCheckCertificate: false + + # Ports for the jmx prometheus agent to export metrics at + webBeanPort: 8000 + ceBeanPort: 8001 + + config: + rules: + - pattern: ".*" + # Overrides config for the CE process Prometheus exporter (by default, the same rules are used for both the Web and CE processes). + # ceConfig: + # rules: + # - pattern: ".*" + # image: curlimages/curl:8.2.0 + # For use behind a corporate proxy when downloading prometheus + # httpProxy: "" + # httpsProxy: "" + # noProxy: "" + # Setting the security context to the default sonarqube user 1000/1000 + securityContext: + runAsUser: 1000 + runAsGroup: 1000 + +prometheusMonitoring: + # Generate a Prometheus Pod Monitor (https://github.com/coreos/prometheus-operator) + # + podMonitor: + # Create PodMonitor Resource for Prometheus scraping + enabled: false + # Specify a custom namespace where the PodMonitor will be created + namespace: "default" + # Specify the interval how often metrics should be scraped + interval: 30s + # Specify the timeout after a scrape is ended + # scrapeTimeout: "" + # Name of the label on target services that prometheus uses as job name + # jobLabel: "" + +# List of plugins to install. +# For example: +# plugins: +# install: +# - "https://github.com/AmadeusITGroup/sonar-stash/releases/download/1.3.0/sonar-stash-plugin-1.3.0.jar" +# - "https://github.com/SonarSource/sonar-ldap/releases/download/2.2-RC3/sonar-ldap-plugin-2.2.0.601.jar" +# +plugins: + install: [] + + # For use behind a corporate proxy when downloading plugins + # httpProxy: "" + # httpsProxy: "" + # noProxy: "" + + # image: curlimages/curl:8.2.0 + # resources: {} + + # .netrc secret file with a key "netrc" to use basic auth while downloading plugins + # netrcCreds: "" + + # Set to true to not validate the server's certificate to download plugin + noCheckCertificate: false + securityContext: + runAsUser: 1000 + runAsGroup: 1000 + +## (DEPRECATED) Please use SONAR_WEB_JAVAOPTS or sonar.web.javaOpts +## +# jvmOpts: "-Djava.net.preferIPv4Stack=true" +jvmOpts: "" + +## (DEPRECATED) Please use SONAR_CE_JAVAOPTS or sonar.ce.javaOpts +jvmCeOpts: "" + +## a monitoring passcode needs to be defined in order to get reasonable probe results +# not setting the monitoring passcode will result in a deployment that will never be ready +monitoringPasscode: "define_it" +# Alternatively, you can define the passcode loading it from an existing secret specifying the right key +# monitoringPasscodeSecretName: "pass-secret-name" +# monitoringPasscodeSecretKey: "pass-key" + +## Environment variables to attach to the pods +## +# env: +# # If you use a different ingress path from /, you have to add it here as the value of SONAR_WEB_CONTEXT +# - name: SONAR_WEB_CONTEXT +# value: /sonarqube +# - name: VARIABLE +# value: my-value + +# Set annotations for pods +annotations: {} + +## We usually don't make specific ressource recommandations, as they are heavily dependend on +## The usage of SonarQube and the surrounding infrastructure. +## Adjust these values to your needs, but make sure that the memory limit is never under 4 GB +resources: + limits: + cpu: 800m + memory: 4Gi + requests: + cpu: 400m + memory: 2Gi + +persistence: + enabled: false + ## Set annotations on pvc + annotations: {} + + ## Specify an existing volume claim instead of creating a new one. + ## When using this option all following options like storageClass, accessMode and size are ignored. + # existingClaim: + + ## If defined, storageClassName: + ## If set to "-", storageClassName: "", which disables dynamic provisioning + ## If undefined (the default) or set to null, no storageClassName spec is + ## set, choosing the default provisioner. (gp2 on AWS, standard on + ## GKE, AWS & OpenStack) + ## + storageClass: + accessMode: ReadWriteOnce + size: 5Gi + uid: 1000 + + ## Specify extra volumes. Refer to ".spec.volumes" specification : https://kubernetes.io/fr/docs/concepts/storage/volumes/ + volumes: [] + ## Specify extra mounts. Refer to ".spec.containers.volumeMounts" specification : https://kubernetes.io/fr/docs/concepts/storage/volumes/ + mounts: [] + +# In case you want to specify different resources for emptyDir than {} +emptyDir: {} + # Example of resouces that might be used: + # medium: Memory + # sizeLimit: 16Mi + +# A custom sonar.properties file can be provided via dictionary. +# For example: +# sonarProperties: +# sonar.forceAuthentication: true +# sonar.security.realm: LDAP +# ldap.url: ldaps://organization.com + +# Additional sonar properties to load from a secret with a key "secret.properties" (must be a string) +# sonarSecretProperties: + +# Kubernetes secret that contains the encryption key for the sonarqube instance. +# The secret must contain the key 'sonar-secret.txt'. +# The 'sonar.secretKeyPath' property will be set automatically. +# sonarSecretKey: "settings-encryption-secret" + +## Override JDBC values +## for external Databases +jdbcOverwrite: + # If enable the JDBC Overwrite, make sure to set `postgresql.enabled=false` + enable: false + # The JDBC url of the external DB + jdbcUrl: "jdbc:postgresql://myPostgress/myDatabase?socketTimeout=1500" + # The DB user that should be used for the JDBC connection + jdbcUsername: "sonarUser" + # Use this if you don't mind the DB password getting stored in plain text within the values file + jdbcPassword: "sonarPass" + ## Alternatively, use a pre-existing k8s secret containing the DB password + # jdbcSecretName: "sonarqube-jdbc" + ## and the secretValueKey of the password found within that secret + # jdbcSecretPasswordKey: "jdbc-password" + +## Configuration values for postgresql dependency +## ref: https://github.com/bitnami/charts/blob/master/bitnami/postgresql/README.md +postgresql: + # Enable to deploy the bitnami PostgreSQL chart + enabled: true + ## postgresql Chart global settings + # global: + # imageRegistry: '' + # imagePullSecrets: '' + ## bitnami/postgres image tag + # image: + # tag: 11.7.0-debian-10-r9 + # existingSecret Name of existing secret to use for PostgreSQL passwords + # The secret has to contain the keys postgresql-password which is the password for postgresqlUsername when it is + # different of postgres, postgresql-postgres-password which will override postgresqlPassword, + # postgresql-replication-password which will override replication.password and postgresql-ldap-password which will be + # used to authenticate on LDAP. The value is evaluated as a template. + # existingSecret: "" + # + # The bitnami chart enforces the key to be "postgresql-password". This value is only here for historic purposes + # existingSecretPasswordKey: "postgresql-password" + postgresqlUsername: "sonarUser" + postgresqlPassword: "sonarPass" + postgresqlDatabase: "sonarDB" + # Specify the TCP port that PostgreSQL should use + service: + port: 5432 + resources: + limits: + cpu: 2 + memory: 2Gi + requests: + cpu: 100m + memory: 200Mi + persistence: + enabled: true + accessMode: ReadWriteOnce + size: 20Gi + storageClass: + securityContext: + # For standard Kubernetes deployment, set enabled=true + # If using OpenShift, enabled=false for restricted SCC and enabled=true for anyuid/nonroot SCC + enabled: true + # fsGroup specification below are not applied if enabled=false. enabled=false is the required setting for OpenShift "restricted SCC" to work successfully. + # postgresql dockerfile sets user as 1001 + fsGroup: 1001 + containerSecurityContext: + # For standard Kubernetes deployment, set enabled=true + # If using OpenShift, enabled=false for restricted SCC and enabled=true for anyuid/nonroot SCC + enabled: true + # runAsUser specification below are not applied if enabled=false. enabled=false is the required setting for OpenShift "restricted SCC" to work successfully. + # postgresql dockerfile sets user as 1001 + runAsUser: 1001 + volumePermissions: + # For standard Kubernetes deployment, set enabled=false + # For OpenShift, set enabled=true and ensure to set volumepermissions.securitycontext.runAsUser below. + enabled: false + # if using restricted SCC set runAsUser: "auto" and if running under anyuid/nonroot SCC - runAsUser needs to match runAsUser above + securityContext: + runAsUser: 0 + shmVolume: + chmod: + enabled: false + serviceAccount: + ## If enabled = true, and name is not set, postgreSQL will create a serviceAccount + enabled: false + # name: + +# Additional labels to add to the pods: +# podLabels: +# key: value +podLabels: {} +# For compatibility with 8.0 replace by "/opt/sq" +# For compatibility with 8.2, leave the default. They changed it back to /opt/sonarqube +sonarqubeFolder: /opt/sonarqube + +tests: + image: "" + enabled: true + resources: {} + +# For OpenShift set create=true to ensure service account is created. +serviceAccount: + create: false + # name: + # automountToken: false # default + ## Annotations for the Service Account + annotations: {} + +# extraConfig is used to load Environment Variables from Secrets and ConfigMaps +# which may have been written by other tools, such as external orchestrators. +# +# These Secrets/ConfigMaps are expected to contain Key/Value pairs, such as: +# +# apiVersion: v1 +# kind: ConfigMap +# metadata: +# name: external-sonarqube-opts +# data: +# SONARQUBE_JDBC_USERNAME: foo +# SONARQUBE_JDBC_URL: jdbc:postgresql://db.example.com:5432/sonar +# +# These vars can then be injected into the environment by uncommenting the following: +# +# extraConfig: +# configmaps: +# - external-sonarqube-opts + +extraConfig: + secrets: [] + configmaps: [] + +# account: +# The values can be set to define the current and the (new) custom admin passwords at the startup (the username will remain "admin") +# adminPassword: admin +# currentAdminPassword: admin +# The above values can be also provided by a secret that contains "password" and "currentPassword" as keys. You can generate such a secret in your cluster +# using "kubectl create secret generic admin-password-secret-name --from-literal=password=admin --from-literal=currentPassword=admin" +# adminPasswordSecretName: "" +# securityContext: {} +# resources: +# limits: +# cpu: 100m +# memory: 128Mi +# requests: +# cpu: 100m +# memory: 128Mi +# curlContainerImage: curlimages/curl:8.2.0 +# adminJobAnnotations: {} +# deprecated please use sonarWebContext at the value top level +# sonarWebContext: / + +terminationGracePeriodSeconds: 60 diff --git a/helm/teleport-cluster/.lint/acme-off.yaml b/helm/teleport-cluster/.lint/acme-off.yaml new file mode 100644 index 0000000..29a9052 --- /dev/null +++ b/helm/teleport-cluster/.lint/acme-off.yaml @@ -0,0 +1,3 @@ +clusterName: test-cluster-name +extraArgs: +- "--insecure" diff --git a/helm/teleport-cluster/.lint/acme-on.yaml b/helm/teleport-cluster/.lint/acme-on.yaml new file mode 100644 index 0000000..02821dc --- /dev/null +++ b/helm/teleport-cluster/.lint/acme-on.yaml @@ -0,0 +1,3 @@ +clusterName: test-acme-cluster +acme: true +acmeEmail: test@email.com diff --git a/helm/teleport-cluster/.lint/acme-uri-staging.yaml b/helm/teleport-cluster/.lint/acme-uri-staging.yaml new file mode 100644 index 0000000..2794d6d --- /dev/null +++ b/helm/teleport-cluster/.lint/acme-uri-staging.yaml @@ -0,0 +1,4 @@ +clusterName: test-acme-cluster +acme: true +acmeEmail: test@email.com +acmeURI: https://acme-staging-v02.api.letsencrypt.org/directory diff --git a/helm/teleport-cluster/.lint/affinity.yaml b/helm/teleport-cluster/.lint/affinity.yaml new file mode 100644 index 0000000..e984e7d --- /dev/null +++ b/helm/teleport-cluster/.lint/affinity.yaml @@ -0,0 +1,29 @@ +clusterName: test-gcp-cluster +chartMode: gcp +gcp: + projectId: gcpproj-123456 + backendTable: test-teleport-firestore-storage-collection + auditLogTable: test-teleport-firestore-auditlog-collection + sessionRecordingBucket: test-gcp-session-storage-bucket +highAvailability: + replicaCount: 2 +affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: gravitational.io/dedicated + operator: In + values: + - teleport + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchExpressions: + - key: app + operator: In + values: + - teleport + topologyKey: kubernetes.io/hostname + weight: 1 diff --git a/helm/teleport-cluster/.lint/annotations.yaml b/helm/teleport-cluster/.lint/annotations.yaml new file mode 100644 index 0000000..4e9fce5 --- /dev/null +++ b/helm/teleport-cluster/.lint/annotations.yaml @@ -0,0 +1,17 @@ +clusterName: helm-lint +annotations: + config: + kubernetes.io/config: "test-annotation" + kubernetes.io/config-different: 2 + deployment: + kubernetes.io/deployment: "test-annotation" + kubernetes.io/deployment-different: 3 + pod: + kubernetes.io/pod: "test-annotation" + kubernetes.io/pod-different: 4 + service: + kubernetes.io/service: "test-annotation" + kubernetes.io/service-different: 5 + serviceAccount: + kubernetes.io/serviceaccount: "test-annotation" + kubernetes.io/serviceaccount-different: 6 diff --git a/helm/teleport-cluster/.lint/auth-connector-name.yaml b/helm/teleport-cluster/.lint/auth-connector-name.yaml new file mode 100644 index 0000000..4e77b8b --- /dev/null +++ b/helm/teleport-cluster/.lint/auth-connector-name.yaml @@ -0,0 +1,3 @@ +clusterName: helm-lint +authentication: + connectorName: "okta" diff --git a/helm/teleport-cluster/.lint/auth-disable-local.yaml b/helm/teleport-cluster/.lint/auth-disable-local.yaml new file mode 100644 index 0000000..b4d6aa1 --- /dev/null +++ b/helm/teleport-cluster/.lint/auth-disable-local.yaml @@ -0,0 +1,5 @@ +clusterName: helm-lint +authentication: + type: "github" + localAuth: false + secondFactor: "off" diff --git a/helm/teleport-cluster/.lint/auth-locking-mode.yaml b/helm/teleport-cluster/.lint/auth-locking-mode.yaml new file mode 100644 index 0000000..4c64cfb --- /dev/null +++ b/helm/teleport-cluster/.lint/auth-locking-mode.yaml @@ -0,0 +1,3 @@ +clusterName: helm-lint +authentication: + lockingMode: "strict" diff --git a/helm/teleport-cluster/.lint/auth-passwordless.yaml b/helm/teleport-cluster/.lint/auth-passwordless.yaml new file mode 100644 index 0000000..9e33d9c --- /dev/null +++ b/helm/teleport-cluster/.lint/auth-passwordless.yaml @@ -0,0 +1,4 @@ +clusterName: helm-lint +authentication: + connectorName: passwordless + secondFactor: webauthn diff --git a/helm/teleport-cluster/.lint/auth-type-legacy.yaml b/helm/teleport-cluster/.lint/auth-type-legacy.yaml new file mode 100644 index 0000000..5420bf1 --- /dev/null +++ b/helm/teleport-cluster/.lint/auth-type-legacy.yaml @@ -0,0 +1,4 @@ +clusterName: helm-lint +authentication: + type: "this-should-be-ignored" +authenticationType: "github" diff --git a/helm/teleport-cluster/.lint/auth-type.yaml b/helm/teleport-cluster/.lint/auth-type.yaml new file mode 100644 index 0000000..9c71d82 --- /dev/null +++ b/helm/teleport-cluster/.lint/auth-type.yaml @@ -0,0 +1,3 @@ +clusterName: helm-lint +authentication: + type: "github" diff --git a/helm/teleport-cluster/.lint/auth-webauthn-legacy.yaml b/helm/teleport-cluster/.lint/auth-webauthn-legacy.yaml new file mode 100644 index 0000000..fd69d97 --- /dev/null +++ b/helm/teleport-cluster/.lint/auth-webauthn-legacy.yaml @@ -0,0 +1,10 @@ +clusterName: helm-lint +authentication: + secondFactor: "off" # this should be overridden +authenticationSecondFactor: + secondFactor: "on" + webauthn: + attestationAllowedCas: + - "/etc/ssl/certs/ca-certificates.crt" + attestationDeniedCas: + - "/etc/ssl/certs/ca-certificates.crt" diff --git a/helm/teleport-cluster/.lint/auth-webauthn.yaml b/helm/teleport-cluster/.lint/auth-webauthn.yaml new file mode 100644 index 0000000..e8702e1 --- /dev/null +++ b/helm/teleport-cluster/.lint/auth-webauthn.yaml @@ -0,0 +1,8 @@ +clusterName: helm-lint +authentication: + secondFactor: "on" + webauthn: + attestationAllowedCas: + - "/etc/ssl/certs/ca-certificates.crt" + attestationDeniedCas: + - "/etc/ssl/certs/ca-certificates.crt" diff --git a/helm/teleport-cluster/.lint/aws-dynamodb-autoscaling.yaml b/helm/teleport-cluster/.lint/aws-dynamodb-autoscaling.yaml new file mode 100644 index 0000000..c1dde28 --- /dev/null +++ b/helm/teleport-cluster/.lint/aws-dynamodb-autoscaling.yaml @@ -0,0 +1,14 @@ +clusterName: test-aws-cluster +chartMode: aws +aws: + region: us-west-2 + backendTable: test-dynamodb-backend-table + auditLogTable: test-dynamodb-auditlog-table + sessionRecordingBucket: test-s3-session-storage-bucket + dynamoAutoScaling: true + readMinCapacity: 5 + readMaxCapacity: 100 + readTargetValue: 50.0 + writeMinCapacity: 5 + writeMaxCapacity: 100 + writeTargetValue: 50.0 diff --git a/helm/teleport-cluster/.lint/aws-ha-acme.yaml b/helm/teleport-cluster/.lint/aws-ha-acme.yaml new file mode 100644 index 0000000..c2c4d2e --- /dev/null +++ b/helm/teleport-cluster/.lint/aws-ha-acme.yaml @@ -0,0 +1,14 @@ +clusterName: test-aws-cluster +chartMode: aws +aws: + region: us-west-2 + backendTable: test-dynamodb-backend-table + auditLogTable: test-dynamodb-auditlog-table + sessionRecordingBucket: test-s3-session-storage-bucket +highAvailability: + replicaCount: 3 + certManager: + enabled: true + issuerName: letsencrypt-production +labels: + env: aws diff --git a/helm/teleport-cluster/.lint/aws-ha-antiaffinity.yaml b/helm/teleport-cluster/.lint/aws-ha-antiaffinity.yaml new file mode 100644 index 0000000..0e639a2 --- /dev/null +++ b/helm/teleport-cluster/.lint/aws-ha-antiaffinity.yaml @@ -0,0 +1,12 @@ +clusterName: test-aws-cluster +chartMode: aws +aws: + region: us-west-2 + backendTable: test-dynamodb-backend-table + auditLogTable: test-dynamodb-auditlog-table + sessionRecordingBucket: test-s3-session-storage-bucket +highAvailability: + replicaCount: 3 + requireAntiAffinity: true +labels: + env: aws diff --git a/helm/teleport-cluster/.lint/aws-ha-log.yaml b/helm/teleport-cluster/.lint/aws-ha-log.yaml new file mode 100644 index 0000000..733466b --- /dev/null +++ b/helm/teleport-cluster/.lint/aws-ha-log.yaml @@ -0,0 +1,17 @@ +clusterName: test-aws-cluster +chartMode: aws +log: + level: DEBUG +aws: + region: us-west-2 + backendTable: test-dynamodb-backend-table + auditLogTable: test-dynamodb-auditlog-table + auditLogMirrorOnStdout: true + sessionRecordingBucket: test-s3-session-storage-bucket +highAvailability: + replicaCount: 2 + certManager: + enabled: true + issuerName: letsencrypt-production +labels: + env: aws diff --git a/helm/teleport-cluster/.lint/aws-ha.yaml b/helm/teleport-cluster/.lint/aws-ha.yaml new file mode 100644 index 0000000..5bb2120 --- /dev/null +++ b/helm/teleport-cluster/.lint/aws-ha.yaml @@ -0,0 +1,11 @@ +clusterName: test-aws-cluster +chartMode: aws +aws: + region: us-west-2 + backendTable: test-dynamodb-backend-table + auditLogTable: test-dynamodb-auditlog-table + sessionRecordingBucket: test-s3-session-storage-bucket +highAvailability: + replicaCount: 3 +labels: + env: aws diff --git a/helm/teleport-cluster/.lint/aws.yaml b/helm/teleport-cluster/.lint/aws.yaml new file mode 100644 index 0000000..0c822e3 --- /dev/null +++ b/helm/teleport-cluster/.lint/aws.yaml @@ -0,0 +1,11 @@ +clusterName: test-aws-cluster +chartMode: aws +aws: + region: us-west-2 + backendTable: test-dynamodb-backend-table + auditLogTable: test-dynamodb-auditlog-table + sessionRecordingBucket: test-s3-session-storage-bucket +acme: true +acmeEmail: test@email.com +labels: + env: aws diff --git a/helm/teleport-cluster/.lint/azure.yaml b/helm/teleport-cluster/.lint/azure.yaml new file mode 100644 index 0000000..f755c36 --- /dev/null +++ b/helm/teleport-cluster/.lint/azure.yaml @@ -0,0 +1,11 @@ +clusterName: test-azure-cluster +chartMode: azure +azure: + databaseHost: "mypostgresinstance.postgres.database.azure.com" + databaseUser: "teleport" + backendDatabase: "teleport_backend" + auditLogDatabase: "teleport_audit" + auditLogMirrorOnStdout: true + sessionRecordingStorageAccount: "mystorageaccount.blob.core.windows.net" + clientID: "1234" + databasePoolMaxConnections: 100 diff --git a/helm/teleport-cluster/.lint/cert-manager.yaml b/helm/teleport-cluster/.lint/cert-manager.yaml new file mode 100644 index 0000000..7748890 --- /dev/null +++ b/helm/teleport-cluster/.lint/cert-manager.yaml @@ -0,0 +1,15 @@ +clusterName: test-cluster +chartMode: aws +aws: + region: us-west-2 + backendTable: test-dynamodb-backend-table + auditLogTable: test-dynamodb-auditlog-table + sessionRecordingBucket: test-s3-session-storage-bucket +highAvailability: + replicaCount: 3 + certManager: + addCommonName: true + enabled: true + issuerGroup: custom.cert-manager.io + issuerName: custom + issuerKind: CustomClusterIssuer diff --git a/helm/teleport-cluster/.lint/cert-secret.yaml b/helm/teleport-cluster/.lint/cert-secret.yaml new file mode 100644 index 0000000..d86eb31 --- /dev/null +++ b/helm/teleport-cluster/.lint/cert-secret.yaml @@ -0,0 +1,15 @@ +clusterName: test-cluster +chartMode: aws +aws: + region: us-west-2 + backendTable: test-dynamodb-backend-table + auditLogTable: test-dynamodb-auditlog-table + sessionRecordingBucket: test-s3-session-storage-bucket +annotations: + certSecret: + kubernetes.io/cert-secret: value +highAvailability: + replicaCount: 3 + certManager: + enabled: true + issuerName: letsencrypt diff --git a/helm/teleport-cluster/.lint/example-minimal-standalone.yaml b/helm/teleport-cluster/.lint/example-minimal-standalone.yaml new file mode 100644 index 0000000..9cdba9a --- /dev/null +++ b/helm/teleport-cluster/.lint/example-minimal-standalone.yaml @@ -0,0 +1,7 @@ +# This setup is not safe for production because the proxy will self-sign its certificate. +# Use those values for testing only + +# The chart should deploy and work only with a clusterName. +# This setup can also cause redirection issues if the proxy is contacted with a hostName instead of an IP address +# as it is not aware of its external hostname and will attempt to perform a redirection. +clusterName: helm-lint diff --git a/helm/teleport-cluster/.lint/existing-tls-secret-with-ca.yaml b/helm/teleport-cluster/.lint/existing-tls-secret-with-ca.yaml new file mode 100644 index 0000000..086c628 --- /dev/null +++ b/helm/teleport-cluster/.lint/existing-tls-secret-with-ca.yaml @@ -0,0 +1,4 @@ +clusterName: test-cluster-name +tls: + existingSecretName: helm-lint-existing-tls-secret + existingCASecretName: helm-lint-existing-tls-secret-ca diff --git a/helm/teleport-cluster/.lint/existing-tls-secret.yaml b/helm/teleport-cluster/.lint/existing-tls-secret.yaml new file mode 100644 index 0000000..37f07ea --- /dev/null +++ b/helm/teleport-cluster/.lint/existing-tls-secret.yaml @@ -0,0 +1,3 @@ +clusterName: test-cluster-name +tls: + existingSecretName: helm-lint-existing-tls-secret diff --git a/helm/teleport-cluster/.lint/extra-env.yaml b/helm/teleport-cluster/.lint/extra-env.yaml new file mode 100644 index 0000000..ea0d122 --- /dev/null +++ b/helm/teleport-cluster/.lint/extra-env.yaml @@ -0,0 +1,4 @@ +clusterName: helm-lint.example.com +extraEnv: + - name: SOME_ENVIRONMENT_VARIABLE + value: "some-value" diff --git a/helm/teleport-cluster/.lint/gcp-ha-acme.yaml b/helm/teleport-cluster/.lint/gcp-ha-acme.yaml new file mode 100644 index 0000000..d122907 --- /dev/null +++ b/helm/teleport-cluster/.lint/gcp-ha-acme.yaml @@ -0,0 +1,14 @@ +clusterName: test-gcp-cluster +chartMode: gcp +gcp: + projectId: gcpproj-123456 + backendTable: test-teleport-firestore-storage-collection + auditLogTable: test-teleport-firestore-auditlog-collection + sessionRecordingBucket: test-gcp-session-storage-bucket +highAvailability: + replicaCount: 3 + certManager: + enabled: true + issuerName: letsencrypt-production +labels: + env: gcp diff --git a/helm/teleport-cluster/.lint/gcp-ha-antiaffinity.yaml b/helm/teleport-cluster/.lint/gcp-ha-antiaffinity.yaml new file mode 100644 index 0000000..9743cad --- /dev/null +++ b/helm/teleport-cluster/.lint/gcp-ha-antiaffinity.yaml @@ -0,0 +1,12 @@ +clusterName: test-gcp-cluster +chartMode: gcp +gcp: + projectId: gcpproj-123456 + backendTable: test-teleport-firestore-storage-collection + auditLogTable: test-teleport-firestore-auditlog-collection + sessionRecordingBucket: test-gcp-session-storage-bucket +highAvailability: + replicaCount: 3 + requireAntiAffinity: true +labels: + env: gcp diff --git a/helm/teleport-cluster/.lint/gcp-ha-log.yaml b/helm/teleport-cluster/.lint/gcp-ha-log.yaml new file mode 100644 index 0000000..d13f73c --- /dev/null +++ b/helm/teleport-cluster/.lint/gcp-ha-log.yaml @@ -0,0 +1,17 @@ +clusterName: test-gcp-cluster +chartMode: gcp +log: + level: DEBUG +gcp: + projectId: gcpproj-123456 + backendTable: test-teleport-firestore-storage-collection + auditLogTable: test-teleport-firestore-auditlog-collection + auditLogMirrorOnStdout: true + sessionRecordingBucket: test-gcp-session-storage-bucket +highAvailability: + replicaCount: 3 + certManager: + enabled: true + issuerName: letsencrypt-production +labels: + env: gcp diff --git a/helm/teleport-cluster/.lint/gcp-ha-workload.yaml b/helm/teleport-cluster/.lint/gcp-ha-workload.yaml new file mode 100644 index 0000000..0568bbf --- /dev/null +++ b/helm/teleport-cluster/.lint/gcp-ha-workload.yaml @@ -0,0 +1,12 @@ +clusterName: test-gcp-cluster +chartMode: gcp +gcp: + projectId: gcpproj-123456 + backendTable: test-teleport-firestore-storage-collection + auditLogTable: test-teleport-firestore-auditlog-collection + sessionRecordingBucket: test-gcp-session-storage-bucket + credentialSecretName: "" +highAvailability: + replicaCount: 3 +labels: + env: gcp diff --git a/helm/teleport-cluster/.lint/gcp-ha.yaml b/helm/teleport-cluster/.lint/gcp-ha.yaml new file mode 100644 index 0000000..26b43d4 --- /dev/null +++ b/helm/teleport-cluster/.lint/gcp-ha.yaml @@ -0,0 +1,11 @@ +clusterName: test-gcp-cluster +chartMode: gcp +gcp: + projectId: gcpproj-123456 + backendTable: test-teleport-firestore-storage-collection + auditLogTable: test-teleport-firestore-auditlog-collection + sessionRecordingBucket: test-gcp-session-storage-bucket +highAvailability: + replicaCount: 3 +labels: + env: gcp diff --git a/helm/teleport-cluster/.lint/gcp.yaml b/helm/teleport-cluster/.lint/gcp.yaml new file mode 100644 index 0000000..56a395b --- /dev/null +++ b/helm/teleport-cluster/.lint/gcp.yaml @@ -0,0 +1,11 @@ +clusterName: test-gcp-cluster +chartMode: gcp +gcp: + projectId: gcpproj-123456 + backendTable: test-teleport-firestore-storage-collection + auditLogTable: test-teleport-firestore-auditlog-collection + sessionRecordingBucket: test-gcp-session-storage-bucket +acme: true +acmeEmail: test@email.com +labels: + env: gcp diff --git a/helm/teleport-cluster/.lint/imagepullsecrets.yaml b/helm/teleport-cluster/.lint/imagepullsecrets.yaml new file mode 100644 index 0000000..f414f8c --- /dev/null +++ b/helm/teleport-cluster/.lint/imagepullsecrets.yaml @@ -0,0 +1,4 @@ +clusterName: test-standalone-cluster +chartMode: standalone +imagePullSecrets: +- name: myRegistryKeySecretName diff --git a/helm/teleport-cluster/.lint/ingress-publicaddr.yaml b/helm/teleport-cluster/.lint/ingress-publicaddr.yaml new file mode 100644 index 0000000..0e9692a --- /dev/null +++ b/helm/teleport-cluster/.lint/ingress-publicaddr.yaml @@ -0,0 +1,8 @@ +clusterName: teleport.example.com +publicAddr: ["my-teleport-ingress.example.com:443"] +ingress: + enabled: true + suppressAutomaticWildcards: true +proxyListenerMode: multiplex +service: + type: ClusterIP diff --git a/helm/teleport-cluster/.lint/ingress.yaml b/helm/teleport-cluster/.lint/ingress.yaml new file mode 100644 index 0000000..e5fbbc4 --- /dev/null +++ b/helm/teleport-cluster/.lint/ingress.yaml @@ -0,0 +1,6 @@ +clusterName: teleport.example.com +ingress: + enabled: true +proxyListenerMode: multiplex +service: + type: ClusterIP diff --git a/helm/teleport-cluster/.lint/initcontainers.yaml b/helm/teleport-cluster/.lint/initcontainers.yaml new file mode 100644 index 0000000..a558e45 --- /dev/null +++ b/helm/teleport-cluster/.lint/initcontainers.yaml @@ -0,0 +1,8 @@ +clusterName: helm-lint +initContainers: +- name: "teleport-init" + image: "alpine" + args: ["echo test"] +- name: "teleport-init2" + image: "alpine" + args: ["echo test2"] diff --git a/helm/teleport-cluster/.lint/kube-cluster-name.yaml b/helm/teleport-cluster/.lint/kube-cluster-name.yaml new file mode 100644 index 0000000..ccd510b --- /dev/null +++ b/helm/teleport-cluster/.lint/kube-cluster-name.yaml @@ -0,0 +1,2 @@ +clusterName: test-aws-cluster +kubeClusterName: test-kube-cluster diff --git a/helm/teleport-cluster/.lint/log-basic.yaml b/helm/teleport-cluster/.lint/log-basic.yaml new file mode 100644 index 0000000..037e189 --- /dev/null +++ b/helm/teleport-cluster/.lint/log-basic.yaml @@ -0,0 +1,4 @@ +clusterName: test-log-cluster +log: + format: json + level: INFO diff --git a/helm/teleport-cluster/.lint/log-extra.yaml b/helm/teleport-cluster/.lint/log-extra.yaml new file mode 100644 index 0000000..7f3e21b --- /dev/null +++ b/helm/teleport-cluster/.lint/log-extra.yaml @@ -0,0 +1,6 @@ +clusterName: test-log-cluster +log: + format: json + level: DEBUG + output: /var/lib/teleport/test.log + extraFields: ["level", "timestamp", "component", "caller"] diff --git a/helm/teleport-cluster/.lint/log-legacy.yaml b/helm/teleport-cluster/.lint/log-legacy.yaml new file mode 100644 index 0000000..b28d3ab --- /dev/null +++ b/helm/teleport-cluster/.lint/log-legacy.yaml @@ -0,0 +1,2 @@ +clusterName: test-log-cluster +logLevel: DEBUG diff --git a/helm/teleport-cluster/.lint/node-selector.yaml b/helm/teleport-cluster/.lint/node-selector.yaml new file mode 100644 index 0000000..d3c1f06 --- /dev/null +++ b/helm/teleport-cluster/.lint/node-selector.yaml @@ -0,0 +1,4 @@ +clusterName: test-cluster-name +nodeSelector: + role: bastion + environment: security diff --git a/helm/teleport-cluster/.lint/operator.yaml b/helm/teleport-cluster/.lint/operator.yaml new file mode 100644 index 0000000..e390d5b --- /dev/null +++ b/helm/teleport-cluster/.lint/operator.yaml @@ -0,0 +1,4 @@ +clusterName: test-cluster-name +operator: + enabled: true +installCRDs: true diff --git a/helm/teleport-cluster/.lint/pdb.yaml b/helm/teleport-cluster/.lint/pdb.yaml new file mode 100644 index 0000000..0504d09 --- /dev/null +++ b/helm/teleport-cluster/.lint/pdb.yaml @@ -0,0 +1,12 @@ +clusterName: helm-lint +chartMode: aws +aws: + region: us-west-2 + backendTable: test-dynamodb-backend-table + auditLogTable: test-dynamodb-auditlog-table + sessionRecordingBucket: test-s3-session-storage-bucket +highAvailability: + replicaCount: 3 + podDisruptionBudget: + enabled: true + minAvailable: 2 diff --git a/helm/teleport-cluster/.lint/persistence-legacy.yaml b/helm/teleport-cluster/.lint/persistence-legacy.yaml new file mode 100644 index 0000000..0d9a124 --- /dev/null +++ b/helm/teleport-cluster/.lint/persistence-legacy.yaml @@ -0,0 +1,4 @@ +clusterName: test-persistence-cluster +standalone: + existingClaimName: "" + volumeSize: 10Gi diff --git a/helm/teleport-cluster/.lint/podmonitor.yaml b/helm/teleport-cluster/.lint/podmonitor.yaml new file mode 100644 index 0000000..1c263f5 --- /dev/null +++ b/helm/teleport-cluster/.lint/podmonitor.yaml @@ -0,0 +1,6 @@ +clusterName: test-kube-cluster-name +podMonitor: + enabled: true + additionalLabels: + prometheus: default + interval: 30s diff --git a/helm/teleport-cluster/.lint/priority-class-name.yaml b/helm/teleport-cluster/.lint/priority-class-name.yaml new file mode 100644 index 0000000..3386375 --- /dev/null +++ b/helm/teleport-cluster/.lint/priority-class-name.yaml @@ -0,0 +1,4 @@ +clusterName: helm-lint +# These are just sample values to test the chart. +# They are not intended to be guidelines or suggestions for running teleport. +priorityClassName: "system-cluster-critical" diff --git a/helm/teleport-cluster/.lint/probe-timeout-seconds.yaml b/helm/teleport-cluster/.lint/probe-timeout-seconds.yaml new file mode 100644 index 0000000..a239435 --- /dev/null +++ b/helm/teleport-cluster/.lint/probe-timeout-seconds.yaml @@ -0,0 +1,4 @@ +clusterName: helm-lint +# These are just sample values to test the chart. +# They are not intended to be guidelines or suggestions for running teleport. +probeTimeoutSeconds: 5 diff --git a/helm/teleport-cluster/.lint/proxy-listener-mode-multiplex.yaml b/helm/teleport-cluster/.lint/proxy-listener-mode-multiplex.yaml new file mode 100644 index 0000000..87ac0b3 --- /dev/null +++ b/helm/teleport-cluster/.lint/proxy-listener-mode-multiplex.yaml @@ -0,0 +1,2 @@ +clusterName: test-proxy-listener-mode +proxyListenerMode: multiplex diff --git a/helm/teleport-cluster/.lint/proxy-listener-mode-separate.yaml b/helm/teleport-cluster/.lint/proxy-listener-mode-separate.yaml new file mode 100644 index 0000000..3be257a --- /dev/null +++ b/helm/teleport-cluster/.lint/proxy-listener-mode-separate.yaml @@ -0,0 +1,2 @@ +clusterName: test-proxy-listener-mode +proxyListenerMode: separate diff --git a/helm/teleport-cluster/.lint/public-addresses.yaml b/helm/teleport-cluster/.lint/public-addresses.yaml new file mode 100644 index 0000000..1122492 --- /dev/null +++ b/helm/teleport-cluster/.lint/public-addresses.yaml @@ -0,0 +1,11 @@ +clusterName: helm-lint +publicAddr: ["loadbalancer.example.com:443"] +sshPublicAddr: ["loadbalancer.example.com:3023"] +tunnelPublicAddr: ["loadbalancer.example.com:3024"] +postgresPublicAddr: ["loadbalancer.example.com:5432"] +mongoPublicAddr: ["loadbalancer.example.com:27017"] +mysqlPublicAddr: ["loadbalancer.example.com:3036"] +kubePublicAddr: ["loadbalancer.example.com:3026"] + +separatePostgresListener: true +separateMongoListener: true diff --git a/helm/teleport-cluster/.lint/resources.yaml b/helm/teleport-cluster/.lint/resources.yaml new file mode 100644 index 0000000..070a85c --- /dev/null +++ b/helm/teleport-cluster/.lint/resources.yaml @@ -0,0 +1,10 @@ +clusterName: helm-lint +# These are just sample values to test the chart. +# They are not intended to be guidelines or suggestions for running teleport. +resources: + limits: + cpu: 2 + memory: 4Gi + requests: + cpu: 1 + memory: 2Gi diff --git a/helm/teleport-cluster/.lint/security-context-empty.yaml b/helm/teleport-cluster/.lint/security-context-empty.yaml new file mode 100644 index 0000000..14ff546 --- /dev/null +++ b/helm/teleport-cluster/.lint/security-context-empty.yaml @@ -0,0 +1 @@ +clusterName: helm-lint diff --git a/helm/teleport-cluster/.lint/security-context.yaml b/helm/teleport-cluster/.lint/security-context.yaml new file mode 100644 index 0000000..32e4015 --- /dev/null +++ b/helm/teleport-cluster/.lint/security-context.yaml @@ -0,0 +1,8 @@ +clusterName: helm-lint +securityContext: + allowPrivilegeEscalation: false + privileged: false + readOnlyRootFilesystem: false + runAsGroup: 99 + runAsNonRoot: true + runAsUser: 99 diff --git a/helm/teleport-cluster/.lint/separate-mongo-listener.yaml b/helm/teleport-cluster/.lint/separate-mongo-listener.yaml new file mode 100644 index 0000000..23bac08 --- /dev/null +++ b/helm/teleport-cluster/.lint/separate-mongo-listener.yaml @@ -0,0 +1,2 @@ +clusterName: helm-lint +separateMongoListener: true diff --git a/helm/teleport-cluster/.lint/separate-postgres-listener.yaml b/helm/teleport-cluster/.lint/separate-postgres-listener.yaml new file mode 100644 index 0000000..0a1196f --- /dev/null +++ b/helm/teleport-cluster/.lint/separate-postgres-listener.yaml @@ -0,0 +1,2 @@ +clusterName: helm-lint +separatePostgresListener: true diff --git a/helm/teleport-cluster/.lint/service-account.yaml b/helm/teleport-cluster/.lint/service-account.yaml new file mode 100644 index 0000000..a6f9678 --- /dev/null +++ b/helm/teleport-cluster/.lint/service-account.yaml @@ -0,0 +1,7 @@ +clusterName: helm-lint +serviceAccount: + create: true + name: helm-lint +annotations: + serviceAccount: + kubernetes.io/serviceaccount: "test-annotation" diff --git a/helm/teleport-cluster/.lint/service.yaml b/helm/teleport-cluster/.lint/service.yaml new file mode 100644 index 0000000..0a8eed6 --- /dev/null +++ b/helm/teleport-cluster/.lint/service.yaml @@ -0,0 +1,5 @@ +clusterName: helm-lint +service: + type: LoadBalancer + spec: + loadBalancerIP: 1.2.3.4 diff --git a/helm/teleport-cluster/.lint/session-recording.yaml b/helm/teleport-cluster/.lint/session-recording.yaml new file mode 100644 index 0000000..8b41012 --- /dev/null +++ b/helm/teleport-cluster/.lint/session-recording.yaml @@ -0,0 +1,2 @@ +clusterName: helm-lint +sessionRecording: "node-sync" diff --git a/helm/teleport-cluster/.lint/standalone-custom-storage-class.yaml b/helm/teleport-cluster/.lint/standalone-custom-storage-class.yaml new file mode 100644 index 0000000..4cf5ade --- /dev/null +++ b/helm/teleport-cluster/.lint/standalone-custom-storage-class.yaml @@ -0,0 +1,9 @@ +clusterName: test-standalone-cluster +chartMode: standalone +persistence: + enabled: true + storageClassName: ebs-ssd +acme: true +acmeEmail: test@email.com +labels: + env: standalone diff --git a/helm/teleport-cluster/.lint/standalone-customsize.yaml b/helm/teleport-cluster/.lint/standalone-customsize.yaml new file mode 100644 index 0000000..c994faa --- /dev/null +++ b/helm/teleport-cluster/.lint/standalone-customsize.yaml @@ -0,0 +1,9 @@ +clusterName: test-standalone-cluster +chartMode: standalone +persistence: + enabled: true + volumeSize: 50Gi +acme: true +acmeEmail: test@email.com +labels: + env: standalone diff --git a/helm/teleport-cluster/.lint/standalone-existingpvc.yaml b/helm/teleport-cluster/.lint/standalone-existingpvc.yaml new file mode 100644 index 0000000..89292ef --- /dev/null +++ b/helm/teleport-cluster/.lint/standalone-existingpvc.yaml @@ -0,0 +1,9 @@ +clusterName: test-standalone-cluster +chartMode: standalone +persistence: + enabled: true + existingClaimName: teleport-storage +acme: true +acmeEmail: test@email.com +labels: + env: standalone diff --git a/helm/teleport-cluster/.lint/tolerations.yaml b/helm/teleport-cluster/.lint/tolerations.yaml new file mode 100644 index 0000000..69d4161 --- /dev/null +++ b/helm/teleport-cluster/.lint/tolerations.yaml @@ -0,0 +1,18 @@ +clusterName: test-aws-cluster +chartMode: aws +aws: + region: us-west-2 + backendTable: test-dynamodb-backend-table + auditLogTable: test-dynamodb-auditlog-table + sessionRecordingBucket: test-s3-session-storage-bucket +highAvailability: + replicaCount: 3 +tolerations: +- key: "dedicated" + operator: "Equal" + value: "teleport" + effect: "NoExecute" +- key: "dedicated" + operator: "Equal" + value: "teleport" + effect: "NoSchedule" diff --git a/helm/teleport-cluster/.lint/version-override.yaml b/helm/teleport-cluster/.lint/version-override.yaml new file mode 100644 index 0000000..689e958 --- /dev/null +++ b/helm/teleport-cluster/.lint/version-override.yaml @@ -0,0 +1,5 @@ +clusterName: test-cluster-name +teleportVersionOverride: 5.2.1 +labels: + env: test + version: 5.2.1 diff --git a/helm/teleport-cluster/.lint/volumes.yaml b/helm/teleport-cluster/.lint/volumes.yaml new file mode 100644 index 0000000..a1ce300 --- /dev/null +++ b/helm/teleport-cluster/.lint/volumes.yaml @@ -0,0 +1,8 @@ +clusterName: helm-lint +extraVolumeMounts: +- name: "my-mount" + mountPath: "/path/to/mount" +extraVolumes: +- name: "my-mount" + secret: + secretName: "mySecret" diff --git a/helm/teleport-cluster/Chart.yaml b/helm/teleport-cluster/Chart.yaml new file mode 100644 index 0000000..73b2a2d --- /dev/null +++ b/helm/teleport-cluster/Chart.yaml @@ -0,0 +1,13 @@ +apiVersion: v2 +appVersion: 13.3.9 +dependencies: +- condition: installCRDs,operator.enabled + name: teleport-operator + repository: "" + version: 13.3.9 +description: Teleport is an access platform for your infrastructure +icon: https://goteleport.com/images/logos/logo-teleport-square.svg +keywords: +- Teleport +name: teleport-cluster +version: 13.3.9 diff --git a/helm/teleport-cluster/README.md b/helm/teleport-cluster/README.md new file mode 100644 index 0000000..27e6235 --- /dev/null +++ b/helm/teleport-cluster/README.md @@ -0,0 +1,64 @@ +# Teleport Cluster + +This chart sets up a single node Teleport cluster. +It uses a persistent volume claim for storage. +Great for getting started with Teleport. + +## Important Notices + +- The chart version follows the Teleport version. e.g. chart v10.x can run Teleport v10.x and v11.x, but is not compatible with Teleport 9.x +- Teleport does mutual TLS to authenticate clients. It currently does not support running behind a L7 LoadBalancer, like a Kubernetes `Ingress`. It requires being exposed through a L4 LoadBalancer (Kubernetes `Service`). + +## Getting Started + +### Single-node example + +To install Teleport in a separate namespace and provision a web certificate using Let's Encrypt, run: + +```bash +$ helm install teleport/teleport-cluster \ + --set acme=true \ + --set acmeEmail=alice@example.com \ + --set clusterName=teleport.example.com\ + --create-namespace \ + --namespace=teleport-cluster \ + ./teleport-cluster/ +``` + +Finally, configure the DNS for `teleport.example.com` to point to the newly created LoadBalancer. + +Note: this guide uses the built-in ACME client to get certificates. +In this setup, Teleport nodes cannot be replicated. If you want to run multiple +Teleport replicas, you must provide a certificate through `tls.existingSecretName` +or by installing [cert-manager](https://cert-manager.io/docs/) and setting the `highAvailability.certManager.*` values. + +### Replicated setup guides + +- [Running an HA Teleport cluster in Kubernetes using an AWS EKS Cluster](https://goteleport.com/docs/deploy-a-cluster/helm-deployments/aws/) +- [Running an HA Teleport cluster in Kubernetes using a Google Cloud GKE cluster](https://goteleport.com/docs/deploy-a-cluster/helm-deployments/gcp/) +- [Running a Teleport cluster in Kubernetes with a custom Teleport config](https://goteleport.com/docs/deploy-a-cluster/helm-deployments/custom/) + +### Creating first user + +The first user can be created by executing a command in one of the auth pods. + +```shell +kubectl exec it -n teleport-cluster statefulset/teleport-cluster-auth -- tctl users add my-username --roles=editor,auditor,access +``` + +The command should output a registration link to finalize the user creation. + +## Uninstalling + +```bash +helm uninstall --namespace teleport-cluster teleport-cluster +``` + +## Documentation + +See https://goteleport.com/docs/kubernetes-access/helm/guides/ for guides on setting up HA Teleport clusters +in EKS or GKE, plus a comprehensive chart reference. + +## Contributing to the chart + +Please read [CONTRIBUTING.md](../CONTRIBUTING.md) before raising a pull request to this chart. diff --git a/helm/teleport-cluster/charts/teleport-operator/Chart.yaml b/helm/teleport-cluster/charts/teleport-operator/Chart.yaml new file mode 100644 index 0000000..944d2ad --- /dev/null +++ b/helm/teleport-cluster/charts/teleport-operator/Chart.yaml @@ -0,0 +1,8 @@ +apiVersion: v2 +appVersion: 13.3.9 +description: Teleport Operator provides management of select Teleport resources. +icon: https://goteleport.com/images/logos/logo-teleport-square.svg +keywords: +- Teleport +name: teleport-operator +version: 13.3.9 diff --git a/helm/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_githubconnectors.yaml b/helm/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_githubconnectors.yaml new file mode 100644 index 0000000..40bbc08 --- /dev/null +++ b/helm/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_githubconnectors.yaml @@ -0,0 +1,168 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + creationTimestamp: null + name: teleportgithubconnectors.resources.teleport.dev +spec: + group: resources.teleport.dev + names: + kind: TeleportGithubConnector + listKind: TeleportGithubConnectorList + plural: teleportgithubconnectors + shortNames: + - githubconnector + - githubconnectors + singular: teleportgithubconnector + scope: Namespaced + versions: + - name: v3 + schema: + openAPIV3Schema: + description: GithubConnector is the Schema for the githubconnectors 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: GithubConnector resource definition v3 from Teleport + properties: + api_endpoint_url: + description: APIEndpointURL is the URL of the API endpoint of the + Github instance this connector is for. + type: string + client_id: + description: ClientID is the Github OAuth app client ID. + type: string + client_secret: + description: ClientSecret is the Github OAuth app client secret. + type: string + display: + description: Display is the connector display name. + type: string + endpoint_url: + description: EndpointURL is the URL of the GitHub instance this connector + is for. + type: string + redirect_url: + description: RedirectURL is the authorization callback URL. + type: string + teams_to_roles: + description: TeamsToRoles maps Github team memberships onto allowed + roles. + items: + properties: + organization: + description: Organization is a Github organization a user belongs + to. + type: string + roles: + description: Roles is a list of allowed logins for this org/team. + items: + type: string + nullable: true + type: array + team: + description: Team is a team within the organization a user belongs + to. + type: string + type: object + type: array + type: object + status: + description: TeleportGithubConnectorStatus defines the observed state + of TeleportGithubConnector + properties: + conditions: + description: Conditions represent the latest available observations + of an object's state + items: + description: "Condition contains details for one aspect of the current + state of this API Resource. --- This struct is intended for direct + use as an array at the field path .status.conditions. For example, + \n type FooStatus struct{ // Represents the observations of a + foo's current state. // Known .status.conditions.type are: \"Available\", + \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge + // +listType=map // +listMapKey=type Conditions []metav1.Condition + `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" + protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition + transitioned from one status to another. This should be when + the underlying condition changed. If that is not known, then + using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating + details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation + that the condition was set based upon. For instance, if .metadata.generation + is currently 12, but the .status.conditions[x].observedGeneration + is 9, the condition is out of date with respect to the current + state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating + the reason for the condition's last transition. Producers + of specific condition types may define expected values and + meanings for this field, and whether the values are considered + a guaranteed API. The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + --- Many .condition.type values are consistent across resources + like Available, but because arbitrary conditions can be useful + (see .node.status.conditions), the ability to deconflict is + important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + teleportResourceID: + format: int64 + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null diff --git a/helm/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_loginrules.yaml b/helm/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_loginrules.yaml new file mode 100644 index 0000000..7b5adc6 --- /dev/null +++ b/helm/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_loginrules.yaml @@ -0,0 +1,145 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + creationTimestamp: null + name: teleportloginrules.resources.teleport.dev +spec: + group: resources.teleport.dev + names: + kind: TeleportLoginRule + listKind: TeleportLoginRuleList + plural: teleportloginrules + shortNames: + - loginrule + - loginrules + singular: teleportloginrule + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + description: LoginRule is the Schema for the loginrules 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: LoginRule resource definition v1 from Teleport + properties: + priority: + description: Priority is the priority of the login rule relative to + other login rules in the same cluster. Login rules with a lower + numbered priority will be evaluated first. + format: int32 + type: integer + traits_expression: + description: TraitsExpression is a predicate expression which should + return the desired traits for the user upon login. + type: string + traits_map: + additionalProperties: + items: + type: string + type: array + description: TraitsMap is a map of trait keys to lists of predicate + expressions which should evaluate to the desired values for that + trait. + nullable: true + type: object + type: object + status: + properties: + conditions: + description: Conditions represent the latest available observations + of an object's state + items: + description: "Condition contains details for one aspect of the current + state of this API Resource. --- This struct is intended for direct + use as an array at the field path .status.conditions. For example, + \n type FooStatus struct{ // Represents the observations of a + foo's current state. // Known .status.conditions.type are: \"Available\", + \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge + // +listType=map // +listMapKey=type Conditions []metav1.Condition + `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" + protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition + transitioned from one status to another. This should be when + the underlying condition changed. If that is not known, then + using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating + details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation + that the condition was set based upon. For instance, if .metadata.generation + is currently 12, but the .status.conditions[x].observedGeneration + is 9, the condition is out of date with respect to the current + state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating + the reason for the condition's last transition. Producers + of specific condition types may define expected values and + meanings for this field, and whether the values are considered + a guaranteed API. The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + --- Many .condition.type values are consistent across resources + like Available, but because arbitrary conditions can be useful + (see .node.status.conditions), the ability to deconflict is + important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + teleportResourceID: + format: int64 + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null diff --git a/helm/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_oidcconnectors.yaml b/helm/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_oidcconnectors.yaml new file mode 100644 index 0000000..1dc0e16 --- /dev/null +++ b/helm/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_oidcconnectors.yaml @@ -0,0 +1,213 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + creationTimestamp: null + name: teleportoidcconnectors.resources.teleport.dev +spec: + group: resources.teleport.dev + names: + kind: TeleportOIDCConnector + listKind: TeleportOIDCConnectorList + plural: teleportoidcconnectors + shortNames: + - oidcconnector + - oidcconnectors + singular: teleportoidcconnector + scope: Namespaced + versions: + - name: v3 + schema: + openAPIV3Schema: + description: OIDCConnector is the Schema for the oidcconnectors 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: OIDCConnector resource definition v3 from Teleport + properties: + acr_values: + description: ACR is an Authentication Context Class Reference value. + The meaning of the ACR value is context-specific and varies for + identity providers. + type: string + allow_unverified_email: + description: AllowUnverifiedEmail tells the connector to accept OIDC + users with unverified emails. + type: boolean + claims_to_roles: + description: ClaimsToRoles specifies a dynamic mapping from claims + to roles. + items: + properties: + claim: + description: Claim is a claim name. + type: string + roles: + description: Roles is a list of static teleport roles to match. + items: + type: string + nullable: true + type: array + value: + description: Value is a claim value to match. + type: string + type: object + type: array + client_id: + description: ClientID is the id of the authentication client (Teleport + Auth server). + type: string + client_secret: + description: ClientSecret is used to authenticate the client. + type: string + display: + description: Display is the friendly name for this provider. + type: string + google_admin_email: + description: GoogleAdminEmail is the email of a google admin to impersonate. + type: string + google_service_account: + description: GoogleServiceAccount is a string containing google service + account credentials. + type: string + google_service_account_uri: + description: GoogleServiceAccountURI is a path to a google service + account uri. + type: string + issuer_url: + description: IssuerURL is the endpoint of the provider, e.g. https://accounts.google.com. + type: string + max_age: + description: MaxAge is the amount of time that user logins are valid + for. If a user logs in, but then does not login again within this + time period, they will be forced to re-authenticate. + format: duration + type: string + prompt: + description: Prompt is an optional OIDC prompt. An empty string omits + prompt. If not specified, it defaults to select_account for backwards + compatibility. + type: string + provider: + description: Provider is the external identity provider. + type: string + redirect_url: + description: RedirectURLs is a list of callback URLs which the identity + provider can use to redirect the client back to the Teleport Proxy + to complete authentication. This list should match the URLs on the + provider's side. The URL used for a given auth request will be chosen + to match the requesting Proxy's public address. If there is no match, + the first url in the list will be used. + items: + type: string + type: array + scope: + description: Scope specifies additional scopes set by provider. + items: + type: string + nullable: true + type: array + username_claim: + description: UsernameClaim specifies the name of the claim from the + OIDC connector to be used as the user's username. + type: string + type: object + status: + description: TeleportOIDCConnectorStatus defines the observed state of + TeleportOIDCConnector + properties: + conditions: + description: Conditions represent the latest available observations + of an object's state + items: + description: "Condition contains details for one aspect of the current + state of this API Resource. --- This struct is intended for direct + use as an array at the field path .status.conditions. For example, + \n type FooStatus struct{ // Represents the observations of a + foo's current state. // Known .status.conditions.type are: \"Available\", + \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge + // +listType=map // +listMapKey=type Conditions []metav1.Condition + `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" + protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition + transitioned from one status to another. This should be when + the underlying condition changed. If that is not known, then + using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating + details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation + that the condition was set based upon. For instance, if .metadata.generation + is currently 12, but the .status.conditions[x].observedGeneration + is 9, the condition is out of date with respect to the current + state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating + the reason for the condition's last transition. Producers + of specific condition types may define expected values and + meanings for this field, and whether the values are considered + a guaranteed API. The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + --- Many .condition.type values are consistent across resources + like Available, but because arbitrary conditions can be useful + (see .node.status.conditions), the ability to deconflict is + important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + teleportResourceID: + format: int64 + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null diff --git a/helm/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_oktaimportrules.yaml b/helm/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_oktaimportrules.yaml new file mode 100644 index 0000000..071d628 --- /dev/null +++ b/helm/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_oktaimportrules.yaml @@ -0,0 +1,183 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + creationTimestamp: null + name: teleportoktaimportrules.resources.teleport.dev +spec: + group: resources.teleport.dev + names: + kind: TeleportOktaImportRule + listKind: TeleportOktaImportRuleList + plural: teleportoktaimportrules + shortNames: + - oktaimportrule + - oktaimportrules + singular: teleportoktaimportrule + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + description: OktaImportRule is the Schema for the oktaimportrules 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: OktaImportRule resource definition v1 from Teleport + properties: + mappings: + description: Mappings is a list of matches that will map match conditions + to labels. + items: + properties: + add_labels: + description: AddLabels specifies which labels to add if any + of the previous matches match. + nullable: true + properties: + key: + type: string + value: + type: string + type: object + match: + description: Match is a set of matching rules for this mapping. + If any of these match, then the mapping will be applied. + items: + properties: + app_ids: + description: AppIDs is a list of app IDs to match against. + items: + type: string + nullable: true + type: array + app_name_regexes: + description: AppNameRegexes is a list of regexes to match + against app names. + items: + type: string + nullable: true + type: array + group_ids: + description: GroupIDs is a list of group IDs to match + against. + items: + type: string + nullable: true + type: array + group_name_regexes: + description: GroupNameRegexes is a list of regexes to + match against group names. + items: + type: string + nullable: true + type: array + type: object + nullable: true + type: array + type: object + nullable: true + type: array + priority: + description: Priority represents the priority of the rule application. + Lower numbered rules will be applied first. + format: int32 + type: integer + type: object + status: + properties: + conditions: + description: Conditions represent the latest available observations + of an object's state + items: + description: "Condition contains details for one aspect of the current + state of this API Resource. --- This struct is intended for direct + use as an array at the field path .status.conditions. For example, + \n type FooStatus struct{ // Represents the observations of a + foo's current state. // Known .status.conditions.type are: \"Available\", + \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge + // +listType=map // +listMapKey=type Conditions []metav1.Condition + `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" + protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition + transitioned from one status to another. This should be when + the underlying condition changed. If that is not known, then + using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating + details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation + that the condition was set based upon. For instance, if .metadata.generation + is currently 12, but the .status.conditions[x].observedGeneration + is 9, the condition is out of date with respect to the current + state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating + the reason for the condition's last transition. Producers + of specific condition types may define expected values and + meanings for this field, and whether the values are considered + a guaranteed API. The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + --- Many .condition.type values are consistent across resources + like Available, but because arbitrary conditions can be useful + (see .node.status.conditions), the ability to deconflict is + important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + teleportResourceID: + format: int64 + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null diff --git a/helm/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_provisiontokens.yaml b/helm/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_provisiontokens.yaml new file mode 100644 index 0000000..81c7d92 --- /dev/null +++ b/helm/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_provisiontokens.yaml @@ -0,0 +1,353 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + creationTimestamp: null + name: teleportprovisiontokens.resources.teleport.dev +spec: + group: resources.teleport.dev + names: + kind: TeleportProvisionToken + listKind: TeleportProvisionTokenList + plural: teleportprovisiontokens + shortNames: + - provisiontoken + - provisiontokens + singular: teleportprovisiontoken + scope: Namespaced + versions: + - name: v2 + schema: + openAPIV3Schema: + description: ProvisionToken is the Schema for the provisiontokens 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: ProvisionToken resource definition v2 from Teleport + properties: + allow: + description: Allow is a list of TokenRules, nodes using this token + must match one allow rule to use this token. + items: + properties: + aws_account: + description: AWSAccount is the AWS account ID. + type: string + aws_arn: + description: AWSARN is used for the IAM join method, the AWS + identity of joining nodes must match this ARN. Supports wildcards + "*" and "?". + type: string + aws_regions: + description: AWSRegions is used for the EC2 join method and + is a list of AWS regions a node is allowed to join from. + items: + type: string + nullable: true + type: array + aws_role: + description: AWSRole is used for the EC2 join method and is + the the ARN of the AWS role that the auth server will assume + in order to call the ec2 API. + type: string + type: object + nullable: true + type: array + aws_iid_ttl: + description: AWSIIDTTL is the TTL to use for AWS EC2 Instance Identity + Documents used to join the cluster with this token. + format: duration + type: string + azure: + description: Azure allows the configuration of options specific to + the "azure" join method. + nullable: true + properties: + allow: + description: Allow is a list of Rules, nodes using this token + must match one allow rule to use this token. + items: + properties: + resource_groups: + items: + type: string + nullable: true + type: array + subscription: + type: string + type: object + nullable: true + type: array + type: object + bot_name: + description: BotName is the name of the bot this token grants access + to, if any + type: string + circleci: + description: CircleCI allows the configuration of options specific + to the "circleci" join method. + nullable: true + properties: + allow: + description: Allow is a list of TokenRules, nodes using this token + must match one allow rule to use this token. + items: + properties: + context_id: + type: string + project_id: + type: string + type: object + nullable: true + type: array + organization_id: + type: string + type: object + gcp: + description: GCP allows the configuration of options specific to the + "gcp" join method. + nullable: true + properties: + allow: + description: Allow is a list of Rules, nodes using this token + must match one allow rule to use this token. + items: + properties: + locations: + items: + type: string + nullable: true + type: array + project_ids: + items: + type: string + nullable: true + type: array + service_accounts: + items: + type: string + nullable: true + type: array + type: object + nullable: true + type: array + type: object + github: + description: GitHub allows the configuration of options specific to + the "github" join method. + nullable: true + properties: + allow: + description: Allow is a list of TokenRules, nodes using this token + must match one allow rule to use this token. + items: + properties: + actor: + type: string + environment: + type: string + ref: + type: string + ref_type: + type: string + repository: + type: string + repository_owner: + type: string + sub: + type: string + workflow: + type: string + type: object + nullable: true + type: array + enterprise_server_host: + description: EnterpriseServerHost allows joining from runners + associated with a GitHub Enterprise Server instance. When unconfigured, + tokens will be validated against github.com, but when configured + to the host of a GHES instance, then the tokens will be validated + against host. This value should be the hostname of the GHES + instance, and should not include the scheme or a path. The instance + must be accessible over HTTPS at this hostname and the certificate + must be trusted by the Auth Server. + type: string + type: object + gitlab: + description: GitLab allows the configuration of options specific to + the "gitlab" join method. + nullable: true + properties: + allow: + description: Allow is a list of TokenRules, nodes using this token + must match one allow rule to use this token. + items: + properties: + environment: + type: string + namespace_path: + type: string + pipeline_source: + type: string + project_path: + type: string + ref: + type: string + ref_type: + type: string + sub: + type: string + type: object + nullable: true + type: array + domain: + description: Domain is the domain of your GitLab instance. This + will default to `gitlab.com` - but can be set to the domain + of your self-hosted GitLab e.g `gitlab.example.com`. + type: string + type: object + join_method: + description: JoinMethod is the joining method required in order to + use this token. Supported joining methods include "token", "ec2", + and "iam". + type: string + kubernetes: + description: Kubernetes allows the configuration of options specific + to the "kubernetes" join method. + nullable: true + properties: + allow: + description: Allow is a list of Rules, nodes using this token + must match one allow rule to use this token. + items: + properties: + service_account: + type: string + type: object + nullable: true + type: array + type: object + roles: + description: Roles is a list of roles associated with the token, that + will be converted to metadata in the SSH and X509 certificates issued + to the user of the token + items: + type: string + nullable: true + type: array + suggested_agent_matcher_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: SuggestedAgentMatcherLabels is a set of labels to be + used by agents to match on resources. When an agent uses this token, + the agent should monitor resources that match those labels. For + databases, this means adding the labels to `db_service.resources.labels`. + Currently, only node-join scripts create a configuration according + to the suggestion. + type: object + suggested_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: SuggestedLabels is a set of labels that resources should + set when using this token to enroll themselves in the cluster. Currently, + only node-join scripts create a configuration according to the suggestion. + type: object + type: object + status: + description: TeleportProvisionTokenStatus defines the observed state of + TeleportProvisionToken + properties: + conditions: + description: Conditions represent the latest available observations + of an object's state + items: + description: "Condition contains details for one aspect of the current + state of this API Resource. --- This struct is intended for direct + use as an array at the field path .status.conditions. For example, + \n type FooStatus struct{ // Represents the observations of a + foo's current state. // Known .status.conditions.type are: \"Available\", + \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge + // +listType=map // +listMapKey=type Conditions []metav1.Condition + `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" + protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition + transitioned from one status to another. This should be when + the underlying condition changed. If that is not known, then + using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating + details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation + that the condition was set based upon. For instance, if .metadata.generation + is currently 12, but the .status.conditions[x].observedGeneration + is 9, the condition is out of date with respect to the current + state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating + the reason for the condition's last transition. Producers + of specific condition types may define expected values and + meanings for this field, and whether the values are considered + a guaranteed API. The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + --- Many .condition.type values are consistent across resources + like Available, but because arbitrary conditions can be useful + (see .node.status.conditions), the ability to deconflict is + important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + teleportResourceID: + format: int64 + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null diff --git a/helm/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_roles.yaml b/helm/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_roles.yaml new file mode 100644 index 0000000..b305702 --- /dev/null +++ b/helm/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_roles.yaml @@ -0,0 +1,2386 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + creationTimestamp: null + name: teleportroles.resources.teleport.dev +spec: + group: resources.teleport.dev + names: + kind: TeleportRole + listKind: TeleportRoleList + plural: teleportroles + singular: teleportrole + scope: Namespaced + versions: + - name: v5 + schema: + openAPIV3Schema: + description: Role is the Schema for the roles 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: Role resource definition v5 from Teleport + properties: + allow: + description: Allow is the set of conditions evaluated to grant access. + properties: + app_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: AppLabels is a map of labels used as part of the + RBAC system. + type: object + app_labels_expression: + description: AppLabelsExpression is a predicate expression used + to allow/deny access to Apps. + type: string + aws_role_arns: + description: AWSRoleARNs is a list of AWS role ARNs this role + is allowed to assume. + items: + type: string + nullable: true + type: array + azure_identities: + description: AzureIdentities is a list of Azure identities this + role is allowed to assume. + items: + type: string + nullable: true + type: array + cluster_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: ClusterLabels is a map of node labels (used to dynamically + grant access to clusters). + type: object + cluster_labels_expression: + description: ClusterLabelsExpression is a predicate expression + used to allow/deny access to remote Teleport clusters. + type: string + db_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: DatabaseLabels are used in RBAC system to allow/deny + access to databases. + type: object + db_labels_expression: + description: DatabaseLabelsExpression is a predicate expression + used to allow/deny access to Databases. + type: string + db_names: + description: DatabaseNames is a list of database names this role + is allowed to connect to. + items: + type: string + nullable: true + type: array + db_roles: + description: DatabaseRoles is a list of databases roles for automatic + user creation. + items: + type: string + nullable: true + type: array + db_service_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: DatabaseServiceLabels are used in RBAC system to + allow/deny access to Database Services. + type: object + db_service_labels_expression: + description: DatabaseServiceLabelsExpression is a predicate expression + used to allow/deny access to Database Services. + type: string + db_users: + description: DatabaseUsers is a list of databases users this role + is allowed to connect as. + items: + type: string + nullable: true + type: array + desktop_groups: + description: DesktopGroups is a list of groups for created desktop + users to be added to + items: + type: string + nullable: true + type: array + gcp_service_accounts: + description: GCPServiceAccounts is a list of GCP service accounts + this role is allowed to assume. + items: + type: string + nullable: true + type: array + group_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: GroupLabels is a map of labels used as part of the + RBAC system. + type: object + group_labels_expression: + description: GroupLabelsExpression is a predicate expression used + to allow/deny access to user groups. + type: string + host_groups: + description: HostGroups is a list of groups for created users + to be added to + items: + type: string + nullable: true + type: array + host_sudoers: + description: HostSudoers is a list of entries to include in a + users sudoer file + items: + type: string + nullable: true + type: array + impersonate: + description: Impersonate specifies what users and roles this role + is allowed to impersonate by issuing certificates or other possible + means. + nullable: true + properties: + roles: + description: Roles is a list of resources this role is allowed + to impersonate + items: + type: string + nullable: true + type: array + users: + description: Users is a list of resources this role is allowed + to impersonate, could be an empty list or a Wildcard pattern + items: + type: string + nullable: true + type: array + where: + description: Where specifies optional advanced matcher + type: string + type: object + join_sessions: + description: JoinSessions specifies policies to allow users to + join other sessions. + items: + properties: + kinds: + description: Kinds are the session kinds this policy applies + to. + items: + type: string + nullable: true + type: array + modes: + description: Modes is a list of permitted participant modes + for this policy. + items: + type: string + nullable: true + type: array + name: + description: Name is the name of the policy. + type: string + roles: + description: Roles is a list of roles that you can join + the session of. + items: + type: string + nullable: true + type: array + type: object + nullable: true + type: array + kubernetes_groups: + description: KubeGroups is a list of kubernetes groups + items: + type: string + nullable: true + type: array + kubernetes_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: KubernetesLabels is a map of kubernetes cluster labels + used for RBAC. + type: object + kubernetes_labels_expression: + description: KubernetesLabelsExpression is a predicate expression + used to allow/deny access to kubernetes clusters. + type: string + kubernetes_resources: + description: KubernetesResources is the Kubernetes Resources this + Role grants access to. + items: + properties: + kind: + description: Kind specifies the Kubernetes Resource type. + At the moment only "pod" is supported. + type: string + name: + description: Name is the resource name. It supports wildcards. + type: string + namespace: + description: Namespace is the resource namespace. It supports + wildcards. + type: string + type: object + type: array + kubernetes_users: + description: KubeUsers is an optional kubernetes users to impersonate + items: + type: string + nullable: true + type: array + logins: + description: Logins is a list of *nix system logins. + items: + type: string + nullable: true + type: array + node_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: NodeLabels is a map of node labels (used to dynamically + grant access to nodes). + type: object + node_labels_expression: + description: NodeLabelsExpression is a predicate expression used + to allow/deny access to SSH nodes. + type: string + request: + nullable: true + properties: + annotations: + additionalProperties: + items: + type: string + type: array + description: Annotations is a collection of annotations to + be programmatically appended to pending access requests + at the time of their creation. These annotations serve as + a mechanism to propagate extra information to plugins. Since + these annotations support variable interpolation syntax, + they also offer a mechanism for forwarding claims from an + external identity provider, to a plugin via {{ `{{external.trait_name}}` }} + style substitutions. + type: object + claims_to_roles: + description: ClaimsToRoles specifies a mapping from claims + (traits) to teleport roles. + items: + properties: + claim: + description: Claim is a claim name. + type: string + roles: + description: Roles is a list of static teleport roles + to match. + items: + type: string + nullable: true + type: array + value: + description: Value is a claim value to match. + type: string + type: object + type: array + max_duration: + description: MaxDuration is the amount of time the access + will be granted for. If this is zero, the default duration + is used. + format: duration + type: string + roles: + description: Roles is the name of roles which will match the + request rule. + items: + type: string + nullable: true + type: array + search_as_roles: + description: SearchAsRoles is a list of extra roles which + should apply to a user while they are searching for resources + as part of a Resource Access Request, and defines the underlying + roles which will be requested as part of any Resource Access + Request. + items: + type: string + nullable: true + type: array + suggested_reviewers: + description: SuggestedReviewers is a list of reviewer suggestions. These + can be teleport usernames, but that is not a requirement. + items: + type: string + nullable: true + type: array + thresholds: + description: Thresholds is a list of thresholds, one of which + must be met in order for reviews to trigger a state-transition. If + no thresholds are provided, a default threshold of 1 for + approval and denial is used. + items: + properties: + approve: + description: Approve is the number of matching approvals + needed for state-transition. + format: int32 + type: integer + deny: + description: Deny is the number of denials needed for + state-transition. + format: int32 + type: integer + filter: + description: Filter is an optional predicate used to + determine which reviews count toward this threshold. + type: string + name: + description: Name is the optional human-readable name + of the threshold. + type: string + type: object + type: array + type: object + require_session_join: + description: RequireSessionJoin specifies policies for required + users to start a session. + items: + properties: + count: + description: Count is the amount of people that need to + be matched for this policy to be fulfilled. + format: int32 + type: integer + filter: + description: Filter is a predicate that determines what + users count towards this policy. + type: string + kinds: + description: Kinds are the session kinds this policy applies + to. + items: + type: string + nullable: true + type: array + modes: + description: Modes is the list of modes that may be used + to fulfill this policy. + items: + type: string + nullable: true + type: array + name: + description: Name is the name of the policy. + type: string + on_leave: + description: OnLeave is the behaviour that's used when the + policy is no longer fulfilled for a live session. + type: string + type: object + nullable: true + type: array + review_requests: + description: ReviewRequests defines conditions for submitting + access reviews. + nullable: true + properties: + claims_to_roles: + description: ClaimsToRoles specifies a mapping from claims + (traits) to teleport roles. + items: + properties: + claim: + description: Claim is a claim name. + type: string + roles: + description: Roles is a list of static teleport roles + to match. + items: + type: string + nullable: true + type: array + value: + description: Value is a claim value to match. + type: string + type: object + type: array + preview_as_roles: + description: PreviewAsRoles is a list of extra roles which + should apply to a reviewer while they are viewing a Resource + Access Request for the purposes of viewing details such + as the hostname and labels of requested resources. + items: + type: string + nullable: true + type: array + roles: + description: Roles is the name of roles which may be reviewed. + items: + type: string + nullable: true + type: array + where: + description: Where is an optional predicate which further + limits which requests are reviewable. + type: string + type: object + rules: + description: Rules is a list of rules and their access levels. + Rules are a high level construct used for access control. + items: + properties: + actions: + description: Actions specifies optional actions taken when + this rule matches + items: + type: string + nullable: true + type: array + resources: + description: Resources is a list of resources + items: + type: string + nullable: true + type: array + verbs: + description: Verbs is a list of verbs + items: + type: string + nullable: true + type: array + where: + description: Where specifies optional advanced matcher + type: string + type: object + type: array + windows_desktop_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: WindowsDesktopLabels are used in the RBAC system + to allow/deny access to Windows desktops. + type: object + windows_desktop_labels_expression: + description: WindowsDesktopLabelsExpression is a predicate expression + used to allow/deny access to Windows desktops. + type: string + windows_desktop_logins: + description: WindowsDesktopLogins is a list of desktop login names + allowed/denied for Windows desktops. + items: + type: string + nullable: true + type: array + type: object + deny: + description: Deny is the set of conditions evaluated to deny access. + Deny takes priority over allow. + properties: + app_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: AppLabels is a map of labels used as part of the + RBAC system. + type: object + app_labels_expression: + description: AppLabelsExpression is a predicate expression used + to allow/deny access to Apps. + type: string + aws_role_arns: + description: AWSRoleARNs is a list of AWS role ARNs this role + is allowed to assume. + items: + type: string + nullable: true + type: array + azure_identities: + description: AzureIdentities is a list of Azure identities this + role is allowed to assume. + items: + type: string + nullable: true + type: array + cluster_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: ClusterLabels is a map of node labels (used to dynamically + grant access to clusters). + type: object + cluster_labels_expression: + description: ClusterLabelsExpression is a predicate expression + used to allow/deny access to remote Teleport clusters. + type: string + db_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: DatabaseLabels are used in RBAC system to allow/deny + access to databases. + type: object + db_labels_expression: + description: DatabaseLabelsExpression is a predicate expression + used to allow/deny access to Databases. + type: string + db_names: + description: DatabaseNames is a list of database names this role + is allowed to connect to. + items: + type: string + nullable: true + type: array + db_roles: + description: DatabaseRoles is a list of databases roles for automatic + user creation. + items: + type: string + nullable: true + type: array + db_service_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: DatabaseServiceLabels are used in RBAC system to + allow/deny access to Database Services. + type: object + db_service_labels_expression: + description: DatabaseServiceLabelsExpression is a predicate expression + used to allow/deny access to Database Services. + type: string + db_users: + description: DatabaseUsers is a list of databases users this role + is allowed to connect as. + items: + type: string + nullable: true + type: array + desktop_groups: + description: DesktopGroups is a list of groups for created desktop + users to be added to + items: + type: string + nullable: true + type: array + gcp_service_accounts: + description: GCPServiceAccounts is a list of GCP service accounts + this role is allowed to assume. + items: + type: string + nullable: true + type: array + group_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: GroupLabels is a map of labels used as part of the + RBAC system. + type: object + group_labels_expression: + description: GroupLabelsExpression is a predicate expression used + to allow/deny access to user groups. + type: string + host_groups: + description: HostGroups is a list of groups for created users + to be added to + items: + type: string + nullable: true + type: array + host_sudoers: + description: HostSudoers is a list of entries to include in a + users sudoer file + items: + type: string + nullable: true + type: array + impersonate: + description: Impersonate specifies what users and roles this role + is allowed to impersonate by issuing certificates or other possible + means. + nullable: true + properties: + roles: + description: Roles is a list of resources this role is allowed + to impersonate + items: + type: string + nullable: true + type: array + users: + description: Users is a list of resources this role is allowed + to impersonate, could be an empty list or a Wildcard pattern + items: + type: string + nullable: true + type: array + where: + description: Where specifies optional advanced matcher + type: string + type: object + join_sessions: + description: JoinSessions specifies policies to allow users to + join other sessions. + items: + properties: + kinds: + description: Kinds are the session kinds this policy applies + to. + items: + type: string + nullable: true + type: array + modes: + description: Modes is a list of permitted participant modes + for this policy. + items: + type: string + nullable: true + type: array + name: + description: Name is the name of the policy. + type: string + roles: + description: Roles is a list of roles that you can join + the session of. + items: + type: string + nullable: true + type: array + type: object + nullable: true + type: array + kubernetes_groups: + description: KubeGroups is a list of kubernetes groups + items: + type: string + nullable: true + type: array + kubernetes_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: KubernetesLabels is a map of kubernetes cluster labels + used for RBAC. + type: object + kubernetes_labels_expression: + description: KubernetesLabelsExpression is a predicate expression + used to allow/deny access to kubernetes clusters. + type: string + kubernetes_resources: + description: KubernetesResources is the Kubernetes Resources this + Role grants access to. + items: + properties: + kind: + description: Kind specifies the Kubernetes Resource type. + At the moment only "pod" is supported. + type: string + name: + description: Name is the resource name. It supports wildcards. + type: string + namespace: + description: Namespace is the resource namespace. It supports + wildcards. + type: string + type: object + type: array + kubernetes_users: + description: KubeUsers is an optional kubernetes users to impersonate + items: + type: string + nullable: true + type: array + logins: + description: Logins is a list of *nix system logins. + items: + type: string + nullable: true + type: array + node_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: NodeLabels is a map of node labels (used to dynamically + grant access to nodes). + type: object + node_labels_expression: + description: NodeLabelsExpression is a predicate expression used + to allow/deny access to SSH nodes. + type: string + request: + nullable: true + properties: + annotations: + additionalProperties: + items: + type: string + type: array + description: Annotations is a collection of annotations to + be programmatically appended to pending access requests + at the time of their creation. These annotations serve as + a mechanism to propagate extra information to plugins. Since + these annotations support variable interpolation syntax, + they also offer a mechanism for forwarding claims from an + external identity provider, to a plugin via {{ `{{external.trait_name}}` }} + style substitutions. + type: object + claims_to_roles: + description: ClaimsToRoles specifies a mapping from claims + (traits) to teleport roles. + items: + properties: + claim: + description: Claim is a claim name. + type: string + roles: + description: Roles is a list of static teleport roles + to match. + items: + type: string + nullable: true + type: array + value: + description: Value is a claim value to match. + type: string + type: object + type: array + max_duration: + description: MaxDuration is the amount of time the access + will be granted for. If this is zero, the default duration + is used. + format: duration + type: string + roles: + description: Roles is the name of roles which will match the + request rule. + items: + type: string + nullable: true + type: array + search_as_roles: + description: SearchAsRoles is a list of extra roles which + should apply to a user while they are searching for resources + as part of a Resource Access Request, and defines the underlying + roles which will be requested as part of any Resource Access + Request. + items: + type: string + nullable: true + type: array + suggested_reviewers: + description: SuggestedReviewers is a list of reviewer suggestions. These + can be teleport usernames, but that is not a requirement. + items: + type: string + nullable: true + type: array + thresholds: + description: Thresholds is a list of thresholds, one of which + must be met in order for reviews to trigger a state-transition. If + no thresholds are provided, a default threshold of 1 for + approval and denial is used. + items: + properties: + approve: + description: Approve is the number of matching approvals + needed for state-transition. + format: int32 + type: integer + deny: + description: Deny is the number of denials needed for + state-transition. + format: int32 + type: integer + filter: + description: Filter is an optional predicate used to + determine which reviews count toward this threshold. + type: string + name: + description: Name is the optional human-readable name + of the threshold. + type: string + type: object + type: array + type: object + require_session_join: + description: RequireSessionJoin specifies policies for required + users to start a session. + items: + properties: + count: + description: Count is the amount of people that need to + be matched for this policy to be fulfilled. + format: int32 + type: integer + filter: + description: Filter is a predicate that determines what + users count towards this policy. + type: string + kinds: + description: Kinds are the session kinds this policy applies + to. + items: + type: string + nullable: true + type: array + modes: + description: Modes is the list of modes that may be used + to fulfill this policy. + items: + type: string + nullable: true + type: array + name: + description: Name is the name of the policy. + type: string + on_leave: + description: OnLeave is the behaviour that's used when the + policy is no longer fulfilled for a live session. + type: string + type: object + nullable: true + type: array + review_requests: + description: ReviewRequests defines conditions for submitting + access reviews. + nullable: true + properties: + claims_to_roles: + description: ClaimsToRoles specifies a mapping from claims + (traits) to teleport roles. + items: + properties: + claim: + description: Claim is a claim name. + type: string + roles: + description: Roles is a list of static teleport roles + to match. + items: + type: string + nullable: true + type: array + value: + description: Value is a claim value to match. + type: string + type: object + type: array + preview_as_roles: + description: PreviewAsRoles is a list of extra roles which + should apply to a reviewer while they are viewing a Resource + Access Request for the purposes of viewing details such + as the hostname and labels of requested resources. + items: + type: string + nullable: true + type: array + roles: + description: Roles is the name of roles which may be reviewed. + items: + type: string + nullable: true + type: array + where: + description: Where is an optional predicate which further + limits which requests are reviewable. + type: string + type: object + rules: + description: Rules is a list of rules and their access levels. + Rules are a high level construct used for access control. + items: + properties: + actions: + description: Actions specifies optional actions taken when + this rule matches + items: + type: string + nullable: true + type: array + resources: + description: Resources is a list of resources + items: + type: string + nullable: true + type: array + verbs: + description: Verbs is a list of verbs + items: + type: string + nullable: true + type: array + where: + description: Where specifies optional advanced matcher + type: string + type: object + type: array + windows_desktop_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: WindowsDesktopLabels are used in the RBAC system + to allow/deny access to Windows desktops. + type: object + windows_desktop_labels_expression: + description: WindowsDesktopLabelsExpression is a predicate expression + used to allow/deny access to Windows desktops. + type: string + windows_desktop_logins: + description: WindowsDesktopLogins is a list of desktop login names + allowed/denied for Windows desktops. + items: + type: string + nullable: true + type: array + type: object + options: + description: Options is for OpenSSH options like agent forwarding. + properties: + cert_extensions: + description: CertExtensions specifies the key/values + items: + properties: + mode: + description: Mode is the type of extension to be used -- + currently critical-option is not supported + format: int32 + type: integer + name: + description: Name specifies the key to be used in the cert + extension. + type: string + type: + description: Type represents the certificate type being + extended, only ssh is supported at this time. + format: int32 + type: integer + value: + description: Value specifies the value to be used in the + cert extension. + type: string + type: object + nullable: true + type: array + cert_format: + description: CertificateFormat defines the format of the user + certificate to allow compatibility with older versions of OpenSSH. + type: string + client_idle_timeout: + description: ClientIdleTimeout sets disconnect clients on idle + timeout behavior, if set to 0 means do not disconnect, otherwise + is set to the idle duration. + format: duration + type: string + create_db_user: + description: CreateDatabaseUser enabled automatic database user + creation. + type: boolean + create_desktop_user: + description: CreateDesktopUser allows users to be automatically + created on a Windows desktop + type: boolean + create_host_user: + description: CreateHostUser allows users to be automatically created + on a host + type: boolean + create_host_user_mode: + description: CreateHostUserMode allows users to be automatically + created on a host when not set to off + format: int32 + type: integer + desktop_clipboard: + description: DesktopClipboard indicates whether clipboard sharing + is allowed between the user's workstation and the remote desktop. + It defaults to true unless explicitly set to false. + type: boolean + desktop_directory_sharing: + description: DesktopDirectorySharing indicates whether directory + sharing is allowed between the user's workstation and the remote + desktop. It defaults to false unless explicitly set to true. + type: boolean + device_trust_mode: + description: DeviceTrustMode is the device authorization mode + used for the resources associated with the role. See DeviceTrust.Mode. + Reserved for future use, not yet used by Teleport. + type: string + disconnect_expired_cert: + description: DisconnectExpiredCert sets disconnect clients on + expired certificates. + type: boolean + enhanced_recording: + description: BPF defines what events to record for the BPF-based + session recorder. + items: + type: string + nullable: true + type: array + forward_agent: + description: ForwardAgent is SSH agent forwarding. + type: boolean + idp: + description: IDP is a set of options related to accessing IdPs + within Teleport. Requires Teleport Enterprise. + nullable: true + properties: + saml: + description: SAML are options related to the Teleport SAML + IdP. + nullable: true + properties: + enabled: + description: Enabled is set to true if this option allows + access to the Teleport SAML IdP. + type: boolean + type: object + type: object + lock: + description: Lock specifies the locking mode (strict|best_effort) + to be applied with the role. + type: string + max_connections: + description: MaxConnections defines the maximum number of concurrent + connections a user may hold. + format: int64 + type: integer + max_kubernetes_connections: + description: MaxKubernetesConnections defines the maximum number + of concurrent Kubernetes sessions a user may hold. + format: int64 + type: integer + max_session_ttl: + description: MaxSessionTTL defines how long a SSH session can + last for. + format: duration + type: string + max_sessions: + description: MaxSessions defines the maximum number of concurrent + sessions per connection. + format: int64 + type: integer + permit_x11_forwarding: + description: PermitX11Forwarding authorizes use of X11 forwarding. + type: boolean + pin_source_ip: + description: PinSourceIP forces the same client IP for certificate + generation and usage + type: boolean + port_forwarding: + description: PortForwarding defines if the certificate will have + "permit-port-forwarding" in the certificate. PortForwarding + is "yes" if not set, that's why this is a pointer + type: boolean + record_session: + description: RecordDesktopSession indicates whether desktop access + sessions should be recorded. It defaults to true unless explicitly + set to false. + nullable: true + properties: + default: + description: Default indicates the default value for the services. + type: string + desktop: + description: Desktop indicates whether desktop sessions should + be recorded. It defaults to true unless explicitly set to + false. + type: boolean + ssh: + description: SSH indicates the session mode used on SSH sessions. + type: string + type: object + request_access: + description: RequestAccess defines the access request strategy + (optional|note|always) where optional is the default. + type: string + request_prompt: + description: RequestPrompt is an optional message which tells + users what they aught to + type: string + require_session_mfa: + description: RequireMFAType is the type of MFA requirement enforced + for this user. + format: int32 + type: integer + ssh_file_copy: + description: SSHFileCopy indicates whether remote file operations + via SCP or SFTP are allowed over an SSH session. It defaults + to true unless explicitly set to false. + type: boolean + type: object + type: object + status: + description: TeleportRoleStatus defines the observed state of TeleportRole + properties: + conditions: + description: Conditions represent the latest available observations + of an object's state + items: + description: "Condition contains details for one aspect of the current + state of this API Resource. --- This struct is intended for direct + use as an array at the field path .status.conditions. For example, + \n type FooStatus struct{ // Represents the observations of a + foo's current state. // Known .status.conditions.type are: \"Available\", + \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge + // +listType=map // +listMapKey=type Conditions []metav1.Condition + `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" + protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition + transitioned from one status to another. This should be when + the underlying condition changed. If that is not known, then + using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating + details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation + that the condition was set based upon. For instance, if .metadata.generation + is currently 12, but the .status.conditions[x].observedGeneration + is 9, the condition is out of date with respect to the current + state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating + the reason for the condition's last transition. Producers + of specific condition types may define expected values and + meanings for this field, and whether the values are considered + a guaranteed API. The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + --- Many .condition.type values are consistent across resources + like Available, but because arbitrary conditions can be useful + (see .node.status.conditions), the ability to deconflict is + important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + teleportResourceID: + format: int64 + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} + - name: v6 + schema: + openAPIV3Schema: + description: Role is the Schema for the roles 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: Role resource definition v6 from Teleport + properties: + allow: + description: Allow is the set of conditions evaluated to grant access. + properties: + app_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: AppLabels is a map of labels used as part of the + RBAC system. + type: object + app_labels_expression: + description: AppLabelsExpression is a predicate expression used + to allow/deny access to Apps. + type: string + aws_role_arns: + description: AWSRoleARNs is a list of AWS role ARNs this role + is allowed to assume. + items: + type: string + nullable: true + type: array + azure_identities: + description: AzureIdentities is a list of Azure identities this + role is allowed to assume. + items: + type: string + nullable: true + type: array + cluster_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: ClusterLabels is a map of node labels (used to dynamically + grant access to clusters). + type: object + cluster_labels_expression: + description: ClusterLabelsExpression is a predicate expression + used to allow/deny access to remote Teleport clusters. + type: string + db_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: DatabaseLabels are used in RBAC system to allow/deny + access to databases. + type: object + db_labels_expression: + description: DatabaseLabelsExpression is a predicate expression + used to allow/deny access to Databases. + type: string + db_names: + description: DatabaseNames is a list of database names this role + is allowed to connect to. + items: + type: string + nullable: true + type: array + db_roles: + description: DatabaseRoles is a list of databases roles for automatic + user creation. + items: + type: string + nullable: true + type: array + db_service_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: DatabaseServiceLabels are used in RBAC system to + allow/deny access to Database Services. + type: object + db_service_labels_expression: + description: DatabaseServiceLabelsExpression is a predicate expression + used to allow/deny access to Database Services. + type: string + db_users: + description: DatabaseUsers is a list of databases users this role + is allowed to connect as. + items: + type: string + nullable: true + type: array + desktop_groups: + description: DesktopGroups is a list of groups for created desktop + users to be added to + items: + type: string + nullable: true + type: array + gcp_service_accounts: + description: GCPServiceAccounts is a list of GCP service accounts + this role is allowed to assume. + items: + type: string + nullable: true + type: array + group_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: GroupLabels is a map of labels used as part of the + RBAC system. + type: object + group_labels_expression: + description: GroupLabelsExpression is a predicate expression used + to allow/deny access to user groups. + type: string + host_groups: + description: HostGroups is a list of groups for created users + to be added to + items: + type: string + nullable: true + type: array + host_sudoers: + description: HostSudoers is a list of entries to include in a + users sudoer file + items: + type: string + nullable: true + type: array + impersonate: + description: Impersonate specifies what users and roles this role + is allowed to impersonate by issuing certificates or other possible + means. + nullable: true + properties: + roles: + description: Roles is a list of resources this role is allowed + to impersonate + items: + type: string + nullable: true + type: array + users: + description: Users is a list of resources this role is allowed + to impersonate, could be an empty list or a Wildcard pattern + items: + type: string + nullable: true + type: array + where: + description: Where specifies optional advanced matcher + type: string + type: object + join_sessions: + description: JoinSessions specifies policies to allow users to + join other sessions. + items: + properties: + kinds: + description: Kinds are the session kinds this policy applies + to. + items: + type: string + nullable: true + type: array + modes: + description: Modes is a list of permitted participant modes + for this policy. + items: + type: string + nullable: true + type: array + name: + description: Name is the name of the policy. + type: string + roles: + description: Roles is a list of roles that you can join + the session of. + items: + type: string + nullable: true + type: array + type: object + nullable: true + type: array + kubernetes_groups: + description: KubeGroups is a list of kubernetes groups + items: + type: string + nullable: true + type: array + kubernetes_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: KubernetesLabels is a map of kubernetes cluster labels + used for RBAC. + type: object + kubernetes_labels_expression: + description: KubernetesLabelsExpression is a predicate expression + used to allow/deny access to kubernetes clusters. + type: string + kubernetes_resources: + description: KubernetesResources is the Kubernetes Resources this + Role grants access to. + items: + properties: + kind: + description: Kind specifies the Kubernetes Resource type. + At the moment only "pod" is supported. + type: string + name: + description: Name is the resource name. It supports wildcards. + type: string + namespace: + description: Namespace is the resource namespace. It supports + wildcards. + type: string + type: object + type: array + kubernetes_users: + description: KubeUsers is an optional kubernetes users to impersonate + items: + type: string + nullable: true + type: array + logins: + description: Logins is a list of *nix system logins. + items: + type: string + nullable: true + type: array + node_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: NodeLabels is a map of node labels (used to dynamically + grant access to nodes). + type: object + node_labels_expression: + description: NodeLabelsExpression is a predicate expression used + to allow/deny access to SSH nodes. + type: string + request: + nullable: true + properties: + annotations: + additionalProperties: + items: + type: string + type: array + description: Annotations is a collection of annotations to + be programmatically appended to pending access requests + at the time of their creation. These annotations serve as + a mechanism to propagate extra information to plugins. Since + these annotations support variable interpolation syntax, + they also offer a mechanism for forwarding claims from an + external identity provider, to a plugin via {{ `{{external.trait_name}}` }} + style substitutions. + type: object + claims_to_roles: + description: ClaimsToRoles specifies a mapping from claims + (traits) to teleport roles. + items: + properties: + claim: + description: Claim is a claim name. + type: string + roles: + description: Roles is a list of static teleport roles + to match. + items: + type: string + nullable: true + type: array + value: + description: Value is a claim value to match. + type: string + type: object + type: array + max_duration: + description: MaxDuration is the amount of time the access + will be granted for. If this is zero, the default duration + is used. + format: duration + type: string + roles: + description: Roles is the name of roles which will match the + request rule. + items: + type: string + nullable: true + type: array + search_as_roles: + description: SearchAsRoles is a list of extra roles which + should apply to a user while they are searching for resources + as part of a Resource Access Request, and defines the underlying + roles which will be requested as part of any Resource Access + Request. + items: + type: string + nullable: true + type: array + suggested_reviewers: + description: SuggestedReviewers is a list of reviewer suggestions. These + can be teleport usernames, but that is not a requirement. + items: + type: string + nullable: true + type: array + thresholds: + description: Thresholds is a list of thresholds, one of which + must be met in order for reviews to trigger a state-transition. If + no thresholds are provided, a default threshold of 1 for + approval and denial is used. + items: + properties: + approve: + description: Approve is the number of matching approvals + needed for state-transition. + format: int32 + type: integer + deny: + description: Deny is the number of denials needed for + state-transition. + format: int32 + type: integer + filter: + description: Filter is an optional predicate used to + determine which reviews count toward this threshold. + type: string + name: + description: Name is the optional human-readable name + of the threshold. + type: string + type: object + type: array + type: object + require_session_join: + description: RequireSessionJoin specifies policies for required + users to start a session. + items: + properties: + count: + description: Count is the amount of people that need to + be matched for this policy to be fulfilled. + format: int32 + type: integer + filter: + description: Filter is a predicate that determines what + users count towards this policy. + type: string + kinds: + description: Kinds are the session kinds this policy applies + to. + items: + type: string + nullable: true + type: array + modes: + description: Modes is the list of modes that may be used + to fulfill this policy. + items: + type: string + nullable: true + type: array + name: + description: Name is the name of the policy. + type: string + on_leave: + description: OnLeave is the behaviour that's used when the + policy is no longer fulfilled for a live session. + type: string + type: object + nullable: true + type: array + review_requests: + description: ReviewRequests defines conditions for submitting + access reviews. + nullable: true + properties: + claims_to_roles: + description: ClaimsToRoles specifies a mapping from claims + (traits) to teleport roles. + items: + properties: + claim: + description: Claim is a claim name. + type: string + roles: + description: Roles is a list of static teleport roles + to match. + items: + type: string + nullable: true + type: array + value: + description: Value is a claim value to match. + type: string + type: object + type: array + preview_as_roles: + description: PreviewAsRoles is a list of extra roles which + should apply to a reviewer while they are viewing a Resource + Access Request for the purposes of viewing details such + as the hostname and labels of requested resources. + items: + type: string + nullable: true + type: array + roles: + description: Roles is the name of roles which may be reviewed. + items: + type: string + nullable: true + type: array + where: + description: Where is an optional predicate which further + limits which requests are reviewable. + type: string + type: object + rules: + description: Rules is a list of rules and their access levels. + Rules are a high level construct used for access control. + items: + properties: + actions: + description: Actions specifies optional actions taken when + this rule matches + items: + type: string + nullable: true + type: array + resources: + description: Resources is a list of resources + items: + type: string + nullable: true + type: array + verbs: + description: Verbs is a list of verbs + items: + type: string + nullable: true + type: array + where: + description: Where specifies optional advanced matcher + type: string + type: object + type: array + windows_desktop_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: WindowsDesktopLabels are used in the RBAC system + to allow/deny access to Windows desktops. + type: object + windows_desktop_labels_expression: + description: WindowsDesktopLabelsExpression is a predicate expression + used to allow/deny access to Windows desktops. + type: string + windows_desktop_logins: + description: WindowsDesktopLogins is a list of desktop login names + allowed/denied for Windows desktops. + items: + type: string + nullable: true + type: array + type: object + deny: + description: Deny is the set of conditions evaluated to deny access. + Deny takes priority over allow. + properties: + app_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: AppLabels is a map of labels used as part of the + RBAC system. + type: object + app_labels_expression: + description: AppLabelsExpression is a predicate expression used + to allow/deny access to Apps. + type: string + aws_role_arns: + description: AWSRoleARNs is a list of AWS role ARNs this role + is allowed to assume. + items: + type: string + nullable: true + type: array + azure_identities: + description: AzureIdentities is a list of Azure identities this + role is allowed to assume. + items: + type: string + nullable: true + type: array + cluster_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: ClusterLabels is a map of node labels (used to dynamically + grant access to clusters). + type: object + cluster_labels_expression: + description: ClusterLabelsExpression is a predicate expression + used to allow/deny access to remote Teleport clusters. + type: string + db_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: DatabaseLabels are used in RBAC system to allow/deny + access to databases. + type: object + db_labels_expression: + description: DatabaseLabelsExpression is a predicate expression + used to allow/deny access to Databases. + type: string + db_names: + description: DatabaseNames is a list of database names this role + is allowed to connect to. + items: + type: string + nullable: true + type: array + db_roles: + description: DatabaseRoles is a list of databases roles for automatic + user creation. + items: + type: string + nullable: true + type: array + db_service_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: DatabaseServiceLabels are used in RBAC system to + allow/deny access to Database Services. + type: object + db_service_labels_expression: + description: DatabaseServiceLabelsExpression is a predicate expression + used to allow/deny access to Database Services. + type: string + db_users: + description: DatabaseUsers is a list of databases users this role + is allowed to connect as. + items: + type: string + nullable: true + type: array + desktop_groups: + description: DesktopGroups is a list of groups for created desktop + users to be added to + items: + type: string + nullable: true + type: array + gcp_service_accounts: + description: GCPServiceAccounts is a list of GCP service accounts + this role is allowed to assume. + items: + type: string + nullable: true + type: array + group_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: GroupLabels is a map of labels used as part of the + RBAC system. + type: object + group_labels_expression: + description: GroupLabelsExpression is a predicate expression used + to allow/deny access to user groups. + type: string + host_groups: + description: HostGroups is a list of groups for created users + to be added to + items: + type: string + nullable: true + type: array + host_sudoers: + description: HostSudoers is a list of entries to include in a + users sudoer file + items: + type: string + nullable: true + type: array + impersonate: + description: Impersonate specifies what users and roles this role + is allowed to impersonate by issuing certificates or other possible + means. + nullable: true + properties: + roles: + description: Roles is a list of resources this role is allowed + to impersonate + items: + type: string + nullable: true + type: array + users: + description: Users is a list of resources this role is allowed + to impersonate, could be an empty list or a Wildcard pattern + items: + type: string + nullable: true + type: array + where: + description: Where specifies optional advanced matcher + type: string + type: object + join_sessions: + description: JoinSessions specifies policies to allow users to + join other sessions. + items: + properties: + kinds: + description: Kinds are the session kinds this policy applies + to. + items: + type: string + nullable: true + type: array + modes: + description: Modes is a list of permitted participant modes + for this policy. + items: + type: string + nullable: true + type: array + name: + description: Name is the name of the policy. + type: string + roles: + description: Roles is a list of roles that you can join + the session of. + items: + type: string + nullable: true + type: array + type: object + nullable: true + type: array + kubernetes_groups: + description: KubeGroups is a list of kubernetes groups + items: + type: string + nullable: true + type: array + kubernetes_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: KubernetesLabels is a map of kubernetes cluster labels + used for RBAC. + type: object + kubernetes_labels_expression: + description: KubernetesLabelsExpression is a predicate expression + used to allow/deny access to kubernetes clusters. + type: string + kubernetes_resources: + description: KubernetesResources is the Kubernetes Resources this + Role grants access to. + items: + properties: + kind: + description: Kind specifies the Kubernetes Resource type. + At the moment only "pod" is supported. + type: string + name: + description: Name is the resource name. It supports wildcards. + type: string + namespace: + description: Namespace is the resource namespace. It supports + wildcards. + type: string + type: object + type: array + kubernetes_users: + description: KubeUsers is an optional kubernetes users to impersonate + items: + type: string + nullable: true + type: array + logins: + description: Logins is a list of *nix system logins. + items: + type: string + nullable: true + type: array + node_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: NodeLabels is a map of node labels (used to dynamically + grant access to nodes). + type: object + node_labels_expression: + description: NodeLabelsExpression is a predicate expression used + to allow/deny access to SSH nodes. + type: string + request: + nullable: true + properties: + annotations: + additionalProperties: + items: + type: string + type: array + description: Annotations is a collection of annotations to + be programmatically appended to pending access requests + at the time of their creation. These annotations serve as + a mechanism to propagate extra information to plugins. Since + these annotations support variable interpolation syntax, + they also offer a mechanism for forwarding claims from an + external identity provider, to a plugin via {{ `{{external.trait_name}}` }} + style substitutions. + type: object + claims_to_roles: + description: ClaimsToRoles specifies a mapping from claims + (traits) to teleport roles. + items: + properties: + claim: + description: Claim is a claim name. + type: string + roles: + description: Roles is a list of static teleport roles + to match. + items: + type: string + nullable: true + type: array + value: + description: Value is a claim value to match. + type: string + type: object + type: array + max_duration: + description: MaxDuration is the amount of time the access + will be granted for. If this is zero, the default duration + is used. + format: duration + type: string + roles: + description: Roles is the name of roles which will match the + request rule. + items: + type: string + nullable: true + type: array + search_as_roles: + description: SearchAsRoles is a list of extra roles which + should apply to a user while they are searching for resources + as part of a Resource Access Request, and defines the underlying + roles which will be requested as part of any Resource Access + Request. + items: + type: string + nullable: true + type: array + suggested_reviewers: + description: SuggestedReviewers is a list of reviewer suggestions. These + can be teleport usernames, but that is not a requirement. + items: + type: string + nullable: true + type: array + thresholds: + description: Thresholds is a list of thresholds, one of which + must be met in order for reviews to trigger a state-transition. If + no thresholds are provided, a default threshold of 1 for + approval and denial is used. + items: + properties: + approve: + description: Approve is the number of matching approvals + needed for state-transition. + format: int32 + type: integer + deny: + description: Deny is the number of denials needed for + state-transition. + format: int32 + type: integer + filter: + description: Filter is an optional predicate used to + determine which reviews count toward this threshold. + type: string + name: + description: Name is the optional human-readable name + of the threshold. + type: string + type: object + type: array + type: object + require_session_join: + description: RequireSessionJoin specifies policies for required + users to start a session. + items: + properties: + count: + description: Count is the amount of people that need to + be matched for this policy to be fulfilled. + format: int32 + type: integer + filter: + description: Filter is a predicate that determines what + users count towards this policy. + type: string + kinds: + description: Kinds are the session kinds this policy applies + to. + items: + type: string + nullable: true + type: array + modes: + description: Modes is the list of modes that may be used + to fulfill this policy. + items: + type: string + nullable: true + type: array + name: + description: Name is the name of the policy. + type: string + on_leave: + description: OnLeave is the behaviour that's used when the + policy is no longer fulfilled for a live session. + type: string + type: object + nullable: true + type: array + review_requests: + description: ReviewRequests defines conditions for submitting + access reviews. + nullable: true + properties: + claims_to_roles: + description: ClaimsToRoles specifies a mapping from claims + (traits) to teleport roles. + items: + properties: + claim: + description: Claim is a claim name. + type: string + roles: + description: Roles is a list of static teleport roles + to match. + items: + type: string + nullable: true + type: array + value: + description: Value is a claim value to match. + type: string + type: object + type: array + preview_as_roles: + description: PreviewAsRoles is a list of extra roles which + should apply to a reviewer while they are viewing a Resource + Access Request for the purposes of viewing details such + as the hostname and labels of requested resources. + items: + type: string + nullable: true + type: array + roles: + description: Roles is the name of roles which may be reviewed. + items: + type: string + nullable: true + type: array + where: + description: Where is an optional predicate which further + limits which requests are reviewable. + type: string + type: object + rules: + description: Rules is a list of rules and their access levels. + Rules are a high level construct used for access control. + items: + properties: + actions: + description: Actions specifies optional actions taken when + this rule matches + items: + type: string + nullable: true + type: array + resources: + description: Resources is a list of resources + items: + type: string + nullable: true + type: array + verbs: + description: Verbs is a list of verbs + items: + type: string + nullable: true + type: array + where: + description: Where specifies optional advanced matcher + type: string + type: object + type: array + windows_desktop_labels: + additionalProperties: + x-kubernetes-preserve-unknown-fields: true + description: WindowsDesktopLabels are used in the RBAC system + to allow/deny access to Windows desktops. + type: object + windows_desktop_labels_expression: + description: WindowsDesktopLabelsExpression is a predicate expression + used to allow/deny access to Windows desktops. + type: string + windows_desktop_logins: + description: WindowsDesktopLogins is a list of desktop login names + allowed/denied for Windows desktops. + items: + type: string + nullable: true + type: array + type: object + options: + description: Options is for OpenSSH options like agent forwarding. + properties: + cert_extensions: + description: CertExtensions specifies the key/values + items: + properties: + mode: + description: Mode is the type of extension to be used -- + currently critical-option is not supported + format: int32 + type: integer + name: + description: Name specifies the key to be used in the cert + extension. + type: string + type: + description: Type represents the certificate type being + extended, only ssh is supported at this time. + format: int32 + type: integer + value: + description: Value specifies the value to be used in the + cert extension. + type: string + type: object + nullable: true + type: array + cert_format: + description: CertificateFormat defines the format of the user + certificate to allow compatibility with older versions of OpenSSH. + type: string + client_idle_timeout: + description: ClientIdleTimeout sets disconnect clients on idle + timeout behavior, if set to 0 means do not disconnect, otherwise + is set to the idle duration. + format: duration + type: string + create_db_user: + description: CreateDatabaseUser enabled automatic database user + creation. + type: boolean + create_desktop_user: + description: CreateDesktopUser allows users to be automatically + created on a Windows desktop + type: boolean + create_host_user: + description: CreateHostUser allows users to be automatically created + on a host + type: boolean + create_host_user_mode: + description: CreateHostUserMode allows users to be automatically + created on a host when not set to off + format: int32 + type: integer + desktop_clipboard: + description: DesktopClipboard indicates whether clipboard sharing + is allowed between the user's workstation and the remote desktop. + It defaults to true unless explicitly set to false. + type: boolean + desktop_directory_sharing: + description: DesktopDirectorySharing indicates whether directory + sharing is allowed between the user's workstation and the remote + desktop. It defaults to false unless explicitly set to true. + type: boolean + device_trust_mode: + description: DeviceTrustMode is the device authorization mode + used for the resources associated with the role. See DeviceTrust.Mode. + Reserved for future use, not yet used by Teleport. + type: string + disconnect_expired_cert: + description: DisconnectExpiredCert sets disconnect clients on + expired certificates. + type: boolean + enhanced_recording: + description: BPF defines what events to record for the BPF-based + session recorder. + items: + type: string + nullable: true + type: array + forward_agent: + description: ForwardAgent is SSH agent forwarding. + type: boolean + idp: + description: IDP is a set of options related to accessing IdPs + within Teleport. Requires Teleport Enterprise. + nullable: true + properties: + saml: + description: SAML are options related to the Teleport SAML + IdP. + nullable: true + properties: + enabled: + description: Enabled is set to true if this option allows + access to the Teleport SAML IdP. + type: boolean + type: object + type: object + lock: + description: Lock specifies the locking mode (strict|best_effort) + to be applied with the role. + type: string + max_connections: + description: MaxConnections defines the maximum number of concurrent + connections a user may hold. + format: int64 + type: integer + max_kubernetes_connections: + description: MaxKubernetesConnections defines the maximum number + of concurrent Kubernetes sessions a user may hold. + format: int64 + type: integer + max_session_ttl: + description: MaxSessionTTL defines how long a SSH session can + last for. + format: duration + type: string + max_sessions: + description: MaxSessions defines the maximum number of concurrent + sessions per connection. + format: int64 + type: integer + permit_x11_forwarding: + description: PermitX11Forwarding authorizes use of X11 forwarding. + type: boolean + pin_source_ip: + description: PinSourceIP forces the same client IP for certificate + generation and usage + type: boolean + port_forwarding: + description: PortForwarding defines if the certificate will have + "permit-port-forwarding" in the certificate. PortForwarding + is "yes" if not set, that's why this is a pointer + type: boolean + record_session: + description: RecordDesktopSession indicates whether desktop access + sessions should be recorded. It defaults to true unless explicitly + set to false. + nullable: true + properties: + default: + description: Default indicates the default value for the services. + type: string + desktop: + description: Desktop indicates whether desktop sessions should + be recorded. It defaults to true unless explicitly set to + false. + type: boolean + ssh: + description: SSH indicates the session mode used on SSH sessions. + type: string + type: object + request_access: + description: RequestAccess defines the access request strategy + (optional|note|always) where optional is the default. + type: string + request_prompt: + description: RequestPrompt is an optional message which tells + users what they aught to + type: string + require_session_mfa: + description: RequireMFAType is the type of MFA requirement enforced + for this user. + format: int32 + type: integer + ssh_file_copy: + description: SSHFileCopy indicates whether remote file operations + via SCP or SFTP are allowed over an SSH session. It defaults + to true unless explicitly set to false. + type: boolean + type: object + type: object + status: + description: TeleportRoleStatus defines the observed state of TeleportRole + properties: + conditions: + description: Conditions represent the latest available observations + of an object's state + items: + description: "Condition contains details for one aspect of the current + state of this API Resource. --- This struct is intended for direct + use as an array at the field path .status.conditions. For example, + \n type FooStatus struct{ // Represents the observations of a + foo's current state. // Known .status.conditions.type are: \"Available\", + \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge + // +listType=map // +listMapKey=type Conditions []metav1.Condition + `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" + protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition + transitioned from one status to another. This should be when + the underlying condition changed. If that is not known, then + using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating + details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation + that the condition was set based upon. For instance, if .metadata.generation + is currently 12, but the .status.conditions[x].observedGeneration + is 9, the condition is out of date with respect to the current + state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating + the reason for the condition's last transition. Producers + of specific condition types may define expected values and + meanings for this field, and whether the values are considered + a guaranteed API. The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + --- Many .condition.type values are consistent across resources + like Available, but because arbitrary conditions can be useful + (see .node.status.conditions), the ability to deconflict is + important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + teleportResourceID: + format: int64 + type: integer + type: object + type: object + served: true + storage: false + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null diff --git a/helm/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_samlconnectors.yaml b/helm/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_samlconnectors.yaml new file mode 100644 index 0000000..c86cc91 --- /dev/null +++ b/helm/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_samlconnectors.yaml @@ -0,0 +1,210 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + creationTimestamp: null + name: teleportsamlconnectors.resources.teleport.dev +spec: + group: resources.teleport.dev + names: + kind: TeleportSAMLConnector + listKind: TeleportSAMLConnectorList + plural: teleportsamlconnectors + shortNames: + - samlconnector + - samlconnectors + singular: teleportsamlconnector + scope: Namespaced + versions: + - name: v2 + schema: + openAPIV3Schema: + description: SAMLConnector is the Schema for the samlconnectors 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: SAMLConnector resource definition v2 from Teleport + properties: + acs: + description: AssertionConsumerService is a URL for assertion consumer + service on the service provider (Teleport's side). + type: string + allow_idp_initiated: + description: AllowIDPInitiated is a flag that indicates if the connector + can be used for IdP-initiated logins. + type: boolean + assertion_key_pair: + description: EncryptionKeyPair is a key pair used for decrypting SAML + assertions. + nullable: true + properties: + cert: + description: Cert is a PEM-encoded x509 certificate. + type: string + private_key: + description: PrivateKey is a PEM encoded x509 private key. + type: string + type: object + attributes_to_roles: + description: AttributesToRoles is a list of mappings of attribute + statements to roles. + items: + properties: + name: + description: Name is an attribute statement name. + type: string + roles: + description: Roles is a list of static teleport roles to map + to. + items: + type: string + nullable: true + type: array + value: + description: Value is an attribute statement value to match. + type: string + type: object + type: array + audience: + description: Audience uniquely identifies our service provider. + type: string + cert: + description: Cert is the identity provider certificate PEM. IDP signs + responses using this certificate. + type: string + display: + description: Display controls how this connector is displayed. + type: string + entity_descriptor: + description: EntityDescriptor is XML with descriptor. It can be used + to supply configuration parameters in one XML file rather than supplying + them in the individual elements. + type: string + entity_descriptor_url: + description: EntityDescriptorURL is a URL that supplies a configuration + XML. + type: string + issuer: + description: Issuer is the identity provider issuer. + type: string + provider: + description: Provider is the external identity provider. + type: string + service_provider_issuer: + description: ServiceProviderIssuer is the issuer of the service provider + (Teleport). + type: string + signing_key_pair: + description: SigningKeyPair is an x509 key pair used to sign AuthnRequest. + nullable: true + properties: + cert: + description: Cert is a PEM-encoded x509 certificate. + type: string + private_key: + description: PrivateKey is a PEM encoded x509 private key. + type: string + type: object + sso: + description: SSO is the URL of the identity provider's SSO service. + type: string + type: object + status: + description: TeleportSAMLConnectorStatus defines the observed state of + TeleportSAMLConnector + properties: + conditions: + description: Conditions represent the latest available observations + of an object's state + items: + description: "Condition contains details for one aspect of the current + state of this API Resource. --- This struct is intended for direct + use as an array at the field path .status.conditions. For example, + \n type FooStatus struct{ // Represents the observations of a + foo's current state. // Known .status.conditions.type are: \"Available\", + \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge + // +listType=map // +listMapKey=type Conditions []metav1.Condition + `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" + protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition + transitioned from one status to another. This should be when + the underlying condition changed. If that is not known, then + using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating + details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation + that the condition was set based upon. For instance, if .metadata.generation + is currently 12, but the .status.conditions[x].observedGeneration + is 9, the condition is out of date with respect to the current + state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating + the reason for the condition's last transition. Producers + of specific condition types may define expected values and + meanings for this field, and whether the values are considered + a guaranteed API. The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + --- Many .condition.type values are consistent across resources + like Available, but because arbitrary conditions can be useful + (see .node.status.conditions), the ability to deconflict is + important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + teleportResourceID: + format: int64 + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null diff --git a/helm/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_users.yaml b/helm/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_users.yaml new file mode 100644 index 0000000..7e41bac --- /dev/null +++ b/helm/teleport-cluster/charts/teleport-operator/templates/resources.teleport.dev_users.yaml @@ -0,0 +1,195 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + creationTimestamp: null + name: teleportusers.resources.teleport.dev +spec: + group: resources.teleport.dev + names: + kind: TeleportUser + listKind: TeleportUserList + plural: teleportusers + shortNames: + - user + - users + singular: teleportuser + scope: Namespaced + versions: + - name: v2 + schema: + openAPIV3Schema: + description: User is the Schema for the users API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: User resource definition v2 from Teleport + properties: + github_identities: + description: GithubIdentities list associated Github OAuth2 identities + that let user log in using externally verified identity + items: + properties: + connector_id: + description: ConnectorID is id of registered OIDC connector, + e.g. 'google-example.com' + type: string + username: + description: Username is username supplied by external identity + provider + type: string + type: object + type: array + oidc_identities: + description: OIDCIdentities lists associated OpenID Connect identities + that let user log in using externally verified identity + items: + properties: + connector_id: + description: ConnectorID is id of registered OIDC connector, + e.g. 'google-example.com' + type: string + username: + description: Username is username supplied by external identity + provider + type: string + type: object + type: array + roles: + description: Roles is a list of roles assigned to user + items: + type: string + nullable: true + type: array + saml_identities: + description: SAMLIdentities lists associated SAML identities that + let user log in using externally verified identity + items: + properties: + connector_id: + description: ConnectorID is id of registered OIDC connector, + e.g. 'google-example.com' + type: string + username: + description: Username is username supplied by external identity + provider + type: string + type: object + type: array + traits: + additionalProperties: + items: + type: string + type: array + description: Traits are key/value pairs received from an identity + provider (through OIDC claims or SAML assertions) or from a system + administrator for local accounts. Traits are used to populate role + variables. + type: object + trusted_device_ids: + description: TrustedDeviceIDs contains the IDs of trusted devices + enrolled by the user. Managed by the Device Trust subsystem, avoid + manual edits. + items: + type: string + nullable: true + type: array + type: object + status: + description: TeleportUserStatus defines the observed state of TeleportUser + properties: + conditions: + description: Conditions represent the latest available observations + of an object's state + items: + description: "Condition contains details for one aspect of the current + state of this API Resource. --- This struct is intended for direct + use as an array at the field path .status.conditions. For example, + \n type FooStatus struct{ // Represents the observations of a + foo's current state. // Known .status.conditions.type are: \"Available\", + \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge + // +listType=map // +listMapKey=type Conditions []metav1.Condition + `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" + protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + properties: + lastTransitionTime: + description: lastTransitionTime is the last time the condition + transitioned from one status to another. This should be when + the underlying condition changed. If that is not known, then + using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: message is a human readable message indicating + details about the transition. This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: observedGeneration represents the .metadata.generation + that the condition was set based upon. For instance, if .metadata.generation + is currently 12, but the .status.conditions[x].observedGeneration + is 9, the condition is out of date with respect to the current + state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: reason contains a programmatic identifier indicating + the reason for the condition's last transition. Producers + of specific condition types may define expected values and + meanings for this field, and whether the values are considered + a guaranteed API. The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + --- Many .condition.type values are consistent across resources + like Available, but because arbitrary conditions can be useful + (see .node.status.conditions), the ability to deconflict is + important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + teleportResourceID: + format: int64 + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} +status: + acceptedNames: + kind: "" + plural: "" + conditions: null + storedVersions: null diff --git a/helm/teleport-cluster/override_values.yaml b/helm/teleport-cluster/override_values.yaml new file mode 100644 index 0000000..4989c7f --- /dev/null +++ b/helm/teleport-cluster/override_values.yaml @@ -0,0 +1,45 @@ +chartMode: standalone +clusterName: teleport.kr.datasaker.io + #teleportVersionOverride: "13.3.8" + +auth: + teleportConfig: + # put any teleport.yaml auth configuration overrides here + teleport: + log: + output: stderr + severity: INFO + + auth_service: + enabled: true + web_idle_timeout: 1h + authentication: + locking_mode: best_effort + persistence: + storageClassName: openebs-hostpath + +proxy: + teleportConfig: + # put any teleport.yaml proxy configuration overrides here + teleport: + log: + output: stderr + severity: INFO + + proxy_service: + https_keypairs_reload_interval: 12h + +podSecurityPolicy: + enabled: false + +proxy_service: + web_listen_addr: 0.0.0.0:3080 + public_addr: teleport.kr.datasaker.io:443 + +resources: + requests: + cpu: "1" + memory: "2Gi" + +highAvailability: + replicaCount: 1 diff --git a/helm/teleport-cluster/teleport_svc.yaml b/helm/teleport-cluster/teleport_svc.yaml new file mode 100644 index 0000000..12fda7a --- /dev/null +++ b/helm/teleport-cluster/teleport_svc.yaml @@ -0,0 +1,44 @@ +apiVersion: v1 +kind: Service +metadata: + name: teleport + namespace: teleport +spec: + allocateLoadBalancerNodePorts: true + externalTrafficPolicy: Cluster + internalTrafficPolicy: Cluster + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: tls + nodePort: 30810 + port: 443 + protocol: TCP + targetPort: 3080 + - name: sshproxy + nodePort: 30811 + port: 3023 + protocol: TCP + targetPort: 3023 + - name: k8s + nodePort: 30812 + port: 3026 + protocol: TCP + targetPort: 3026 + - name: sshtun + nodePort: 30813 + port: 3024 + protocol: TCP + targetPort: 3024 + - name: mysql + nodePort: 30814 + port: 3036 + protocol: TCP + targetPort: 3036 + selector: + app.kubernetes.io/component: proxy + app.kubernetes.io/instance: teleport + app.kubernetes.io/name: teleport-cluster + sessionAffinity: None + type: LoadBalancer diff --git a/helm/teleport-cluster/templates/NOTES.txt b/helm/teleport-cluster/templates/NOTES.txt new file mode 100644 index 0000000..f85e1fa --- /dev/null +++ b/helm/teleport-cluster/templates/NOTES.txt @@ -0,0 +1,35 @@ +{{- if .Values.highAvailability.certManager.enabled }} +You have enabled cert-manager support in high availability mode. + +There may be a short delay before Teleport pods start while an ACME certificate is issued. +You can check the status of the certificate with `kubectl -n {{ .Release.Namespace }} describe certificate/{{ .Release.Name }}` + +NOTE: For certificates to be provisioned, you must also install cert-manager (https://cert-manager.io/docs/) and configure an appropriate + Issuer with access to your DNS provider to handle DNS01 challenges (https://cert-manager.io/docs/configuration/acme/dns01/#supported-dns01-providers) + +For more information, please see the Helm guides in the Teleport docs (https://goteleport.com/docs/kubernetes-access/helm/guides/) +{{- end }} + +{{- if and .Values.podSecurityPolicy.enabled (semverCompare "<1.23.0-0" .Capabilities.KubeVersion.Version) }} + +SECURITY WARNING: Kubernetes 1.25 removes PodSecurityPolicy support and Helm +doesn't support upgrading from 1.24 to 1.25 with PSPs enabled. Since version 12 +the `teleport-cluster` chart doesn't deploy PSPs on Kubernetes 1.23 or older. +Instead, we recommend you to configure Pod Security AdmissionControllers for +the namespace "{{.Release.Namespace}}" by adding the label +`pod-security.kubernetes.io/enforce: baseline` on the namespace resource. + +See https://goteleport.com/docs/deploy-a-cluster/helm-deployments/migration-kubernetes-1-25-psp/ + +To remove this warning, explicitly set "podSecurityPolicy.enabled=false". +{{- end }} + +{{- if .Values.teleportVersionOverride }} + +DANGER: `teleportVersionOverride` MUST NOT be used to control the Teleport version. +This chart is designed to run Teleport version {{ .Chart.AppVersion }}. +You will face compatibility issues trying to run a different Teleport version with it. + +If you want to run Teleport version {{.Values.teleportVersionOverride}}, +you should use `helm --version {{.Values.teleportVersionOverride}}` instead. +{{- end }} diff --git a/helm/teleport-cluster/templates/_helpers.tpl b/helm/teleport-cluster/templates/_helpers.tpl new file mode 100644 index 0000000..e5c2219 --- /dev/null +++ b/helm/teleport-cluster/templates/_helpers.tpl @@ -0,0 +1,91 @@ +{{/* +Create the name of the service account to use +if serviceAccount is not defined or serviceAccount.name is empty, use .Release.Name +*/}} +{{- define "teleport-cluster.auth.serviceAccountName" -}} +{{- coalesce .Values.serviceAccount.name .Release.Name -}} +{{- end -}} + +{{- define "teleport-cluster.proxy.serviceAccountName" -}} +{{- coalesce .Values.serviceAccount.name .Release.Name -}}-proxy +{{- end -}} + +{{- define "teleport-cluster.version" -}} +{{- coalesce .Values.teleportVersionOverride .Chart.Version }} +{{- end -}} + +{{- define "teleport-cluster.majorVersion" -}} +{{- (semver (include "teleport-cluster.version" .)).Major -}} +{{- end -}} + +{{- define "teleport-cluster.previousMajorVersion" -}} +{{- sub (include "teleport-cluster.majorVersion" . | atoi ) 1 -}} +{{- end -}} + +{{/* Proxy selector labels */}} +{{- define "teleport-cluster.proxy.selectorLabels" -}} +app.kubernetes.io/name: '{{ default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}' +app.kubernetes.io/instance: '{{ .Release.Name }}' +app.kubernetes.io/component: 'proxy' +{{- end -}} + +{{/* Proxy all labels */}} +{{- define "teleport-cluster.proxy.labels" -}} +{{ include "teleport-cluster.proxy.selectorLabels" . }} +helm.sh/chart: '{{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}' +app.kubernetes.io/managed-by: '{{ .Release.Service }}' +app.kubernetes.io/version: '{{ include "teleport-cluster.version" . }}' +teleport.dev/majorVersion: '{{ include "teleport-cluster.majorVersion" . }}' +{{- end -}} + +{{/* Auth pods selector labels */}} +{{- define "teleport-cluster.auth.selectorLabels" -}} +app.kubernetes.io/name: '{{ default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}' +app.kubernetes.io/instance: '{{ .Release.Name }}' +app.kubernetes.io/component: 'auth' +{{- end -}} + +{{/* All pods all labels */}} +{{- define "teleport-cluster.labels" -}} +{{ include "teleport-cluster.selectorLabels" . }} +helm.sh/chart: '{{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}' +app.kubernetes.io/managed-by: '{{ .Release.Service }}' +app.kubernetes.io/version: '{{ include "teleport-cluster.version" . }}' +teleport.dev/majorVersion: '{{ include "teleport-cluster.majorVersion" . }}' +{{- end -}} + +{{/* All pods selector labels */}} +{{- define "teleport-cluster.selectorLabels" -}} +app.kubernetes.io/name: '{{ default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}' +app.kubernetes.io/instance: '{{ .Release.Name }}' +{{- end -}} + +{{/* Auth pods all labels */}} +{{- define "teleport-cluster.auth.labels" -}} +{{ include "teleport-cluster.auth.selectorLabels" . }} +helm.sh/chart: '{{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}' +app.kubernetes.io/managed-by: '{{ .Release.Service }}' +app.kubernetes.io/version: '{{ include "teleport-cluster.version" . }}' +teleport.dev/majorVersion: '{{ include "teleport-cluster.majorVersion" . }}' +{{- end -}} + +{{/* ServiceNames are limited to 63 characters, we might have to truncate the ReleaseName + to make sure the auth serviceName won't exceed this limit */}} +{{- define "teleport-cluster.auth.serviceName" -}} +{{- .Release.Name | trunc 58 | trimSuffix "-" -}}-auth +{{- end -}} + +{{- define "teleport-cluster.auth.currentVersionServiceName" -}} +{{- .Release.Name | trunc 54 | trimSuffix "-" -}}-auth-v{{ include "teleport-cluster.majorVersion" . }} +{{- end -}} + +{{- define "teleport-cluster.auth.previousVersionServiceName" -}} +{{- .Release.Name | trunc 54 | trimSuffix "-" -}}-auth-v{{ include "teleport-cluster.previousMajorVersion" . }} +{{- end -}} + + +{{/* In most places we want to use the FQDN instead of relying on Kubernetes ndots behaviour + for performance reasons */}} +{{- define "teleport-cluster.auth.serviceFQDN" -}} +{{ include "teleport-cluster.auth.serviceName" . }}.{{ .Release.Namespace }}.svc.cluster.local +{{- end -}} diff --git a/helm/teleport-cluster/templates/auth/_config.aws.tpl b/helm/teleport-cluster/templates/auth/_config.aws.tpl new file mode 100644 index 0000000..9fb0863 --- /dev/null +++ b/helm/teleport-cluster/templates/auth/_config.aws.tpl @@ -0,0 +1,26 @@ +{{- define "teleport-cluster.auth.config.aws" -}} +{{ include "teleport-cluster.auth.config.common" . }} + storage: + type: dynamodb + region: {{ required "aws.region is required in chart values" .Values.aws.region }} + table_name: {{ required "aws.backendTable is required in chart values" .Values.aws.backendTable }} + {{- if .Values.aws.auditLogMirrorOnStdout }} + audit_events_uri: ['dynamodb://{{ required "aws.auditLogTable is required in chart values" .Values.aws.auditLogTable }}', 'stdout://'] + {{- else }} + audit_events_uri: ['dynamodb://{{ required "aws.auditLogTable is required in chart values" .Values.aws.auditLogTable }}'] + {{- end }} + audit_sessions_uri: s3://{{ required "aws.sessionRecordingBucket is required in chart values" .Values.aws.sessionRecordingBucket }} + continuous_backups: {{ required "aws.backups is required in chart values" .Values.aws.backups }} + {{- if .Values.aws.dynamoAutoScaling }} + auto_scaling: true + billing_mode: provisioned + read_min_capacity: {{ required "aws.readMinCapacity is required when aws.dynamoAutoScaling is true" .Values.aws.readMinCapacity }} + read_max_capacity: {{ required "aws.readMaxCapacity is required when aws.dynamoAutoScaling is true" .Values.aws.readMaxCapacity }} + read_target_value: {{ required "aws.readTargetValue is required when aws.dynamoAutoScaling is true" .Values.aws.readTargetValue }} + write_min_capacity: {{ required "aws.writeMinCapacity is required when aws.dynamoAutoScaling is true" .Values.aws.writeMinCapacity }} + write_max_capacity: {{ required "aws.writeMaxCapacity is required when aws.dynamoAutoScaling is true" .Values.aws.writeMaxCapacity }} + write_target_value: {{ required "aws.writeTargetValue is required when aws.dynamoAutoScaling is true" .Values.aws.writeTargetValue }} + {{- else }} + auto_scaling: false + {{- end }} +{{- end -}} diff --git a/helm/teleport-cluster/templates/auth/_config.azure.tpl b/helm/teleport-cluster/templates/auth/_config.azure.tpl new file mode 100644 index 0000000..6bdabd0 --- /dev/null +++ b/helm/teleport-cluster/templates/auth/_config.azure.tpl @@ -0,0 +1,38 @@ +{{/* Helper to build the database connection string, adds paraneters if needed */}} +{{- define "teleport-cluster.auth.config.azure.conn_string.query" }} + {{- if .Values.azure.databasePoolMaxConnections -}} + {{- printf "sslmode=verify-full&pool_max_conns=%v" .Values.azure.databasePoolMaxConnections -}} + {{- else -}} + sslmode=verify-full + {{- end -}} +{{- end -}} + +{{- define "teleport-cluster.auth.config.azure" -}} +{{ include "teleport-cluster.auth.config.common" . }} + storage: + type: postgresql + auth_mode: azure + conn_string: {{ urlJoin (dict + "scheme" "postgresql" + "userinfo" .Values.azure.databaseUser + "host" .Values.azure.databaseHost + "path" .Values.azure.backendDatabase + "query" (include "teleport-cluster.auth.config.azure.conn_string.query" .) + ) | toYaml }} + audit_sessions_uri: {{ urlJoin (dict + "scheme" "azblob" + "host" .Values.azure.sessionRecordingStorageAccount + ) | toYaml }} + audit_events_uri: + - {{ urlJoin (dict + "scheme" "postgresql" + "userinfo" .Values.azure.databaseUser + "host" .Values.azure.databaseHost + "path" .Values.azure.auditLogDatabase + "query" "sslmode=verify-full" + "fragment" "auth_mode=azure" + ) | toYaml }} +{{- if .Values.azure.auditLogMirrorOnStdout }} + - "stdout://" +{{- end }} +{{- end -}} diff --git a/helm/teleport-cluster/templates/auth/_config.common.tpl b/helm/teleport-cluster/templates/auth/_config.common.tpl new file mode 100644 index 0000000..bdfda15 --- /dev/null +++ b/helm/teleport-cluster/templates/auth/_config.common.tpl @@ -0,0 +1,65 @@ +{{- define "teleport-cluster.auth.config.common" -}} +{{- $authentication := mustMergeOverwrite .Values.authentication (default dict .Values.authenticationSecondFactor) -}} +{{- $logLevel := (coalesce .Values.logLevel .Values.log.level "INFO") -}} +version: v3 +kubernetes_service: + enabled: true + listen_addr: 0.0.0.0:3026 + public_addr: "{{ include "teleport-cluster.auth.serviceFQDN" . }}:3026" +{{- if .Values.kubeClusterName }} + kube_cluster_name: {{ .Values.kubeClusterName }} +{{- else }} + kube_cluster_name: {{ .Values.clusterName }} +{{- end }} +{{- if .Values.labels }} + labels: {{- toYaml .Values.labels | nindent 8 }} +{{- end }} +proxy_service: + enabled: false +ssh_service: + enabled: false +auth_service: + enabled: true + cluster_name: {{ required "clusterName is required in chart values" .Values.clusterName }} +{{- if .Values.enterprise }} + license_file: '/var/lib/license/license.pem' +{{- end }} + authentication: + type: "{{ required "authentication.type is required in chart values" (coalesce .Values.authenticationType $authentication.type) }}" + local_auth: {{ $authentication.localAuth }} +{{- if $authentication.connectorName }} + connector_name: "{{ $authentication.connectorName }}" +{{- end }} +{{- if $authentication.lockingMode }} + locking_mode: "{{ $authentication.lockingMode }}" +{{- end }} +{{- if $authentication.secondFactor }} + second_factor: "{{ $authentication.secondFactor }}" + {{- if not (or (eq $authentication.secondFactor "off") (eq $authentication.secondFactor "otp")) }} + webauthn: + rp_id: {{ required "clusterName is required in chart values" .Values.clusterName }} + {{- if $authentication.webauthn }} + {{- if $authentication.webauthn.attestationAllowedCas }} + attestation_allowed_cas: {{- toYaml $authentication.webauthn.attestationAllowedCas | nindent 12 }} + {{- end }} + {{- if $authentication.webauthn.attestationDeniedCas }} + attestation_denied_cas: {{- toYaml $authentication.webauthn.attestationDeniedCas | nindent 12 }} + {{- end }} + {{- end }} + {{- end }} +{{- end }} +{{- if .Values.sessionRecording }} + session_recording: {{ .Values.sessionRecording }} +{{- end }} +{{- if .Values.proxyListenerMode }} + proxy_listener_mode: {{ .Values.proxyListenerMode }} +{{- end }} +teleport: + auth_server: 127.0.0.1:3025 + log: + severity: {{ $logLevel }} + output: {{ .Values.log.output }} + format: + output: {{ .Values.log.format }} + extra_fields: {{ .Values.log.extraFields | toJson }} +{{- end -}} diff --git a/helm/teleport-cluster/templates/auth/_config.gcp.tpl b/helm/teleport-cluster/templates/auth/_config.gcp.tpl new file mode 100644 index 0000000..f55743b --- /dev/null +++ b/helm/teleport-cluster/templates/auth/_config.gcp.tpl @@ -0,0 +1,16 @@ +{{- define "teleport-cluster.auth.config.gcp" -}} +{{ include "teleport-cluster.auth.config.common" . }} + storage: + type: firestore + project_id: {{ required "gcp.projectId is required in chart values" .Values.gcp.projectId }} + collection_name: {{ required "gcp.backendTable is required in chart values" .Values.gcp.backendTable }} + {{- if .Values.gcp.credentialSecretName }} + credentials_path: /etc/teleport-secrets/gcp-credentials.json + {{- end }} + {{- if .Values.gcp.auditLogMirrorOnStdout }} + audit_events_uri: ['firestore://{{ required "gcp.auditLogTable is required in chart values" .Values.gcp.auditLogTable }}?projectID={{ required "gcp.projectId is required in chart values" .Values.gcp.projectId }}{{ empty .Values.gcp.credentialSecretName | ternary "" "&credentialsPath=/etc/teleport-secrets/gcp-credentials.json"}}', 'stdout://'] + {{- else }} + audit_events_uri: ['firestore://{{ required "gcp.auditLogTable is required in chart values" .Values.gcp.auditLogTable }}?projectID={{ required "gcp.projectId is required in chart values" .Values.gcp.projectId }}{{ empty .Values.gcp.credentialSecretName | ternary "" "&credentialsPath=/etc/teleport-secrets/gcp-credentials.json"}}'] + {{- end }} + audit_sessions_uri: "gs://{{ required "gcp.sessionRecordingBucket is required in chart values" .Values.gcp.sessionRecordingBucket }}?projectID={{ required "gcp.projectId is required in chart values" .Values.gcp.projectId }}{{ empty .Values.gcp.credentialSecretName | ternary "" "&credentialsPath=/etc/teleport-secrets/gcp-credentials.json"}}" +{{- end -}} diff --git a/helm/teleport-cluster/templates/auth/_config.scratch.tpl b/helm/teleport-cluster/templates/auth/_config.scratch.tpl new file mode 100644 index 0000000..36c3264 --- /dev/null +++ b/helm/teleport-cluster/templates/auth/_config.scratch.tpl @@ -0,0 +1,12 @@ +{{- define "teleport-cluster.auth.config.scratch" -}} +proxy_service: + enabled: false +ssh_service: + enabled: false +auth_service: + enabled: true +{{- end -}} + +{{- define "teleport-cluster.auth.config.custom" -}} +{{ fail "'custom' mode has been removed with chart v12 because of the proxy/auth split breaking change, see https://goteleport.com/docs/deploy-a-cluster/helm-deployments/migration-v12/" }} +{{- end -}} diff --git a/helm/teleport-cluster/templates/auth/_config.standalone.tpl b/helm/teleport-cluster/templates/auth/_config.standalone.tpl new file mode 100644 index 0000000..db5ff58 --- /dev/null +++ b/helm/teleport-cluster/templates/auth/_config.standalone.tpl @@ -0,0 +1,3 @@ +{{- define "teleport-cluster.auth.config.standalone" -}} +{{ include "teleport-cluster.auth.config.common" . }} +{{- end -}} diff --git a/helm/teleport-cluster/templates/auth/clusterrole.yaml b/helm/teleport-cluster/templates/auth/clusterrole.yaml new file mode 100644 index 0000000..6bf0886 --- /dev/null +++ b/helm/teleport-cluster/templates/auth/clusterrole.yaml @@ -0,0 +1,71 @@ +{{- if .Values.rbac.create -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ .Release.Name }} +rules: +- apiGroups: + - "" + resources: + - users + - groups + - serviceaccounts + verbs: + - impersonate +- apiGroups: + - "" + resources: + - pods + verbs: + - get +- apiGroups: + - "authorization.k8s.io" + resources: + - selfsubjectaccessreviews + verbs: + - create + +{{ if .Values.operator.enabled }} +- apiGroups: + - "resources.teleport.dev" + resources: + - teleportroles + - teleportroles/status + - teleportusers + - teleportusers/status + - teleportgithubconnectors + - teleportgithubconnectors/status + - teleportoidcconnectors + - teleportoidcconnectors/status + - teleportsamlconnectors + - teleportsamlconnectors/status + - teleportloginrules + - teleportloginrules/status + - teleportprovisiontokens + - teleportprovisiontokens/status + - teleportoktaimportrules + - teleportoktaimportrules/status + verbs: + - get + - list + - patch + - update + - watch + +- apiGroups: + - "coordination.k8s.io" + resources: + - leases + verbs: + - create + - get + - update + +- apiGroups: + - "" + resources: + - events + verbs: + - create +{{- end -}} +{{- end -}} diff --git a/helm/teleport-cluster/templates/auth/clusterrolebinding.yaml b/helm/teleport-cluster/templates/auth/clusterrolebinding.yaml new file mode 100644 index 0000000..ba39919 --- /dev/null +++ b/helm/teleport-cluster/templates/auth/clusterrolebinding.yaml @@ -0,0 +1,31 @@ +{{- if .Values.rbac.create -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ .Release.Name }} + labels: {{- include "teleport-cluster.auth.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ .Release.Name }} +subjects: +- kind: ServiceAccount + name: {{ include "teleport-cluster.auth.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +--- +# This ClusterRoleBinding allows the auth service-account to validate Kubernetes tokens +# This is required for proxies to join using their Kubernetes tokens +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ .Release.Name }}-auth + labels: {{- include "teleport-cluster.auth.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: system:auth-delegator +subjects: +- kind: ServiceAccount + name: {{ include "teleport-cluster.auth.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +{{- end }} diff --git a/helm/teleport-cluster/templates/auth/config.yaml b/helm/teleport-cluster/templates/auth/config.yaml new file mode 100644 index 0000000..b5b53cb --- /dev/null +++ b/helm/teleport-cluster/templates/auth/config.yaml @@ -0,0 +1,28 @@ +{{- $auth := mustMergeOverwrite (mustDeepCopy .Values) .Values.auth -}} +{{- $configTemplate := printf "teleport-cluster.auth.config.%s" $auth.chartMode -}} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-auth + namespace: {{ .Release.Namespace }} + labels: {{- include "teleport-cluster.auth.labels" . | nindent 4 }} +{{- if $auth.annotations.config }} + annotations: {{- toYaml $auth.annotations.config | nindent 4 }} +{{- end }} +data: +{{- if $auth.createProxyToken }} + apply-on-startup.yaml: |2 + kind: token + version: v2 + metadata: + name: {{ .Release.Name }}-proxy + expires: "2050-01-01T00:00:00Z" + spec: + roles: [Proxy] + join_method: kubernetes + kubernetes: + allow: + - service_account: "{{ .Release.Namespace }}:{{ include "teleport-cluster.proxy.serviceAccountName" . }}" +{{- end }} + teleport.yaml: |2 + {{- mustMergeOverwrite (include $configTemplate . | fromYaml) $auth.teleportConfig | toYaml | nindent 4 -}} diff --git a/helm/teleport-cluster/templates/auth/deployment.yaml b/helm/teleport-cluster/templates/auth/deployment.yaml new file mode 100644 index 0000000..8c71803 --- /dev/null +++ b/helm/teleport-cluster/templates/auth/deployment.yaml @@ -0,0 +1,321 @@ +{{- $auth := mustMergeOverwrite (mustDeepCopy .Values) .Values.auth -}} +{{- $replicated := gt (int $auth.highAvailability.replicaCount) 1 -}} +{{- $projectedServiceAccountToken := semverCompare ">=1.20.0-0" .Capabilities.KubeVersion.Version }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Release.Name }}-auth + namespace: {{ .Release.Namespace }} + labels: + {{- include "teleport-cluster.auth.labels" . | nindent 4 }} + app: {{ .Release.Name }} +{{- if $auth.annotations.deployment }} + annotations: {{- toYaml $auth.annotations.deployment | nindent 4 }} +{{- end }} +spec: + replicas: {{ $auth.highAvailability.replicaCount }} +{{- if and $replicated $auth.highAvailability.minReadySeconds }} + minReadySeconds: {{ $auth.highAvailability.minReadySeconds }} +{{- end }} + strategy: +{{- if $replicated }} + # some backends support a maximum amount of auth pods (e.g. DynamoDB), + # we don't want to exceed this during a rollout. + type: RollingUpdate + rollingUpdate: + maxSurge: 0 + maxUnavailable: 1 +{{- else }} + # using a single replica can be because of a non-replicable storage or when applying upgrade migrations. + # In those cases, we don't want a rolling update. + type: Recreate +{{- end }} + selector: + matchLabels: {{- include "teleport-cluster.auth.selectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + # ConfigMap checksum, to recreate the pod on config changes. + checksum/config: {{ include (print $.Template.BasePath "/auth/config.yaml") . | sha256sum }} +{{- if $auth.annotations.pod }} + {{- toYaml $auth.annotations.pod | nindent 8 }} +{{- end }} + labels: + {{- include "teleport-cluster.auth.labels" . | nindent 8 }} + app: {{ .Release.Name }} +{{- if eq $auth.chartMode "azure"}} + azure.workload.identity/use: "true" +{{- end }} + spec: +{{- if $auth.nodeSelector }} + nodeSelector: {{- toYaml $auth.nodeSelector | nindent 8 }} +{{- end }} + affinity: +{{- if $auth.affinity }} + {{- if $auth.highAvailability.requireAntiAffinity }} + {{- fail "Cannot use highAvailability.requireAntiAffinity when affinity is also set in chart values - unset one or the other" }} + {{- end }} + {{- toYaml $auth.affinity | nindent 8 }} +{{- else }} + podAntiAffinity: + {{- if $auth.highAvailability.requireAntiAffinity }} + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: app.kubernetes.io/instance + operator: In + values: + - {{ .Release.Name }} + - key: app.kubernetes.io/component + operator: In + values: + - auth + topologyKey: "kubernetes.io/hostname" + {{- else if $replicated }} + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 50 + podAffinityTerm: + labelSelector: + matchExpressions: + - key: app.kubernetes.io/instance + operator: In + values: + - {{ .Release.Name }} + - key: app.kubernetes.io/component + operator: In + values: + - auth + topologyKey: "kubernetes.io/hostname" + {{- end }} +{{- end }} +{{- if $auth.tolerations }} + tolerations: {{- toYaml $auth.tolerations | nindent 6 }} +{{- end }} +{{- if $auth.imagePullSecrets }} + imagePullSecrets: + {{- toYaml $auth.imagePullSecrets | nindent 6 }} +{{- end }} +{{- if $auth.initContainers }} + initContainers: + {{- range $initContainer := $auth.initContainers }} + {{- if and (not $initContainer.resources) $auth.resources }} + {{- $_ := set $initContainer "resources" $auth.resources }} + {{- end }} + {{- list $initContainer | toYaml | nindent 8 }} + {{- /* Note: this will break if the user sets volumeMounts to its initContainer */}} + volumeMounts: + {{- if $auth.enterprise }} + - mountPath: /var/lib/license + name: "license" + readOnly: true + {{- end }} + {{- if and ($auth.gcp.credentialSecretName) (eq $auth.chartMode "gcp") }} + - mountPath: /etc/teleport-secrets + name: "gcp-credentials" + readOnly: true + {{- end }} + - mountPath: /etc/teleport + name: "config" + readOnly: true + - mountPath: /var/lib/teleport + name: "data" + {{- if $projectedServiceAccountToken }} + - mountPath: /var/run/secrets/kubernetes.io/serviceaccount + name: auth-serviceaccount-token + readOnly: true + {{- end }} + {{- if $auth.extraVolumeMounts }} + {{- toYaml $auth.extraVolumeMounts | nindent 10 }} + {{- end }} + {{- end }} +{{- end }} + containers: + - name: "teleport" + image: '{{ if $auth.enterprise }}{{ $auth.enterpriseImage }}{{ else }}{{ $auth.image }}{{ end }}:{{ include "teleport-cluster.version" . }}' + imagePullPolicy: {{ $auth.imagePullPolicy }} + {{- if or $auth.extraEnv $auth.tls.existingCASecretName }} + env: + {{- if (gt (len $auth.extraEnv) 0) }} + {{- toYaml $auth.extraEnv | nindent 8 }} + {{- end }} + {{- if $auth.tls.existingCASecretName }} + - name: SSL_CERT_FILE + value: /etc/teleport-tls-ca/ca.pem + {{- end }} + {{- end }} + args: + - "--diag-addr=0.0.0.0:3000" + {{- if $auth.insecureSkipProxyTLSVerify }} + - "--insecure" + {{- end }} + {{- if $auth.createProxyToken }} + - "--apply-on-startup=/etc/teleport/apply-on-startup.yaml" + {{- end }} + {{- if $auth.extraArgs }} + {{- toYaml $auth.extraArgs | nindent 8 }} + {{- end }} + ports: + - name: diag + containerPort: 3000 + protocol: TCP + - name: auth + containerPort: 3025 + protocol: TCP + - name: kube + containerPort: 3026 + protocol: TCP + livenessProbe: + httpGet: + path: /healthz + port: diag + initialDelaySeconds: 5 # wait 5s for agent to start + periodSeconds: 5 # poll health every 5s + failureThreshold: 6 # consider agent unhealthy after 30s (6 * 5s) + timeoutSeconds: {{ .Values.probeTimeoutSeconds }} + readinessProbe: + httpGet: + path: /readyz + port: diag + initialDelaySeconds: 5 # wait 5s for agent to register + periodSeconds: 5 # poll health every 5s + failureThreshold: 12 # consider agent unhealthy after 60s (12 * 5s) + timeoutSeconds: {{ .Values.probeTimeoutSeconds }} + lifecycle: + # waiting during preStop ensures no new request will hit the Terminating pod + # on clusters using kube-proxy (kube-proxy syncs the node iptables rules every 30s) + preStop: + exec: + command: + - teleport + - wait + - duration + - 30s +{{- if $auth.postStart.command }} + postStart: + exec: + command: {{ toYaml $auth.postStart.command | nindent 14 }} +{{- end }} +{{- if $auth.resources }} + resources: + {{- toYaml $auth.resources | nindent 10 }} +{{- end }} +{{- if $auth.securityContext }} + securityContext: {{- toYaml $auth.securityContext | nindent 10 }} +{{- end }} + volumeMounts: +{{- if $auth.enterprise }} + - mountPath: /var/lib/license + name: "license" + readOnly: true +{{- end }} +{{- if and ($auth.gcp.credentialSecretName) (eq $auth.chartMode "gcp") }} + - mountPath: /etc/teleport-secrets + name: "gcp-credentials" + readOnly: true +{{- end }} +{{- if $auth.tls.existingCASecretName }} + - mountPath: /etc/teleport-tls-ca + name: "teleport-tls-ca" + readOnly: true +{{- end }} + - mountPath: /etc/teleport + name: "config" + readOnly: true + - mountPath: /var/lib/teleport + name: "data" +{{- if $projectedServiceAccountToken }} + - mountPath: /var/run/secrets/kubernetes.io/serviceaccount + name: auth-serviceaccount-token + readOnly: true +{{- end }} +{{- if $auth.extraVolumeMounts }} + {{- toYaml $auth.extraVolumeMounts | nindent 8 }} +{{- end }} +{{- /* Operator uses '.Values' instead of '$auth' as it will likely be moved out of the auth pods */}} +{{- if .Values.operator.enabled }} + - name: "operator" + image: '{{ .Values.operator.image }}:{{ include "teleport-cluster.version" . }}' + imagePullPolicy: {{ .Values.imagePullPolicy }} + livenessProbe: + httpGet: + path: /healthz + port: 8081 + initialDelaySeconds: 15 + periodSeconds: 20 + readinessProbe: + httpGet: + path: /readyz + port: 8081 + initialDelaySeconds: 5 + periodSeconds: 10 + {{- if .Values.operator.resources }} + resources: {{- toYaml .Values.operator.resources | nindent 10 }} + {{- end }} + volumeMounts: + - mountPath: /etc/teleport + name: "config" + readOnly: true + - mountPath: /var/lib/teleport + name: "data" + {{- if $projectedServiceAccountToken }} + - mountPath: /var/run/secrets/kubernetes.io/serviceaccount + name: auth-serviceaccount-token + readOnly: true + {{- end }} +{{ end }} +{{- if $projectedServiceAccountToken }} + automountServiceAccountToken: false +{{- end }} + volumes: +{{- if $projectedServiceAccountToken }} + # This projected token volume mimics the `automountServiceAccountToken` + # behaviour but defaults to a 1h TTL instead of 1y. + - name: auth-serviceaccount-token + projected: + sources: + - serviceAccountToken: + path: token + - configMap: + items: + - key: ca.crt + path: ca.crt + name: kube-root-ca.crt + - downwardAPI: + items: + - path: "namespace" + fieldRef: + fieldPath: metadata.namespace +{{- end }} +{{- if $auth.enterprise }} + - name: license + secret: + secretName: "license" +{{- end }} +{{- if and ($auth.gcp.credentialSecretName) (eq $auth.chartMode "gcp") }} + - name: gcp-credentials + secret: + secretName: {{ $auth.gcp.credentialSecretName | quote }} +{{- end }} +{{- if $auth.tls.existingCASecretName }} + - name: teleport-tls-ca + secret: + secretName: {{ $auth.tls.existingCASecretName }} +{{- end }} + - name: "config" + configMap: + name: {{ .Release.Name }}-auth + - name: "data" + {{- if and ($auth.persistence.enabled) ( and (not (eq $auth.chartMode "gcp")) (not (eq $auth.chartMode "aws")) (not (eq $auth.chartMode "azure"))) }} + persistentVolumeClaim: + claimName: {{ if $auth.persistence.existingClaimName }}{{ $auth.persistence.existingClaimName }}{{ else }}{{ .Release.Name }}{{ end }} + {{- else }} + emptyDir: {} + {{- end }} +{{- if $auth.extraVolumes }} + {{- toYaml $auth.extraVolumes | nindent 6 }} +{{- end }} +{{- if $auth.priorityClassName }} + priorityClassName: {{ $auth.priorityClassName }} +{{- end }} + serviceAccountName: {{ include "teleport-cluster.auth.serviceAccountName" . }} + terminationGracePeriodSeconds: {{ $auth.terminationGracePeriodSeconds }} diff --git a/helm/teleport-cluster/templates/auth/pdb.yaml b/helm/teleport-cluster/templates/auth/pdb.yaml new file mode 100644 index 0000000..0109589 --- /dev/null +++ b/helm/teleport-cluster/templates/auth/pdb.yaml @@ -0,0 +1,17 @@ +{{- $auth := mustMergeOverwrite (mustDeepCopy .Values) .Values.auth -}} +{{- if $auth.highAvailability.podDisruptionBudget.enabled }} +{{- if .Capabilities.APIVersions.Has "policy/v1" }} +apiVersion: policy/v1 +{{- else }} +apiVersion: policy/v1beta1 +{{- end }} +kind: PodDisruptionBudget +metadata: + name: {{ .Release.Name }}-auth + namespace: {{ .Release.Namespace }} + labels: {{- include "teleport-cluster.auth.labels" . | nindent 4 }} +spec: + minAvailable: {{ $auth.highAvailability.podDisruptionBudget.minAvailable }} + selector: + matchLabels: {{- include "teleport-cluster.auth.selectorLabels" . | nindent 6 }} +{{- end }} diff --git a/helm/teleport-cluster/templates/auth/predeploy_config.yaml b/helm/teleport-cluster/templates/auth/predeploy_config.yaml new file mode 100644 index 0000000..1419440 --- /dev/null +++ b/helm/teleport-cluster/templates/auth/predeploy_config.yaml @@ -0,0 +1,31 @@ +{{- $auth := mustMergeOverwrite (mustDeepCopy .Values) .Values.auth -}} +{{- if $auth.validateConfigOnDeploy }} +{{- $configTemplate := printf "teleport-cluster.auth.config.%s" $auth.chartMode -}} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-auth-test + namespace: {{ .Release.Namespace }} + labels: {{- include "teleport-cluster.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": pre-install,pre-upgrade + "helm.sh/hook-weight": "4" + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded +data: +{{- if $auth.createProxyToken }} + apply-on-startup.yaml: |2 + kind: token + version: v2 + metadata: + name: {{ .Release.Name }}-proxy + expires: "3000-01-01T00:00:00Z" + spec: + roles: [Proxy] + join_method: kubernetes + kubernetes: + allow: + - service_account: "{{ .Release.Namespace }}:{{ include "teleport-cluster.proxy.serviceAccountName" . }}" +{{- end }} + teleport.yaml: |2 + {{- mustMergeOverwrite (include $configTemplate . | fromYaml) $auth.teleportConfig | toYaml | nindent 4 -}} +{{- end }} diff --git a/helm/teleport-cluster/templates/auth/predeploy_job.yaml b/helm/teleport-cluster/templates/auth/predeploy_job.yaml new file mode 100644 index 0000000..a03225d --- /dev/null +++ b/helm/teleport-cluster/templates/auth/predeploy_job.yaml @@ -0,0 +1,103 @@ +{{- $auth := mustMergeOverwrite (mustDeepCopy .Values) .Values.auth -}} +{{- if $auth.validateConfigOnDeploy }} +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ .Release.Name }}-auth-test + namespace: {{ .Release.Namespace }} + labels: {{- include "teleport-cluster.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": pre-install,pre-upgrade + "helm.sh/hook-weight": "5" + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded +spec: + backoffLimit: 1 + template: + spec: +{{- if $auth.affinity }} + affinity: {{- toYaml $auth.affinity | nindent 8 }} +{{- end }} +{{- if $auth.tolerations }} + tolerations: {{- toYaml $auth.tolerations | nindent 6 }} +{{- end }} +{{- if $auth.imagePullSecrets }} + imagePullSecrets: + {{- toYaml $auth.imagePullSecrets | nindent 6 }} +{{- end }} + restartPolicy: Never + containers: + - name: "teleport-config-check" + image: '{{ if $auth.enterprise }}{{ $auth.enterpriseImage }}{{ else }}{{ $auth.image }}{{ end }}:{{ include "teleport-cluster.version" . }}' + imagePullPolicy: {{ $auth.imagePullPolicy }} +{{- if $auth.resources }} + resources: + {{- toYaml $auth.resources | nindent 10 }} +{{- end }} +{{- if or $auth.extraEnv $auth.tls.existingCASecretName }} + env: + {{- if (gt (len $auth.extraEnv) 0) }} + {{- toYaml $auth.extraEnv | nindent 8 }} + {{- end }} + {{- if $auth.tls.existingCASecretName }} + - name: SSL_CERT_FILE + value: /etc/teleport-tls-ca/ca.pem + {{- end }} +{{- end }} + command: + - "teleport" + - "configure" + args: + - "--test" + - "/etc/teleport/teleport.yaml" +{{- if .Values.securityContext }} + securityContext: {{- toYaml .Values.securityContext | nindent 10 }} +{{- end }} + volumeMounts: +{{- if .Values.enterprise }} + - mountPath: /var/lib/license + name: "license" + readOnly: true +{{- end }} +{{- if and (.Values.gcp.credentialSecretName) (eq .Values.chartMode "gcp") }} + - mountPath: /etc/teleport-secrets + name: "gcp-credentials" + readOnly: true +{{- end }} +{{- if .Values.tls.existingCASecretName }} + - mountPath: /etc/teleport-tls-ca + name: "teleport-tls-ca" + readOnly: true +{{- end }} + - mountPath: /etc/teleport + name: "config" + readOnly: true + - mountPath: /var/lib/teleport + name: "data" +{{- if .Values.extraVolumeMounts }} + {{- toYaml .Values.extraVolumeMounts | nindent 8 }} +{{- end }} + volumes: +{{- if .Values.enterprise }} + - name: license + secret: + secretName: "license" +{{- end }} +{{- if and (.Values.gcp.credentialSecretName) (eq .Values.chartMode "gcp") }} + - name: gcp-credentials + secret: + secretName: {{ .Values.gcp.credentialSecretName | quote }} +{{- end }} +{{- if .Values.tls.existingCASecretName }} + - name: teleport-tls-ca + secret: + secretName: {{ .Values.tls.existingCASecretName }} +{{- end }} + - name: "config" + configMap: + name: {{ .Release.Name }}-auth-test + - name: "data" + emptyDir: {} +{{- if .Values.extraVolumes }} + {{- toYaml .Values.extraVolumes | nindent 6 }} +{{- end }} +{{- end }} diff --git a/helm/teleport-cluster/templates/auth/pvc.yaml b/helm/teleport-cluster/templates/auth/pvc.yaml new file mode 100644 index 0000000..640e3eb --- /dev/null +++ b/helm/teleport-cluster/templates/auth/pvc.yaml @@ -0,0 +1,24 @@ +{{- $auth := mustMergeOverwrite (mustDeepCopy .Values) .Values.auth -}} +{{- if $auth.persistence.enabled }} + {{/* Disable persistence for cloud modes */}} + {{- if and (not (eq $auth.chartMode "aws")) (not (eq $auth.chartMode "gcp")) (not (eq $auth.chartMode "azure")) }} + {{/* No need to create a PVC if we reuse an existing claim */}} + {{- if not $auth.persistence.existingClaimName }} +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ .Release.Name }} + namespace: {{ .Release.Namespace }} + labels: {{- include "teleport-cluster.auth.labels" . | nindent 4 }} +spec: + accessModes: + - ReadWriteOnce + {{- if $auth.persistence.storageClassName }} + storageClassName: {{ $auth.persistence.storageClassName }} + {{- end }} + resources: + requests: + storage: {{ required "persistence.volumeSize is required in chart values" $auth.persistence.volumeSize }} + {{- end }} + {{- end }} +{{- end }} diff --git a/helm/teleport-cluster/templates/auth/service-previous-version.yaml b/helm/teleport-cluster/templates/auth/service-previous-version.yaml new file mode 100644 index 0000000..75b4b06 --- /dev/null +++ b/helm/teleport-cluster/templates/auth/service-previous-version.yaml @@ -0,0 +1,31 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "teleport-cluster.auth.previousVersionServiceName" . }} + namespace: {{ .Release.Namespace }} + labels: {{- include "teleport-cluster.auth.labels" . | nindent 4 }} +spec: + # This is a headless service. Resolving it will return the list of all auth pods running the previous major version + # Proxies should not connect to auth pods from the previous major version + # Proxy rollout should be held until this headLessService does not match pods anymore. + clusterIP: "None" + # Publishing not ready addresses ensures that unhealthy or terminating pods are still accounted for + publishNotReadyAddresses: true + selector: + {{- include "teleport-cluster.auth.selectorLabels" . | nindent 4 }} + teleport.dev/majorVersion: {{ include "teleport-cluster.previousMajorVersion" . | quote }} +--- +apiVersion: v1 +kind: Service +metadata: + name: {{ include "teleport-cluster.auth.currentVersionServiceName" . }} + namespace: {{ .Release.Namespace }} + labels: {{- include "teleport-cluster.auth.labels" . | nindent 4 }} +spec: + # This is a headless service. Resolving it will return the list of all auth pods running the current major version + clusterIP: "None" + # Publishing not ready addresses ensures that unhealthy or terminating pods are still accounted for + publishNotReadyAddresses: true + selector: + {{- include "teleport-cluster.auth.selectorLabels" . | nindent 4 }} + teleport.dev/majorVersion: {{ include "teleport-cluster.majorVersion" . | quote }} diff --git a/helm/teleport-cluster/templates/auth/service.yaml b/helm/teleport-cluster/templates/auth/service.yaml new file mode 100644 index 0000000..e5175fb --- /dev/null +++ b/helm/teleport-cluster/templates/auth/service.yaml @@ -0,0 +1,21 @@ +{{- $auth := mustMergeOverwrite (mustDeepCopy .Values) .Values.auth -}} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "teleport-cluster.auth.serviceName" . }} + namespace: {{ .Release.Namespace }} + labels: {{- include "teleport-cluster.auth.labels" . | nindent 4 }} +{{- if $auth.annotations.service }} + annotations: {{- toYaml $auth.annotations.service | nindent 4 }} +{{- end }} +spec: + ports: + - name: auth + port: 3025 + targetPort: 3025 + protocol: TCP + - name: kube + port: 3026 + targetPort: 3026 + protocol: TCP + selector: {{- include "teleport-cluster.auth.selectorLabels" . | nindent 4 }} diff --git a/helm/teleport-cluster/templates/auth/serviceaccount.yaml b/helm/teleport-cluster/templates/auth/serviceaccount.yaml new file mode 100644 index 0000000..2ee2e1a --- /dev/null +++ b/helm/teleport-cluster/templates/auth/serviceaccount.yaml @@ -0,0 +1,17 @@ +{{- $auth := mustMergeOverwrite (mustDeepCopy .Values) .Values.auth -}} +{{- if $auth.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "teleport-cluster.auth.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} + {{- if or $auth.annotations.serviceAccount $auth.azure.clientID }} + annotations: + {{- if $auth.annotations.serviceAccount }} + {{- toYaml $auth.annotations.serviceAccount | nindent 4 }} + {{- end }} + {{- if $auth.azure.clientID }} + azure.workload.identity/client-id: "{{ $auth.azure.clientID }}" + {{- end }} + {{- end -}} +{{- end }} diff --git a/helm/teleport-cluster/templates/podmonitor.yaml b/helm/teleport-cluster/templates/podmonitor.yaml new file mode 100644 index 0000000..7201cae --- /dev/null +++ b/helm/teleport-cluster/templates/podmonitor.yaml @@ -0,0 +1,31 @@ +{{- if.Values.podMonitor.enabled -}} +apiVersion: monitoring.coreos.com/v1 +kind: PodMonitor +metadata: + name: {{ .Release.Name }} + namespace: {{ .Release.Namespace }} + labels: + {{- include "teleport-cluster.labels" . | nindent 4 }} + {{- with .Values.podMonitor.additionalLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + jobLabel: {{ .Release.Name }} + namespaceSelector: + matchNames: + - {{ .Release.Namespace }} + selector: + matchLabels: {{- include "teleport-cluster.selectorLabels" . | nindent 6 }} + podMetricsEndpoints: + - port: diag + path: /metrics + {{- with .Values.podMonitor.interval }} + interval: {{ . | quote }} + {{- end }} + podTargetLabels: + - "app.kubernetes.io/name" + - "app.kubernetes.io/instance" + - "app.kubernetes.io/component" + - "app.kubernetes.io/version" + - "teleport.dev/majorVersion" +{{- end }} diff --git a/helm/teleport-cluster/templates/proxy/_config.aws.tpl b/helm/teleport-cluster/templates/proxy/_config.aws.tpl new file mode 100644 index 0000000..3e4d97a --- /dev/null +++ b/helm/teleport-cluster/templates/proxy/_config.aws.tpl @@ -0,0 +1,3 @@ +{{- define "teleport-cluster.proxy.config.aws" -}} +{{ include "teleport-cluster.proxy.config.common" . }} +{{- end -}} diff --git a/helm/teleport-cluster/templates/proxy/_config.azure.tpl b/helm/teleport-cluster/templates/proxy/_config.azure.tpl new file mode 100644 index 0000000..96ccbc7 --- /dev/null +++ b/helm/teleport-cluster/templates/proxy/_config.azure.tpl @@ -0,0 +1,3 @@ +{{- define "teleport-cluster.proxy.config.azure" -}} +{{ include "teleport-cluster.proxy.config.common" . }} +{{- end -}} diff --git a/helm/teleport-cluster/templates/proxy/_config.common.tpl b/helm/teleport-cluster/templates/proxy/_config.common.tpl new file mode 100644 index 0000000..b6c5e41 --- /dev/null +++ b/helm/teleport-cluster/templates/proxy/_config.common.tpl @@ -0,0 +1,76 @@ +{{- define "teleport-cluster.proxy.config.common" -}} +{{- $logLevel := (coalesce .Values.logLevel .Values.log.level "INFO") -}} +version: v3 +teleport: + join_params: + method: kubernetes + token_name: "{{.Release.Name}}-proxy" + auth_server: "{{ include "teleport-cluster.auth.serviceFQDN" . }}:3025" + log: + severity: {{ $logLevel }} + output: {{ .Values.log.output }} + format: + output: {{ .Values.log.format }} + extra_fields: {{ .Values.log.extraFields | toJson }} +ssh_service: + enabled: false +auth_service: + enabled: false +proxy_service: + enabled: true +{{- if .Values.publicAddr }} + public_addr: {{- toYaml .Values.publicAddr | nindent 8 }} +{{- else }} + public_addr: '{{ required "clusterName is required in chart values" .Values.clusterName }}:443' +{{- end }} +{{- if ne .Values.proxyListenerMode "multiplex" }} + listen_addr: 0.0.0.0:3023 + {{- if .Values.sshPublicAddr }} + ssh_public_addr: {{- toYaml .Values.sshPublicAddr | nindent 8 }} + {{- end }} + tunnel_listen_addr: 0.0.0.0:3024 + {{- if .Values.tunnelPublicAddr }} + tunnel_public_addr: {{- toYaml .Values.tunnelPublicAddr | nindent 8 }} + {{- end }} + kube_listen_addr: 0.0.0.0:3026 + {{- if .Values.kubePublicAddr }} + kube_public_addr: {{- toYaml .Values.kubePublicAddr | nindent 8 }} + {{- end }} + mysql_listen_addr: 0.0.0.0:3036 + {{- if .Values.mysqlPublicAddr }} + mysql_public_addr: {{- toYaml .Values.mysqlPublicAddr | nindent 8 }} + {{- end }} + {{- if .Values.separatePostgresListener }} + postgres_listen_addr: 0.0.0.0:5432 + {{- if .Values.postgresPublicAddr }} + postgres_public_addr: {{- toYaml .Values.postgresPublicAddr | nindent 8 }} + {{- else }} + postgres_public_addr: {{ .Values.clusterName }}:5432 + {{- end }} + {{- end }} + {{- if .Values.separateMongoListener }} + mongo_listen_addr: 0.0.0.0:27017 + {{- if .Values.mongoPublicAddr }} + mongo_public_addr: {{- toYaml .Values.mongoPublicAddr | nindent 8 }} + {{- else }} + mongo_public_addr: {{ .Values.clusterName }}:27017 + {{- end }} + {{- end }} +{{- end }} +{{- if or .Values.highAvailability.certManager.enabled .Values.tls.existingSecretName }} + https_keypairs: + - key_file: /etc/teleport-tls/tls.key + cert_file: /etc/teleport-tls/tls.crt + https_keypairs_reload_interval: 12h +{{- else if .Values.acme }} + acme: + enabled: {{ .Values.acme }} + email: {{ required "acmeEmail is required in chart values" .Values.acmeEmail }} + {{- if .Values.acmeURI }} + uri: {{ .Values.acmeURI }} + {{- end }} +{{- end }} +{{- if and .Values.ingress.enabled (semverCompare ">= 13.2.0-0" (include "teleport-cluster.version" .)) }} + trust_x_forwarded_for: true +{{- end }} +{{- end -}} diff --git a/helm/teleport-cluster/templates/proxy/_config.gcp.tpl b/helm/teleport-cluster/templates/proxy/_config.gcp.tpl new file mode 100644 index 0000000..cf9c79d --- /dev/null +++ b/helm/teleport-cluster/templates/proxy/_config.gcp.tpl @@ -0,0 +1,3 @@ +{{- define "teleport-cluster.proxy.config.gcp" -}} +{{ include "teleport-cluster.proxy.config.common" . }} +{{- end -}} diff --git a/helm/teleport-cluster/templates/proxy/_config.scratch.tpl b/helm/teleport-cluster/templates/proxy/_config.scratch.tpl new file mode 100644 index 0000000..0efddce --- /dev/null +++ b/helm/teleport-cluster/templates/proxy/_config.scratch.tpl @@ -0,0 +1,12 @@ +{{- define "teleport-cluster.proxy.config.scratch" -}} +ssh_service: + enabled: false +auth_service: + enabled: false +proxy_service: + enabled: true +{{- end -}} + +{{- define "teleport-cluster.proxy.config.custom" -}} +{{ fail "'custom' mode has been removed with chart v12 because of the proxy/auth split breaking change, see https://goteleport.com/docs/deploy-a-cluster/helm-deployments/migration-v12/" }} +{{- end -}} diff --git a/helm/teleport-cluster/templates/proxy/_config.standalone.tpl b/helm/teleport-cluster/templates/proxy/_config.standalone.tpl new file mode 100644 index 0000000..7355813 --- /dev/null +++ b/helm/teleport-cluster/templates/proxy/_config.standalone.tpl @@ -0,0 +1,3 @@ +{{- define "teleport-cluster.proxy.config.standalone" -}} +{{ include "teleport-cluster.proxy.config.common" . }} +{{- end -}} diff --git a/helm/teleport-cluster/templates/proxy/certificate.yaml b/helm/teleport-cluster/templates/proxy/certificate.yaml new file mode 100644 index 0000000..d1a98ee --- /dev/null +++ b/helm/teleport-cluster/templates/proxy/certificate.yaml @@ -0,0 +1,27 @@ +{{- $proxy := mustMergeOverwrite (mustDeepCopy .Values) .Values.proxy -}} +{{- if $proxy.highAvailability.certManager.enabled }} + {{- $domain := (required "clusterName is required in chartValues when certManager is enabled" $proxy.clusterName) }} + {{- $domainWildcard := printf "*.%s" (required "clusterName is required in chartValues when certManager is enabled" $proxy.clusterName) }} +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: {{ .Release.Name }} + namespace: {{ .Release.Namespace }} + labels: {{- include "teleport-cluster.proxy.labels" . | nindent 4 }} +spec: + secretName: teleport-tls + {{- if $proxy.highAvailability.certManager.addCommonName }} + commonName: {{ quote $domain }} + {{- end }} + dnsNames: + - {{ quote $domain }} + - {{ quote $domainWildcard }} + issuerRef: + name: {{ required "highAvailability.certManager.issuerName is required in chart values" $proxy.highAvailability.certManager.issuerName }} + kind: {{ required "highAvailability.certManager.issuerKind is required in chart values" $proxy.highAvailability.certManager.issuerKind }} + group: {{ required "highAvailability.certManager.issuerGroup is required in chart values" $proxy.highAvailability.certManager.issuerGroup }} + {{- with $proxy.annotations.certSecret }} + secretTemplate: + annotations: {{- toYaml . | nindent 6 }} + {{- end }} +{{- end }} diff --git a/helm/teleport-cluster/templates/proxy/config.yaml b/helm/teleport-cluster/templates/proxy/config.yaml new file mode 100644 index 0000000..8cd7788 --- /dev/null +++ b/helm/teleport-cluster/templates/proxy/config.yaml @@ -0,0 +1,16 @@ +{{- $proxy := mustMergeOverwrite (mustDeepCopy .Values) .Values.proxy -}} +{{- $configTemplate := printf "teleport-cluster.proxy.config.%s" $proxy.chartMode -}} +{{- if (contains ":" $proxy.clusterName) -}} + {{- fail "clusterName must not contain a colon, you can override the cluster's public address with publicAddr" -}} +{{- end -}} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-proxy + namespace: {{ .Release.Namespace }} +{{- if $proxy.annotations.config }} + annotations: {{- toYaml $proxy.annotations.config | nindent 4 }} +{{- end }} +data: + teleport.yaml: |2 + {{- mustMergeOverwrite (include $configTemplate . | fromYaml) $proxy.teleportConfig | toYaml | nindent 4 -}} diff --git a/helm/teleport-cluster/templates/proxy/deployment.yaml b/helm/teleport-cluster/templates/proxy/deployment.yaml new file mode 100644 index 0000000..a77c339 --- /dev/null +++ b/helm/teleport-cluster/templates/proxy/deployment.yaml @@ -0,0 +1,307 @@ +{{- $proxy := mustMergeOverwrite (mustDeepCopy .Values) .Values.proxy -}} +{{- $replicable := or $proxy.highAvailability.certManager.enabled $proxy.tls.existingSecretName -}} +{{- $projectedServiceAccountToken := semverCompare ">=1.20.0-0" .Capabilities.KubeVersion.Version }} +# Deployment is {{ if not $replicable }}not {{end}}replicable +{{- if and $proxy.highAvailability.certManager.enabled $proxy.tls.existingSecretName }} +{{- fail "Cannot set both highAvailability.certManager.enabled and tls.existingSecretName, choose one or the other" }} +{{- end }} +{{- if and $proxy.acme $proxy.tls.existingSecretName }} +{{- fail "Cannot set both acme.enabled and tls.existingSecretName, choose one or the other" }} +{{- end }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Release.Name }}-proxy + namespace: {{ .Release.Namespace }} + labels: {{- include "teleport-cluster.proxy.labels" . | nindent 4 }} +{{- if $proxy.annotations.deployment }} + annotations: {{- toYaml $proxy.annotations.deployment | nindent 4 }} +{{- end }} +spec: +{{- /* + If proxies cannot be replicated we use a single replica. + By default we want to upgrade all users to at least 2 replicas, if they had a higher replica count we take it. + If a user wants to force a single proxy, they can use the `proxy` specific override. + + $proxySpecificHA is a hack to avoid .Values.proxy.highAvailability to be nil, which would cause a fail when + accessing .Values.proxy.highAvailability.replicaCount. +*/}} +{{- if $replicable }} + {{- $proxySpecificHA := default (dict) .Values.proxy.highAvailability }} + {{- if $proxySpecificHA.replicaCount }} + replicas: {{ $proxySpecificHA.replicaCount }} + {{- else }} + replicas: {{ max .Values.highAvailability.replicaCount 2 }} + {{- end }} + {{- if $proxy.highAvailability.minReadySeconds }} + minReadySeconds: {{ $proxy.highAvailability.minReadySeconds }} + {{- end }} +{{- else }} + replicas: 1 +{{- end }} + selector: + matchLabels: {{- include "teleport-cluster.proxy.selectorLabels" . | nindent 6 }} + template: + metadata: + annotations: + # ConfigMap checksum, to recreate the pod on config changes. + checksum/config: {{ include (print $.Template.BasePath "/proxy/config.yaml") . | sha256sum }} +{{- if $proxy.annotations.pod }} + {{- toYaml $proxy.annotations.pod | nindent 8 }} +{{- end }} + labels: {{- include "teleport-cluster.proxy.labels" . | nindent 8 }} + spec: +{{- if $proxy.nodeSelector }} + nodeSelector: {{- toYaml $proxy.nodeSelector | nindent 8 }} +{{- end }} + affinity: +{{- if $proxy.affinity }} + {{- if $proxy.highAvailability.requireAntiAffinity }} + {{- fail "Cannot use highAvailability.requireAntiAffinity when affinity is also set in chart values - unset one or the other" }} + {{- end }} + {{- toYaml $proxy.affinity | nindent 8 }} +{{- else }} + podAntiAffinity: + {{- if $proxy.highAvailability.requireAntiAffinity }} + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: app.kubernetes.io/instance + operator: In + values: + - {{ .Release.Name }} + - key: app.kubernetes.io/component + operator: In + values: + - proxy + topologyKey: "kubernetes.io/hostname" + {{- else if gt (int $proxy.highAvailability.replicaCount) 1 }} + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 50 + podAffinityTerm: + labelSelector: + matchExpressions: + - key: app.kubernetes.io/instance + operator: In + values: + - {{ .Release.Name }} + - key: app.kubernetes.io/component + operator: In + values: + - proxy + topologyKey: "kubernetes.io/hostname" + {{- end }} +{{- end }} +{{- if $proxy.tolerations }} + tolerations: {{- toYaml $proxy.tolerations | nindent 6 }} +{{- end }} +{{- if $proxy.imagePullSecrets }} + imagePullSecrets: + {{- toYaml $proxy.imagePullSecrets | nindent 6 }} +{{- end }} + initContainers: + # wait-auth-update is responsible for holding off the proxy rollout until all auths are running the + # next major version in case of major upgrade. + - name: wait-auth-update + image: '{{ if $proxy.enterprise }}{{ $proxy.enterpriseImage }}{{ else }}{{ $proxy.image }}{{ end }}:{{ include "teleport-cluster.version" . }}' + command: + - teleport + - wait + - no-resolve + - '{{ include "teleport-cluster.auth.previousVersionServiceName" . }}.{{ .Release.Namespace }}.svc.cluster.local' +{{- if $proxy.securityContext }} + securityContext: {{- toYaml $proxy.securityContext | nindent 12 }} +{{- end }} +{{- if $proxy.initContainers }} + {{- range $initContainer := $proxy.initContainers }} + {{- if and (not $initContainer.resources) $proxy.resources }} + {{- $_ := set $initContainer "resources" $proxy.resources }} + {{- end }} + {{- list $initContainer | toYaml | nindent 8 }} + {{- /* Note: this will break if the user sets volumeMounts to its initContainer */}} + volumeMounts: + {{- if or $proxy.highAvailability.certManager.enabled $proxy.tls.existingSecretName }} + - mountPath: /etc/teleport-tls + name: "teleport-tls" + readOnly: true + {{- end }} + - mountPath: /etc/teleport + name: "config" + readOnly: true + - mountPath: /var/lib/teleport + name: "data" + {{- if $proxy.extraVolumeMounts }} + {{- toYaml $proxy.extraVolumeMounts | nindent 10 }} + {{- end }} + {{- end }} +{{- end }} + containers: + - name: "teleport" + image: '{{ if $proxy.enterprise }}{{ $proxy.enterpriseImage }}{{ else }}{{ $proxy.image }}{{ end }}:{{ include "teleport-cluster.version" . }}' + imagePullPolicy: {{ $proxy.imagePullPolicy }} + {{- if or $proxy.extraEnv $proxy.tls.existingCASecretName }} + env: + {{- if (gt (len $proxy.extraEnv) 0) }} + {{- toYaml $proxy.extraEnv | nindent 8 }} + {{- end }} + {{- if $proxy.tls.existingCASecretName }} + - name: SSL_CERT_FILE + value: /etc/teleport-tls-ca/ca.pem + {{- end }} + {{- end }} + args: + - "--diag-addr=0.0.0.0:3000" + {{- if $proxy.insecureSkipProxyTLSVerify }} + - "--insecure" + {{- end }} + {{- if $proxy.extraArgs }} + {{- toYaml $proxy.extraArgs | nindent 8 }} + {{- end }} + ports: + - name: tls + containerPort: 3080 + protocol: TCP + {{- if $proxy.enterprise }} + - name: proxypeering + containerPort: 3021 + protocol: TCP + {{- end }} + {{- if ne $proxy.proxyListenerMode "multiplex" }} + - name: sshproxy + containerPort: 3023 + protocol: TCP + - name: sshtun + containerPort: 3024 + protocol: TCP + - name: kube + containerPort: 3026 + protocol: TCP + - name: mysql + containerPort: 3036 + protocol: TCP + {{- if $proxy.separatePostgresListener }} + - name: postgres + containerPort: 5432 + protocol: TCP + {{- end }} + {{- if $proxy.separateMongoListener }} + - name: mongo + containerPort: 27017 + protocol: TCP + {{- end }} + {{- end }} + - name: diag + containerPort: 3000 + protocol: TCP + livenessProbe: + httpGet: + path: /healthz + port: diag + initialDelaySeconds: 5 # wait 5s for agent to start + periodSeconds: 5 # poll health every 5s + failureThreshold: 6 # consider agent unhealthy after 30s (6 * 5s) + timeoutSeconds: {{ $proxy.probeTimeoutSeconds }} + readinessProbe: + httpGet: + path: /readyz + port: diag + initialDelaySeconds: 5 # wait 5s for agent to register + periodSeconds: 5 # poll health every 5s + failureThreshold: 12 # consider agent unhealthy after 60s (12 * 5s) + timeoutSeconds: {{ $proxy.probeTimeoutSeconds }} + lifecycle: + # waiting during preStop ensures no new request will hit the Terminating pod + # on clusters using kube-proxy (kube-proxy syncs the node iptables rules every 30s) + preStop: + exec: + command: + - teleport + - wait + - duration + - 30s +{{- if $proxy.postStart.command }} + postStart: + exec: + command: {{ toYaml $proxy.postStart.command | nindent 14 }} +{{- end }} +{{- if $proxy.resources }} + resources: + {{- toYaml $proxy.resources | nindent 10 }} +{{- end }} +{{- if $proxy.securityContext }} + securityContext: {{- toYaml $proxy.securityContext | nindent 10 }} +{{- end }} + volumeMounts: +{{- if or $proxy.highAvailability.certManager.enabled $proxy.tls.existingSecretName }} + - mountPath: /etc/teleport-tls + name: "teleport-tls" + readOnly: true +{{- end }} +{{- if $proxy.tls.existingCASecretName }} + - mountPath: /etc/teleport-tls-ca + name: "teleport-tls-ca" + readOnly: true +{{- end }} + - mountPath: /etc/teleport + name: "config" + readOnly: true + - mountPath: /var/lib/teleport + name: "data" +{{- if $projectedServiceAccountToken }} + - mountPath: /var/run/secrets/kubernetes.io/serviceaccount + name: proxy-serviceaccount-token + readOnly: true +{{- end }} +{{- if $proxy.extraVolumeMounts }} + {{- toYaml $proxy.extraVolumeMounts | nindent 8 }} +{{- end }} +{{- if $projectedServiceAccountToken }} + automountServiceAccountToken: false +{{- end }} + volumes: +{{- if $projectedServiceAccountToken }} + # This projected token volume mimics the `automountServiceAccountToken` + # behaviour but defaults to a 1h TTL instead of 1y. + - name: proxy-serviceaccount-token + projected: + sources: + - serviceAccountToken: + path: token + - configMap: + items: + - key: ca.crt + path: ca.crt + name: kube-root-ca.crt + - downwardAPI: + items: + - path: "namespace" + fieldRef: + fieldPath: metadata.namespace +{{- end }} +{{- if $proxy.highAvailability.certManager.enabled }} + - name: teleport-tls + secret: + secretName: teleport-tls +{{- else if $proxy.tls.existingSecretName }} + - name: teleport-tls + secret: + secretName: {{ $proxy.tls.existingSecretName }} +{{- end }} +{{- if $proxy.tls.existingCASecretName }} + - name: teleport-tls-ca + secret: + secretName: {{ $proxy.tls.existingCASecretName }} +{{- end }} + - name: "config" + configMap: + name: {{ .Release.Name }}-proxy + - name: "data" + emptyDir: {} +{{- if $proxy.extraVolumes }} + {{- toYaml $proxy.extraVolumes | nindent 6 }} +{{- end }} +{{- if $proxy.priorityClassName }} + priorityClassName: {{ $proxy.priorityClassName }} +{{- end }} + serviceAccountName: {{ include "teleport-cluster.proxy.serviceAccountName" . }} + terminationGracePeriodSeconds: {{ $proxy.terminationGracePeriodSeconds }} diff --git a/helm/teleport-cluster/templates/proxy/ingress.yaml b/helm/teleport-cluster/templates/proxy/ingress.yaml new file mode 100644 index 0000000..e0a2e38 --- /dev/null +++ b/helm/teleport-cluster/templates/proxy/ingress.yaml @@ -0,0 +1,57 @@ +{{- $proxy := mustMergeOverwrite (mustDeepCopy .Values) .Values.proxy -}} +{{- if .Values.ingress.enabled -}} + {{- if (not (eq .Values.proxyListenerMode "multiplex")) -}} + {{- fail "Use of an ingress requires TLS multiplexing to be enabled, so you must also set proxyListenerMode=multiplex - see https://goteleport.com/docs/architecture/tls-routing/" -}} + {{- end -}} + {{- $publicAddr := coalesce .Values.publicAddr (list .Values.clusterName) -}} + {{- /* Trim ports from all public addresses if present */ -}} + {{- range $publicAddr -}} + {{- $address := . -}} + {{- if (contains ":" $address) -}} + {{- $split := split ":" $address -}} + {{- $address = $split._0 -}} + {{- $publicAddr = append (mustWithout $publicAddr .) $address -}} + {{- end -}} + {{- $wildcard := printf "*.%s" $address -}} + {{- /* Add wildcard versions of all public addresses to ingress, unless 1) suppressed or 2) wildcard version already exists */ -}} + {{- if and (not $.Values.ingress.suppressAutomaticWildcards) (not (hasPrefix "*." $address)) (not (has $wildcard $publicAddr)) -}} + {{- $publicAddr = append $publicAddr (printf "*.%s" $address) -}} + {{- end -}} + {{- end -}} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ .Release.Name }}-proxy + namespace: {{ .Release.Namespace }} + labels: {{- include "teleport-cluster.proxy.labels" . | nindent 4 }} + {{- if $proxy.annotations.ingress }} + annotations: {{- toYaml $proxy.annotations.ingress | nindent 4 }} + {{- end }} +spec: + {{- with $proxy.ingress.spec }} + {{- toYaml . | nindent 2 }} + {{- end }} + tls: + - hosts: + {{- range $publicAddr }} + - {{ quote . }} + {{- end }} + {{- if $proxy.highAvailability.certManager.enabled }} + secretName: teleport-tls + {{- else if $proxy.tls.existingSecretName }} + secretName: {{ $proxy.tls.existingSecretName }} + {{- end }} + rules: + {{- range $publicAddr }} + - host: {{ quote . }} + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: {{ $.Release.Name }} + port: + number: 443 + {{- end }} +{{- end }} diff --git a/helm/teleport-cluster/templates/proxy/pdb.yaml b/helm/teleport-cluster/templates/proxy/pdb.yaml new file mode 100644 index 0000000..f220031 --- /dev/null +++ b/helm/teleport-cluster/templates/proxy/pdb.yaml @@ -0,0 +1,17 @@ +{{- $proxy := mustMergeOverwrite (mustDeepCopy .Values) .Values.proxy -}} +{{- if $proxy.highAvailability.podDisruptionBudget.enabled }} +{{- if .Capabilities.APIVersions.Has "policy/v1" }} +apiVersion: policy/v1 +{{- else }} +apiVersion: policy/v1beta1 +{{- end }} +kind: PodDisruptionBudget +metadata: + name: {{ .Release.Name }}-proxy + namespace: {{ .Release.Namespace }} + labels: {{- include "teleport-cluster.proxy.labels" . | nindent 4 }} +spec: + minAvailable: {{ $proxy.highAvailability.podDisruptionBudget.minAvailable }} + selector: + matchLabels: {{- include "teleport-cluster.proxy.selectorLabels" . | nindent 6 }} +{{- end }} diff --git a/helm/teleport-cluster/templates/proxy/predeploy_config.yaml b/helm/teleport-cluster/templates/proxy/predeploy_config.yaml new file mode 100644 index 0000000..6e2d374 --- /dev/null +++ b/helm/teleport-cluster/templates/proxy/predeploy_config.yaml @@ -0,0 +1,16 @@ +{{- $proxy := mustMergeOverwrite (mustDeepCopy .Values) .Values.proxy -}} +{{- if $proxy.validateConfigOnDeploy }} +{{- $configTemplate := printf "teleport-cluster.proxy.config.%s" $proxy.chartMode -}} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-proxy-test + namespace: {{ .Release.Namespace }} + annotations: + "helm.sh/hook": pre-install,pre-upgrade + "helm.sh/hook-weight": "4" + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded +data: + teleport.yaml: |2 + {{- mustMergeOverwrite (include $configTemplate . | fromYaml) $proxy.teleportConfig | toYaml | nindent 4 -}} +{{- end }} diff --git a/helm/teleport-cluster/templates/proxy/predeploy_job.yaml b/helm/teleport-cluster/templates/proxy/predeploy_job.yaml new file mode 100644 index 0000000..e0fb551 --- /dev/null +++ b/helm/teleport-cluster/templates/proxy/predeploy_job.yaml @@ -0,0 +1,99 @@ +{{- $proxy := mustMergeOverwrite (mustDeepCopy .Values) .Values.proxy -}} +{{- if $proxy.validateConfigOnDeploy }} +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ .Release.Name }}-proxy-test + namespace: {{ .Release.Namespace }} + labels: {{- include "teleport-cluster.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": pre-install,pre-upgrade + "helm.sh/hook-weight": "5" + "helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded +spec: + backoffLimit: 1 + template: + spec: +{{- if $proxy.affinity }} + affinity: {{- toYaml $proxy.affinity | nindent 8 }} +{{- end }} +{{- if $proxy.tolerations }} + tolerations: {{- toYaml $proxy.tolerations | nindent 6 }} +{{- end }} +{{- if $proxy.imagePullSecrets }} + imagePullSecrets: + {{- toYaml $proxy.imagePullSecrets | nindent 6 }} +{{- end }} + restartPolicy: Never + containers: + - name: "teleport" + image: '{{ if $proxy.enterprise }}{{ $proxy.enterpriseImage }}{{ else }}{{ $proxy.image }}{{ end }}:{{ include "teleport-cluster.version" . }}' + imagePullPolicy: {{ $proxy.imagePullPolicy }} +{{- if $proxy.resources }} + resources: + {{- toYaml $proxy.resources | nindent 10 }} +{{- end }} +{{- if or $proxy.extraEnv $proxy.tls.existingCASecretName }} + env: + {{- if (gt (len $proxy.extraEnv) 0) }} + {{- toYaml $proxy.extraEnv | nindent 8 }} + {{- end }} + {{- if $proxy.tls.existingCASecretName }} + - name: SSL_CERT_FILE + value: /etc/teleport-tls-ca/ca.pem + {{- end }} +{{- end }} + command: + - "teleport" + - "configure" + args: + - "--test" + - "/etc/teleport/teleport.yaml" +{{- if $proxy.securityContext }} + securityContext: {{- toYaml $proxy.securityContext | nindent 10 }} +{{- end }} + volumeMounts: +{{- if or $proxy.highAvailability.certManager.enabled $proxy.tls.existingSecretName }} + - mountPath: /etc/teleport-tls + name: "teleport-tls" + readOnly: true +{{- end }} +{{- if $proxy.tls.existingCASecretName }} + - mountPath: /etc/teleport-tls-ca + name: "teleport-tls-ca" + readOnly: true +{{- end }} + - mountPath: /etc/teleport + name: "config" + readOnly: true + - mountPath: /var/lib/teleport + name: "data" +{{- if $proxy.extraVolumeMounts }} + {{- toYaml $proxy.extraVolumeMounts | nindent 8 }} +{{- end }} + volumes: +{{- if $proxy.highAvailability.certManager.enabled }} + - name: teleport-tls + secret: + secretName: teleport-tls + # this avoids deadlock during initial setup + optional: true +{{- else if $proxy.tls.existingSecretName }} + - name: teleport-tls + secret: + secretName: {{ $proxy.tls.existingSecretName }} +{{- end }} +{{- if $proxy.tls.existingCASecretName }} + - name: teleport-tls-ca + secret: + secretName: {{ $proxy.tls.existingCASecretName }} +{{- end }} + - name: "config" + configMap: + name: {{ .Release.Name }}-proxy-test + - name: "data" + emptyDir: {} +{{- if $proxy.extraVolumes }} + {{- toYaml $proxy.extraVolumes | nindent 6 }} +{{- end }} +{{- end }} diff --git a/helm/teleport-cluster/templates/proxy/service.yaml b/helm/teleport-cluster/templates/proxy/service.yaml new file mode 100644 index 0000000..b7e9c27 --- /dev/null +++ b/helm/teleport-cluster/templates/proxy/service.yaml @@ -0,0 +1,70 @@ +{{- $proxy := mustMergeOverwrite (mustDeepCopy .Values) .Values.proxy -}} +{{- $backendProtocol := ternary "ssl" "tcp" (hasKey $proxy.annotations.service "service.beta.kubernetes.io/aws-load-balancer-ssl-cert") -}} +{{- /* Fail early if proxy service type is set to LoadBalancer when ingress.enabled=true */ -}} +{{- if and $proxy.ingress.enabled (eq $proxy.service.type "LoadBalancer") -}} + {{- fail "proxy.service.type must not be LoadBalancer when using an ingress - any load balancer should be provisioned by your ingress controller. Set proxy.service.type=ClusterIP instead" -}} +{{- end -}} +apiVersion: v1 +kind: Service +metadata: + name: {{ .Release.Name }} + namespace: {{ .Release.Namespace }} + labels: {{- include "teleport-cluster.proxy.labels" . | nindent 4 }} + {{- if (or ($proxy.annotations.service) (eq $proxy.chartMode "aws")) }} + annotations: + {{- if and (eq $proxy.chartMode "aws") (not $proxy.ingress.enabled) }} + {{- if not (hasKey $proxy.annotations.service "service.beta.kubernetes.io/aws-load-balancer-backend-protocol")}} + service.beta.kubernetes.io/aws-load-balancer-backend-protocol: {{ $backendProtocol }} + {{- end }} + {{- if not (or (hasKey $proxy.annotations.service "service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled") (hasKey $proxy.annotations.service "service.beta.kubernetes.io/aws-load-balancer-attributes"))}} + service.beta.kubernetes.io/aws-load-balancer-cross-zone-load-balancing-enabled: "true" + {{- end }} + {{- if not (hasKey $proxy.annotations.service "service.beta.kubernetes.io/aws-load-balancer-type")}} + service.beta.kubernetes.io/aws-load-balancer-type: nlb + {{- end }} + {{- end }} + {{- if $proxy.annotations.service }} + {{- toYaml $proxy.annotations.service | nindent 4 }} + {{- end }} + {{- end }} +spec: + type: {{ default "LoadBalancer" $proxy.service.type }} +{{- with $proxy.service.spec }} + {{- toYaml . | nindent 2 }} +{{- end }} + ports: + - name: tls + port: 443 + targetPort: 3080 + protocol: TCP +{{- if ne $proxy.proxyListenerMode "multiplex" }} + - name: sshproxy + port: 3023 + targetPort: 3023 + protocol: TCP + - name: k8s + port: 3026 + targetPort: 3026 + protocol: TCP + - name: sshtun + port: 3024 + targetPort: 3024 + protocol: TCP + - name: mysql + port: 3036 + targetPort: 3036 + protocol: TCP + {{- if $proxy.separatePostgresListener }} + - name: postgres + port: 5432 + targetPort: 5432 + protocol: TCP + {{- end }} + {{- if $proxy.separateMongoListener }} + - name: mongo + port: 27017 + targetPort: 27017 + protocol: TCP + {{- end }} +{{- end }} + selector: {{- include "teleport-cluster.proxy.selectorLabels" . | nindent 4 }} diff --git a/helm/teleport-cluster/templates/proxy/serviceaccount.yaml b/helm/teleport-cluster/templates/proxy/serviceaccount.yaml new file mode 100644 index 0000000..66a9c4b --- /dev/null +++ b/helm/teleport-cluster/templates/proxy/serviceaccount.yaml @@ -0,0 +1,11 @@ +{{- $proxy := mustMergeOverwrite (mustDeepCopy .Values) .Values.proxy -}} +{{- if $proxy.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "teleport-cluster.proxy.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +{{- if $proxy.annotations.serviceAccount }} + annotations: {{- toYaml $proxy.annotations.serviceAccount | nindent 4 }} +{{- end -}} +{{- end }} diff --git a/helm/teleport-cluster/templates/psp.yaml b/helm/teleport-cluster/templates/psp.yaml new file mode 100644 index 0000000..8abd2d7 --- /dev/null +++ b/helm/teleport-cluster/templates/psp.yaml @@ -0,0 +1,68 @@ +{{/* PSPs are deprecated in 1.22 and removed in 1.25. However Helm doesn't handle their removal properly in 1.25 + We must remove them before 1.25 to ensure the Helm state doesn't corrupt. As this is a breaking change, this + only applies to v12+ charts. v11 and below will only show a warning from the NOTES.txt. + Users must use PSAs instead (beta in 1.23, GA in 1.25). The "teleport-cluster" chart runs in "baseline" mode */}} +{{- if and .Values.podSecurityPolicy.enabled (semverCompare "<1.23.0-0" .Capabilities.KubeVersion.Version) -}} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ .Release.Name }} + annotations: + seccomp.security.alpha.kubernetes.io/allowedProfileNames: 'docker/default,runtime/default' + seccomp.security.alpha.kubernetes.io/defaultProfileName: 'runtime/default' +spec: + privileged: false + allowPrivilegeEscalation: false + requiredDropCapabilities: + - ALL + seLinux: + rule: RunAsAny + supplementalGroups: + rule: MustRunAs + ranges: + # Forbid adding the root group. + - min: 1 + max: 65535 + runAsUser: + rule: MustRunAsNonRoot + fsGroup: + rule: MustRunAs + ranges: + # Forbid adding the root group. + - min: 1 + max: 65535 + readOnlyRootFilesystem: true + volumes: + - '*' + hostNetwork: false + hostIPC: false + hostPID: false +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ .Release.Name }}-psp + namespace: {{ .Release.Namespace }} +rules: +- apiGroups: + - policy + resources: + - podsecuritypolicies + verbs: + - use + resourceNames: + - {{ .Release.Name }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ .Release.Name }}-psp + namespace: {{ .Release.Namespace }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ .Release.Name }}-psp +subjects: +- kind: ServiceAccount + name: {{ .Release.Name }} +{{- end -}} diff --git a/helm/teleport-cluster/tests/README.md b/helm/teleport-cluster/tests/README.md new file mode 100644 index 0000000..d81e659 --- /dev/null +++ b/helm/teleport-cluster/tests/README.md @@ -0,0 +1,23 @@ +## Unit tests for Helm charts + +Helm chart unit tests run here using the [helm-unittest](https://github.com/quintush/helm-unittest/) Helm plugin. + +*Note: there are multiple forks for the helm-unittest plugin. +They are not compatible and don't provide the same featureset (e.g. including templates from sub-directories). +Our tests rely on features and bugfixes that are only available on the quintush fork +(which seems to be the most maintained at the time of writing)* + +If you get a snapshot error during your testing, you should verify that your changes intended to alter the output, then run +this command from the root of your Teleport checkout to update the snapshots: + +```bash +make -C build.assets test-helm-update-snapshots +``` + +After this, re-run the tests to make sure everything is fine: + +```bash +make -C build.assets test-helm +``` + +Commit the updated snapshots along with your changes. diff --git a/helm/teleport-cluster/tests/__snapshot__/auth_clusterrole_test.yaml.snap b/helm/teleport-cluster/tests/__snapshot__/auth_clusterrole_test.yaml.snap new file mode 100644 index 0000000..75650c0 --- /dev/null +++ b/helm/teleport-cluster/tests/__snapshot__/auth_clusterrole_test.yaml.snap @@ -0,0 +1,66 @@ +adds operator permissions to ClusterRole: + 1: | + apiVersion: rbac.authorization.k8s.io/v1 + kind: ClusterRole + metadata: + name: RELEASE-NAME + rules: + - apiGroups: + - "" + resources: + - users + - groups + - serviceaccounts + verbs: + - impersonate + - apiGroups: + - "" + resources: + - pods + verbs: + - get + - apiGroups: + - authorization.k8s.io + resources: + - selfsubjectaccessreviews + verbs: + - create + - apiGroups: + - resources.teleport.dev + resources: + - teleportroles + - teleportroles/status + - teleportusers + - teleportusers/status + - teleportgithubconnectors + - teleportgithubconnectors/status + - teleportoidcconnectors + - teleportoidcconnectors/status + - teleportsamlconnectors + - teleportsamlconnectors/status + - teleportloginrules + - teleportloginrules/status + - teleportprovisiontokens + - teleportprovisiontokens/status + - teleportoktaimportrules + - teleportoktaimportrules/status + verbs: + - get + - list + - patch + - update + - watch + - apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - create + - get + - update + - apiGroups: + - "" + resources: + - events + verbs: + - create diff --git a/helm/teleport-cluster/tests/__snapshot__/auth_config_test.yaml.snap b/helm/teleport-cluster/tests/__snapshot__/auth_config_test.yaml.snap new file mode 100644 index 0000000..ed8eb56 --- /dev/null +++ b/helm/teleport-cluster/tests/__snapshot__/auth_config_test.yaml.snap @@ -0,0 +1,1674 @@ +adds a proxy token by default: + 1: | + | + kind: token + version: v2 + metadata: + name: RELEASE-NAME-proxy + expires: "2050-01-01T00:00:00Z" + spec: + roles: [Proxy] + join_method: kubernetes + kubernetes: + allow: + - service_account: "NAMESPACE:RELEASE-NAME-proxy" +matches snapshot for acme-off.yaml: + 1: | + |- + auth_service: + authentication: + local_auth: true + second_factor: "on" + type: local + webauthn: + rp_id: test-cluster-name + cluster_name: test-cluster-name + enabled: true + proxy_listener_mode: separate + kubernetes_service: + enabled: true + kube_cluster_name: test-cluster-name + listen_addr: 0.0.0.0:3026 + public_addr: RELEASE-NAME-auth.NAMESPACE.svc.cluster.local:3026 + proxy_service: + enabled: false + ssh_service: + enabled: false + teleport: + auth_server: 127.0.0.1:3025 + log: + format: + extra_fields: + - timestamp + - level + - component + - caller + output: text + output: stderr + severity: INFO + version: v3 +matches snapshot for acme-on.yaml: + 1: | + |- + auth_service: + authentication: + local_auth: true + second_factor: "on" + type: local + webauthn: + rp_id: test-acme-cluster + cluster_name: test-acme-cluster + enabled: true + proxy_listener_mode: separate + kubernetes_service: + enabled: true + kube_cluster_name: test-acme-cluster + listen_addr: 0.0.0.0:3026 + public_addr: RELEASE-NAME-auth.NAMESPACE.svc.cluster.local:3026 + proxy_service: + enabled: false + ssh_service: + enabled: false + teleport: + auth_server: 127.0.0.1:3025 + log: + format: + extra_fields: + - timestamp + - level + - component + - caller + output: text + output: stderr + severity: INFO + version: v3 +matches snapshot for acme-uri-staging.yaml: + 1: | + |- + auth_service: + authentication: + local_auth: true + second_factor: "on" + type: local + webauthn: + rp_id: test-acme-cluster + cluster_name: test-acme-cluster + enabled: true + proxy_listener_mode: separate + kubernetes_service: + enabled: true + kube_cluster_name: test-acme-cluster + listen_addr: 0.0.0.0:3026 + public_addr: RELEASE-NAME-auth.NAMESPACE.svc.cluster.local:3026 + proxy_service: + enabled: false + ssh_service: + enabled: false + teleport: + auth_server: 127.0.0.1:3025 + log: + format: + extra_fields: + - timestamp + - level + - component + - caller + output: text + output: stderr + severity: INFO + version: v3 +matches snapshot for auth-connector-name.yaml: + 1: | + |- + auth_service: + authentication: + connector_name: okta + local_auth: true + second_factor: "on" + type: local + webauthn: + rp_id: helm-lint + cluster_name: helm-lint + enabled: true + proxy_listener_mode: separate + kubernetes_service: + enabled: true + kube_cluster_name: helm-lint + listen_addr: 0.0.0.0:3026 + public_addr: RELEASE-NAME-auth.NAMESPACE.svc.cluster.local:3026 + proxy_service: + enabled: false + ssh_service: + enabled: false + teleport: + auth_server: 127.0.0.1:3025 + log: + format: + extra_fields: + - timestamp + - level + - component + - caller + output: text + output: stderr + severity: INFO + version: v3 +matches snapshot for auth-disable-local.yaml: + 1: | + |- + auth_service: + authentication: + local_auth: false + second_factor: "off" + type: github + cluster_name: helm-lint + enabled: true + proxy_listener_mode: separate + kubernetes_service: + enabled: true + kube_cluster_name: helm-lint + listen_addr: 0.0.0.0:3026 + public_addr: RELEASE-NAME-auth.NAMESPACE.svc.cluster.local:3026 + proxy_service: + enabled: false + ssh_service: + enabled: false + teleport: + auth_server: 127.0.0.1:3025 + log: + format: + extra_fields: + - timestamp + - level + - component + - caller + output: text + output: stderr + severity: INFO + version: v3 +matches snapshot for auth-locking-mode.yaml: + 1: | + |- + auth_service: + authentication: + local_auth: true + locking_mode: strict + second_factor: "on" + type: local + webauthn: + rp_id: helm-lint + cluster_name: helm-lint + enabled: true + proxy_listener_mode: separate + kubernetes_service: + enabled: true + kube_cluster_name: helm-lint + listen_addr: 0.0.0.0:3026 + public_addr: RELEASE-NAME-auth.NAMESPACE.svc.cluster.local:3026 + proxy_service: + enabled: false + ssh_service: + enabled: false + teleport: + auth_server: 127.0.0.1:3025 + log: + format: + extra_fields: + - timestamp + - level + - component + - caller + output: text + output: stderr + severity: INFO + version: v3 +matches snapshot for auth-passwordless.yaml: + 1: | + |- + auth_service: + authentication: + connector_name: passwordless + local_auth: true + second_factor: webauthn + type: local + webauthn: + rp_id: helm-lint + cluster_name: helm-lint + enabled: true + proxy_listener_mode: separate + kubernetes_service: + enabled: true + kube_cluster_name: helm-lint + listen_addr: 0.0.0.0:3026 + public_addr: RELEASE-NAME-auth.NAMESPACE.svc.cluster.local:3026 + proxy_service: + enabled: false + ssh_service: + enabled: false + teleport: + auth_server: 127.0.0.1:3025 + log: + format: + extra_fields: + - timestamp + - level + - component + - caller + output: text + output: stderr + severity: INFO + version: v3 +matches snapshot for auth-type-legacy.yaml: + 1: | + |- + auth_service: + authentication: + local_auth: true + second_factor: "on" + type: github + webauthn: + rp_id: helm-lint + cluster_name: helm-lint + enabled: true + proxy_listener_mode: separate + kubernetes_service: + enabled: true + kube_cluster_name: helm-lint + listen_addr: 0.0.0.0:3026 + public_addr: RELEASE-NAME-auth.NAMESPACE.svc.cluster.local:3026 + proxy_service: + enabled: false + ssh_service: + enabled: false + teleport: + auth_server: 127.0.0.1:3025 + log: + format: + extra_fields: + - timestamp + - level + - component + - caller + output: text + output: stderr + severity: INFO + version: v3 +matches snapshot for auth-type.yaml: + 1: | + |- + auth_service: + authentication: + local_auth: true + second_factor: "on" + type: github + webauthn: + rp_id: helm-lint + cluster_name: helm-lint + enabled: true + proxy_listener_mode: separate + kubernetes_service: + enabled: true + kube_cluster_name: helm-lint + listen_addr: 0.0.0.0:3026 + public_addr: RELEASE-NAME-auth.NAMESPACE.svc.cluster.local:3026 + proxy_service: + enabled: false + ssh_service: + enabled: false + teleport: + auth_server: 127.0.0.1:3025 + log: + format: + extra_fields: + - timestamp + - level + - component + - caller + output: text + output: stderr + severity: INFO + version: v3 +matches snapshot for auth-webauthn-legacy.yaml: + 1: | + |- + auth_service: + authentication: + local_auth: true + second_factor: "on" + type: local + webauthn: + attestation_allowed_cas: + - /etc/ssl/certs/ca-certificates.crt + attestation_denied_cas: + - /etc/ssl/certs/ca-certificates.crt + rp_id: helm-lint + cluster_name: helm-lint + enabled: true + proxy_listener_mode: separate + kubernetes_service: + enabled: true + kube_cluster_name: helm-lint + listen_addr: 0.0.0.0:3026 + public_addr: RELEASE-NAME-auth.NAMESPACE.svc.cluster.local:3026 + proxy_service: + enabled: false + ssh_service: + enabled: false + teleport: + auth_server: 127.0.0.1:3025 + log: + format: + extra_fields: + - timestamp + - level + - component + - caller + output: text + output: stderr + severity: INFO + version: v3 +matches snapshot for auth-webauthn.yaml: + 1: | + |- + auth_service: + authentication: + local_auth: true + second_factor: "on" + type: local + webauthn: + attestation_allowed_cas: + - /etc/ssl/certs/ca-certificates.crt + attestation_denied_cas: + - /etc/ssl/certs/ca-certificates.crt + rp_id: helm-lint + cluster_name: helm-lint + enabled: true + proxy_listener_mode: separate + kubernetes_service: + enabled: true + kube_cluster_name: helm-lint + listen_addr: 0.0.0.0:3026 + public_addr: RELEASE-NAME-auth.NAMESPACE.svc.cluster.local:3026 + proxy_service: + enabled: false + ssh_service: + enabled: false + teleport: + auth_server: 127.0.0.1:3025 + log: + format: + extra_fields: + - timestamp + - level + - component + - caller + output: text + output: stderr + severity: INFO + version: v3 +matches snapshot for aws-dynamodb-autoscaling.yaml: + 1: | + |- + auth_service: + authentication: + local_auth: true + second_factor: "on" + type: local + webauthn: + rp_id: test-aws-cluster + cluster_name: test-aws-cluster + enabled: true + proxy_listener_mode: separate + kubernetes_service: + enabled: true + kube_cluster_name: test-aws-cluster + listen_addr: 0.0.0.0:3026 + public_addr: RELEASE-NAME-auth.NAMESPACE.svc.cluster.local:3026 + proxy_service: + enabled: false + ssh_service: + enabled: false + teleport: + auth_server: 127.0.0.1:3025 + log: + format: + extra_fields: + - timestamp + - level + - component + - caller + output: text + output: stderr + severity: INFO + storage: + audit_events_uri: + - dynamodb://test-dynamodb-auditlog-table + audit_sessions_uri: s3://test-s3-session-storage-bucket + auto_scaling: true + billing_mode: provisioned + continuous_backups: false + read_max_capacity: 100 + read_min_capacity: 5 + read_target_value: 50 + region: us-west-2 + table_name: test-dynamodb-backend-table + type: dynamodb + write_max_capacity: 100 + write_min_capacity: 5 + write_target_value: 50 + version: v3 +matches snapshot for aws-ha-acme.yaml: + 1: | + |- + auth_service: + authentication: + local_auth: true + second_factor: "on" + type: local + webauthn: + rp_id: test-aws-cluster + cluster_name: test-aws-cluster + enabled: true + proxy_listener_mode: separate + kubernetes_service: + enabled: true + kube_cluster_name: test-aws-cluster + labels: + env: aws + listen_addr: 0.0.0.0:3026 + public_addr: RELEASE-NAME-auth.NAMESPACE.svc.cluster.local:3026 + proxy_service: + enabled: false + ssh_service: + enabled: false + teleport: + auth_server: 127.0.0.1:3025 + log: + format: + extra_fields: + - timestamp + - level + - component + - caller + output: text + output: stderr + severity: INFO + storage: + audit_events_uri: + - dynamodb://test-dynamodb-auditlog-table + audit_sessions_uri: s3://test-s3-session-storage-bucket + auto_scaling: false + continuous_backups: false + region: us-west-2 + table_name: test-dynamodb-backend-table + type: dynamodb + version: v3 +matches snapshot for aws-ha-antiaffinity.yaml: + 1: | + |- + auth_service: + authentication: + local_auth: true + second_factor: "on" + type: local + webauthn: + rp_id: test-aws-cluster + cluster_name: test-aws-cluster + enabled: true + proxy_listener_mode: separate + kubernetes_service: + enabled: true + kube_cluster_name: test-aws-cluster + labels: + env: aws + listen_addr: 0.0.0.0:3026 + public_addr: RELEASE-NAME-auth.NAMESPACE.svc.cluster.local:3026 + proxy_service: + enabled: false + ssh_service: + enabled: false + teleport: + auth_server: 127.0.0.1:3025 + log: + format: + extra_fields: + - timestamp + - level + - component + - caller + output: text + output: stderr + severity: INFO + storage: + audit_events_uri: + - dynamodb://test-dynamodb-auditlog-table + audit_sessions_uri: s3://test-s3-session-storage-bucket + auto_scaling: false + continuous_backups: false + region: us-west-2 + table_name: test-dynamodb-backend-table + type: dynamodb + version: v3 +matches snapshot for aws-ha-log.yaml: + 1: | + |- + auth_service: + authentication: + local_auth: true + second_factor: "on" + type: local + webauthn: + rp_id: test-aws-cluster + cluster_name: test-aws-cluster + enabled: true + proxy_listener_mode: separate + kubernetes_service: + enabled: true + kube_cluster_name: test-aws-cluster + labels: + env: aws + listen_addr: 0.0.0.0:3026 + public_addr: RELEASE-NAME-auth.NAMESPACE.svc.cluster.local:3026 + proxy_service: + enabled: false + ssh_service: + enabled: false + teleport: + auth_server: 127.0.0.1:3025 + log: + format: + extra_fields: + - timestamp + - level + - component + - caller + output: text + output: stderr + severity: DEBUG + storage: + audit_events_uri: + - dynamodb://test-dynamodb-auditlog-table + - stdout:// + audit_sessions_uri: s3://test-s3-session-storage-bucket + auto_scaling: false + continuous_backups: false + region: us-west-2 + table_name: test-dynamodb-backend-table + type: dynamodb + version: v3 +matches snapshot for aws-ha.yaml: + 1: | + |- + auth_service: + authentication: + local_auth: true + second_factor: "on" + type: local + webauthn: + rp_id: test-aws-cluster + cluster_name: test-aws-cluster + enabled: true + proxy_listener_mode: separate + kubernetes_service: + enabled: true + kube_cluster_name: test-aws-cluster + labels: + env: aws + listen_addr: 0.0.0.0:3026 + public_addr: RELEASE-NAME-auth.NAMESPACE.svc.cluster.local:3026 + proxy_service: + enabled: false + ssh_service: + enabled: false + teleport: + auth_server: 127.0.0.1:3025 + log: + format: + extra_fields: + - timestamp + - level + - component + - caller + output: text + output: stderr + severity: INFO + storage: + audit_events_uri: + - dynamodb://test-dynamodb-auditlog-table + audit_sessions_uri: s3://test-s3-session-storage-bucket + auto_scaling: false + continuous_backups: false + region: us-west-2 + table_name: test-dynamodb-backend-table + type: dynamodb + version: v3 +matches snapshot for aws.yaml: + 1: | + |- + auth_service: + authentication: + local_auth: true + second_factor: "on" + type: local + webauthn: + rp_id: test-aws-cluster + cluster_name: test-aws-cluster + enabled: true + proxy_listener_mode: separate + kubernetes_service: + enabled: true + kube_cluster_name: test-aws-cluster + labels: + env: aws + listen_addr: 0.0.0.0:3026 + public_addr: RELEASE-NAME-auth.NAMESPACE.svc.cluster.local:3026 + proxy_service: + enabled: false + ssh_service: + enabled: false + teleport: + auth_server: 127.0.0.1:3025 + log: + format: + extra_fields: + - timestamp + - level + - component + - caller + output: text + output: stderr + severity: INFO + storage: + audit_events_uri: + - dynamodb://test-dynamodb-auditlog-table + audit_sessions_uri: s3://test-s3-session-storage-bucket + auto_scaling: false + continuous_backups: false + region: us-west-2 + table_name: test-dynamodb-backend-table + type: dynamodb + version: v3 +matches snapshot for azure.yaml: + 1: | + |- + auth_service: + authentication: + local_auth: true + second_factor: "on" + type: local + webauthn: + rp_id: test-azure-cluster + cluster_name: test-azure-cluster + enabled: true + proxy_listener_mode: separate + kubernetes_service: + enabled: true + kube_cluster_name: test-azure-cluster + listen_addr: 0.0.0.0:3026 + public_addr: RELEASE-NAME-auth.NAMESPACE.svc.cluster.local:3026 + proxy_service: + enabled: false + ssh_service: + enabled: false + teleport: + auth_server: 127.0.0.1:3025 + log: + format: + extra_fields: + - timestamp + - level + - component + - caller + output: text + output: stderr + severity: INFO + storage: + audit_events_uri: + - postgresql://teleport@mypostgresinstance.postgres.database.azure.com/teleport_audit?sslmode=verify-full#auth_mode=azure + - stdout:// + audit_sessions_uri: azblob://mystorageaccount.blob.core.windows.net + auth_mode: azure + conn_string: postgresql://teleport@mypostgresinstance.postgres.database.azure.com/teleport_backend?sslmode=verify-full&pool_max_conns=100 + type: postgresql + version: v3 +matches snapshot for azure.yaml without pool_max_conn: + 1: | + |- + auth_service: + authentication: + local_auth: true + second_factor: "on" + type: local + webauthn: + rp_id: test-azure-cluster + cluster_name: test-azure-cluster + enabled: true + proxy_listener_mode: separate + kubernetes_service: + enabled: true + kube_cluster_name: test-azure-cluster + listen_addr: 0.0.0.0:3026 + public_addr: RELEASE-NAME-auth.NAMESPACE.svc.cluster.local:3026 + proxy_service: + enabled: false + ssh_service: + enabled: false + teleport: + auth_server: 127.0.0.1:3025 + log: + format: + extra_fields: + - timestamp + - level + - component + - caller + output: text + output: stderr + severity: INFO + storage: + audit_events_uri: + - postgresql://teleport@mypostgresinstance.postgres.database.azure.com/teleport_audit?sslmode=verify-full#auth_mode=azure + - stdout:// + audit_sessions_uri: azblob://mystorageaccount.blob.core.windows.net + auth_mode: azure + conn_string: postgresql://teleport@mypostgresinstance.postgres.database.azure.com/teleport_backend?sslmode=verify-full + type: postgresql + version: v3 +matches snapshot for existing-tls-secret-with-ca.yaml: + 1: | + |- + auth_service: + authentication: + local_auth: true + second_factor: "on" + type: local + webauthn: + rp_id: test-cluster-name + cluster_name: test-cluster-name + enabled: true + proxy_listener_mode: separate + kubernetes_service: + enabled: true + kube_cluster_name: test-cluster-name + listen_addr: 0.0.0.0:3026 + public_addr: RELEASE-NAME-auth.NAMESPACE.svc.cluster.local:3026 + proxy_service: + enabled: false + ssh_service: + enabled: false + teleport: + auth_server: 127.0.0.1:3025 + log: + format: + extra_fields: + - timestamp + - level + - component + - caller + output: text + output: stderr + severity: INFO + version: v3 +matches snapshot for existing-tls-secret.yaml: + 1: | + |- + auth_service: + authentication: + local_auth: true + second_factor: "on" + type: local + webauthn: + rp_id: test-cluster-name + cluster_name: test-cluster-name + enabled: true + proxy_listener_mode: separate + kubernetes_service: + enabled: true + kube_cluster_name: test-cluster-name + listen_addr: 0.0.0.0:3026 + public_addr: RELEASE-NAME-auth.NAMESPACE.svc.cluster.local:3026 + proxy_service: + enabled: false + ssh_service: + enabled: false + teleport: + auth_server: 127.0.0.1:3025 + log: + format: + extra_fields: + - timestamp + - level + - component + - caller + output: text + output: stderr + severity: INFO + version: v3 +matches snapshot for gcp-ha-acme.yaml: + 1: | + |- + auth_service: + authentication: + local_auth: true + second_factor: "on" + type: local + webauthn: + rp_id: test-gcp-cluster + cluster_name: test-gcp-cluster + enabled: true + proxy_listener_mode: separate + kubernetes_service: + enabled: true + kube_cluster_name: test-gcp-cluster + labels: + env: gcp + listen_addr: 0.0.0.0:3026 + public_addr: RELEASE-NAME-auth.NAMESPACE.svc.cluster.local:3026 + proxy_service: + enabled: false + ssh_service: + enabled: false + teleport: + auth_server: 127.0.0.1:3025 + log: + format: + extra_fields: + - timestamp + - level + - component + - caller + output: text + output: stderr + severity: INFO + storage: + audit_events_uri: + - firestore://test-teleport-firestore-auditlog-collection?projectID=gcpproj-123456&credentialsPath=/etc/teleport-secrets/gcp-credentials.json + audit_sessions_uri: gs://test-gcp-session-storage-bucket?projectID=gcpproj-123456&credentialsPath=/etc/teleport-secrets/gcp-credentials.json + collection_name: test-teleport-firestore-storage-collection + credentials_path: /etc/teleport-secrets/gcp-credentials.json + project_id: gcpproj-123456 + type: firestore + version: v3 +matches snapshot for gcp-ha-antiaffinity.yaml: + 1: | + |- + auth_service: + authentication: + local_auth: true + second_factor: "on" + type: local + webauthn: + rp_id: test-gcp-cluster + cluster_name: test-gcp-cluster + enabled: true + proxy_listener_mode: separate + kubernetes_service: + enabled: true + kube_cluster_name: test-gcp-cluster + labels: + env: gcp + listen_addr: 0.0.0.0:3026 + public_addr: RELEASE-NAME-auth.NAMESPACE.svc.cluster.local:3026 + proxy_service: + enabled: false + ssh_service: + enabled: false + teleport: + auth_server: 127.0.0.1:3025 + log: + format: + extra_fields: + - timestamp + - level + - component + - caller + output: text + output: stderr + severity: INFO + storage: + audit_events_uri: + - firestore://test-teleport-firestore-auditlog-collection?projectID=gcpproj-123456&credentialsPath=/etc/teleport-secrets/gcp-credentials.json + audit_sessions_uri: gs://test-gcp-session-storage-bucket?projectID=gcpproj-123456&credentialsPath=/etc/teleport-secrets/gcp-credentials.json + collection_name: test-teleport-firestore-storage-collection + credentials_path: /etc/teleport-secrets/gcp-credentials.json + project_id: gcpproj-123456 + type: firestore + version: v3 +matches snapshot for gcp-ha-log.yaml: + 1: | + |- + auth_service: + authentication: + local_auth: true + second_factor: "on" + type: local + webauthn: + rp_id: test-gcp-cluster + cluster_name: test-gcp-cluster + enabled: true + proxy_listener_mode: separate + kubernetes_service: + enabled: true + kube_cluster_name: test-gcp-cluster + labels: + env: gcp + listen_addr: 0.0.0.0:3026 + public_addr: RELEASE-NAME-auth.NAMESPACE.svc.cluster.local:3026 + proxy_service: + enabled: false + ssh_service: + enabled: false + teleport: + auth_server: 127.0.0.1:3025 + log: + format: + extra_fields: + - timestamp + - level + - component + - caller + output: text + output: stderr + severity: DEBUG + storage: + audit_events_uri: + - firestore://test-teleport-firestore-auditlog-collection?projectID=gcpproj-123456&credentialsPath=/etc/teleport-secrets/gcp-credentials.json + - stdout:// + audit_sessions_uri: gs://test-gcp-session-storage-bucket?projectID=gcpproj-123456&credentialsPath=/etc/teleport-secrets/gcp-credentials.json + collection_name: test-teleport-firestore-storage-collection + credentials_path: /etc/teleport-secrets/gcp-credentials.json + project_id: gcpproj-123456 + type: firestore + version: v3 +matches snapshot for gcp.yaml: + 1: | + |- + auth_service: + authentication: + local_auth: true + second_factor: "on" + type: local + webauthn: + rp_id: test-gcp-cluster + cluster_name: test-gcp-cluster + enabled: true + proxy_listener_mode: separate + kubernetes_service: + enabled: true + kube_cluster_name: test-gcp-cluster + labels: + env: gcp + listen_addr: 0.0.0.0:3026 + public_addr: RELEASE-NAME-auth.NAMESPACE.svc.cluster.local:3026 + proxy_service: + enabled: false + ssh_service: + enabled: false + teleport: + auth_server: 127.0.0.1:3025 + log: + format: + extra_fields: + - timestamp + - level + - component + - caller + output: text + output: stderr + severity: INFO + storage: + audit_events_uri: + - firestore://test-teleport-firestore-auditlog-collection?projectID=gcpproj-123456&credentialsPath=/etc/teleport-secrets/gcp-credentials.json + audit_sessions_uri: gs://test-gcp-session-storage-bucket?projectID=gcpproj-123456&credentialsPath=/etc/teleport-secrets/gcp-credentials.json + collection_name: test-teleport-firestore-storage-collection + credentials_path: /etc/teleport-secrets/gcp-credentials.json + project_id: gcpproj-123456 + type: firestore + version: v3 +matches snapshot for initcontainers.yaml: + 1: | + |- + auth_service: + authentication: + local_auth: true + second_factor: "on" + type: local + webauthn: + rp_id: helm-lint + cluster_name: helm-lint + enabled: true + proxy_listener_mode: separate + kubernetes_service: + enabled: true + kube_cluster_name: helm-lint + listen_addr: 0.0.0.0:3026 + public_addr: RELEASE-NAME-auth.NAMESPACE.svc.cluster.local:3026 + proxy_service: + enabled: false + ssh_service: + enabled: false + teleport: + auth_server: 127.0.0.1:3025 + log: + format: + extra_fields: + - timestamp + - level + - component + - caller + output: text + output: stderr + severity: INFO + version: v3 +matches snapshot for kube-cluster-name.yaml: + 1: | + |- + auth_service: + authentication: + local_auth: true + second_factor: "on" + type: local + webauthn: + rp_id: test-aws-cluster + cluster_name: test-aws-cluster + enabled: true + proxy_listener_mode: separate + kubernetes_service: + enabled: true + kube_cluster_name: test-kube-cluster + listen_addr: 0.0.0.0:3026 + public_addr: RELEASE-NAME-auth.NAMESPACE.svc.cluster.local:3026 + proxy_service: + enabled: false + ssh_service: + enabled: false + teleport: + auth_server: 127.0.0.1:3025 + log: + format: + extra_fields: + - timestamp + - level + - component + - caller + output: text + output: stderr + severity: INFO + version: v3 +matches snapshot for log-basic.yaml: + 1: | + |- + auth_service: + authentication: + local_auth: true + second_factor: "on" + type: local + webauthn: + rp_id: test-log-cluster + cluster_name: test-log-cluster + enabled: true + proxy_listener_mode: separate + kubernetes_service: + enabled: true + kube_cluster_name: test-log-cluster + listen_addr: 0.0.0.0:3026 + public_addr: RELEASE-NAME-auth.NAMESPACE.svc.cluster.local:3026 + proxy_service: + enabled: false + ssh_service: + enabled: false + teleport: + auth_server: 127.0.0.1:3025 + log: + format: + extra_fields: + - timestamp + - level + - component + - caller + output: json + output: stderr + severity: INFO + version: v3 +matches snapshot for log-extra.yaml: + 1: | + |- + auth_service: + authentication: + local_auth: true + second_factor: "on" + type: local + webauthn: + rp_id: test-log-cluster + cluster_name: test-log-cluster + enabled: true + proxy_listener_mode: separate + kubernetes_service: + enabled: true + kube_cluster_name: test-log-cluster + listen_addr: 0.0.0.0:3026 + public_addr: RELEASE-NAME-auth.NAMESPACE.svc.cluster.local:3026 + proxy_service: + enabled: false + ssh_service: + enabled: false + teleport: + auth_server: 127.0.0.1:3025 + log: + format: + extra_fields: + - level + - timestamp + - component + - caller + output: json + output: /var/lib/teleport/test.log + severity: DEBUG + version: v3 +matches snapshot for log-legacy.yaml: + 1: | + |- + auth_service: + authentication: + local_auth: true + second_factor: "on" + type: local + webauthn: + rp_id: test-log-cluster + cluster_name: test-log-cluster + enabled: true + proxy_listener_mode: separate + kubernetes_service: + enabled: true + kube_cluster_name: test-log-cluster + listen_addr: 0.0.0.0:3026 + public_addr: RELEASE-NAME-auth.NAMESPACE.svc.cluster.local:3026 + proxy_service: + enabled: false + ssh_service: + enabled: false + teleport: + auth_server: 127.0.0.1:3025 + log: + format: + extra_fields: + - timestamp + - level + - component + - caller + output: text + output: stderr + severity: DEBUG + version: v3 +matches snapshot for priority-class-name.yaml: + 1: | + |- + auth_service: + authentication: + local_auth: true + second_factor: "on" + type: local + webauthn: + rp_id: helm-lint + cluster_name: helm-lint + enabled: true + proxy_listener_mode: separate + kubernetes_service: + enabled: true + kube_cluster_name: helm-lint + listen_addr: 0.0.0.0:3026 + public_addr: RELEASE-NAME-auth.NAMESPACE.svc.cluster.local:3026 + proxy_service: + enabled: false + ssh_service: + enabled: false + teleport: + auth_server: 127.0.0.1:3025 + log: + format: + extra_fields: + - timestamp + - level + - component + - caller + output: text + output: stderr + severity: INFO + version: v3 +matches snapshot for proxy-listener-mode-multiplex.yaml: + 1: | + |- + auth_service: + authentication: + local_auth: true + second_factor: "on" + type: local + webauthn: + rp_id: test-proxy-listener-mode + cluster_name: test-proxy-listener-mode + enabled: true + proxy_listener_mode: multiplex + kubernetes_service: + enabled: true + kube_cluster_name: test-proxy-listener-mode + listen_addr: 0.0.0.0:3026 + public_addr: RELEASE-NAME-auth.NAMESPACE.svc.cluster.local:3026 + proxy_service: + enabled: false + ssh_service: + enabled: false + teleport: + auth_server: 127.0.0.1:3025 + log: + format: + extra_fields: + - timestamp + - level + - component + - caller + output: text + output: stderr + severity: INFO + version: v3 +matches snapshot for proxy-listener-mode-separate.yaml: + 1: | + |- + auth_service: + authentication: + local_auth: true + second_factor: "on" + type: local + webauthn: + rp_id: test-proxy-listener-mode + cluster_name: test-proxy-listener-mode + enabled: true + proxy_listener_mode: separate + kubernetes_service: + enabled: true + kube_cluster_name: test-proxy-listener-mode + listen_addr: 0.0.0.0:3026 + public_addr: RELEASE-NAME-auth.NAMESPACE.svc.cluster.local:3026 + proxy_service: + enabled: false + ssh_service: + enabled: false + teleport: + auth_server: 127.0.0.1:3025 + log: + format: + extra_fields: + - timestamp + - level + - component + - caller + output: text + output: stderr + severity: INFO + version: v3 +matches snapshot for public-addresses.yaml: + 1: | + |- + auth_service: + authentication: + local_auth: true + second_factor: "on" + type: local + webauthn: + rp_id: helm-lint + cluster_name: helm-lint + enabled: true + proxy_listener_mode: separate + kubernetes_service: + enabled: true + kube_cluster_name: helm-lint + listen_addr: 0.0.0.0:3026 + public_addr: RELEASE-NAME-auth.NAMESPACE.svc.cluster.local:3026 + proxy_service: + enabled: false + ssh_service: + enabled: false + teleport: + auth_server: 127.0.0.1:3025 + log: + format: + extra_fields: + - timestamp + - level + - component + - caller + output: text + output: stderr + severity: INFO + version: v3 +matches snapshot for separate-mongo-listener.yaml: + 1: | + |- + auth_service: + authentication: + local_auth: true + second_factor: "on" + type: local + webauthn: + rp_id: helm-lint + cluster_name: helm-lint + enabled: true + proxy_listener_mode: separate + kubernetes_service: + enabled: true + kube_cluster_name: helm-lint + listen_addr: 0.0.0.0:3026 + public_addr: RELEASE-NAME-auth.NAMESPACE.svc.cluster.local:3026 + proxy_service: + enabled: false + ssh_service: + enabled: false + teleport: + auth_server: 127.0.0.1:3025 + log: + format: + extra_fields: + - timestamp + - level + - component + - caller + output: text + output: stderr + severity: INFO + version: v3 +matches snapshot for separate-postgres-listener.yaml: + 1: | + |- + auth_service: + authentication: + local_auth: true + second_factor: "on" + type: local + webauthn: + rp_id: helm-lint + cluster_name: helm-lint + enabled: true + proxy_listener_mode: separate + kubernetes_service: + enabled: true + kube_cluster_name: helm-lint + listen_addr: 0.0.0.0:3026 + public_addr: RELEASE-NAME-auth.NAMESPACE.svc.cluster.local:3026 + proxy_service: + enabled: false + ssh_service: + enabled: false + teleport: + auth_server: 127.0.0.1:3025 + log: + format: + extra_fields: + - timestamp + - level + - component + - caller + output: text + output: stderr + severity: INFO + version: v3 +matches snapshot for service.yaml: + 1: | + |- + auth_service: + authentication: + local_auth: true + second_factor: "on" + type: local + webauthn: + rp_id: helm-lint + cluster_name: helm-lint + enabled: true + proxy_listener_mode: separate + kubernetes_service: + enabled: true + kube_cluster_name: helm-lint + listen_addr: 0.0.0.0:3026 + public_addr: RELEASE-NAME-auth.NAMESPACE.svc.cluster.local:3026 + proxy_service: + enabled: false + ssh_service: + enabled: false + teleport: + auth_server: 127.0.0.1:3025 + log: + format: + extra_fields: + - timestamp + - level + - component + - caller + output: text + output: stderr + severity: INFO + version: v3 +matches snapshot for session-recording.yaml: + 1: | + |- + auth_service: + authentication: + local_auth: true + second_factor: "on" + type: local + webauthn: + rp_id: helm-lint + cluster_name: helm-lint + enabled: true + proxy_listener_mode: separate + session_recording: node-sync + kubernetes_service: + enabled: true + kube_cluster_name: helm-lint + listen_addr: 0.0.0.0:3026 + public_addr: RELEASE-NAME-auth.NAMESPACE.svc.cluster.local:3026 + proxy_service: + enabled: false + ssh_service: + enabled: false + teleport: + auth_server: 127.0.0.1:3025 + log: + format: + extra_fields: + - timestamp + - level + - component + - caller + output: text + output: stderr + severity: INFO + version: v3 +matches snapshot for standalone-customsize.yaml: + 1: | + |- + auth_service: + authentication: + local_auth: true + second_factor: "on" + type: local + webauthn: + rp_id: test-standalone-cluster + cluster_name: test-standalone-cluster + enabled: true + proxy_listener_mode: separate + kubernetes_service: + enabled: true + kube_cluster_name: test-standalone-cluster + labels: + env: standalone + listen_addr: 0.0.0.0:3026 + public_addr: RELEASE-NAME-auth.NAMESPACE.svc.cluster.local:3026 + proxy_service: + enabled: false + ssh_service: + enabled: false + teleport: + auth_server: 127.0.0.1:3025 + log: + format: + extra_fields: + - timestamp + - level + - component + - caller + output: text + output: stderr + severity: INFO + version: v3 +matches snapshot for standalone-existingpvc.yaml: + 1: | + |- + auth_service: + authentication: + local_auth: true + second_factor: "on" + type: local + webauthn: + rp_id: test-standalone-cluster + cluster_name: test-standalone-cluster + enabled: true + proxy_listener_mode: separate + kubernetes_service: + enabled: true + kube_cluster_name: test-standalone-cluster + labels: + env: standalone + listen_addr: 0.0.0.0:3026 + public_addr: RELEASE-NAME-auth.NAMESPACE.svc.cluster.local:3026 + proxy_service: + enabled: false + ssh_service: + enabled: false + teleport: + auth_server: 127.0.0.1:3025 + log: + format: + extra_fields: + - timestamp + - level + - component + - caller + output: text + output: stderr + severity: INFO + version: v3 +matches snapshot for tolerations.yaml: + 1: | + |- + auth_service: + authentication: + local_auth: true + second_factor: "on" + type: local + webauthn: + rp_id: test-aws-cluster + cluster_name: test-aws-cluster + enabled: true + proxy_listener_mode: separate + kubernetes_service: + enabled: true + kube_cluster_name: test-aws-cluster + listen_addr: 0.0.0.0:3026 + public_addr: RELEASE-NAME-auth.NAMESPACE.svc.cluster.local:3026 + proxy_service: + enabled: false + ssh_service: + enabled: false + teleport: + auth_server: 127.0.0.1:3025 + log: + format: + extra_fields: + - timestamp + - level + - component + - caller + output: text + output: stderr + severity: INFO + storage: + audit_events_uri: + - dynamodb://test-dynamodb-auditlog-table + audit_sessions_uri: s3://test-s3-session-storage-bucket + auto_scaling: false + continuous_backups: false + region: us-west-2 + table_name: test-dynamodb-backend-table + type: dynamodb + version: v3 +matches snapshot for version-override.yaml: + 1: | + |- + auth_service: + authentication: + local_auth: true + second_factor: "on" + type: local + webauthn: + rp_id: test-cluster-name + cluster_name: test-cluster-name + enabled: true + proxy_listener_mode: separate + kubernetes_service: + enabled: true + kube_cluster_name: test-cluster-name + labels: + env: test + version: 5.2.1 + listen_addr: 0.0.0.0:3026 + public_addr: RELEASE-NAME-auth.NAMESPACE.svc.cluster.local:3026 + proxy_service: + enabled: false + ssh_service: + enabled: false + teleport: + auth_server: 127.0.0.1:3025 + log: + format: + extra_fields: + - timestamp + - level + - component + - caller + output: text + output: stderr + severity: INFO + version: v3 +matches snapshot for volumes.yaml: + 1: | + |- + auth_service: + authentication: + local_auth: true + second_factor: "on" + type: local + webauthn: + rp_id: helm-lint + cluster_name: helm-lint + enabled: true + proxy_listener_mode: separate + kubernetes_service: + enabled: true + kube_cluster_name: helm-lint + listen_addr: 0.0.0.0:3026 + public_addr: RELEASE-NAME-auth.NAMESPACE.svc.cluster.local:3026 + proxy_service: + enabled: false + ssh_service: + enabled: false + teleport: + auth_server: 127.0.0.1:3025 + log: + format: + extra_fields: + - timestamp + - level + - component + - caller + output: text + output: stderr + severity: INFO + version: v3 diff --git a/helm/teleport-cluster/tests/__snapshot__/auth_deployment_test.yaml.snap b/helm/teleport-cluster/tests/__snapshot__/auth_deployment_test.yaml.snap new file mode 100644 index 0000000..f3f40c9 --- /dev/null +++ b/helm/teleport-cluster/tests/__snapshot__/auth_deployment_test.yaml.snap @@ -0,0 +1,518 @@ +should add an operator side-car when operator is enabled: + 1: | + image: public.ecr.aws/gravitational/teleport-operator:13.3.9 + imagePullPolicy: IfNotPresent + livenessProbe: + httpGet: + path: /healthz + port: 8081 + initialDelaySeconds: 15 + periodSeconds: 20 + name: operator + readinessProbe: + httpGet: + path: /readyz + port: 8081 + initialDelaySeconds: 5 + periodSeconds: 10 + volumeMounts: + - mountPath: /etc/teleport + name: config + readOnly: true + - mountPath: /var/lib/teleport + name: data + - mountPath: /var/run/secrets/kubernetes.io/serviceaccount + name: auth-serviceaccount-token + readOnly: true +? should not add named PersistentVolumeClaim as volume when in scratch mode, persistence.existingClaimName + is set and persistence.enabled is false +: 1: | + affinity: + podAntiAffinity: null + automountServiceAccountToken: false + containers: + - args: + - --diag-addr=0.0.0.0:3000 + - --apply-on-startup=/etc/teleport/apply-on-startup.yaml + image: public.ecr.aws/gravitational/teleport-distroless:13.3.9 + imagePullPolicy: IfNotPresent + lifecycle: + preStop: + exec: + command: + - teleport + - wait + - duration + - 30s + livenessProbe: + failureThreshold: 6 + httpGet: + path: /healthz + port: diag + initialDelaySeconds: 5 + periodSeconds: 5 + timeoutSeconds: 1 + name: teleport + ports: + - containerPort: 3000 + name: diag + protocol: TCP + - containerPort: 3025 + name: auth + protocol: TCP + - containerPort: 3026 + name: kube + protocol: TCP + readinessProbe: + failureThreshold: 12 + httpGet: + path: /readyz + port: diag + initialDelaySeconds: 5 + periodSeconds: 5 + timeoutSeconds: 1 + volumeMounts: + - mountPath: /etc/teleport + name: config + readOnly: true + - mountPath: /var/lib/teleport + name: data + - mountPath: /var/run/secrets/kubernetes.io/serviceaccount + name: auth-serviceaccount-token + readOnly: true + serviceAccountName: RELEASE-NAME + terminationGracePeriodSeconds: 60 + volumes: + - name: auth-serviceaccount-token + projected: + sources: + - serviceAccountToken: + path: token + - configMap: + items: + - key: ca.crt + path: ca.crt + name: kube-root-ca.crt + - downwardAPI: + items: + - fieldRef: + fieldPath: metadata.namespace + path: namespace + - configMap: + name: RELEASE-NAME-auth + name: config + - emptyDir: {} + name: data +should provision initContainer correctly when set in values: + 1: | + - args: + - echo test + image: alpine + name: teleport-init + resources: + limits: + cpu: 2 + memory: 4Gi + requests: + cpu: 1 + memory: 2Gi + volumeMounts: + - mountPath: /etc/teleport + name: config + readOnly: true + - mountPath: /var/lib/teleport + name: data + - mountPath: /var/run/secrets/kubernetes.io/serviceaccount + name: auth-serviceaccount-token + readOnly: true + - args: + - echo test2 + image: alpine + name: teleport-init2 + resources: + limits: + cpu: 2 + memory: 4Gi + requests: + cpu: 1 + memory: 2Gi + volumeMounts: + - mountPath: /etc/teleport + name: config + readOnly: true + - mountPath: /var/lib/teleport + name: data + - mountPath: /var/run/secrets/kubernetes.io/serviceaccount + name: auth-serviceaccount-token + readOnly: true +should set affinity when set in values: + 1: | + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: gravitational.io/dedicated + operator: In + values: + - teleport +should set imagePullSecrets when set in values: + 1: | + - name: myRegistryKeySecretName +should set nodeSelector when set in values: + 1: | + affinity: + podAntiAffinity: null + automountServiceAccountToken: false + containers: + - args: + - --diag-addr=0.0.0.0:3000 + - --apply-on-startup=/etc/teleport/apply-on-startup.yaml + image: public.ecr.aws/gravitational/teleport-distroless:13.3.9 + imagePullPolicy: IfNotPresent + lifecycle: + preStop: + exec: + command: + - teleport + - wait + - duration + - 30s + livenessProbe: + failureThreshold: 6 + httpGet: + path: /healthz + port: diag + initialDelaySeconds: 5 + periodSeconds: 5 + timeoutSeconds: 1 + name: teleport + ports: + - containerPort: 3000 + name: diag + protocol: TCP + - containerPort: 3025 + name: auth + protocol: TCP + - containerPort: 3026 + name: kube + protocol: TCP + readinessProbe: + failureThreshold: 12 + httpGet: + path: /readyz + port: diag + initialDelaySeconds: 5 + periodSeconds: 5 + timeoutSeconds: 1 + volumeMounts: + - mountPath: /etc/teleport + name: config + readOnly: true + - mountPath: /var/lib/teleport + name: data + - mountPath: /var/run/secrets/kubernetes.io/serviceaccount + name: auth-serviceaccount-token + readOnly: true + nodeSelector: + environment: security + role: bastion + serviceAccountName: RELEASE-NAME + terminationGracePeriodSeconds: 60 + volumes: + - name: auth-serviceaccount-token + projected: + sources: + - serviceAccountToken: + path: token + - configMap: + items: + - key: ca.crt + path: ca.crt + name: kube-root-ca.crt + - downwardAPI: + items: + - fieldRef: + fieldPath: metadata.namespace + path: namespace + - configMap: + name: RELEASE-NAME-auth + name: config + - name: data + persistentVolumeClaim: + claimName: RELEASE-NAME +should set required affinity when highAvailability.requireAntiAffinity is set: + 1: | + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: app.kubernetes.io/instance + operator: In + values: + - RELEASE-NAME + - key: app.kubernetes.io/component + operator: In + values: + - auth + topologyKey: kubernetes.io/hostname +should set resources when set in values: + 1: | + affinity: + podAntiAffinity: null + automountServiceAccountToken: false + containers: + - args: + - --diag-addr=0.0.0.0:3000 + - --apply-on-startup=/etc/teleport/apply-on-startup.yaml + image: public.ecr.aws/gravitational/teleport-distroless:13.3.9 + imagePullPolicy: IfNotPresent + lifecycle: + preStop: + exec: + command: + - teleport + - wait + - duration + - 30s + livenessProbe: + failureThreshold: 6 + httpGet: + path: /healthz + port: diag + initialDelaySeconds: 5 + periodSeconds: 5 + timeoutSeconds: 1 + name: teleport + ports: + - containerPort: 3000 + name: diag + protocol: TCP + - containerPort: 3025 + name: auth + protocol: TCP + - containerPort: 3026 + name: kube + protocol: TCP + readinessProbe: + failureThreshold: 12 + httpGet: + path: /readyz + port: diag + initialDelaySeconds: 5 + periodSeconds: 5 + timeoutSeconds: 1 + resources: + limits: + cpu: 2 + memory: 4Gi + requests: + cpu: 1 + memory: 2Gi + volumeMounts: + - mountPath: /etc/teleport + name: config + readOnly: true + - mountPath: /var/lib/teleport + name: data + - mountPath: /var/run/secrets/kubernetes.io/serviceaccount + name: auth-serviceaccount-token + readOnly: true + serviceAccountName: RELEASE-NAME + terminationGracePeriodSeconds: 60 + volumes: + - name: auth-serviceaccount-token + projected: + sources: + - serviceAccountToken: + path: token + - configMap: + items: + - key: ca.crt + path: ca.crt + name: kube-root-ca.crt + - downwardAPI: + items: + - fieldRef: + fieldPath: metadata.namespace + path: namespace + - configMap: + name: RELEASE-NAME-auth + name: config + - name: data + persistentVolumeClaim: + claimName: RELEASE-NAME +should set securityContext when set in values: + 1: | + affinity: + podAntiAffinity: null + automountServiceAccountToken: false + containers: + - args: + - --diag-addr=0.0.0.0:3000 + - --apply-on-startup=/etc/teleport/apply-on-startup.yaml + image: public.ecr.aws/gravitational/teleport-distroless:13.3.9 + imagePullPolicy: IfNotPresent + lifecycle: + preStop: + exec: + command: + - teleport + - wait + - duration + - 30s + livenessProbe: + failureThreshold: 6 + httpGet: + path: /healthz + port: diag + initialDelaySeconds: 5 + periodSeconds: 5 + timeoutSeconds: 1 + name: teleport + ports: + - containerPort: 3000 + name: diag + protocol: TCP + - containerPort: 3025 + name: auth + protocol: TCP + - containerPort: 3026 + name: kube + protocol: TCP + readinessProbe: + failureThreshold: 12 + httpGet: + path: /readyz + port: diag + initialDelaySeconds: 5 + periodSeconds: 5 + timeoutSeconds: 1 + securityContext: + allowPrivilegeEscalation: false + privileged: false + readOnlyRootFilesystem: false + runAsGroup: 99 + runAsNonRoot: true + runAsUser: 99 + volumeMounts: + - mountPath: /etc/teleport + name: config + readOnly: true + - mountPath: /var/lib/teleport + name: data + - mountPath: /var/run/secrets/kubernetes.io/serviceaccount + name: auth-serviceaccount-token + readOnly: true + serviceAccountName: RELEASE-NAME + terminationGracePeriodSeconds: 60 + volumes: + - name: auth-serviceaccount-token + projected: + sources: + - serviceAccountToken: + path: token + - configMap: + items: + - key: ca.crt + path: ca.crt + name: kube-root-ca.crt + - downwardAPI: + items: + - fieldRef: + fieldPath: metadata.namespace + path: namespace + - configMap: + name: RELEASE-NAME-auth + name: config + - name: data + persistentVolumeClaim: + claimName: RELEASE-NAME +should set tolerations when set in values: + 1: | + - effect: NoExecute + key: dedicated + operator: Equal + value: teleport + - effect: NoSchedule + key: dedicated + operator: Equal + value: teleport +should use OSS image and not mount license when enterprise is not set in values: + 1: | + affinity: + podAntiAffinity: null + automountServiceAccountToken: false + containers: + - args: + - --diag-addr=0.0.0.0:3000 + - --apply-on-startup=/etc/teleport/apply-on-startup.yaml + image: public.ecr.aws/gravitational/teleport-distroless:12.2.1 + imagePullPolicy: IfNotPresent + lifecycle: + preStop: + exec: + command: + - teleport + - wait + - duration + - 30s + livenessProbe: + failureThreshold: 6 + httpGet: + path: /healthz + port: diag + initialDelaySeconds: 5 + periodSeconds: 5 + timeoutSeconds: 1 + name: teleport + ports: + - containerPort: 3000 + name: diag + protocol: TCP + - containerPort: 3025 + name: auth + protocol: TCP + - containerPort: 3026 + name: kube + protocol: TCP + readinessProbe: + failureThreshold: 12 + httpGet: + path: /readyz + port: diag + initialDelaySeconds: 5 + periodSeconds: 5 + timeoutSeconds: 1 + volumeMounts: + - mountPath: /etc/teleport + name: config + readOnly: true + - mountPath: /var/lib/teleport + name: data + - mountPath: /var/run/secrets/kubernetes.io/serviceaccount + name: auth-serviceaccount-token + readOnly: true + serviceAccountName: RELEASE-NAME + terminationGracePeriodSeconds: 60 + volumes: + - name: auth-serviceaccount-token + projected: + sources: + - serviceAccountToken: + path: token + - configMap: + items: + - key: ca.crt + path: ca.crt + name: kube-root-ca.crt + - downwardAPI: + items: + - fieldRef: + fieldPath: metadata.namespace + path: namespace + - configMap: + name: RELEASE-NAME-auth + name: config + - name: data + persistentVolumeClaim: + claimName: RELEASE-NAME diff --git a/helm/teleport-cluster/tests/__snapshot__/ingress_test.yaml.snap b/helm/teleport-cluster/tests/__snapshot__/ingress_test.yaml.snap new file mode 100644 index 0000000..f8a7288 --- /dev/null +++ b/helm/teleport-cluster/tests/__snapshot__/ingress_test.yaml.snap @@ -0,0 +1,55 @@ +does not add additional wildcard publicAddrs when Ingress is enabled and a publicAddr already contains a wildcard: + 1: | + - hosts: + - helm-lint.example.com + - '*.helm-lint.example.com' + - helm-lint-second-domain.example.com + - '*.helm-lint-second-domain.example.com' +does not set a wildcard of clusterName as a hostname when Ingress is enabled and ingress.suppressAutomaticWildcards is true: + 1: | + - hosts: + - teleport.example.com +? does not set a wildcard of publicAddr as a hostname when Ingress is enabled, publicAddr + is set and ingress.suppressAutomaticWildcards is true +: 1: | + - hosts: + - helm-lint.example.com +does not set tls.secretName by default: + 1: | + - hosts: + - teleport.example.com + - '*.teleport.example.com' +exposes all publicAddrs and wildcard publicAddrs as hostnames when Ingress is enabled and multiple publicAddrs are set: + 1: | + - hosts: + - helm-lint.example.com + - helm-lint-second-domain.example.com + - '*.helm-lint.example.com' + - '*.helm-lint-second-domain.example.com' +sets the clusterName and wildcard of clusterName as hostnames when Ingress is enabled: + 1: | + - hosts: + - teleport.example.com + - '*.teleport.example.com' +sets the publicAddr and wildcard of publicAddr as hostnames when Ingress is enabled and publicAddr is set: + 1: | + - hosts: + - helm-lint.example.com + - '*.helm-lint.example.com' +sets tls.secretName the value of tls.existingSecretName when set: + 1: | + - hosts: + - teleport.example.com + - '*.teleport.example.com' + secretName: helm-lint-tls-secret +sets tls.secretName when cert-manager is enabled: + 1: | + - hosts: + - teleport.example.com + - '*.teleport.example.com' + secretName: teleport-tls +trims ports from publicAddr and uses it as the hostname when Ingress is enabled and publicAddr is set: + 1: | + - hosts: + - helm-lint.example.com + - '*.helm-lint.example.com' diff --git a/helm/teleport-cluster/tests/__snapshot__/predeploy_test.yaml.snap b/helm/teleport-cluster/tests/__snapshot__/predeploy_test.yaml.snap new file mode 100644 index 0000000..288859d --- /dev/null +++ b/helm/teleport-cluster/tests/__snapshot__/predeploy_test.yaml.snap @@ -0,0 +1,6 @@ +should set imagePullSecrets on auth predeploy job when set in values: + 1: | + - name: myRegistryKeySecretName +should set imagePullSecrets on proxy predeploy job when set in values: + 1: | + - name: myRegistryKeySecretName diff --git a/helm/teleport-cluster/tests/__snapshot__/proxy_certificate_test.yaml.snap b/helm/teleport-cluster/tests/__snapshot__/proxy_certificate_test.yaml.snap new file mode 100644 index 0000000..319cbd8 --- /dev/null +++ b/helm/teleport-cluster/tests/__snapshot__/proxy_certificate_test.yaml.snap @@ -0,0 +1,16 @@ +should request a certificate for cluster name when cert-manager is enabled (cert-manager.yaml): + 1: | + - test-cluster + - '*.test-cluster' + 2: | + group: custom.cert-manager.io + kind: CustomClusterIssuer + name: custom +should request a certificate for cluster name when cert-manager is enabled (cert-secret.yaml): + 1: | + - test-cluster + - '*.test-cluster' + 2: | + group: cert-manager.io + kind: Issuer + name: letsencrypt diff --git a/helm/teleport-cluster/tests/__snapshot__/proxy_config_test.yaml.snap b/helm/teleport-cluster/tests/__snapshot__/proxy_config_test.yaml.snap new file mode 100644 index 0000000..d2858df --- /dev/null +++ b/helm/teleport-cluster/tests/__snapshot__/proxy_config_test.yaml.snap @@ -0,0 +1,530 @@ +generates a config WITHOUT proxy_service.trust_x_forwarded_for=true when version < 13.2.0 and ingress.enabled is not set: + 1: | + |- + auth_service: + enabled: false + proxy_service: + enabled: true + kube_listen_addr: 0.0.0.0:3026 + listen_addr: 0.0.0.0:3023 + mysql_listen_addr: 0.0.0.0:3036 + public_addr: helm-test.example.com:443 + tunnel_listen_addr: 0.0.0.0:3024 + ssh_service: + enabled: false + teleport: + auth_server: RELEASE-NAME-auth.NAMESPACE.svc.cluster.local:3025 + join_params: + method: kubernetes + token_name: RELEASE-NAME-proxy + log: + format: + extra_fields: + - timestamp + - level + - component + - caller + output: text + output: stderr + severity: INFO + version: v3 +generates a config WITHOUT proxy_service.trust_x_forwarded_for=true when version < 13.2.0 and ingress.enabled=true: + 1: | + |- + auth_service: + enabled: false + proxy_service: + enabled: true + public_addr: helm-test.example.com:443 + ssh_service: + enabled: false + teleport: + auth_server: RELEASE-NAME-auth.NAMESPACE.svc.cluster.local:3025 + join_params: + method: kubernetes + token_name: RELEASE-NAME-proxy + log: + format: + extra_fields: + - timestamp + - level + - component + - caller + output: text + output: stderr + severity: INFO + version: v3 +generates a config WITHOUT proxy_service.trust_x_forwarded_for=true when version >=13.2.0 and ingress.enabled is not set: + 1: | + |- + auth_service: + enabled: false + proxy_service: + enabled: true + kube_listen_addr: 0.0.0.0:3026 + listen_addr: 0.0.0.0:3023 + mysql_listen_addr: 0.0.0.0:3036 + public_addr: helm-test.example.com:443 + tunnel_listen_addr: 0.0.0.0:3024 + ssh_service: + enabled: false + teleport: + auth_server: RELEASE-NAME-auth.NAMESPACE.svc.cluster.local:3025 + join_params: + method: kubernetes + token_name: RELEASE-NAME-proxy + log: + format: + extra_fields: + - timestamp + - level + - component + - caller + output: text + output: stderr + severity: INFO + version: v3 +generates a config with a clusterName containing a regular string: + 1: | + |- + auth_service: + enabled: false + proxy_service: + enabled: true + kube_listen_addr: 0.0.0.0:3026 + listen_addr: 0.0.0.0:3023 + mysql_listen_addr: 0.0.0.0:3036 + public_addr: helm-test.example.com:443 + tunnel_listen_addr: 0.0.0.0:3024 + ssh_service: + enabled: false + teleport: + auth_server: RELEASE-NAME-auth.NAMESPACE.svc.cluster.local:3025 + join_params: + method: kubernetes + token_name: RELEASE-NAME-proxy + log: + format: + extra_fields: + - timestamp + - level + - component + - caller + output: text + output: stderr + severity: INFO + version: v3 +generates a config with proxy_service.trust_x_forwarded_for=true when version = 14.0.0-rc.1 and ingress.enabled=true: + 1: | + |- + auth_service: + enabled: false + proxy_service: + enabled: true + public_addr: helm-test.example.com:443 + trust_x_forwarded_for: true + ssh_service: + enabled: false + teleport: + auth_server: RELEASE-NAME-auth.NAMESPACE.svc.cluster.local:3025 + join_params: + method: kubernetes + token_name: RELEASE-NAME-proxy + log: + format: + extra_fields: + - timestamp + - level + - component + - caller + output: text + output: stderr + severity: INFO + version: v3 +generates a config with proxy_service.trust_x_forwarded_for=true when version >=13.2.0 and ingress.enabled=true: + 1: | + |- + auth_service: + enabled: false + proxy_service: + enabled: true + public_addr: helm-test.example.com:443 + trust_x_forwarded_for: true + ssh_service: + enabled: false + teleport: + auth_server: RELEASE-NAME-auth.NAMESPACE.svc.cluster.local:3025 + join_params: + method: kubernetes + token_name: RELEASE-NAME-proxy + log: + format: + extra_fields: + - timestamp + - level + - component + - caller + output: text + output: stderr + severity: INFO + version: v3 +matches snapshot for acme-on.yaml: + 1: | + |- + auth_service: + enabled: false + proxy_service: + acme: + email: test@email.com + enabled: true + enabled: true + kube_listen_addr: 0.0.0.0:3026 + listen_addr: 0.0.0.0:3023 + mysql_listen_addr: 0.0.0.0:3036 + public_addr: test-acme-cluster:443 + tunnel_listen_addr: 0.0.0.0:3024 + ssh_service: + enabled: false + teleport: + auth_server: RELEASE-NAME-auth.NAMESPACE.svc.cluster.local:3025 + join_params: + method: kubernetes + token_name: RELEASE-NAME-proxy + log: + format: + extra_fields: + - timestamp + - level + - component + - caller + output: text + output: stderr + severity: INFO + version: v3 +matches snapshot for acme-uri-staging.yaml: + 1: | + |- + auth_service: + enabled: false + proxy_service: + acme: + email: test@email.com + enabled: true + uri: https://acme-staging-v02.api.letsencrypt.org/directory + enabled: true + kube_listen_addr: 0.0.0.0:3026 + listen_addr: 0.0.0.0:3023 + mysql_listen_addr: 0.0.0.0:3036 + public_addr: test-acme-cluster:443 + tunnel_listen_addr: 0.0.0.0:3024 + ssh_service: + enabled: false + teleport: + auth_server: RELEASE-NAME-auth.NAMESPACE.svc.cluster.local:3025 + join_params: + method: kubernetes + token_name: RELEASE-NAME-proxy + log: + format: + extra_fields: + - timestamp + - level + - component + - caller + output: text + output: stderr + severity: INFO + version: v3 +matches snapshot for aws-ha-acme.yaml: + 1: | + |- + auth_service: + enabled: false + proxy_service: + enabled: true + https_keypairs: + - cert_file: /etc/teleport-tls/tls.crt + key_file: /etc/teleport-tls/tls.key + https_keypairs_reload_interval: 12h + kube_listen_addr: 0.0.0.0:3026 + listen_addr: 0.0.0.0:3023 + mysql_listen_addr: 0.0.0.0:3036 + public_addr: test-aws-cluster:443 + tunnel_listen_addr: 0.0.0.0:3024 + ssh_service: + enabled: false + teleport: + auth_server: RELEASE-NAME-auth.NAMESPACE.svc.cluster.local:3025 + join_params: + method: kubernetes + token_name: RELEASE-NAME-proxy + log: + format: + extra_fields: + - timestamp + - level + - component + - caller + output: text + output: stderr + severity: INFO + version: v3 +matches snapshot for existing-tls-secret.yaml: + 1: | + |- + auth_service: + enabled: false + proxy_service: + enabled: true + https_keypairs: + - cert_file: /etc/teleport-tls/tls.crt + key_file: /etc/teleport-tls/tls.key + https_keypairs_reload_interval: 12h + kube_listen_addr: 0.0.0.0:3026 + listen_addr: 0.0.0.0:3023 + mysql_listen_addr: 0.0.0.0:3036 + public_addr: test-cluster-name:443 + tunnel_listen_addr: 0.0.0.0:3024 + ssh_service: + enabled: false + teleport: + auth_server: RELEASE-NAME-auth.NAMESPACE.svc.cluster.local:3025 + join_params: + method: kubernetes + token_name: RELEASE-NAME-proxy + log: + format: + extra_fields: + - timestamp + - level + - component + - caller + output: text + output: stderr + severity: INFO + version: v3 +matches snapshot for log-basic.yaml: + 1: | + |- + auth_service: + enabled: false + proxy_service: + enabled: true + kube_listen_addr: 0.0.0.0:3026 + listen_addr: 0.0.0.0:3023 + mysql_listen_addr: 0.0.0.0:3036 + public_addr: test-log-cluster:443 + tunnel_listen_addr: 0.0.0.0:3024 + ssh_service: + enabled: false + teleport: + auth_server: RELEASE-NAME-auth.NAMESPACE.svc.cluster.local:3025 + join_params: + method: kubernetes + token_name: RELEASE-NAME-proxy + log: + format: + extra_fields: + - timestamp + - level + - component + - caller + output: json + output: stderr + severity: INFO + version: v3 +matches snapshot for log-extra.yaml: + 1: | + |- + auth_service: + enabled: false + proxy_service: + enabled: true + kube_listen_addr: 0.0.0.0:3026 + listen_addr: 0.0.0.0:3023 + mysql_listen_addr: 0.0.0.0:3036 + public_addr: test-log-cluster:443 + tunnel_listen_addr: 0.0.0.0:3024 + ssh_service: + enabled: false + teleport: + auth_server: RELEASE-NAME-auth.NAMESPACE.svc.cluster.local:3025 + join_params: + method: kubernetes + token_name: RELEASE-NAME-proxy + log: + format: + extra_fields: + - level + - timestamp + - component + - caller + output: json + output: /var/lib/teleport/test.log + severity: DEBUG + version: v3 +matches snapshot for proxy-listener-mode-multiplex.yaml: + 1: | + |- + auth_service: + enabled: false + proxy_service: + enabled: true + public_addr: test-proxy-listener-mode:443 + ssh_service: + enabled: false + teleport: + auth_server: RELEASE-NAME-auth.NAMESPACE.svc.cluster.local:3025 + join_params: + method: kubernetes + token_name: RELEASE-NAME-proxy + log: + format: + extra_fields: + - timestamp + - level + - component + - caller + output: text + output: stderr + severity: INFO + version: v3 +matches snapshot for proxy-listener-mode-separate.yaml: + 1: | + |- + auth_service: + enabled: false + proxy_service: + enabled: true + kube_listen_addr: 0.0.0.0:3026 + listen_addr: 0.0.0.0:3023 + mysql_listen_addr: 0.0.0.0:3036 + public_addr: test-proxy-listener-mode:443 + tunnel_listen_addr: 0.0.0.0:3024 + ssh_service: + enabled: false + teleport: + auth_server: RELEASE-NAME-auth.NAMESPACE.svc.cluster.local:3025 + join_params: + method: kubernetes + token_name: RELEASE-NAME-proxy + log: + format: + extra_fields: + - timestamp + - level + - component + - caller + output: text + output: stderr + severity: INFO + version: v3 +matches snapshot for public-addresses.yaml: + 1: | + |- + auth_service: + enabled: false + proxy_service: + enabled: true + kube_listen_addr: 0.0.0.0:3026 + kube_public_addr: + - loadbalancer.example.com:3026 + listen_addr: 0.0.0.0:3023 + mongo_listen_addr: 0.0.0.0:27017 + mongo_public_addr: + - loadbalancer.example.com:27017 + mysql_listen_addr: 0.0.0.0:3036 + mysql_public_addr: + - loadbalancer.example.com:3036 + postgres_listen_addr: 0.0.0.0:5432 + postgres_public_addr: + - loadbalancer.example.com:5432 + public_addr: + - loadbalancer.example.com:443 + ssh_public_addr: + - loadbalancer.example.com:3023 + tunnel_listen_addr: 0.0.0.0:3024 + tunnel_public_addr: + - loadbalancer.example.com:3024 + ssh_service: + enabled: false + teleport: + auth_server: RELEASE-NAME-auth.NAMESPACE.svc.cluster.local:3025 + join_params: + method: kubernetes + token_name: RELEASE-NAME-proxy + log: + format: + extra_fields: + - timestamp + - level + - component + - caller + output: text + output: stderr + severity: INFO + version: v3 +matches snapshot for separate-mongo-listener.yaml: + 1: | + |- + auth_service: + enabled: false + proxy_service: + enabled: true + kube_listen_addr: 0.0.0.0:3026 + listen_addr: 0.0.0.0:3023 + mongo_listen_addr: 0.0.0.0:27017 + mongo_public_addr: helm-lint:27017 + mysql_listen_addr: 0.0.0.0:3036 + public_addr: helm-lint:443 + tunnel_listen_addr: 0.0.0.0:3024 + ssh_service: + enabled: false + teleport: + auth_server: RELEASE-NAME-auth.NAMESPACE.svc.cluster.local:3025 + join_params: + method: kubernetes + token_name: RELEASE-NAME-proxy + log: + format: + extra_fields: + - timestamp + - level + - component + - caller + output: text + output: stderr + severity: INFO + version: v3 +matches snapshot for separate-postgres-listener.yaml: + 1: | + |- + auth_service: + enabled: false + proxy_service: + enabled: true + kube_listen_addr: 0.0.0.0:3026 + listen_addr: 0.0.0.0:3023 + mysql_listen_addr: 0.0.0.0:3036 + postgres_listen_addr: 0.0.0.0:5432 + postgres_public_addr: helm-lint:5432 + public_addr: helm-lint:443 + tunnel_listen_addr: 0.0.0.0:3024 + ssh_service: + enabled: false + teleport: + auth_server: RELEASE-NAME-auth.NAMESPACE.svc.cluster.local:3025 + join_params: + method: kubernetes + token_name: RELEASE-NAME-proxy + log: + format: + extra_fields: + - timestamp + - level + - component + - caller + output: text + output: stderr + severity: INFO + version: v3 diff --git a/helm/teleport-cluster/tests/__snapshot__/proxy_deployment_test.yaml.snap b/helm/teleport-cluster/tests/__snapshot__/proxy_deployment_test.yaml.snap new file mode 100644 index 0000000..73629a8 --- /dev/null +++ b/helm/teleport-cluster/tests/__snapshot__/proxy_deployment_test.yaml.snap @@ -0,0 +1,495 @@ +should provision initContainer correctly when set in values: + 1: | + - command: + - teleport + - wait + - no-resolve + - RELEASE-NAME-auth-v12.NAMESPACE.svc.cluster.local + image: public.ecr.aws/gravitational/teleport-distroless:13.3.9 + name: wait-auth-update + - args: + - echo test + image: alpine + name: teleport-init + resources: + limits: + cpu: 2 + memory: 4Gi + requests: + cpu: 1 + memory: 2Gi + volumeMounts: + - mountPath: /etc/teleport + name: config + readOnly: true + - mountPath: /var/lib/teleport + name: data + - args: + - echo test2 + image: alpine + name: teleport-init2 + resources: + limits: + cpu: 2 + memory: 4Gi + requests: + cpu: 1 + memory: 2Gi + volumeMounts: + - mountPath: /etc/teleport + name: config + readOnly: true + - mountPath: /var/lib/teleport + name: data +should set affinity when set in values: + 1: | + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: gravitational.io/dedicated + operator: In + values: + - teleport +should set imagePullSecrets when set in values: + 1: | + - name: myRegistryKeySecretName +should set nodeSelector when set in values: + 1: | + affinity: + podAntiAffinity: null + automountServiceAccountToken: false + containers: + - args: + - --diag-addr=0.0.0.0:3000 + image: public.ecr.aws/gravitational/teleport-distroless:13.3.9 + imagePullPolicy: IfNotPresent + lifecycle: + preStop: + exec: + command: + - teleport + - wait + - duration + - 30s + livenessProbe: + failureThreshold: 6 + httpGet: + path: /healthz + port: diag + initialDelaySeconds: 5 + periodSeconds: 5 + timeoutSeconds: 1 + name: teleport + ports: + - containerPort: 3080 + name: tls + protocol: TCP + - containerPort: 3023 + name: sshproxy + protocol: TCP + - containerPort: 3024 + name: sshtun + protocol: TCP + - containerPort: 3026 + name: kube + protocol: TCP + - containerPort: 3036 + name: mysql + protocol: TCP + - containerPort: 3000 + name: diag + protocol: TCP + readinessProbe: + failureThreshold: 12 + httpGet: + path: /readyz + port: diag + initialDelaySeconds: 5 + periodSeconds: 5 + timeoutSeconds: 1 + volumeMounts: + - mountPath: /etc/teleport + name: config + readOnly: true + - mountPath: /var/lib/teleport + name: data + - mountPath: /var/run/secrets/kubernetes.io/serviceaccount + name: proxy-serviceaccount-token + readOnly: true + initContainers: + - command: + - teleport + - wait + - no-resolve + - RELEASE-NAME-auth-v12.NAMESPACE.svc.cluster.local + image: public.ecr.aws/gravitational/teleport-distroless:13.3.9 + name: wait-auth-update + nodeSelector: + environment: security + role: bastion + serviceAccountName: RELEASE-NAME-proxy + terminationGracePeriodSeconds: 60 + volumes: + - name: proxy-serviceaccount-token + projected: + sources: + - serviceAccountToken: + path: token + - configMap: + items: + - key: ca.crt + path: ca.crt + name: kube-root-ca.crt + - downwardAPI: + items: + - fieldRef: + fieldPath: metadata.namespace + path: namespace + - configMap: + name: RELEASE-NAME-proxy + name: config + - emptyDir: {} + name: data +should set required affinity when highAvailability.requireAntiAffinity is set: + 1: | + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: app.kubernetes.io/instance + operator: In + values: + - RELEASE-NAME + - key: app.kubernetes.io/component + operator: In + values: + - proxy + topologyKey: kubernetes.io/hostname +should set resources when set in values: + 1: | + affinity: + podAntiAffinity: null + automountServiceAccountToken: false + containers: + - args: + - --diag-addr=0.0.0.0:3000 + image: public.ecr.aws/gravitational/teleport-distroless:13.3.9 + imagePullPolicy: IfNotPresent + lifecycle: + preStop: + exec: + command: + - teleport + - wait + - duration + - 30s + livenessProbe: + failureThreshold: 6 + httpGet: + path: /healthz + port: diag + initialDelaySeconds: 5 + periodSeconds: 5 + timeoutSeconds: 1 + name: teleport + ports: + - containerPort: 3080 + name: tls + protocol: TCP + - containerPort: 3023 + name: sshproxy + protocol: TCP + - containerPort: 3024 + name: sshtun + protocol: TCP + - containerPort: 3026 + name: kube + protocol: TCP + - containerPort: 3036 + name: mysql + protocol: TCP + - containerPort: 3000 + name: diag + protocol: TCP + readinessProbe: + failureThreshold: 12 + httpGet: + path: /readyz + port: diag + initialDelaySeconds: 5 + periodSeconds: 5 + timeoutSeconds: 1 + resources: + limits: + cpu: 2 + memory: 4Gi + requests: + cpu: 1 + memory: 2Gi + volumeMounts: + - mountPath: /etc/teleport + name: config + readOnly: true + - mountPath: /var/lib/teleport + name: data + - mountPath: /var/run/secrets/kubernetes.io/serviceaccount + name: proxy-serviceaccount-token + readOnly: true + initContainers: + - command: + - teleport + - wait + - no-resolve + - RELEASE-NAME-auth-v12.NAMESPACE.svc.cluster.local + image: public.ecr.aws/gravitational/teleport-distroless:13.3.9 + name: wait-auth-update + serviceAccountName: RELEASE-NAME-proxy + terminationGracePeriodSeconds: 60 + volumes: + - name: proxy-serviceaccount-token + projected: + sources: + - serviceAccountToken: + path: token + - configMap: + items: + - key: ca.crt + path: ca.crt + name: kube-root-ca.crt + - downwardAPI: + items: + - fieldRef: + fieldPath: metadata.namespace + path: namespace + - configMap: + name: RELEASE-NAME-proxy + name: config + - emptyDir: {} + name: data +should set securityContext for initContainers when set in values: + 1: | + affinity: + podAntiAffinity: null + automountServiceAccountToken: false + containers: + - args: + - --diag-addr=0.0.0.0:3000 + image: public.ecr.aws/gravitational/teleport-distroless:13.3.9 + imagePullPolicy: IfNotPresent + lifecycle: + preStop: + exec: + command: + - teleport + - wait + - duration + - 30s + livenessProbe: + failureThreshold: 6 + httpGet: + path: /healthz + port: diag + initialDelaySeconds: 5 + periodSeconds: 5 + timeoutSeconds: 1 + name: teleport + ports: + - containerPort: 3080 + name: tls + protocol: TCP + - containerPort: 3023 + name: sshproxy + protocol: TCP + - containerPort: 3024 + name: sshtun + protocol: TCP + - containerPort: 3026 + name: kube + protocol: TCP + - containerPort: 3036 + name: mysql + protocol: TCP + - containerPort: 3000 + name: diag + protocol: TCP + readinessProbe: + failureThreshold: 12 + httpGet: + path: /readyz + port: diag + initialDelaySeconds: 5 + periodSeconds: 5 + timeoutSeconds: 1 + securityContext: + allowPrivilegeEscalation: false + privileged: false + readOnlyRootFilesystem: false + runAsGroup: 99 + runAsNonRoot: true + runAsUser: 99 + volumeMounts: + - mountPath: /etc/teleport + name: config + readOnly: true + - mountPath: /var/lib/teleport + name: data + - mountPath: /var/run/secrets/kubernetes.io/serviceaccount + name: proxy-serviceaccount-token + readOnly: true + initContainers: + - command: + - teleport + - wait + - no-resolve + - RELEASE-NAME-auth-v12.NAMESPACE.svc.cluster.local + image: public.ecr.aws/gravitational/teleport-distroless:13.3.9 + name: wait-auth-update + securityContext: + allowPrivilegeEscalation: false + privileged: false + readOnlyRootFilesystem: false + runAsGroup: 99 + runAsNonRoot: true + runAsUser: 99 + serviceAccountName: RELEASE-NAME-proxy + terminationGracePeriodSeconds: 60 + volumes: + - name: proxy-serviceaccount-token + projected: + sources: + - serviceAccountToken: + path: token + - configMap: + items: + - key: ca.crt + path: ca.crt + name: kube-root-ca.crt + - downwardAPI: + items: + - fieldRef: + fieldPath: metadata.namespace + path: namespace + - configMap: + name: RELEASE-NAME-proxy + name: config + - emptyDir: {} + name: data +should set securityContext when set in values: + 1: | + affinity: + podAntiAffinity: null + automountServiceAccountToken: false + containers: + - args: + - --diag-addr=0.0.0.0:3000 + image: public.ecr.aws/gravitational/teleport-distroless:13.3.9 + imagePullPolicy: IfNotPresent + lifecycle: + preStop: + exec: + command: + - teleport + - wait + - duration + - 30s + livenessProbe: + failureThreshold: 6 + httpGet: + path: /healthz + port: diag + initialDelaySeconds: 5 + periodSeconds: 5 + timeoutSeconds: 1 + name: teleport + ports: + - containerPort: 3080 + name: tls + protocol: TCP + - containerPort: 3023 + name: sshproxy + protocol: TCP + - containerPort: 3024 + name: sshtun + protocol: TCP + - containerPort: 3026 + name: kube + protocol: TCP + - containerPort: 3036 + name: mysql + protocol: TCP + - containerPort: 3000 + name: diag + protocol: TCP + readinessProbe: + failureThreshold: 12 + httpGet: + path: /readyz + port: diag + initialDelaySeconds: 5 + periodSeconds: 5 + timeoutSeconds: 1 + securityContext: + allowPrivilegeEscalation: false + privileged: false + readOnlyRootFilesystem: false + runAsGroup: 99 + runAsNonRoot: true + runAsUser: 99 + volumeMounts: + - mountPath: /etc/teleport + name: config + readOnly: true + - mountPath: /var/lib/teleport + name: data + - mountPath: /var/run/secrets/kubernetes.io/serviceaccount + name: proxy-serviceaccount-token + readOnly: true + initContainers: + - command: + - teleport + - wait + - no-resolve + - RELEASE-NAME-auth-v12.NAMESPACE.svc.cluster.local + image: public.ecr.aws/gravitational/teleport-distroless:13.3.9 + name: wait-auth-update + securityContext: + allowPrivilegeEscalation: false + privileged: false + readOnlyRootFilesystem: false + runAsGroup: 99 + runAsNonRoot: true + runAsUser: 99 + serviceAccountName: RELEASE-NAME-proxy + terminationGracePeriodSeconds: 60 + volumes: + - name: proxy-serviceaccount-token + projected: + sources: + - serviceAccountToken: + path: token + - configMap: + items: + - key: ca.crt + path: ca.crt + name: kube-root-ca.crt + - downwardAPI: + items: + - fieldRef: + fieldPath: metadata.namespace + path: namespace + - configMap: + name: RELEASE-NAME-proxy + name: config + - emptyDir: {} + name: data +should set tolerations when set in values: + 1: | + - effect: NoExecute + key: dedicated + operator: Equal + value: teleport + - effect: NoSchedule + key: dedicated + operator: Equal + value: teleport diff --git a/helm/teleport-cluster/tests/__snapshot__/proxy_service_test.yaml.snap b/helm/teleport-cluster/tests/__snapshot__/proxy_service_test.yaml.snap new file mode 100644 index 0000000..a10b5e5 --- /dev/null +++ b/helm/teleport-cluster/tests/__snapshot__/proxy_service_test.yaml.snap @@ -0,0 +1,68 @@ +does not expose separate listener ports by default when ingress.enabled=true: + 1: | + - name: tls + port: 443 + protocol: TCP + targetPort: 3080 +does not expose separate listener ports when running in separate mode and ingress.enabled=true: + 1: | + - name: tls + port: 443 + protocol: TCP + targetPort: 3080 +exposes a single port when running in multiplex mode: + 1: | + - name: tls + port: 443 + protocol: TCP + targetPort: 3080 +exposes a single port when running in multiplex mode and ingress.enabled=true: + 1: | + - name: tls + port: 443 + protocol: TCP + targetPort: 3080 +exposes separate listener ports by default: + 1: | + - name: tls + port: 443 + protocol: TCP + targetPort: 3080 + - name: sshproxy + port: 3023 + protocol: TCP + targetPort: 3023 + - name: k8s + port: 3026 + protocol: TCP + targetPort: 3026 + - name: sshtun + port: 3024 + protocol: TCP + targetPort: 3024 + - name: mysql + port: 3036 + protocol: TCP + targetPort: 3036 +exposes separate listener ports when running in separate mode: + 1: | + - name: tls + port: 443 + protocol: TCP + targetPort: 3080 + - name: sshproxy + port: 3023 + protocol: TCP + targetPort: 3023 + - name: k8s + port: 3026 + protocol: TCP + targetPort: 3026 + - name: sshtun + port: 3024 + protocol: TCP + targetPort: 3024 + - name: mysql + port: 3036 + protocol: TCP + targetPort: 3036 diff --git a/helm/teleport-cluster/tests/__snapshot__/psp_test.yaml.snap b/helm/teleport-cluster/tests/__snapshot__/psp_test.yaml.snap new file mode 100644 index 0000000..d950054 --- /dev/null +++ b/helm/teleport-cluster/tests/__snapshot__/psp_test.yaml.snap @@ -0,0 +1,62 @@ +creates a PodSecurityPolicy when enabled in values and supported: + 1: | + apiVersion: policy/v1beta1 + kind: PodSecurityPolicy + metadata: + annotations: + seccomp.security.alpha.kubernetes.io/allowedProfileNames: docker/default,runtime/default + seccomp.security.alpha.kubernetes.io/defaultProfileName: runtime/default + name: RELEASE-NAME + spec: + allowPrivilegeEscalation: false + fsGroup: + ranges: + - max: 65535 + min: 1 + rule: MustRunAs + hostIPC: false + hostNetwork: false + hostPID: false + privileged: false + readOnlyRootFilesystem: true + requiredDropCapabilities: + - ALL + runAsUser: + rule: MustRunAsNonRoot + seLinux: + rule: RunAsAny + supplementalGroups: + ranges: + - max: 65535 + min: 1 + rule: MustRunAs + volumes: + - '*' + 2: | + apiVersion: rbac.authorization.k8s.io/v1 + kind: Role + metadata: + name: RELEASE-NAME-psp + namespace: NAMESPACE + rules: + - apiGroups: + - policy + resourceNames: + - RELEASE-NAME + resources: + - podsecuritypolicies + verbs: + - use + 3: | + apiVersion: rbac.authorization.k8s.io/v1 + kind: RoleBinding + metadata: + name: RELEASE-NAME-psp + namespace: NAMESPACE + roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: RELEASE-NAME-psp + subjects: + - kind: ServiceAccount + name: RELEASE-NAME diff --git a/helm/teleport-cluster/tests/auth_clusterrole_test.yaml b/helm/teleport-cluster/tests/auth_clusterrole_test.yaml new file mode 100644 index 0000000..6e26d74 --- /dev/null +++ b/helm/teleport-cluster/tests/auth_clusterrole_test.yaml @@ -0,0 +1,19 @@ +suite: Auth ClusterRole +templates: + - auth/clusterrole.yaml +tests: + - it: creates a ClusterRole + asserts: + - hasDocuments: + count: 1 + - isKind: + of: ClusterRole + - it: adds operator permissions to ClusterRole + values: + - ../.lint/operator.yaml + asserts: + - hasDocuments: + count: 1 + - isKind: + of: ClusterRole + - matchSnapshot: {} diff --git a/helm/teleport-cluster/tests/auth_clusterrolebinding_test.yaml b/helm/teleport-cluster/tests/auth_clusterrolebinding_test.yaml new file mode 100644 index 0000000..45117b1 --- /dev/null +++ b/helm/teleport-cluster/tests/auth_clusterrolebinding_test.yaml @@ -0,0 +1,20 @@ +suite: Auth ClusterRoleBinding +templates: + - auth/clusterrolebinding.yaml +tests: + - it: creates a ClusterRoleBinding + asserts: + - hasDocuments: + count: 2 + - isKind: + of: ClusterRoleBinding + - it: uses the provided serviceAccount name + values: + - ../.lint/service-account.yaml + asserts: + - contains: + path: subjects + any: true + content: + kind: ServiceAccount + name: "helm-lint" diff --git a/helm/teleport-cluster/tests/auth_config_test.yaml b/helm/teleport-cluster/tests/auth_config_test.yaml new file mode 100644 index 0000000..ea2ed14 --- /dev/null +++ b/helm/teleport-cluster/tests/auth_config_test.yaml @@ -0,0 +1,512 @@ +suite: ConfigMap +templates: + - auth/config.yaml +tests: + - it: matches snapshot for acme-off.yaml + values: + - ../.lint/acme-off.yaml + asserts: + - hasDocuments: + count: 1 + - isKind: + of: ConfigMap + - matchSnapshot: + path: data.teleport\.yaml + + - it: matches snapshot for acme-on.yaml + values: + - ../.lint/acme-on.yaml + asserts: + - hasDocuments: + count: 1 + - isKind: + of: ConfigMap + - matchSnapshot: + path: data.teleport\.yaml + + - it: matches snapshot for acme-uri-staging.yaml + values: + - ../.lint/acme-on.yaml + asserts: + - hasDocuments: + count: 1 + - isKind: + of: ConfigMap + - matchSnapshot: + path: data.teleport\.yaml + + - it: wears annotations (annotations.yaml) + values: + - ../.lint/annotations.yaml + asserts: + - hasDocuments: + count: 1 + - isKind: + of: ConfigMap + - equal: + path: metadata.annotations.kubernetes\.io/config + value: test-annotation + - equal: + path: metadata.annotations.kubernetes\.io/config-different + value: 2 + + - it: matches snapshot for auth-connector-name.yaml + values: + - ../.lint/auth-connector-name.yaml + asserts: + - hasDocuments: + count: 1 + - isKind: + of: ConfigMap + - matchSnapshot: + path: data.teleport\.yaml + + - it: matches snapshot for auth-disable-local.yaml + values: + - ../.lint/auth-disable-local.yaml + asserts: + - hasDocuments: + count: 1 + - isKind: + of: ConfigMap + - matchSnapshot: + path: data.teleport\.yaml + + - it: matches snapshot for auth-locking-mode.yaml + values: + - ../.lint/auth-locking-mode.yaml + asserts: + - hasDocuments: + count: 1 + - isKind: + of: ConfigMap + - matchSnapshot: + path: data.teleport\.yaml + + - it: matches snapshot for auth-passwordless.yaml + values: + - ../.lint/auth-passwordless.yaml + asserts: + - hasDocuments: + count: 1 + - isKind: + of: ConfigMap + - matchSnapshot: + path: data.teleport\.yaml + + - it: matches snapshot for auth-type.yaml + values: + - ../.lint/auth-type.yaml + asserts: + - hasDocuments: + count: 1 + - isKind: + of: ConfigMap + - matchSnapshot: + path: data.teleport\.yaml + + - it: matches snapshot for auth-type-legacy.yaml + values: + - ../.lint/auth-type-legacy.yaml + asserts: + - hasDocuments: + count: 1 + - isKind: + of: ConfigMap + - matchSnapshot: + path: data.teleport\.yaml + + - it: matches snapshot for auth-webauthn.yaml + values: + - ../.lint/auth-webauthn.yaml + asserts: + - hasDocuments: + count: 1 + - isKind: + of: ConfigMap + - matchSnapshot: + path: data.teleport\.yaml + + - it: matches snapshot for auth-webauthn-legacy.yaml + values: + - ../.lint/auth-webauthn-legacy.yaml + asserts: + - hasDocuments: + count: 1 + - isKind: + of: ConfigMap + - matchSnapshot: + path: data.teleport\.yaml + + - it: matches snapshot for aws.yaml + values: + - ../.lint/aws.yaml + asserts: + - hasDocuments: + count: 1 + - isKind: + of: ConfigMap + - matchSnapshot: + path: data.teleport\.yaml + + - it: matches snapshot for aws-dynamodb-autoscaling.yaml + values: + - ../.lint/aws-dynamodb-autoscaling.yaml + asserts: + - hasDocuments: + count: 1 + - isKind: + of: ConfigMap + - matchSnapshot: + path: data.teleport\.yaml + + - it: matches snapshot for aws-ha.yaml + values: + - ../.lint/aws-ha.yaml + asserts: + - hasDocuments: + count: 1 + - isKind: + of: ConfigMap + - matchSnapshot: + path: data.teleport\.yaml + + - it: matches snapshot for aws-ha-acme.yaml + values: + - ../.lint/aws-ha-acme.yaml + asserts: + - hasDocuments: + count: 1 + - isKind: + of: ConfigMap + - matchSnapshot: + path: data.teleport\.yaml + + - it: matches snapshot for aws-ha-antiaffinity.yaml + values: + - ../.lint/aws-ha-antiaffinity.yaml + asserts: + - hasDocuments: + count: 1 + - isKind: + of: ConfigMap + - matchSnapshot: + path: data.teleport\.yaml + + - it: matches snapshot for aws-ha-log.yaml + values: + - ../.lint/aws-ha-log.yaml + asserts: + - hasDocuments: + count: 1 + - isKind: + of: ConfigMap + - matchSnapshot: + path: data.teleport\.yaml + + - it: matches snapshot for existing-tls-secret.yaml + values: + - ../.lint/existing-tls-secret.yaml + asserts: + - hasDocuments: + count: 1 + - isKind: + of: ConfigMap + - matchSnapshot: + path: data.teleport\.yaml + + - it: matches snapshot for existing-tls-secret-with-ca.yaml + values: + - ../.lint/existing-tls-secret-with-ca.yaml + asserts: + - hasDocuments: + count: 1 + - isKind: + of: ConfigMap + - matchSnapshot: + path: data.teleport\.yaml + + - it: matches snapshot for gcp-ha-acme.yaml + values: + - ../.lint/gcp-ha-acme.yaml + asserts: + - hasDocuments: + count: 1 + - isKind: + of: ConfigMap + - matchSnapshot: + path: data.teleport\.yaml + + - it: matches snapshot for gcp-ha-antiaffinity.yaml + values: + - ../.lint/gcp-ha-antiaffinity.yaml + asserts: + - hasDocuments: + count: 1 + - isKind: + of: ConfigMap + - matchSnapshot: + path: data.teleport\.yaml + + - it: matches snapshot for gcp-ha-log.yaml + values: + - ../.lint/gcp-ha-log.yaml + asserts: + - hasDocuments: + count: 1 + - isKind: + of: ConfigMap + - matchSnapshot: + path: data.teleport\.yaml + + - it: matches snapshot for gcp.yaml + values: + - ../.lint/gcp.yaml + asserts: + - hasDocuments: + count: 1 + - isKind: + of: ConfigMap + - matchSnapshot: + path: data.teleport\.yaml + + - it: matches snapshot for initcontainers.yaml + values: + - ../.lint/initcontainers.yaml + asserts: + - hasDocuments: + count: 1 + - isKind: + of: ConfigMap + - matchSnapshot: + path: data.teleport\.yaml + + - it: matches snapshot for kube-cluster-name.yaml + values: + - ../.lint/kube-cluster-name.yaml + asserts: + - hasDocuments: + count: 1 + - isKind: + of: ConfigMap + - matchSnapshot: + path: data.teleport\.yaml + + - it: matches snapshot for log-basic.yaml + values: + - ../.lint/log-basic.yaml + asserts: + - hasDocuments: + count: 1 + - isKind: + of: ConfigMap + - matchSnapshot: + path: data.teleport\.yaml + + - it: matches snapshot for log-extra.yaml + values: + - ../.lint/log-extra.yaml + asserts: + - hasDocuments: + count: 1 + - isKind: + of: ConfigMap + - matchSnapshot: + path: data.teleport\.yaml + + - it: matches snapshot for log-legacy.yaml + values: + - ../.lint/log-legacy.yaml + asserts: + - hasDocuments: + count: 1 + - isKind: + of: ConfigMap + - matchSnapshot: + path: data.teleport\.yaml + + - it: matches snapshot for priority-class-name.yaml + values: + - ../.lint/priority-class-name.yaml + asserts: + - hasDocuments: + count: 1 + - isKind: + of: ConfigMap + - matchSnapshot: + path: data.teleport\.yaml + + - it: matches snapshot for proxy-listener-mode-multiplex.yaml + values: + - ../.lint/proxy-listener-mode-multiplex.yaml + asserts: + - hasDocuments: + count: 1 + - isKind: + of: ConfigMap + - matchSnapshot: + path: data.teleport\.yaml + + - it: matches snapshot for proxy-listener-mode-separate.yaml + values: + - ../.lint/proxy-listener-mode-separate.yaml + asserts: + - hasDocuments: + count: 1 + - isKind: + of: ConfigMap + - matchSnapshot: + path: data.teleport\.yaml + + - it: matches snapshot for service.yaml + values: + - ../.lint/service.yaml + asserts: + - hasDocuments: + count: 1 + - isKind: + of: ConfigMap + - matchSnapshot: + path: data.teleport\.yaml + + - it: matches snapshot for separate-mongo-listener.yaml + values: + - ../.lint/separate-mongo-listener.yaml + asserts: + - hasDocuments: + count: 1 + - isKind: + of: ConfigMap + - matchSnapshot: + path: data.teleport\.yaml + + - it: matches snapshot for separate-postgres-listener.yaml + values: + - ../.lint/separate-postgres-listener.yaml + asserts: + - hasDocuments: + count: 1 + - isKind: + of: ConfigMap + - matchSnapshot: + path: data.teleport\.yaml + + - it: matches snapshot for public-addresses.yaml + values: + - ../.lint/public-addresses.yaml + asserts: + - hasDocuments: + count: 1 + - isKind: + of: ConfigMap + - matchSnapshot: + path: data.teleport\.yaml + + - it: matches snapshot for session-recording.yaml + values: + - ../.lint/session-recording.yaml + asserts: + - hasDocuments: + count: 1 + - isKind: + of: ConfigMap + - matchSnapshot: + path: data.teleport\.yaml + + - it: matches snapshot for standalone-customsize.yaml + values: + - ../.lint/standalone-customsize.yaml + asserts: + - hasDocuments: + count: 1 + - isKind: + of: ConfigMap + - matchSnapshot: + path: data.teleport\.yaml + + - it: matches snapshot for standalone-existingpvc.yaml + values: + - ../.lint/standalone-existingpvc.yaml + asserts: + - hasDocuments: + count: 1 + - isKind: + of: ConfigMap + - matchSnapshot: + path: data.teleport\.yaml + + - it: matches snapshot for tolerations.yaml + values: + - ../.lint/tolerations.yaml + asserts: + - hasDocuments: + count: 1 + - isKind: + of: ConfigMap + - matchSnapshot: + path: data.teleport\.yaml + + - it: matches snapshot for version-override.yaml + values: + - ../.lint/version-override.yaml + asserts: + - hasDocuments: + count: 1 + - isKind: + of: ConfigMap + - matchSnapshot: + path: data.teleport\.yaml + + - it: matches snapshot for volumes.yaml + values: + - ../.lint/volumes.yaml + asserts: + - hasDocuments: + count: 1 + - isKind: + of: ConfigMap + - matchSnapshot: + path: data.teleport\.yaml + + - it: adds a proxy token by default + set: + clusterName: teleport.example.com + asserts: + - notEqual: + path: data.apply-on-startup\.yaml + value: null + - matchSnapshot: + path: data.apply-on-startup\.yaml + + - it: matches snapshot for azure.yaml + values: + - ../.lint/azure.yaml + asserts: + - hasDocuments: + count: 1 + - isKind: + of: ConfigMap + - matchSnapshot: + path: data.teleport\.yaml + + - it: matches snapshot for azure.yaml without pool_max_conn + values: + - ../.lint/azure.yaml + set: + azure: + databasePoolMaxConnections: 0 + asserts: + - hasDocuments: + count: 1 + - isKind: + of: ConfigMap + - matchSnapshot: + path: data.teleport\.yaml + + - it: sets "provisioned" billing mode when autoscaling is enabled + values: + - ../.lint/aws-dynamodb-autoscaling.yaml + asserts: + - matchRegex: + path: data.teleport\.yaml + pattern: 'billing_mode: provisioned' diff --git a/helm/teleport-cluster/tests/auth_deployment_test.yaml b/helm/teleport-cluster/tests/auth_deployment_test.yaml new file mode 100644 index 0000000..cc8cb58 --- /dev/null +++ b/helm/teleport-cluster/tests/auth_deployment_test.yaml @@ -0,0 +1,826 @@ +suite: Auth Deployment +templates: + - auth/deployment.yaml + - auth/config.yaml +tests: + - it: sets Statefulset annotations when specified + template: auth/deployment.yaml + values: + - ../.lint/annotations.yaml + asserts: + - equal: + path: metadata.annotations.kubernetes\.io/deployment + value: test-annotation + - equal: + path: metadata.annotations.kubernetes\.io/deployment-different + value: 3 + + - it: sets Pod annotations when specified + template: auth/deployment.yaml + values: + - ../.lint/annotations.yaml + asserts: + - equal: + path: spec.template.metadata.annotations.kubernetes\.io/pod + value: test-annotation + - equal: + path: spec.template.metadata.annotations.kubernetes\.io/pod-different + value: 4 + + - it: should not have more than one replica in standalone mode + template: auth/deployment.yaml + set: + chartMode: standalone + clusterName: helm-lint.example.com + asserts: + - equal: + path: spec.replicas + value: 1 + + - it: should have multiple replicas when replicaCount is set + template: auth/deployment.yaml + set: + chartMode: scratch + clusterName: helm-lint.example.com + highAvailability: + replicaCount: 3 + asserts: + - equal: + path: spec.replicas + value: 3 + + - it: should set affinity when set in values + template: auth/deployment.yaml + set: + clusterName: helm-lint.example.com + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: gravitational.io/dedicated + operator: In + values: + - teleport + asserts: + - isNotNull: + path: spec.template.spec.affinity + - matchSnapshot: + path: spec.template.spec.affinity + + - it: should set nodeSelector when set in values + template: auth/deployment.yaml + set: + chartMode: scratch + clusterName: helm-lint.example.com + nodeSelector: + role: bastion + environment: security + asserts: + - isNotNull: + path: spec.template.spec.nodeSelector + - matchSnapshot: + path: spec.template.spec + + - it: should set required affinity when highAvailability.requireAntiAffinity is set + template: auth/deployment.yaml + values: + - ../.lint/aws-ha-antiaffinity.yaml + asserts: + - isNotNull: + path: spec.template.spec.affinity + - isNotNull: + path: spec.template.spec.affinity.podAntiAffinity + - isNotNull: + path: spec.template.spec.affinity.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution + - matchSnapshot: + path: spec.template.spec.affinity + + - it: should set tolerations when set in values + template: auth/deployment.yaml + values: + - ../.lint/tolerations.yaml + asserts: + - isNotNull: + path: spec.template.spec.tolerations + - matchSnapshot: + path: spec.template.spec.tolerations + + - it: should set resources when set in values + template: auth/deployment.yaml + values: + - ../.lint/resources.yaml + asserts: + - equal: + path: spec.template.spec.containers[0].resources.limits.cpu + value: 2 + - equal: + path: spec.template.spec.containers[0].resources.limits.memory + value: 4Gi + - equal: + path: spec.template.spec.containers[0].resources.requests.cpu + value: 1 + - equal: + path: spec.template.spec.containers[0].resources.requests.memory + value: 2Gi + - matchSnapshot: + path: spec.template.spec + + - it: should set securityContext when set in values + template: auth/deployment.yaml + values: + - ../.lint/security-context.yaml + asserts: + - equal: + path: spec.template.spec.containers[0].securityContext.allowPrivilegeEscalation + value: false + - equal: + path: spec.template.spec.containers[0].securityContext.privileged + value: false + - equal: + path: spec.template.spec.containers[0].securityContext.readOnlyRootFilesystem + value: false + - equal: + path: spec.template.spec.containers[0].securityContext.runAsGroup + value: 99 + - equal: + path: spec.template.spec.containers[0].securityContext.runAsNonRoot + value: true + - equal: + path: spec.template.spec.containers[0].securityContext.runAsUser + value: 99 + - matchSnapshot: + path: spec.template.spec + + - it: should not set securityContext when is empty object (default value) + template: auth/deployment.yaml + values: + - ../.lint/security-context-empty.yaml + asserts: + - isNull: + path: spec.template.spec.containers[0].securityContext + + # we can't use the dynamic chart version or appVersion as a variable in the tests, + # so we override it manually and check that gets set instead + # this saves us having to update the test every time we cut a new release + - it: should use enterprise image and mount license when enterprise is set in values + template: auth/deployment.yaml + set: + clusterName: helm-lint.example.com + enterprise: true + teleportVersionOverride: 12.2.1 + asserts: + - equal: + path: spec.template.spec.containers[0].image + value: public.ecr.aws/gravitational/teleport-ent-distroless:12.2.1 + - contains: + path: spec.template.spec.containers[0].volumeMounts + content: + mountPath: /var/lib/license + name: "license" + readOnly: true + - contains: + path: spec.template.spec.volumes + content: + name: license + secret: + secretName: license + + - it: should use OSS image and not mount license when enterprise is not set in values + template: auth/deployment.yaml + set: + clusterName: helm-lint + teleportVersionOverride: 12.2.1 + asserts: + - equal: + path: spec.template.spec.containers[0].image + value: public.ecr.aws/gravitational/teleport-distroless:12.2.1 + - notContains: + path: spec.template.spec.containers[0].volumeMounts + content: + mountPath: /var/lib/license + name: "license" + readOnly: true + - notContains: + path: spec.template.spec.volumes + content: + name: license + secret: + secretName: license + - matchSnapshot: + path: spec.template.spec + + - it: should mount GCP credentials in GCP mode + template: auth/deployment.yaml + values: + - ../.lint/gcp-ha.yaml + asserts: + - contains: + path: spec.template.spec.containers[0].volumeMounts + content: + mountPath: /etc/teleport-secrets + name: "gcp-credentials" + readOnly: true + - contains: + path: spec.template.spec.volumes + content: + name: gcp-credentials + secret: + secretName: teleport-gcp-credentials + + - it: should not mount secret when credentialSecretName is blank in values + template: auth/deployment.yaml + values: + - ../.lint/gcp-ha-workload.yaml + asserts: + - notContains: + path: spec.template.spec.containers[0].volumeMounts + content: + mountPath: /etc/teleport-secrets + name: "gcp-credentials" + readOnly: true + - notContains: + path: spec.template.spec.volumes + content: + name: gcp-credentials + secret: + secretName: teleport-gcp-credentials + + - it: should mount GCP credentials for initContainer in GCP mode + template: auth/deployment.yaml + values: + - ../.lint/gcp-ha.yaml + - ../.lint/initcontainers.yaml + asserts: + - contains: + path: spec.template.spec.initContainers[0].volumeMounts + content: + mountPath: /etc/teleport-secrets + name: "gcp-credentials" + readOnly: true + + - it: should mount ConfigMap containing Teleport config + template: auth/deployment.yaml + set: + clusterName: helm-lint.example.com + asserts: + - contains: + path: spec.template.spec.containers[0].volumeMounts + content: + mountPath: /etc/teleport + name: "config" + readOnly: true + - contains: + path: spec.template.spec.volumes + content: + name: config + configMap: + name: RELEASE-NAME-auth + + - it: should mount extraVolumes and extraVolumeMounts on container and initContainers + template: auth/deployment.yaml + values: + - ../.lint/volumes.yaml + - ../.lint/initcontainers.yaml + asserts: + - contains: + path: spec.template.spec.containers[0].volumeMounts + content: + mountPath: /path/to/mount + name: my-mount + - contains: + path: spec.template.spec.initContainers[0].volumeMounts + content: + mountPath: /path/to/mount + name: my-mount + - contains: + path: spec.template.spec.initContainers[1].volumeMounts + content: + mountPath: /path/to/mount + name: my-mount + - contains: + path: spec.template.spec.volumes + content: + name: my-mount + secret: + secretName: mySecret + - it: should set imagePullPolicy when set in values + template: auth/deployment.yaml + set: + clusterName: helm-lint.example.com + imagePullPolicy: Always + asserts: + - equal: + path: spec.template.spec.containers[0].imagePullPolicy + value: Always + + - it: should set environment when extraEnv set in values + template: auth/deployment.yaml + values: + - ../.lint/extra-env.yaml + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: SOME_ENVIRONMENT_VARIABLE + value: "some-value" + + - it: should set imagePullSecrets when set in values + template: auth/deployment.yaml + values: + - ../.lint/imagepullsecrets.yaml + asserts: + - equal: + path: spec.template.spec.imagePullSecrets[0].name + value: myRegistryKeySecretName + - matchSnapshot: + path: spec.template.spec.imagePullSecrets + + - it: should provision initContainer correctly when set in values + template: auth/deployment.yaml + values: + - ../.lint/initcontainers.yaml + - ../.lint/resources.yaml + - ../.lint/extra-env.yaml + asserts: + - contains: + path: spec.template.spec.initContainers[0].args + content: "echo test" + - equal: + path: spec.template.spec.initContainers[0].name + value: "teleport-init" + - equal: + path: spec.template.spec.initContainers[0].image + value: "alpine" + - equal: + path: spec.template.spec.initContainers[0].resources.limits.cpu + value: 2 + - equal: + path: spec.template.spec.initContainers[0].resources.limits.memory + value: 4Gi + - equal: + path: spec.template.spec.initContainers[0].resources.requests.cpu + value: 1 + - equal: + path: spec.template.spec.initContainers[0].resources.requests.memory + value: 2Gi + - contains: + path: spec.template.spec.initContainers[1].args + content: "echo test2" + - equal: + path: spec.template.spec.initContainers[1].name + value: "teleport-init2" + - equal: + path: spec.template.spec.initContainers[1].image + value: "alpine" + - equal: + path: spec.template.spec.initContainers[1].resources.limits.cpu + value: 2 + - equal: + path: spec.template.spec.initContainers[1].resources.limits.memory + value: 4Gi + - equal: + path: spec.template.spec.initContainers[1].resources.requests.cpu + value: 1 + - equal: + path: spec.template.spec.initContainers[1].resources.requests.memory + value: 2Gi + - matchSnapshot: + path: spec.template.spec.initContainers + + - it: should add insecureSkipProxyTLSVerify to args when set in values + template: auth/deployment.yaml + set: + clusterName: helm-lint.example.com + insecureSkipProxyTLSVerify: true + asserts: + - contains: + path: spec.template.spec.containers[0].args + content: "--insecure" + + - it: should expose diag port + template: auth/deployment.yaml + set: + clusterName: helm-lint.example.com + asserts: + - contains: + path: spec.template.spec.containers[0].ports + content: + name: diag + containerPort: 3000 + protocol: TCP + + - it: should expose auth port + template: auth/deployment.yaml + set: + clusterName: helm-lint.example.com + asserts: + - contains: + path: spec.template.spec.containers[0].ports + content: + name: auth + containerPort: 3025 + protocol: TCP + + - it: should expose kube port + template: auth/deployment.yaml + set: + clusterName: helm-lint.example.com + asserts: + - contains: + path: spec.template.spec.containers[0].ports + content: + name: kube + containerPort: 3026 + protocol: TCP + + - it: should set postStart command if set in values + template: auth/deployment.yaml + set: + clusterName: helm-lint.example.com + postStart: + command: ["/bin/echo", "test"] + asserts: + - equal: + path: spec.template.spec.containers[0].lifecycle.postStart.exec.command + value: ["/bin/echo", "test"] + + - it: should add PersistentVolumeClaim as volume when in standalone mode and persistence.enabled is true + template: auth/deployment.yaml + set: + chartMode: standalone + clusterName: helm-lint.example.com + persistence: + enabled: true + asserts: + - contains: + path: spec.template.spec.volumes + content: + name: data + persistentVolumeClaim: + claimName: RELEASE-NAME + + - it: should not add PersistentVolumeClaim as volume when in standalone mode and persistence.enabled is false + template: auth/deployment.yaml + set: + chartMode: standalone + clusterName: helm-lint.example.com + persistence: + enabled: false + asserts: + - notContains: + path: spec.template.spec.volumes + content: + name: data + persistentVolumeClaim: + claimName: RELEASE-NAME + + - it: should add PersistentVolumeClaim as volume when in scratch mode and persistence.enabled is true + template: auth/deployment.yaml + set: + chartMode: scratch + clusterName: helm-lint.example.com + persistence: + enabled: true + asserts: + - contains: + path: spec.template.spec.volumes + content: + name: data + persistentVolumeClaim: + claimName: RELEASE-NAME + + - it: should not add PersistentVolumeClaim as volume when in scratch mode and persistence.enabled is false + template: auth/deployment.yaml + set: + chartMode: scratch + clusterName: helm-lint.example.com + persistence: + enabled: false + asserts: + - notContains: + path: spec.template.spec.volumes + content: + name: data + persistentVolumeClaim: + claimName: RELEASE-NAME + + - it: should add an operator side-car when operator is enabled + template: auth/deployment.yaml + values: + - ../.lint/operator.yaml + asserts: + - equal: + path: spec.template.spec.containers[1].name + value: operator + - matchSnapshot: + path: spec.template.spec.containers[1] + + - it: should add named PersistentVolumeClaim as volume when in standalone mode, persistence.existingClaimName is set and persistence.enabled is true + template: auth/deployment.yaml + values: + - ../.lint/standalone-existingpvc.yaml + asserts: + - contains: + path: spec.template.spec.volumes + content: + name: data + persistentVolumeClaim: + claimName: teleport-storage + + - it: should not add named PersistentVolumeClaim as volume when in standalone mode, persistence.existingClaimName is set but persistence.enabled is false + template: auth/deployment.yaml + values: + - ../.lint/standalone-existingpvc.yaml + set: + persistence: + enabled: false + asserts: + - notContains: + path: spec.template.spec.volumes + content: + name: data + persistentVolumeClaim: + claimName: teleport-storage + + - it: should add named PersistentVolumeClaim as volume when in scratch mode and persistence.existingClaimName is set + template: auth/deployment.yaml + values: + - ../.lint/standalone-existingpvc.yaml + asserts: + - contains: + path: spec.template.spec.volumes + content: + name: data + persistentVolumeClaim: + claimName: teleport-storage + + - it: should not add named PersistentVolumeClaim as volume when in scratch mode, persistence.existingClaimName is set and persistence.enabled is false + template: auth/deployment.yaml + values: + - ../.lint/standalone-existingpvc.yaml + set: + persistence: + enabled: false + asserts: + - notContains: + path: spec.template.spec.volumes + content: + name: data + persistentVolumeClaim: + claimName: teleport-storage + - matchSnapshot: + path: spec.template.spec + + - it: should add emptyDir for data in AWS mode + template: auth/deployment.yaml + values: + - ../.lint/aws-ha.yaml + asserts: + - contains: + path: spec.template.spec.volumes + content: + name: data + emptyDir: {} + + - it: should add emptyDir for data in GCP mode + template: auth/deployment.yaml + values: + - ../.lint/gcp-ha.yaml + asserts: + - contains: + path: spec.template.spec.volumes + content: + name: data + emptyDir: {} + + - it: should set priorityClassName when set in values + template: auth/deployment.yaml + values: + - ../.lint/priority-class-name.yaml + asserts: + - equal: + path: spec.template.spec.priorityClassName + value: system-cluster-critical + + - it: should set probeTimeoutSeconds when set in values + template: auth/deployment.yaml + values: + - ../.lint/probe-timeout-seconds.yaml + asserts: + - equal: + path: spec.template.spec.containers[0].livenessProbe.timeoutSeconds + value: 5 + - equal: + path: spec.template.spec.containers[0].readinessProbe.timeoutSeconds + value: 5 + + - it: should mount tls.existingCASecretName and set environment when set in values + template: auth/deployment.yaml + values: + - ../.lint/existing-tls-secret-with-ca.yaml + asserts: + - contains: + path: spec.template.spec.volumes + content: + name: teleport-tls-ca + secret: + secretName: helm-lint-existing-tls-secret-ca + - contains: + path: spec.template.spec.containers[0].volumeMounts + content: + mountPath: /etc/teleport-tls-ca + name: teleport-tls-ca + readOnly: true + - contains: + path: spec.template.spec.containers[0].env + content: + name: SSL_CERT_FILE + value: /etc/teleport-tls-ca/ca.pem + + - it: should mount tls.existingCASecretName and set extra environment when set in values + template: auth/deployment.yaml + values: + - ../.lint/existing-tls-secret-with-ca.yaml + - ../.lint/extra-env.yaml + asserts: + - contains: + path: spec.template.spec.volumes + content: + name: teleport-tls-ca + secret: + secretName: helm-lint-existing-tls-secret-ca + - contains: + path: spec.template.spec.containers[0].volumeMounts + content: + mountPath: /etc/teleport-tls-ca + name: teleport-tls-ca + readOnly: true + - contains: + path: spec.template.spec.containers[0].env + content: + name: SSL_CERT_FILE + value: /etc/teleport-tls-ca/ca.pem + - contains: + path: spec.template.spec.containers[0].env + content: + name: SOME_ENVIRONMENT_VARIABLE + value: some-value + + - it: should set minReadySeconds when replicaCount > 1 + template: auth/deployment.yaml + set: + chartMode: scratch + highAvailability: + minReadySeconds: 60 + replicaCount: 3 + asserts: + - equal: + path: spec.minReadySeconds + value: 60 + + - it: should not set minReadySeconds when replicaCount = 1 + template: auth/deployment.yaml + set: + chartMode: scratch + highAvailability: + minReadySeconds: 60 + replicaCount: 1 + asserts: + - equal: + path: spec.minReadySeconds + value: null + + - it: should use Recreate strategy when replicaCount = 1 + template: auth/deployment.yaml + set: + chartMode: scratch + highAvailability: + replicaCount: 1 + asserts: + - equal: + path: spec.strategy.type + value: Recreate + + - it: should not set strategy when replicaCount > 1 + template: auth/deployment.yaml + set: + chartMode: scratch + highAvailability: + replicaCount: 2 + asserts: + - equal: + path: spec.strategy.type + value: RollingUpdate + + - it: should not perform surge rolling updates when replicaCount > 1 + template: auth/deployment.yaml + set: + chartMode: scratch + highAvailability: + replicaCount: 2 + asserts: + - equal: + path: spec.strategy.rollingUpdate.maxSurge + value: 0 + - equal: + path: spec.strategy.rollingUpdate.maxUnavailable + value: 1 + + - it: mounts regular tokens on older Kubernetes versions + template: auth/deployment.yaml + set: + clusterName: helm-lint + operator: + enabled: true + capabilities: + majorVersion: 1 + minorVersion: 18 + asserts: + - notEqual: + path: spec.template.spec.automountServiceAccountToken + value: false + - notContains: + path: spec.template.spec.volumes + content: + name: auth-serviceaccount-token + projected: + sources: + - serviceAccountToken: + path: token + - configMap: + items: + - key: ca.crt + path: ca.crt + name: kube-root-ca.crt + - downwardAPI: + items: + - path: "namespace" + fieldRef: + fieldPath: metadata.namespace + - notContains: + path: spec.template.spec.containers[0].volumeMounts + content: + mountPath: /var/run/secrets/kubernetes.io/serviceaccount + name: auth-serviceaccount-token + readOnly: true + - notContains: + path: spec.template.spec.containers[1].volumeMounts + content: + mountPath: /var/run/secrets/kubernetes.io/serviceaccount + name: auth-serviceaccount-token + readOnly: true + + - it: mounts tokens through projected volumes on newer Kubernetes versions + template: auth/deployment.yaml + set: + clusterName: helm-lint + operator: + enabled: true + capabilities: + majorVersion: 1 + minorVersion: 21 + asserts: + - equal: + path: spec.template.spec.automountServiceAccountToken + value: false + - contains: + path: spec.template.spec.volumes + content: + name: auth-serviceaccount-token + projected: + sources: + - serviceAccountToken: + path: token + - configMap: + items: + - key: ca.crt + path: ca.crt + name: kube-root-ca.crt + - downwardAPI: + items: + - path: "namespace" + fieldRef: + fieldPath: metadata.namespace + - contains: + path: spec.template.spec.containers[0].volumeMounts + content: + mountPath: /var/run/secrets/kubernetes.io/serviceaccount + name: auth-serviceaccount-token + readOnly: true + - contains: + path: spec.template.spec.containers[1].volumeMounts + content: + mountPath: /var/run/secrets/kubernetes.io/serviceaccount + name: auth-serviceaccount-token + readOnly: true + + - it: should add the azure workload identity label to auth pods in azure mode + template: auth/deployment.yaml + set: + chartMode: azure + clusterName: teleport.example.com + asserts: + - equal: + path: spec.template.metadata.labels.azure\.workload\.identity/use + value: "true" diff --git a/helm/teleport-cluster/tests/auth_pdb_test.yaml b/helm/teleport-cluster/tests/auth_pdb_test.yaml new file mode 100644 index 0000000..0ef9aad --- /dev/null +++ b/helm/teleport-cluster/tests/auth_pdb_test.yaml @@ -0,0 +1,23 @@ +suite: Auth PodDisruptionBudget +templates: + - auth/pdb.yaml +tests: + - it: not should create a PDB when disabled in values + set: + highAvailability: + podDisruptionBudget: + enabled: false + asserts: + - hasDocuments: + count: 0 + - it: should create a PDB when enabled in values (pdb.yaml) + values: + - ../.lint/pdb.yaml + asserts: + - hasDocuments: + count: 1 + - isKind: + of: PodDisruptionBudget + - equal: + path: spec.minAvailable + value: 2 diff --git a/helm/teleport-cluster/tests/auth_pvc_test.yaml b/helm/teleport-cluster/tests/auth_pvc_test.yaml new file mode 100644 index 0000000..3fbd87c --- /dev/null +++ b/helm/teleport-cluster/tests/auth_pvc_test.yaml @@ -0,0 +1,87 @@ +suite: Auth PersistentVolumeClaim +templates: + - auth/pvc.yaml +tests: + - it: creates a PersistentVolumeClaim when chartMode=standalone with default size + set: + chartMode: standalone + asserts: + - hasDocuments: + count: 1 + - isKind: + of: PersistentVolumeClaim + - equal: + path: spec.resources.requests.storage + value: "10Gi" + + - it: creates a PersistentVolumeClaim when chartMode=scratch + set: + chartMode: scratch + asserts: + - hasDocuments: + count: 1 + - isKind: + of: PersistentVolumeClaim + + - it: uses a custom size when set + values: + - ../.lint/standalone-customsize.yaml + asserts: + - hasDocuments: + count: 1 + - isKind: + of: PersistentVolumeClaim + - equal: + path: spec.resources.requests.storage + value: 50Gi + + - it: uses a custom storage class when set + values: + - ../.lint/standalone-custom-storage-class.yaml + asserts: + - hasDocuments: + count: 1 + - isKind: + of: PersistentVolumeClaim + - equal: + path: spec.storageClassName + value: ebs-ssd + + - it: does not create a PersistentVolumeClaim when chartMode=standalone and existingClaimName is not blank + set: + chartMode: standalone + persistence: + existingClaimName: test-claim + asserts: + - hasDocuments: + count: 0 + + - it: does not create a PersistentVolumeClaim when chartMode=scratch and existingClaimName is not blank + set: + chartMode: scratch + persistence: + existingClaimName: test-claim + asserts: + - hasDocuments: + count: 0 + + - it: does not create a PersistentVolumeClaim when chartMode=aws + set: + chartMode: aws + asserts: + - hasDocuments: + count: 0 + + - it: does not create a PersistentVolumeClaim when chartMode=gcp + set: + chartMode: gcp + asserts: + - hasDocuments: + count: 0 + + - it: does not create a PersistentVolumeClaim when chartMode=azure + set: + chartMode: azure + asserts: + - hasDocuments: + count: 0 diff --git a/helm/teleport-cluster/tests/auth_serviceaccount_test.yaml b/helm/teleport-cluster/tests/auth_serviceaccount_test.yaml new file mode 100644 index 0000000..532407f --- /dev/null +++ b/helm/teleport-cluster/tests/auth_serviceaccount_test.yaml @@ -0,0 +1,32 @@ +suite: Auth ServiceAccount +templates: + - auth/serviceaccount.yaml +tests: + - it: sets ServiceAccount annotations when specified + values: + - ../.lint/annotations.yaml + asserts: + - equal: + path: metadata.annotations.kubernetes\.io/serviceaccount + value: test-annotation + - equal: + path: metadata.annotations.kubernetes\.io/serviceaccount-different + value: 6 + + - it: changes ServiceAccount name when specified + values: + - ../.lint/service-account.yaml + asserts: + - equal: + path: metadata.name + value: "helm-lint" + + - it: sets Azure client ID when set + set: + chartMode: azure + azure: + clientID: "1234" + asserts: + - equal: + path: metadata.annotations.azure\.workload\.identity/client-id + value: "1234" diff --git a/helm/teleport-cluster/tests/ingress_test.yaml b/helm/teleport-cluster/tests/ingress_test.yaml new file mode 100644 index 0000000..b750167 --- /dev/null +++ b/helm/teleport-cluster/tests/ingress_test.yaml @@ -0,0 +1,538 @@ +suite: Proxy Ingress +templates: + - proxy/ingress.yaml +tests: + - it: does not create an Ingress by default + set: + clusterName: teleport.example.com + asserts: + - hasDocuments: + count: 0 + + - it: creates an Ingress when ingress.enabled=true and proxyListenerMode=multiplex + values: + - ../.lint/ingress.yaml + asserts: + - hasDocuments: + count: 1 + - isKind: + of: Ingress + + - it: fails to deploy an Ingress when ingress.enabled=true and proxyListenerMode is not set + values: + - ../.lint/ingress.yaml + set: + proxyListenerMode: "" + asserts: + - failedTemplate: + errorMessage: "Use of an ingress requires TLS multiplexing to be enabled, so you must also set proxyListenerMode=multiplex - see https://goteleport.com/docs/architecture/tls-routing/" + + - it: fails to deploy an Ingress when ingress.enabled=true and proxyListenerMode=separate + values: + - ../.lint/ingress.yaml + set: + proxyListenerMode: separate + asserts: + - failedTemplate: + errorMessage: "Use of an ingress requires TLS multiplexing to be enabled, so you must also set proxyListenerMode=multiplex - see https://goteleport.com/docs/architecture/tls-routing/" + + - it: wears annotations when set + values: + - ../.lint/ingress.yaml + set: + annotations: + ingress: + test-annotation: test-annotation-value + another-annotation: some-other-value + asserts: + - hasDocuments: + count: 1 + - isKind: + of: Ingress + - equal: + path: metadata.annotations.test-annotation + value: test-annotation-value + - equal: + path: metadata.annotations.another-annotation + value: some-other-value + + - it: sets the clusterName and wildcard of clusterName as hostnames when Ingress is enabled + values: + - ../.lint/ingress.yaml + asserts: + - equal: + path: spec.tls[0].hosts[0] + value: "teleport.example.com" + - contains: + path: spec.tls + content: + hosts: + - "teleport.example.com" + - "*.teleport.example.com" + - equal: + path: spec.rules[0].host + value: "teleport.example.com" + - contains: + path: spec.rules + content: + host: "teleport.example.com" + http: + paths: + - backend: + service: + name: RELEASE-NAME + port: + number: 443 + path: / + pathType: Prefix + - equal: + path: spec.rules[1].host + value: "*.teleport.example.com" + - contains: + path: spec.rules + content: + host: "*.teleport.example.com" + http: + paths: + - backend: + service: + name: RELEASE-NAME + port: + number: 443 + path: / + pathType: Prefix + - matchSnapshot: + path: spec.tls + + - it: does not set a wildcard of clusterName as a hostname when Ingress is enabled and ingress.suppressAutomaticWildcards is true + values: + - ../.lint/ingress.yaml + set: + ingress: + suppressAutomaticWildcards: true + asserts: + - equal: + path: spec.tls[0].hosts[0] + value: "teleport.example.com" + - contains: + path: spec.tls + content: + hosts: + - "teleport.example.com" + - equal: + path: spec.rules[0].host + value: "teleport.example.com" + - contains: + path: spec.rules + content: + host: "teleport.example.com" + http: + paths: + - backend: + service: + name: RELEASE-NAME + port: + number: 443 + path: / + pathType: Prefix + - notContains: + path: spec.rules + content: + host: "*.teleport.example.com" + http: + paths: + - backend: + service: + name: RELEASE-NAME + port: + number: 443 + path: / + pathType: Prefix + - matchSnapshot: + path: spec.tls + + - it: sets the publicAddr and wildcard of publicAddr as hostnames when Ingress is enabled and publicAddr is set + values: + - ../.lint/ingress.yaml + set: + publicAddr: ["helm-lint.example.com"] + asserts: + - equal: + path: spec.tls[0].hosts[0] + value: "helm-lint.example.com" + - contains: + path: spec.tls + content: + hosts: + - "helm-lint.example.com" + - "*.helm-lint.example.com" + - equal: + path: spec.rules[0].host + value: helm-lint.example.com + - contains: + path: spec.rules + content: + host: "helm-lint.example.com" + http: + paths: + - backend: + service: + name: RELEASE-NAME + port: + number: 443 + path: / + pathType: Prefix + - equal: + path: spec.rules[1].host + value: "*.helm-lint.example.com" + - contains: + path: spec.rules + content: + host: "*.helm-lint.example.com" + http: + paths: + - backend: + service: + name: RELEASE-NAME + port: + number: 443 + path: / + pathType: Prefix + - matchSnapshot: + path: spec.tls + + - it: does not set a wildcard of publicAddr as a hostname when Ingress is enabled, publicAddr is set and ingress.suppressAutomaticWildcards is true + values: + - ../.lint/ingress.yaml + set: + publicAddr: ["helm-lint.example.com"] + ingress: + suppressAutomaticWildcards: true + asserts: + - equal: + path: spec.tls[0].hosts[0] + value: "helm-lint.example.com" + - contains: + path: spec.tls + content: + hosts: + - "helm-lint.example.com" + - equal: + path: spec.rules[0].host + value: helm-lint.example.com + - contains: + path: spec.rules + content: + host: "helm-lint.example.com" + http: + paths: + - backend: + service: + name: RELEASE-NAME + port: + number: 443 + path: / + pathType: Prefix + - notContains: + path: spec.rules + content: + host: "*.helm-lint.example.com" + http: + paths: + - backend: + service: + name: RELEASE-NAME + port: + number: 443 + path: / + pathType: Prefix + - matchSnapshot: + path: spec.tls + + - it: trims ports from publicAddr and uses it as the hostname when Ingress is enabled and publicAddr is set + values: + - ../.lint/ingress.yaml + set: + publicAddr: ["helm-lint.example.com:443"] + asserts: + - equal: + path: spec.tls[0].hosts[0] + value: "helm-lint.example.com" + - contains: + path: spec.tls + content: + hosts: + - "helm-lint.example.com" + - "*.helm-lint.example.com" + - equal: + path: spec.rules[0].host + value: "helm-lint.example.com" + - contains: + path: spec.rules + content: + host: helm-lint.example.com + http: + paths: + - backend: + service: + name: RELEASE-NAME + port: + number: 443 + path: / + pathType: Prefix + - equal: + path: spec.rules[1].host + value: "*.helm-lint.example.com" + - contains: + path: spec.rules + content: + host: "*.helm-lint.example.com" + http: + paths: + - backend: + service: + name: RELEASE-NAME + port: + number: 443 + path: / + pathType: Prefix + - matchSnapshot: + path: spec.tls + + - it: exposes all publicAddrs and wildcard publicAddrs as hostnames when Ingress is enabled and multiple publicAddrs are set + values: + - ../.lint/ingress.yaml + set: + publicAddr: ["helm-lint.example.com", "helm-lint-second-domain.example.com"] + asserts: + - equal: + path: spec.tls[0].hosts[0] + value: "helm-lint.example.com" + - equal: + path: spec.tls[0].hosts[1] + value: "helm-lint-second-domain.example.com" + - contains: + path: spec.tls + content: + hosts: + - "helm-lint.example.com" + - "helm-lint-second-domain.example.com" + - "*.helm-lint.example.com" + - "*.helm-lint-second-domain.example.com" + - equal: + path: spec.rules[0].host + value: "helm-lint.example.com" + - equal: + path: spec.rules[1].host + value: "helm-lint-second-domain.example.com" + - equal: + path: spec.rules[2].host + value: "*.helm-lint.example.com" + - equal: + path: spec.rules[3].host + value: "*.helm-lint-second-domain.example.com" + - contains: + path: spec.rules + content: + host: "helm-lint.example.com" + http: + paths: + - backend: + service: + name: RELEASE-NAME + port: + number: 443 + path: / + pathType: Prefix + - contains: + path: spec.rules + content: + host: "helm-lint-second-domain.example.com" + http: + paths: + - backend: + service: + name: RELEASE-NAME + port: + number: 443 + path: / + pathType: Prefix + - contains: + path: spec.rules + content: + host: "*.helm-lint.example.com" + http: + paths: + - backend: + service: + name: RELEASE-NAME + port: + number: 443 + path: / + pathType: Prefix + - contains: + path: spec.rules + content: + host: "*.helm-lint-second-domain.example.com" + http: + paths: + - backend: + service: + name: RELEASE-NAME + port: + number: 443 + path: / + pathType: Prefix + - matchSnapshot: + path: spec.tls + + # this is a very contrived example which wouldn't even work in reality + # it's just to test the logic in the hostname generation code + - it: does not add additional wildcard publicAddrs when Ingress is enabled and a publicAddr already contains a wildcard + values: + - ../.lint/ingress.yaml + set: + publicAddr: ["helm-lint.example.com", "*.helm-lint.example.com", "helm-lint-second-domain.example.com:443"] + asserts: + - equal: + path: spec.tls[0].hosts[0] + value: "helm-lint.example.com" + - equal: + path: spec.tls[0].hosts[1] + value: "*.helm-lint.example.com" + - equal: + path: spec.tls[0].hosts[2] + value: "helm-lint-second-domain.example.com" + - equal: + path: spec.tls[0].hosts[3] + value: "*.helm-lint-second-domain.example.com" + - contains: + path: spec.tls + content: + hosts: + - "helm-lint.example.com" + - "*.helm-lint.example.com" + - "helm-lint-second-domain.example.com" + - "*.helm-lint-second-domain.example.com" + - equal: + path: spec.rules[0].host + value: "helm-lint.example.com" + - equal: + path: spec.rules[1].host + value: "*.helm-lint.example.com" + - equal: + path: spec.rules[2].host + value: "helm-lint-second-domain.example.com" + - equal: + path: spec.rules[3].host + value: "*.helm-lint-second-domain.example.com" + - contains: + path: spec.rules + content: + host: "helm-lint.example.com" + http: + paths: + - backend: + service: + name: RELEASE-NAME + port: + number: 443 + path: / + pathType: Prefix + - contains: + path: spec.rules + content: + host: "*.helm-lint.example.com" + http: + paths: + - backend: + service: + name: RELEASE-NAME + port: + number: 443 + path: / + pathType: Prefix + - contains: + path: spec.rules + content: + host: "helm-lint-second-domain.example.com" + http: + paths: + - backend: + service: + name: RELEASE-NAME + port: + number: 443 + path: / + pathType: Prefix + - contains: + path: spec.rules + content: + host: "*.helm-lint-second-domain.example.com" + http: + paths: + - backend: + service: + name: RELEASE-NAME + port: + number: 443 + path: / + pathType: Prefix + - matchSnapshot: + path: spec.tls + + - it: sets spec when passed + values: + - ../.lint/ingress.yaml + set: + ingress: + spec: + ingressClassName: nginx + otherSpecStuff: lint + asserts: + - hasDocuments: + count: 1 + - isKind: + of: Ingress + - equal: + path: spec.ingressClassName + value: nginx + - equal: + path: spec.otherSpecStuff + value: lint + + - it: does not set tls.secretName by default + values: + - ../.lint/ingress.yaml + asserts: + - isEmpty: + path: spec.tls[0].secretName + - matchSnapshot: + path: spec.tls + + - it: sets tls.secretName when cert-manager is enabled + values: + - ../.lint/ingress.yaml + set: + highAvailability: + certManager: + enabled: true + asserts: + - equal: + path: spec.tls[0].secretName + value: teleport-tls + - matchSnapshot: + path: spec.tls + + - it: sets tls.secretName the value of tls.existingSecretName when set + values: + - ../.lint/ingress.yaml + set: + tls: + existingSecretName: helm-lint-tls-secret + asserts: + - equal: + path: spec.tls[0].secretName + value: helm-lint-tls-secret + - matchSnapshot: + path: spec.tls diff --git a/helm/teleport-cluster/tests/podmonitor_test.yaml b/helm/teleport-cluster/tests/podmonitor_test.yaml new file mode 100644 index 0000000..ccdf692 --- /dev/null +++ b/helm/teleport-cluster/tests/podmonitor_test.yaml @@ -0,0 +1,40 @@ +suite: PodMonitor +templates: + - podmonitor.yaml +tests: + - it: does not create a PodMonitor by default + set: + clusterName: test-kube-cluster-name + asserts: + - hasDocuments: + count: 0 + + - it: creates a PodMonitor when enabled + set: + clusterName: test-kube-cluster-name + podMonitor: + enabled: true + asserts: + - hasDocuments: + count: 1 + - isKind: + of: PodMonitor + + - it: configures scrape interval if provided + set: + clusterName: test-kube-cluster-name + podMonitor: + enabled: true + interval: 2m + asserts: + - equal: + path: spec.podMetricsEndpoints[0].interval + value: 2m + + - it: wears additional labels if provided + asserts: + - equal: + path: metadata.labels.prometheus + value: default + values: + - ../.lint/podmonitor.yaml \ No newline at end of file diff --git a/helm/teleport-cluster/tests/predeploy_test.yaml b/helm/teleport-cluster/tests/predeploy_test.yaml new file mode 100644 index 0000000..fb32cfa --- /dev/null +++ b/helm/teleport-cluster/tests/predeploy_test.yaml @@ -0,0 +1,111 @@ +suite: Pre-Deploy Config Test Hooks +templates: + - auth/predeploy_job.yaml + - auth/predeploy_config.yaml + - proxy/predeploy_job.yaml + - proxy/predeploy_config.yaml +tests: + - it: Deploys the auth-test config + template: auth/predeploy_config.yaml + set: + clusterName: helm-lint + asserts: + - containsDocument: + kind: ConfigMap + apiVersion: v1 + name: RELEASE-NAME-auth-test + namespace: NAMESPACE + + - it: Deploys the proxy-test config + template: proxy/predeploy_config.yaml + set: + clusterName: helm-lint + asserts: + - containsDocument: + kind: ConfigMap + apiVersion: v1 + name: RELEASE-NAME-proxy-test + namespace: NAMESPACE + + - it: Deploys the auth-test job + template: auth/predeploy_job.yaml + set: + clusterName: helm-lint + asserts: + - containsDocument: + kind: Job + apiVersion: batch/v1 + name: RELEASE-NAME-auth-test + namespace: NAMESPACE + + - it: Is executed as a pre-install and pre-upgrade hook + set: + clusterName: helm-lint + asserts: + - equal: + path: metadata.annotations.helm\.sh/hook + value: pre-install,pre-upgrade + + - it: Does not render hooks when config validation is disabled + set: + clusterName: helm-lint + validateConfigOnDeploy: false + asserts: + - hasDocuments: + count: 0 + - it: should set resources on auth predeploy job when set in values + template: auth/predeploy_job.yaml + values: + - ../.lint/resources.yaml + asserts: + - equal: + path: spec.template.spec.containers[0].resources.limits.cpu + value: 2 + - equal: + path: spec.template.spec.containers[0].resources.limits.memory + value: 4Gi + - equal: + path: spec.template.spec.containers[0].resources.requests.cpu + value: 1 + - equal: + path: spec.template.spec.containers[0].resources.requests.memory + value: 2Gi + - it: should set resources on proxy predeploy job when set in values + template: proxy/predeploy_job.yaml + values: + - ../.lint/resources.yaml + asserts: + - equal: + path: spec.template.spec.containers[0].resources.limits.cpu + value: 2 + - equal: + path: spec.template.spec.containers[0].resources.limits.memory + value: 4Gi + - equal: + path: spec.template.spec.containers[0].resources.requests.cpu + value: 1 + - equal: + path: spec.template.spec.containers[0].resources.requests.memory + value: 2Gi + + - it: should set imagePullSecrets on proxy predeploy job when set in values + template: proxy/predeploy_job.yaml + values: + - ../.lint/imagepullsecrets.yaml + asserts: + - equal: + path: spec.template.spec.imagePullSecrets[0].name + value: myRegistryKeySecretName + - matchSnapshot: + path: spec.template.spec.imagePullSecrets + + - it: should set imagePullSecrets on auth predeploy job when set in values + template: auth/predeploy_job.yaml + values: + - ../.lint/imagepullsecrets.yaml + asserts: + - equal: + path: spec.template.spec.imagePullSecrets[0].name + value: myRegistryKeySecretName + - matchSnapshot: + path: spec.template.spec.imagePullSecrets diff --git a/helm/teleport-cluster/tests/proxy_certificate_test.yaml b/helm/teleport-cluster/tests/proxy_certificate_test.yaml new file mode 100644 index 0000000..d1d8f0c --- /dev/null +++ b/helm/teleport-cluster/tests/proxy_certificate_test.yaml @@ -0,0 +1,29 @@ +suite: Proxy Certificate +templates: + - proxy/certificate.yaml +tests: + - it: should request a certificate for cluster name when cert-manager is enabled (cert-manager.yaml) + values: + - ../.lint/cert-manager.yaml + asserts: + - hasDocuments: + count: 1 + - isKind: + of: Certificate + - matchSnapshot: + path: spec.dnsNames + - matchSnapshot: + path: spec.issuerRef + + - it: should request a certificate for cluster name when cert-manager is enabled (cert-secret.yaml) + values: + - ../.lint/cert-secret.yaml + asserts: + - hasDocuments: + count: 1 + - isKind: + of: Certificate + - matchSnapshot: + path: spec.dnsNames + - matchSnapshot: + path: spec.issuerRef diff --git a/helm/teleport-cluster/tests/proxy_config_test.yaml b/helm/teleport-cluster/tests/proxy_config_test.yaml new file mode 100644 index 0000000..cbacce9 --- /dev/null +++ b/helm/teleport-cluster/tests/proxy_config_test.yaml @@ -0,0 +1,235 @@ +suite: ConfigMap +templates: + - proxy/config.yaml +tests: + - it: matches snapshot for log-basic.yaml + values: + - ../.lint/log-basic.yaml + asserts: + - hasDocuments: + count: 1 + - isKind: + of: ConfigMap + - matchSnapshot: + path: data.teleport\.yaml + + - it: matches snapshot for log-extra.yaml + values: + - ../.lint/log-extra.yaml + asserts: + - hasDocuments: + count: 1 + - isKind: + of: ConfigMap + - matchSnapshot: + path: data.teleport\.yaml + + - it: matches snapshot for public-addresses.yaml + values: + - ../.lint/public-addresses.yaml + asserts: + - hasDocuments: + count: 1 + - isKind: + of: ConfigMap + - matchSnapshot: + path: data.teleport\.yaml + + - it: wears annotations (annotations.yaml) + values: + - ../.lint/annotations.yaml + asserts: + - hasDocuments: + count: 1 + - isKind: + of: ConfigMap + - equal: + path: metadata.annotations.kubernetes\.io/config + value: test-annotation + - equal: + path: metadata.annotations.kubernetes\.io/config-different + value: 2 + + - it: matches snapshot for proxy-listener-mode-multiplex.yaml + values: + - ../.lint/proxy-listener-mode-multiplex.yaml + asserts: + - hasDocuments: + count: 1 + - isKind: + of: ConfigMap + - matchSnapshot: + path: data.teleport\.yaml + + - it: matches snapshot for proxy-listener-mode-separate.yaml + values: + - ../.lint/proxy-listener-mode-separate.yaml + asserts: + - hasDocuments: + count: 1 + - isKind: + of: ConfigMap + - matchSnapshot: + path: data.teleport\.yaml + + - it: matches snapshot for separate-mongo-listener.yaml + values: + - ../.lint/separate-mongo-listener.yaml + asserts: + - hasDocuments: + count: 1 + - isKind: + of: ConfigMap + - matchSnapshot: + path: data.teleport\.yaml + + - it: matches snapshot for separate-postgres-listener.yaml + values: + - ../.lint/separate-postgres-listener.yaml + asserts: + - hasDocuments: + count: 1 + - isKind: + of: ConfigMap + - matchSnapshot: + path: data.teleport\.yaml + + - it: matches snapshot for aws-ha-acme.yaml + values: + - ../.lint/aws-ha-acme.yaml + asserts: + - hasDocuments: + count: 1 + - isKind: + of: ConfigMap + - matchSnapshot: + path: data.teleport\.yaml + + - it: matches snapshot for existing-tls-secret.yaml + values: + - ../.lint/existing-tls-secret.yaml + asserts: + - hasDocuments: + count: 1 + - isKind: + of: ConfigMap + - matchSnapshot: + path: data.teleport\.yaml + + - it: matches snapshot for acme-on.yaml + values: + - ../.lint/acme-on.yaml + asserts: + - hasDocuments: + count: 1 + - isKind: + of: ConfigMap + - matchSnapshot: + path: data.teleport\.yaml + + - it: matches snapshot for acme-uri-staging.yaml + values: + - ../.lint/acme-uri-staging.yaml + asserts: + - hasDocuments: + count: 1 + - isKind: + of: ConfigMap + - matchSnapshot: + path: data.teleport\.yaml + + - it: generates a config with a clusterName containing a regular string + set: + clusterName: "helm-test.example.com" + asserts: + - hasDocuments: + count: 1 + - isKind: + of: ConfigMap + - matchSnapshot: + path: data.teleport\.yaml + + - it: fails when clusterName contains a regular string and a colon + set: + clusterName: "helm-test:cluster-1" + asserts: + - failedTemplate: + errorMessage: "clusterName must not contain a colon, you can override the cluster's public address with publicAddr" + + - it: fails when clusterName contains a port + set: + clusterName: "helm-test.example.com:443" + asserts: + - failedTemplate: + errorMessage: "clusterName must not contain a colon, you can override the cluster's public address with publicAddr" + + - it: generates a config with proxy_service.trust_x_forwarded_for=true when version >=13.2.0 and ingress.enabled=true + chart: + version: 13.2.0 + values: + - ../.lint/ingress.yaml + set: + clusterName: "helm-test.example.com" + asserts: + - hasDocuments: + count: 1 + - isKind: + of: ConfigMap + - matchSnapshot: + path: data.teleport\.yaml + + - it: generates a config with proxy_service.trust_x_forwarded_for=true when version = 14.0.0-rc.1 and ingress.enabled=true + chart: + version: "14.0.0-rc.1" + values: + - ../.lint/ingress.yaml + set: + clusterName: "helm-test.example.com" + asserts: + - hasDocuments: + count: 1 + - isKind: + of: ConfigMap + - matchSnapshot: + path: data.teleport\.yaml + + - it: generates a config WITHOUT proxy_service.trust_x_forwarded_for=true when version >=13.2.0 and ingress.enabled is not set + chart: + version: 13.2.0 + set: + clusterName: "helm-test.example.com" + asserts: + - hasDocuments: + count: 1 + - isKind: + of: ConfigMap + - matchSnapshot: + path: data.teleport\.yaml + + - it: generates a config WITHOUT proxy_service.trust_x_forwarded_for=true when version < 13.2.0 and ingress.enabled=true + chart: + version: 13.1.5 + values: + - ../.lint/ingress.yaml + set: + clusterName: "helm-test.example.com" + asserts: + - hasDocuments: + count: 1 + - isKind: + of: ConfigMap + - matchSnapshot: + path: data.teleport\.yaml + + - it: generates a config WITHOUT proxy_service.trust_x_forwarded_for=true when version < 13.2.0 and ingress.enabled is not set + chart: + version: 13.1.5 + set: + clusterName: "helm-test.example.com" + asserts: + - hasDocuments: + count: 1 + - isKind: + of: ConfigMap + - matchSnapshot: + path: data.teleport\.yaml diff --git a/helm/teleport-cluster/tests/proxy_deployment_test.yaml b/helm/teleport-cluster/tests/proxy_deployment_test.yaml new file mode 100644 index 0000000..4c4ddf4 --- /dev/null +++ b/helm/teleport-cluster/tests/proxy_deployment_test.yaml @@ -0,0 +1,899 @@ +suite: Proxy Deployment +templates: + - proxy/deployment.yaml + - proxy/config.yaml +tests: + - it: sets Deployment annotations when specified + template: proxy/deployment.yaml + values: + - ../.lint/annotations.yaml + asserts: + - equal: + path: metadata.annotations.kubernetes\.io/deployment + value: test-annotation + - equal: + path: metadata.annotations.kubernetes\.io/deployment-different + value: 3 + + - it: sets Pod annotations when specified + template: proxy/deployment.yaml + values: + - ../.lint/annotations.yaml + asserts: + - equal: + path: spec.template.metadata.annotations.kubernetes\.io/pod + value: test-annotation + - equal: + path: spec.template.metadata.annotations.kubernetes\.io/pod-different + value: 4 + + - it: should not have more than one replica if no certificate is passed + template: proxy/deployment.yaml + set: + clusterName: helm-lint.example.com + asserts: + - equal: + path: spec.replicas + value: 1 + + - it: should have multiple replicas by default when a certificate is passed through a secret + template: proxy/deployment.yaml + set: + clusterName: helm-lint.example.com + tls: + existingSecretName: my-certs + asserts: + - equal: + path: spec.replicas + value: 2 + + - it: should have multiple replicas by default when certManager is configured + template: proxy/deployment.yaml + set: + clusterName: helm-lint.example.com + highAvailability: + certManager: + enabled: true + asserts: + - equal: + path: spec.replicas + value: 2 + + - it: should have multiple replicas when global replicaCount is set and a certificate is passed + template: proxy/deployment.yaml + set: + clusterName: helm-lint.example.com + highAvailability: + replicaCount: 3 + certManager: + enabled: true + asserts: + - equal: + path: spec.replicas + value: 3 + + - it: should have a single replica when proxy-specific replicaCount is set to 1 and a cert is passed + template: proxy/deployment.yaml + set: + clusterName: helm-lint.example.com + highAvailability: + certManager: + enabled: true + proxy: + highAvailability: + replicaCount: 1 + asserts: + - equal: + path: spec.replicas + value: 1 + + - it: should set affinity when set in values + template: proxy/deployment.yaml + set: + clusterName: helm-lint.example.com + highAvailability: + replicaCount: 3 + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: gravitational.io/dedicated + operator: In + values: + - teleport + asserts: + - isNotNull: + path: spec.template.spec.affinity + - matchSnapshot: + path: spec.template.spec.affinity + + - it: should set required affinity when highAvailability.requireAntiAffinity is set + template: proxy/deployment.yaml + values: + - ../.lint/aws-ha-antiaffinity.yaml + asserts: + - isNotNull: + path: spec.template.spec.affinity + - isNotNull: + path: spec.template.spec.affinity.podAntiAffinity + - isNotNull: + path: spec.template.spec.affinity.podAntiAffinity.requiredDuringSchedulingIgnoredDuringExecution + - matchSnapshot: + path: spec.template.spec.affinity + + - it: should set tolerations when set in values + template: proxy/deployment.yaml + values: + - ../.lint/tolerations.yaml + asserts: + - isNotNull: + path: spec.template.spec.tolerations + - matchSnapshot: + path: spec.template.spec.tolerations + + - it: should set resources when set in values + template: proxy/deployment.yaml + values: + - ../.lint/resources.yaml + asserts: + - equal: + path: spec.template.spec.containers[0].resources.limits.cpu + value: 2 + - equal: + path: spec.template.spec.containers[0].resources.limits.memory + value: 4Gi + - equal: + path: spec.template.spec.containers[0].resources.requests.cpu + value: 1 + - equal: + path: spec.template.spec.containers[0].resources.requests.memory + value: 2Gi + - matchSnapshot: + path: spec.template.spec + + - it: should set securityContext when set in values + template: proxy/deployment.yaml + values: + - ../.lint/security-context.yaml + asserts: + - equal: + path: spec.template.spec.containers[0].securityContext.allowPrivilegeEscalation + value: false + - equal: + path: spec.template.spec.containers[0].securityContext.privileged + value: false + - equal: + path: spec.template.spec.containers[0].securityContext.readOnlyRootFilesystem + value: false + - equal: + path: spec.template.spec.containers[0].securityContext.runAsGroup + value: 99 + - equal: + path: spec.template.spec.containers[0].securityContext.runAsNonRoot + value: true + - equal: + path: spec.template.spec.containers[0].securityContext.runAsUser + value: 99 + - matchSnapshot: + path: spec.template.spec + + - it: should not set securityContext when is empty object (default value) + template: proxy/deployment.yaml + values: + - ../.lint/security-context-empty.yaml + asserts: + - isNull: + path: spec.template.spec.containers[0].securityContext + + - it: should set securityContext for initContainers when set in values + template: proxy/deployment.yaml + values: + - ../.lint/security-context.yaml + asserts: + - equal: + path: spec.template.spec.initContainers[0].securityContext.allowPrivilegeEscalation + value: false + - equal: + path: spec.template.spec.initContainers[0].securityContext.privileged + value: false + - equal: + path: spec.template.spec.initContainers[0].securityContext.readOnlyRootFilesystem + value: false + - equal: + path: spec.template.spec.initContainers[0].securityContext.runAsGroup + value: 99 + - equal: + path: spec.template.spec.initContainers[0].securityContext.runAsNonRoot + value: true + - equal: + path: spec.template.spec.initContainers[0].securityContext.runAsUser + value: 99 + - matchSnapshot: + path: spec.template.spec + + + - it: should not set securityContext for initContainers when is empty object (default value) + template: proxy/deployment.yaml + values: + - ../.lint/security-context-empty.yaml + asserts: + - isNull: + path: spec.template.spec.initContainers[0].securityContext + + # we can't use the dynamic chart version or appVersion as a variable in the tests, + # so we override it manually and check that gets set instead + # this saves us having to update the test every time we cut a new release + - it: should use enterprise image when enterprise is set in values + template: proxy/deployment.yaml + set: + clusterName: helm-lint.example.com + enterprise: true + teleportVersionOverride: 12.2.1 + asserts: + - equal: + path: spec.template.spec.containers[0].image + value: public.ecr.aws/gravitational/teleport-ent-distroless:12.2.1 + + - it: should use OSS image when enterprise is not set in values + template: proxy/deployment.yaml + set: + clusterName: helm-lint + teleportVersionOverride: 12.2.1 + asserts: + - equal: + path: spec.template.spec.containers[0].image + value: public.ecr.aws/gravitational/teleport-distroless:12.2.1 + + - it: should mount TLS certs when cert-manager is enabled + template: proxy/deployment.yaml + values: + - ../.lint/gcp-ha-acme.yaml + - ../.lint/initcontainers.yaml + asserts: + - contains: + path: spec.template.spec.containers[0].volumeMounts + content: + mountPath: /etc/teleport-tls + name: "teleport-tls" + readOnly: true + - contains: + path: spec.template.spec.volumes + content: + name: teleport-tls + secret: + secretName: teleport-tls + - contains: + path: spec.template.spec.initContainers[1].volumeMounts + content: + mountPath: /etc/teleport-tls + name: "teleport-tls" + readOnly: true + - contains: + path: spec.template.spec.initContainers[2].volumeMounts + content: + mountPath: /etc/teleport-tls + name: "teleport-tls" + readOnly: true + + - it: should mount ConfigMap containing Teleport config + template: proxy/deployment.yaml + set: + clusterName: helm-lint.example.com + asserts: + - contains: + path: spec.template.spec.containers[0].volumeMounts + content: + mountPath: /etc/teleport + name: "config" + readOnly: true + - contains: + path: spec.template.spec.volumes + content: + name: config + configMap: + name: RELEASE-NAME-proxy + + - it: should mount extraVolumes and extraVolumeMounts on container and initContainers + template: proxy/deployment.yaml + values: + - ../.lint/volumes.yaml + - ../.lint/initcontainers.yaml + asserts: + - contains: + path: spec.template.spec.containers[0].volumeMounts + content: + mountPath: /path/to/mount + name: my-mount + - contains: + path: spec.template.spec.initContainers[1].volumeMounts + content: + mountPath: /path/to/mount + name: my-mount + - contains: + path: spec.template.spec.initContainers[2].volumeMounts + content: + mountPath: /path/to/mount + name: my-mount + - contains: + path: spec.template.spec.volumes + content: + name: my-mount + secret: + secretName: mySecret + + - it: should set imagePullPolicy when set in values + template: proxy/deployment.yaml + set: + clusterName: helm-lint.example.com + imagePullPolicy: Always + asserts: + - equal: + path: spec.template.spec.containers[0].imagePullPolicy + value: Always + + - it: should set environment when extraEnv set in values + template: proxy/deployment.yaml + values: + - ../.lint/extra-env.yaml + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: SOME_ENVIRONMENT_VARIABLE + value: "some-value" + + - it: should set imagePullSecrets when set in values + template: proxy/deployment.yaml + values: + - ../.lint/imagepullsecrets.yaml + asserts: + - equal: + path: spec.template.spec.imagePullSecrets[0].name + value: myRegistryKeySecretName + - matchSnapshot: + path: spec.template.spec.imagePullSecrets + + - it: should provision initContainer correctly when set in values + template: proxy/deployment.yaml + values: + - ../.lint/initcontainers.yaml + - ../.lint/resources.yaml + - ../.lint/extra-env.yaml + asserts: + - contains: + path: spec.template.spec.initContainers[1].args + content: "echo test" + - equal: + path: spec.template.spec.initContainers[1].name + value: "teleport-init" + - equal: + path: spec.template.spec.initContainers[1].image + value: "alpine" + - equal: + path: spec.template.spec.initContainers[1].resources.limits.cpu + value: 2 + - equal: + path: spec.template.spec.initContainers[1].resources.limits.memory + value: 4Gi + - equal: + path: spec.template.spec.initContainers[1].resources.requests.cpu + value: 1 + - equal: + path: spec.template.spec.initContainers[1].resources.requests.memory + value: 2Gi + - contains: + path: spec.template.spec.initContainers[2].args + content: "echo test2" + - equal: + path: spec.template.spec.initContainers[2].name + value: "teleport-init2" + - equal: + path: spec.template.spec.initContainers[2].image + value: "alpine" + - equal: + path: spec.template.spec.initContainers[2].resources.limits.cpu + value: 2 + - equal: + path: spec.template.spec.initContainers[2].resources.limits.memory + value: 4Gi + - equal: + path: spec.template.spec.initContainers[2].resources.requests.cpu + value: 1 + - equal: + path: spec.template.spec.initContainers[2].resources.requests.memory + value: 2Gi + - matchSnapshot: + path: spec.template.spec.initContainers + + - it: should add insecureSkipProxyTLSVerify to args when set in values + template: proxy/deployment.yaml + set: + clusterName: helm-lint.example.com + insecureSkipProxyTLSVerify: true + asserts: + - contains: + path: spec.template.spec.containers[0].args + content: "--insecure" + + - it: should expose diag port + template: proxy/deployment.yaml + set: + clusterName: helm-lint.example.com + asserts: + - contains: + path: spec.template.spec.containers[0].ports + content: + name: diag + containerPort: 3000 + protocol: TCP + + - it: should expose tls port + template: proxy/deployment.yaml + set: + clusterName: helm-lint.example.com + asserts: + - contains: + path: spec.template.spec.containers[0].ports + content: + name: tls + containerPort: 3080 + protocol: TCP + + - it: should expose tls port when proxyListenerMode is multiplex + template: proxy/deployment.yaml + set: + clusterName: helm-lint.example.com + proxyListenerMode: multiplex + asserts: + - contains: + path: spec.template.spec.containers[0].ports + content: + name: tls + containerPort: 3080 + protocol: TCP + + - it: should not expose proxy peering port by default + template: proxy/deployment.yaml + set: + clusterName: helm-lint.example.com + asserts: + - notContains: + path: spec.template.spec.containers[0].ports + content: + name: proxypeering + containerPort: 3021 + protocol: TCP + + - it: should expose proxy peering port when enterprise is true + template: proxy/deployment.yaml + set: + clusterName: helm-lint.example.com + enterprise: true + asserts: + - contains: + path: spec.template.spec.containers[0].ports + content: + name: proxypeering + containerPort: 3021 + protocol: TCP + + - it: should expose sshproxy port by default + template: proxy/deployment.yaml + set: + clusterName: helm-lint.example.com + asserts: + - contains: + path: spec.template.spec.containers[0].ports + content: + name: sshproxy + containerPort: 3023 + protocol: TCP + + - it: should not expose sshproxy port when proxyListenerMode is multiplex + template: proxy/deployment.yaml + set: + clusterName: helm-lint.example.com + proxyListenerMode: multiplex + asserts: + - notContains: + path: spec.template.spec.containers[0].ports + content: + name: sshproxy + containerPort: 3023 + protocol: TCP + + - it: should expose sshtun port by default + template: proxy/deployment.yaml + set: + clusterName: helm-lint.example.com + asserts: + - contains: + path: spec.template.spec.containers[0].ports + content: + name: sshtun + containerPort: 3024 + protocol: TCP + + - it: should not expose sshtun port when proxyListenerMode is multiplex + template: proxy/deployment.yaml + set: + clusterName: helm-lint.example.com + proxyListenerMode: multiplex + asserts: + - notContains: + path: spec.template.spec.containers[0].ports + content: + name: sshtun + containerPort: 3024 + protocol: TCP + + - it: should expose k8s port by default + template: proxy/deployment.yaml + set: + clusterName: helm-lint.example.com + asserts: + - contains: + path: spec.template.spec.containers[0].ports + content: + name: kube + containerPort: 3026 + protocol: TCP + + - it: should not expose k8s port when proxyListenerMode is multiplex + template: proxy/deployment.yaml + set: + clusterName: helm-lint.example.com + proxyListenerMode: multiplex + asserts: + - notContains: + path: spec.template.spec.containers[0].ports + content: + name: kube + containerPort: 3026 + protocol: TCP + + - it: should expose mysql port by default + template: proxy/deployment.yaml + set: + clusterName: helm-lint.example.com + asserts: + - contains: + path: spec.template.spec.containers[0].ports + content: + name: mysql + containerPort: 3036 + protocol: TCP + + - it: should not expose mysql port when proxyListenerMode is multiplex + template: proxy/deployment.yaml + set: + clusterName: helm-lint.example.com + proxyListenerMode: multiplex + asserts: + - notContains: + path: spec.template.spec.containers[0].ports + content: + name: mysql + containerPort: 3036 + protocol: TCP + + - it: should expose postgres port when separate postgres listener is enabled + template: proxy/deployment.yaml + set: + clusterName: helm-lint.example.com + separatePostgresListener: true + asserts: + - contains: + path: spec.template.spec.containers[0].ports + content: + name: postgres + containerPort: 5432 + protocol: TCP + + - it: should not expose postgres port when proxyListenerMode is multiplex and separate postgres listener is enabled + template: proxy/deployment.yaml + set: + clusterName: helm-lint.example.com + proxyListenerMode: multiplex + separatePostgresListener: true + asserts: + - notContains: + path: spec.template.spec.containers[0].ports + content: + name: postgres + containerPort: 5432 + protocol: TCP + + - it: should expose mongo port when separate mongo listener is enabled + template: proxy/deployment.yaml + set: + clusterName: helm-lint.example.com + separateMongoListener: true + asserts: + - contains: + path: spec.template.spec.containers[0].ports + content: + name: mongo + containerPort: 27017 + protocol: TCP + + - it: should not expose mongo port when when proxyListenerMode is multiplex and separate mongo listener is enabled + template: proxy/deployment.yaml + set: + clusterName: helm-lint.example.com + proxyListenerMode: multiplex + separateMongoListener: true + asserts: + - notContains: + path: spec.template.spec.containers[0].ports + content: + name: mongo + containerPort: 27017 + protocol: TCP + + - it: should set postStart command if set in values + template: proxy/deployment.yaml + set: + clusterName: helm-lint.example.com + postStart: + command: ["/bin/echo", "test"] + asserts: + - equal: + path: spec.template.spec.containers[0].lifecycle.postStart.exec.command + value: ["/bin/echo", "test"] + + - it: should add and mount emptyDir for data + template: proxy/deployment.yaml + set: + clusterName: helm-lint.example.com + asserts: + - contains: + path: spec.template.spec.containers[0].volumeMounts + content: + mountPath: /var/lib/teleport + name: data + - contains: + path: spec.template.spec.volumes + content: + name: data + emptyDir: {} + + - it: should set priorityClassName when set in values + template: proxy/deployment.yaml + values: + - ../.lint/priority-class-name.yaml + asserts: + - equal: + path: spec.template.spec.priorityClassName + value: system-cluster-critical + + - it: should set probeTimeoutSeconds when set in values + template: proxy/deployment.yaml + values: + - ../.lint/probe-timeout-seconds.yaml + asserts: + - equal: + path: spec.template.spec.containers[0].livenessProbe.timeoutSeconds + value: 5 + - equal: + path: spec.template.spec.containers[0].readinessProbe.timeoutSeconds + value: 5 + + - it: should not mount TLS secrets when when highAvailability.certManager.enabled is false and tls.existingSecretName is not set + template: proxy/deployment.yaml + set: + clusterName: helm-lint-test-cluster + asserts: + - notContains: + path: spec.template.spec.volumes + content: + name: teleport-tls + secret: + secretName: teleport-tls + - notContains: + path: spec.template.spec.containers[0].volumeMounts + content: + mountPath: /etc/teleport-tls + name: teleport-tls + readOnly: true + + - it: should mount cert-manager TLS secret when highAvailability.certManager.enabled is true + template: proxy/deployment.yaml + values: + - ../.lint/cert-manager.yaml + asserts: + - contains: + path: spec.template.spec.volumes + content: + name: teleport-tls + secret: + secretName: teleport-tls + - contains: + path: spec.template.spec.containers[0].volumeMounts + content: + mountPath: /etc/teleport-tls + name: teleport-tls + readOnly: true + + - it: should mount tls.existingSecretName when set in values + template: proxy/deployment.yaml + values: + - ../.lint/existing-tls-secret.yaml + asserts: + - contains: + path: spec.template.spec.volumes + content: + name: teleport-tls + secret: + secretName: helm-lint-existing-tls-secret + - contains: + path: spec.template.spec.containers[0].volumeMounts + content: + mountPath: /etc/teleport-tls + name: teleport-tls + readOnly: true + + - it: should mount tls.existingCASecretName and set environment when set in values + template: proxy/deployment.yaml + values: + - ../.lint/existing-tls-secret-with-ca.yaml + asserts: + - contains: + path: spec.template.spec.volumes + content: + name: teleport-tls-ca + secret: + secretName: helm-lint-existing-tls-secret-ca + - contains: + path: spec.template.spec.containers[0].volumeMounts + content: + mountPath: /etc/teleport-tls-ca + name: teleport-tls-ca + readOnly: true + - contains: + path: spec.template.spec.containers[0].env + content: + name: SSL_CERT_FILE + value: /etc/teleport-tls-ca/ca.pem + + - it: should mount tls.existingCASecretName and set extra environment when set in values + template: proxy/deployment.yaml + values: + - ../.lint/existing-tls-secret-with-ca.yaml + - ../.lint/extra-env.yaml + asserts: + - contains: + path: spec.template.spec.volumes + content: + name: teleport-tls-ca + secret: + secretName: helm-lint-existing-tls-secret-ca + - contains: + path: spec.template.spec.containers[0].volumeMounts + content: + mountPath: /etc/teleport-tls-ca + name: teleport-tls-ca + readOnly: true + - contains: + path: spec.template.spec.containers[0].env + content: + name: SSL_CERT_FILE + value: /etc/teleport-tls-ca/ca.pem + - contains: + path: spec.template.spec.containers[0].env + content: + name: SOME_ENVIRONMENT_VARIABLE + value: some-value + + - it: should set minReadySeconds when replicaCount > 1 + template: proxy/deployment.yaml + set: + clusterName: helm-lint + highAvailability: + certManager: + enabled: true + replicaCount: 3 + minReadySeconds: 60 + asserts: + - equal: + path: spec.minReadySeconds + value: 60 + + - it: should not set minReadySeconds when replicaCount = 1 + template: proxy/deployment.yaml + set: + chartMode: scratch + highAvailability: + minReadySeconds: 60 + replicaCount: 1 + asserts: + - equal: + path: spec.minReadySeconds + value: null + + - it: should set nodeSelector when set in values + template: proxy/deployment.yaml + set: + chartMode: scratch + clusterName: helm-lint.example.com + nodeSelector: + role: bastion + environment: security + asserts: + - isNotNull: + path: spec.template.spec.nodeSelector + - matchSnapshot: + path: spec.template.spec + + - it: mounts regular tokens on older Kubernetes versions + template: proxy/deployment.yaml + set: + clusterName: helm-lint + capabilities: + majorVersion: 1 + minorVersion: 18 + asserts: + - notEqual: + path: spec.template.spec.automountServiceAccountToken + value: false + - notContains: + path: spec.template.spec.volumes + content: + name: proxy-serviceaccount-token + projected: + sources: + - serviceAccountToken: + path: token + - configMap: + items: + - key: ca.crt + path: ca.crt + name: kube-root-ca.crt + - downwardAPI: + items: + - path: "namespace" + fieldRef: + fieldPath: metadata.namespace + - notContains: + path: spec.template.spec.containers[0].volumeMounts + content: + mountPath: /var/run/secrets/kubernetes.io/serviceaccount + name: proxy-serviceaccount-token + readOnly: true + + - it: mounts tokens through projected volumes on newer Kubernetes versions + template: proxy/deployment.yaml + set: + clusterName: helm-lint + capabilities: + majorVersion: 1 + minorVersion: 21 + asserts: + - equal: + path: spec.template.spec.automountServiceAccountToken + value: false + - contains: + path: spec.template.spec.volumes + content: + name: proxy-serviceaccount-token + projected: + sources: + - serviceAccountToken: + path: token + - configMap: + items: + - key: ca.crt + path: ca.crt + name: kube-root-ca.crt + - downwardAPI: + items: + - path: "namespace" + fieldRef: + fieldPath: metadata.namespace + - contains: + path: spec.template.spec.containers[0].volumeMounts + content: + mountPath: /var/run/secrets/kubernetes.io/serviceaccount + name: proxy-serviceaccount-token + readOnly: true diff --git a/helm/teleport-cluster/tests/proxy_pdb_test.yaml b/helm/teleport-cluster/tests/proxy_pdb_test.yaml new file mode 100644 index 0000000..851a0a7 --- /dev/null +++ b/helm/teleport-cluster/tests/proxy_pdb_test.yaml @@ -0,0 +1,23 @@ +suite: Proxy PodDisruptionBudget +templates: + - proxy/pdb.yaml +tests: + - it: not should create a PDB when disabled in values + set: + highAvailability: + podDisruptionBudget: + enabled: false + asserts: + - hasDocuments: + count: 0 + - it: should create a PDB when enabled in values (pdb.yaml) + values: + - ../.lint/pdb.yaml + asserts: + - hasDocuments: + count: 1 + - isKind: + of: PodDisruptionBudget + - equal: + path: spec.minAvailable + value: 2 diff --git a/helm/teleport-cluster/tests/proxy_service_test.yaml b/helm/teleport-cluster/tests/proxy_service_test.yaml new file mode 100644 index 0000000..29ed547 --- /dev/null +++ b/helm/teleport-cluster/tests/proxy_service_test.yaml @@ -0,0 +1,381 @@ +suite: Proxy Service +templates: + - proxy/service.yaml +tests: + - it: uses a LoadBalancer by default + set: + clusterName: teleport.example.com + asserts: + - hasDocuments: + count: 1 + - isKind: + of: Service + - equal: + path: spec.type + value: LoadBalancer + + - it: uses a ClusterIP when service.type=ClusterIP + set: + clusterName: teleport.example.com + service: + type: ClusterIP + asserts: + - hasDocuments: + count: 1 + - isKind: + of: Service + - equal: + path: spec.type + value: ClusterIP + + - it: uses a ClusterIP when proxy.service.type=ClusterIP + set: + clusterName: teleport.example.com + service: + type: NodePort + proxy: + service: + type: ClusterIP + asserts: + - hasDocuments: + count: 1 + - isKind: + of: Service + - equal: + path: spec.type + value: ClusterIP + + - it: fails to deploy when ingress.enabled=true and proxy.service.type is set to LoadBalancer (default) + set: + clusterName: teleport.example.com + ingress: + enabled: true + asserts: + - failedTemplate: + errorMessage: "proxy.service.type must not be LoadBalancer when using an ingress - any load balancer should be provisioned by your ingress controller. Set proxy.service.type=ClusterIP instead" + + - it: uses a ClusterIP when ingress.enabled=true and service.type=ClusterIP + set: + clusterName: teleport.example.com + ingress: + enabled: true + service: + type: ClusterIP + asserts: + - hasDocuments: + count: 1 + - isKind: + of: Service + - equal: + path: spec.type + value: ClusterIP + + - it: uses a ClusterIP when ingress.enabled=true and proxy.service.type=ClusterIP + set: + clusterName: teleport.example.com + ingress: + enabled: true + proxy: + service: + type: ClusterIP + asserts: + - hasDocuments: + count: 1 + - isKind: + of: Service + - equal: + path: spec.type + value: ClusterIP + + - it: uses a NodePort when ingress.enabled=true and proxy.service.type=NodePort + set: + clusterName: teleport.example.com + ingress: + enabled: true + proxy: + service: + type: NodePort + asserts: + - hasDocuments: + count: 1 + - isKind: + of: Service + - equal: + path: spec.type + value: NodePort + + - it: uses a NodePort when ingress.enabled=true and service.type=NodePort + set: + clusterName: teleport.example.com + ingress: + enabled: true + service: + type: NodePort + asserts: + - hasDocuments: + count: 1 + - isKind: + of: Service + - equal: + path: spec.type + value: NodePort + + - it: uses a NodePort when ingress.enabled=true and proxy.service.type is overridden + set: + clusterName: teleport.example.com + ingress: + enabled: true + proxy: + service: + type: NodePort + asserts: + - hasDocuments: + count: 1 + - isKind: + of: Service + - equal: + path: spec.type + value: NodePort + + - it: sets AWS annotations when chartMode=aws + set: + clusterName: teleport.example.com + chartMode: aws + asserts: + - hasDocuments: + count: 1 + - isKind: + of: Service + - equal: + path: spec.type + value: LoadBalancer + - equal: + path: metadata.annotations.service\.beta\.kubernetes\.io/aws-load-balancer-type + value: nlb + - equal: + path: metadata.annotations.service\.beta\.kubernetes\.io/aws-load-balancer-backend-protocol + value: tcp + - equal: + path: metadata.annotations.service\.beta\.kubernetes\.io/aws-load-balancer-cross-zone-load-balancing-enabled + value: "true" + + - it: sets service annotations when specified + values: + - ../.lint/annotations.yaml + asserts: + - equal: + path: metadata.annotations.kubernetes\.io/service + value: test-annotation + - equal: + path: metadata.annotations.kubernetes\.io/service-different + value: 5 + + - it: adds a separate Postgres listener port when separatePostgresListener is true + values: + - ../.lint/separate-postgres-listener.yaml + asserts: + - contains: + path: spec.ports + content: + name: postgres + port: 5432 + targetPort: 5432 + protocol: TCP + + - it: does not add a separate Postgres listener port when separatePostgresListener is true and ingress.enabled=true + values: + - ../.lint/separate-postgres-listener.yaml + set: + ingress: + enabled: true + proxyListenerMode: multiplex + service: + type: ClusterIP + asserts: + - notContains: + path: spec.ports + content: + name: postgres + port: 5432 + targetPort: 5432 + protocol: TCP + + - it: adds a separate Mongo listener port when separateMongoListener is true + values: + - ../.lint/separate-mongo-listener.yaml + asserts: + - contains: + path: spec.ports + content: + name: mongo + port: 27017 + targetPort: 27017 + protocol: TCP + + - it: does not add a separate Mongo listener port when separateMongoListener is true and ingress.enabled=true + values: + - ../.lint/separate-mongo-listener.yaml + set: + ingress: + enabled: true + proxyListenerMode: multiplex + service: + type: ClusterIP + asserts: + - notContains: + path: spec.ports + content: + name: mongo + port: 27017 + targetPort: 27017 + protocol: TCP + + - it: sets AWS backend protocol annotation to ssl when in AWS mode and ACM annotation is set + values: + - ../.lint/aws-ha.yaml + set: + annotations: + service: + service.beta.kubernetes.io/aws-load-balancer-ssl-cert: arn:aws:acm:us-east-1:1234567890:certificate/a857a76c-51d0-4d3d-8000-465bb3e9829b + service.beta.kubernetes.io/aws-load-balancer-ssl-ports: 443 + asserts: + - equal: + path: metadata.annotations.service\.beta\.kubernetes\.io/aws-load-balancer-backend-protocol + value: ssl + + - it: does not add AWS backend protocol annotation when in AWS mode, ACM annotation is set and ingress is enabled + values: + - ../.lint/aws-ha.yaml + set: + ingress: + enabled: true + service: + type: ClusterIP + annotations: + service: + service.beta.kubernetes.io/aws-load-balancer-ssl-cert: arn:aws:acm:us-east-1:1234567890:certificate/a857a76c-51d0-4d3d-8000-465bb3e9829b + service.beta.kubernetes.io/aws-load-balancer-ssl-ports: 443 + asserts: + - isNull: + path: metadata.annotations.service\.beta\.kubernetes\.io/aws-load-balancer-backend-protocol + + - it: sets AWS backend protocol annotation to tcp when in AWS mode and ACM annotation is not set + values: + - ../.lint/aws-ha.yaml + asserts: + - equal: + path: metadata.annotations.service\.beta\.kubernetes\.io/aws-load-balancer-backend-protocol + value: tcp + + - it: does not set AWS backend protocol annotation when in AWS mode, ACM annotation is not set and ingress is enabled + values: + - ../.lint/aws-ha.yaml + set: + ingress: + enabled: true + service: + type: ClusterIP + annotations: + service: + # required so at least one service annotation exists, to avoid non map type error + service.beta.kubernetes.io/random-annotation: helm-lint + asserts: + - isNull: + path: metadata.annotations.service\.beta\.kubernetes\.io/aws-load-balancer-backend-protocol + + - it: exposes separate listener ports by default + values: + - ../.lint/example-minimal-standalone.yaml + asserts: + - matchSnapshot: + path: spec.ports + + - it: does not expose separate listener ports by default when ingress.enabled=true + values: + - ../.lint/example-minimal-standalone.yaml + set: + ingress: + enabled: true + proxyListenerMode: multiplex + service: + type: ClusterIP + asserts: + - notContains: + path: spec.ports + content: + - name: sshproxy + port: 3023 + targetPort: 3023 + protocol: TCP + - name: k8s + port: 3026 + targetPort: 3026 + protocol: TCP + - name: sshtun + port: 3024 + targetPort: 3024 + protocol: TCP + - name: mysql + port: 3036 + targetPort: 3036 + protocol: TCP + - matchSnapshot: + path: spec.ports + + - it: exposes separate listener ports when running in separate mode + values: + - ../.lint/proxy-listener-mode-separate.yaml + asserts: + - matchSnapshot: + path: spec.ports + + - it: does not expose separate listener ports when running in separate mode and ingress.enabled=true + values: + - ../.lint/proxy-listener-mode-separate.yaml + set: + ingress: + enabled: true + proxyListenerMode: multiplex + service: + type: ClusterIP + asserts: + - notContains: + path: spec.ports + content: + - name: sshproxy + port: 3023 + targetPort: 3023 + protocol: TCP + - name: k8s + port: 3026 + targetPort: 3026 + protocol: TCP + - name: sshtun + port: 3024 + targetPort: 3024 + protocol: TCP + - name: mysql + port: 3036 + targetPort: 3036 + protocol: TCP + - matchSnapshot: + path: spec.ports + + - it: exposes a single port when running in multiplex mode + values: + - ../.lint/proxy-listener-mode-multiplex.yaml + asserts: + - matchSnapshot: + path: spec.ports + + - it: exposes a single port when running in multiplex mode and ingress.enabled=true + values: + - ../.lint/proxy-listener-mode-multiplex.yaml + set: + ingress: + enabled: true + service: + type: ClusterIP + asserts: + - matchSnapshot: + path: spec.ports diff --git a/helm/teleport-cluster/tests/proxy_serviceaccount_test.yaml b/helm/teleport-cluster/tests/proxy_serviceaccount_test.yaml new file mode 100644 index 0000000..14ec87f --- /dev/null +++ b/helm/teleport-cluster/tests/proxy_serviceaccount_test.yaml @@ -0,0 +1,22 @@ +suite: Proxy ServiceAccount +templates: + - proxy/serviceaccount.yaml +tests: + - it: sets ServiceAccount annotations when specified + values: + - ../.lint/annotations.yaml + asserts: + - equal: + path: metadata.annotations.kubernetes\.io/serviceaccount + value: test-annotation + - equal: + path: metadata.annotations.kubernetes\.io/serviceaccount-different + value: 6 + + - it: changes ServiceAccount name when specified and appends "-proxy" + values: + - ../.lint/service-account.yaml + asserts: + - equal: + path: metadata.name + value: "helm-lint-proxy" diff --git a/helm/teleport-cluster/tests/psp_test.yaml b/helm/teleport-cluster/tests/psp_test.yaml new file mode 100644 index 0000000..fa3b66e --- /dev/null +++ b/helm/teleport-cluster/tests/psp_test.yaml @@ -0,0 +1,35 @@ +suite: PodSecurityPolicy +templates: + - psp.yaml +tests: + - it: creates a PodSecurityPolicy when enabled in values and supported + capabilities: + majorVersion: 1 + minorVersion: 22 + set: + podSecurityPolicy: + enabled: true + asserts: + - hasDocuments: + count: 3 + - documentIndex: 0 + isKind: + of: PodSecurityPolicy + - documentIndex: 1 + isKind: + of: Role + - documentIndex: 2 + isKind: + of: RoleBinding + - matchSnapshot: {} + + - it: does not create a PodSecurityPolicy when enabled in values but not supported + set: + podSecurityPolicy: + enabled: true + capabilities: + majorVersion: 1 + minorVersion: 25 + asserts: + - hasDocuments: + count: 0 diff --git a/helm/teleport-cluster/values.schema.json b/helm/teleport-cluster/values.schema.json new file mode 100644 index 0000000..3169457 --- /dev/null +++ b/helm/teleport-cluster/values.schema.json @@ -0,0 +1,923 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema", + "type": "object", + "required": [ + "clusterName", + "authentication", + "enterprise", + "operator", + "podSecurityPolicy", + "labels", + "chartMode", + "validateConfigOnDeploy", + "highAvailability", + "podMonitor", + "tls", + "image", + "enterpriseImage", + "log", + "affinity", + "nodeSelector", + "annotations", + "extraVolumes", + "extraVolumeMounts", + "imagePullPolicy", + "initContainers", + "resources", + "tolerations", + "probeTimeoutSeconds" + ], + "properties": { + "clusterName": { + "$id": "#/properties/clusterName", + "type": "string", + "default": "" + }, + "auth": { + "$id": "#/properties/auth", + "type": "object" + }, + "proxy": { + "$id": "#/properties/proxy", + "type": "object" + }, + "createProxyToken": { + "$id": "#/properties/createProxyToken", + "type": "boolean", + "default": true + }, + "podMonitor": { + "$id": "#/properties/podMonitor", + "type": "object", + "required": ["enabled"], + "properties": { + "enabled": { + "$id": "#/properties/podMonitor/enabled", + "type": "boolean", + "default": false + }, + "additionalLabels": { + "$id": "#/properties/podMonitor/additionalLabels", + "type": "object", + "default": {"prometheus": "default"}, + "additionalProperties": {"type": "string"} + }, + "interval": { + "$id": "#/properties/podMonitor/interval", + "type": "string", + "default": "30s" + } + } + }, + "authentication": { + "$id": "#/properties/authentication", + "type": "object", + "required": ["type", "localAuth"], + "properties": { + "type": { + "$id": "#/properties/authentication/properties/type", + "type": "string", + "default": "local" + }, + "connectorName": { + "$id": "#/properties/authentication/properties/connectorName", + "type": "string", + "default": "" + }, + "localAuth": { + "$id": "#/properties/authentication/properties/localAuth", + "type": "boolean", + "default": true + }, + "lockingMode": { + "$id": "#/properties/authentication/properties/lockingMode", + "type": "string", + "default": "" + }, + "secondFactor": { + "$id": "#/properties/authentication/properties/secondFactor", + "type": "string", + "enum": ["off", "on", "otp", "optional", "webauthn"], + "default": "otp" + }, + "webauthn": { + "$id": "#/properties/authentication/properties/webauthn", + "type": "object", + "required": [], + "properties": { + "attestationAllowedCas": { + "$id": "#/properties/authentication/properties/webauthn/properties/attestationAllowedCas", + "type": "array", + "default": [] + }, + "attestationDeniedCas": { + "$id": "#/properties/authentication/properties/webauthn/properties/attestationDeniedCas", + "type": "array", + "default": [] + } + } + } + } + }, + "authenticationType": { + "$id": "#/properties/authenticationType", + "type": "string" + }, + "authenticationSecondFactor": { + "$id": "#/properties/authenticationSecondFactor", + "type": "object", + "required": [], + "properties": { + "secondFactor": { + "$id": "#/properties/authenticationSecondFactor/properties/secondFactor", + "type": "string", + "enum": ["off", "on", "otp", "optional", "webauthn"], + "default": "otp" + }, + "webauthn": { + "$id": "#/properties/authenticationSecondFactor/properties/webauthn", + "type": "object", + "required": [], + "properties": { + "attestationAllowedCas": { + "$id": "#/properties/authenticationSecondFactor/properties/webauthn/properties/attestationAllowedCas", + "type": "array", + "default": [] + }, + "attestationDeniedCas": { + "$id": "#/properties/authenticationSecondFactor/properties/webauthn/properties/attestationDeniedCas", + "type": "array", + "default": [] + } + } + } + } + }, + "proxyListenerMode": { + "$id": "#/properties/proxyListenerMode", + "type": "string", + "default": "" + }, + "sessionRecording": { + "$id": "#/properties/sessionRecording", + "type": "string", + "default": "" + }, + "separatePostgresListener": { + "$id": "#/properties/separatePostgresListener", + "type": "boolean", + "default": false + }, + "separateMongoListener": { + "$id": "#/properties/separateMongoListener", + "type": "boolean", + "default": false + }, + "publicAddr": { + "$id": "#/properties/publicAddr", + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "kubePublicAddr": { + "$id": "#/properties/kubePublicAddr", + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "mongoPublicAddr": { + "$id": "#/properties/mongoPublicAddr", + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "mysqlPublicAddr": { + "$id": "#/properties/mysqlPublicAddr", + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "postgresPublicAddr": { + "$id": "#/properties/postgresPublicAddr", + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "sshPublicAddr": { + "$id": "#/properties/sshPublicAddr", + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "tunnelPublicAddr": { + "$id": "#/properties/tunnelPublicAddr", + "type": "array", + "items": { + "type": "string" + }, + "default": [] + }, + "teleportVersionOverride": { + "$id": "#/properties/teleportVersionOverride", + "type": "string", + "default": "" + }, + "acme": { + "$id": "#/properties/acme", + "type": "boolean", + "default": false + }, + "acmeEmail": { + "$id": "#/properties/acmeEmail", + "type": "string", + "default": "" + }, + "acmeURI": { + "$id": "#/properties/acmeURI", + "type": "string", + "default": "" + }, + "enterprise": { + "$id": "#/properties/enterprise", + "type": "boolean", + "default": false + }, + "installCRDs": { + "$id": "#/properties/installCRDs", + "type": "boolean" + }, + "operator": { + "$id": "#/properties/operator", + "type": "object", + "required": ["enabled"], + "properties": { + "enabled": { + "$id": "#/properties/operator/properties/enabled", + "type": "boolean", + "default": false + }, + "image": { + "$id": "#/properties/operator/properties/image", + "type": "string", + "default": "public.ecr.aws/gravitational/teleport-operator" + }, + "resources": { + "$id": "#/properties/operator/properties/resources", + "type": "object", + "default": {} + } + } + }, + "podSecurityPolicy": { + "$id": "#/properties/podSecurityPolicy", + "type": "object", + "required": [ + "enabled" + ], + "properties": { + "enabled": { + "$id": "#/properties/podSecurityPolicy/properties/enabled", + "type": "boolean", + "default": true + } + } + }, + "labels": { + "$id": "#/properties/labels", + "type": "object", + "default": {} + }, + "chartMode": { + "$id": "#/properties/chartMode", + "type": "string", + "enum": [ + "standalone", + "aws", + "azure", + "gcp", + "scratch" + ], + "default": "standalone" + }, + "validateConfigOnDeploy": { + "$id": "#/properties/validateConfigOnDeploy", + "type": "boolean", + "default": true + }, + "standalone": { + "$id": "#/properties/standalone", + "type": "object", + "required": [ + "volumeSize" + ], + "properties": { + "existingClaimName": { + "$id": "#/properties/standalone/properties/existingClaimName", + "type": "string", + "default": "" + }, + "volumeSize": { + "$id": "#/properties/standalone/properties/volumeSize", + "type": "string", + "default": "" + } + } + }, + "persistence": { + "$id": "#/properties/persistence", + "type": "object", + "required": [ + "enabled", + "volumeSize" + ], + "properties": { + "enabled": { + "$id": "#/properties/persistence/properties/enabled", + "type": "boolean", + "default": "true" + }, + "existingClaimName": { + "$id": "#/properties/persistence/properties/existingClaimName", + "type": "string", + "default": "" + }, + "storageClassName": { + "$id": "#/properties/persistence/properties/storageClassName", + "type": "string", + "default": "" + }, + "volumeSize": { + "$id": "#/properties/persistence/properties/volumeSize", + "type": "string", + "default": "" + } + } + }, + "aws": { + "$id": "#/properties/aws", + "type": "object", + "properties": { + "region": { + "$id": "#/properties/aws/properties/region", + "type": "string", + "default": "" + }, + "backendTable": { + "$id": "#/properties/aws/properties/backendTable", + "type": "string", + "default": "" + }, + "auditLogTable": { + "$id": "#/properties/aws/properties/auditLogTable", + "type": "string", + "default": "" + }, + "auditLogMirrorOnStdout": { + "$id": "#/properties/aws/properties/auditLogMirrorOnStdout", + "type": "boolean", + "default": "false" + }, + "sessionRecordingBucket": { + "$id": "#/properties/aws/properties/sessionRecordingBucket", + "type": "string", + "default": "" + }, + "backups": { + "$id": "#/properties/aws/properties/backups", + "type": "boolean", + "default": false + }, + "dynamoAutoScaling": { + "$id": "#/properties/aws/properties/dynamoAutoScaling", + "type": "boolean", + "default": false + } + }, + "if": { + "properties": { + "dynamoAutoScaling": { + "const": true + } + } + }, + "then": { + "properties": { + "readMinCapacity": { + "$id": "#/properties/aws/properties/readMinCapacity", + "type": "integer" + }, + "readMaxCapacity": { + "$id": "#/properties/aws/properties/readMaxCapacity", + "type": "integer" + }, + "readTargetValue": { + "$id": "#/properties/aws/properties/readTargetValue", + "type": "number" + }, + "writeMinCapacity": { + "$id": "#/properties/aws/properties/writeMinCapacity", + "type": "integer" + }, + "writeMaxCapacity": { + "$id": "#/properties/aws/properties/writeMaxCapacity", + "type": "integer" + }, + "writeTargetValue": { + "$id": "#/properties/aws/properties/writeTargetValue", + "type": "number" + } + } + }, + "else": { + "properties": { + "readMinCapacity": { + "$id": "#/properties/aws/properties/readMinCapacity", + "type": "null" + }, + "readMaxCapacity": { + "$id": "#/properties/aws/properties/readMaxCapacity", + "type": "null" + }, + "readTargetValue": { + "$id": "#/properties/aws/properties/readTargetValue", + "type": "null" + }, + "writeMinCapacity": { + "$id": "#/properties/aws/properties/writeMinCapacity", + "type": "null" + }, + "writeMaxCapacity": { + "$id": "#/properties/aws/properties/writeMaxCapacity", + "type": "null" + }, + "writeTargetValue": { + "$id": "#/properties/aws/properties/writeTargetValue", + "type": "null" + } + } + } + }, + "azure": { + "$id": "#/properties/azure", + "type": "object", + "properties": { + "databaseHost": { + "$id": "#/properties/azure/properties/databaseHost", + "type": "string", + "default": "" + }, + "databaseUser": { + "$id": "#/properties/azure/properties/databaseUser", + "type": "string", + "default": "" + }, + "backendDatabase": { + "$id": "#/properties/azure/properties/backendDatabase", + "type": "string", + "default": "teleport_backend" + }, + "auditLogDatabase": { + "$id": "#/properties/azure/properties/auditLogDatabase", + "type": "string", + "default": "teleport_audit" + }, + "auditLogMirrorOnStdout": { + "$id": "#/properties/azure/properties/auditLogMirrorOnStdout", + "type": "boolean", + "default": false + }, + "sessionRecordingStorageAccount": { + "$id": "#/properties/azure/properties/sessionRecordingStorageAccount", + "type": "string", + "default": "" + }, + "clientID": { + "$id": "#/properties/azure/properties/clientID", + "type": "string", + "default": "" + }, + "databasePoolMaxConnections": { + "$id": "#/properties/azure/properties/databasePoolMaxConnections", + "type": "integer", + "default": 0 + } + } + }, + "gcp": { + "$id": "#/properties/gcp", + "type": "object", + "properties": { + "projectId": { + "$id": "#/properties/gcp/properties/projectId", + "type": "string", + "default": "" + }, + "backendTable": { + "$id": "#/properties/gcp/properties/backendTable", + "type": "string", + "default": "" + }, + "auditLogTable": { + "$id": "#/properties/gcp/properties/auditLogTable", + "type": "string", + "default": "" + }, + "auditLogMirrorOnStdout": { + "$id": "#/properties/aws/properties/auditLogMirrorOnStdout", + "type": "boolean", + "default": "false" + }, + "sessionRecordingBucket": { + "$id": "#/properties/gcp/properties/sessionRecordingBucket", + "type": "string", + "default": "" + }, + "credentialSecretName": { + "$id": "#/properties/gcp/properties/credentialSecretName", + "type": "string", + "default": "teleport-gcp-credentials" + } + } + }, + "highAvailability": { + "$id": "#/properties/highAvailability", + "type": "object", + "required": [ + "replicaCount", + "requireAntiAffinity", + "certManager", + "minReadySeconds", + "podDisruptionBudget" + ], + "properties": { + "replicaCount": { + "$id": "#/properties/highAvailability/properties/replicaCount", + "type": "integer", + "default": 1 + }, + "requireAntiAffinity": { + "$id": "#/properties/highAvailability/properties/requireAntiAffinity", + "type": "boolean", + "default": false + }, + "certManager": { + "$id": "#/properties/highAvailability/properties/certManager", + "type": "object", + "required": [ + "enabled", + "issuerName", + "issuerKind", + "issuerGroup" + ], + "properties": { + "addCommonName": { + "$id": "#/properties/highAvailability/properties/certManager/properties/addCommonName", + "type": "boolean", + "default": "false" + }, + "enabled": { + "$id": "#/properties/highAvailability/properties/certManager/properties/enabled", + "type": "boolean", + "default": "false" + }, + "issuerName": { + "$id": "#/properties/highAvailability/properties/certManager/properties/issuerName", + "type": "string", + "default": "" + }, + "issuerKind": { + "$id": "#/properties/highAvailability/properties/certManager/properties/issuerKind", + "type": "string", + "default": "Issuer" + }, + "issuerGroup": { + "$id": "#/properties/highAvailability/properties/certManager/properties/issuerGroup", + "type": "string", + "default": "cert-manager.io" + } + } + }, + "minReadySeconds": { + "$id": "#/properties/highAvailability/properties/minReadySeconds", + "type": "integer", + "default": 15 + }, + "podDisruptionBudget": { + "$id": "#/properties/highAvailability/properties/podDisruptionBudget", + "type": "object", + "required": [ + "enabled", + "minAvailable" + ], + "properties": { + "enabled": { + "$id": "#/properties/highAvailability/properties/podDisruptionBudget/properties/enabled", + "type": "boolean", + "default": false + }, + "minAvailable": { + "$id": "#/properties/highAvailability/properties/podDisruptionBudget/properties/minAvailable", + "type": "integer", + "default": 1 + } + } + } + } + }, + "tls": { + "$id": "#/properties/tls", + "type": "object", + "required": [ + "existingSecretName", + "existingCASecretName" + ], + "properties": { + "existingSecretName": { + "$id": "#/properties/tls/properties/existingSecretName", + "type": "string", + "default": "" + }, + "existingCASecretName": { + "$id": "#/properties/tls/properties/existingCASecretName", + "type": "string", + "default": "" + } + } + }, + "image": { + "$id": "#/properties/image", + "type": "string", + "default": "public.ecr.aws/gravitational/teleport-distroless" + }, + "enterpriseImage": { + "$id": "#/properties/enterpriseImage", + "type": "string", + "default": "public.ecr.aws/gravitational/teleport-ent-distroless" + }, + "imagePullSecrets": { + "$id": "#/properties/imagePullSecrets", + "type": "array", + "default": [] + }, + "logLevel": { + "$id": "#/properties/logLevel", + "type": "string", + "enum": [ + "DEBUG", + "INFO", + "WARN", + "WARNING", + "ERROR" + ], + "default": "INFO" + }, + "log": { + "$id": "#/properties/log", + "type": "object", + "required": [ + "output", + "format", + "extraFields" + ], + "properties": { + "level": { + "$id": "#/properties/log/properties/level", + "type": "string", + "enum": ["DEBUG", "INFO", "WARN", "WARNING", "ERROR"], + "default": "INFO" + }, + "deployment": { + "$id": "#/properties/log/properties/output", + "type": "string", + "default": {} + }, + "pod": { + "$id": "#/properties/log/properties/format", + "type": "string", + "default": {} + }, + "service": { + "$id": "#/properties/log/properties/extraFields", + "type": "array", + "default": {} + } + } + }, + "affinity": { + "$id": "#/properties/affinity", + "type": "object", + "default": {} + }, + "nodeSelector": { + "$id": "#/properties/nodeSelector", + "type": "object", + "default": {} + }, + "annotations": { + "$id": "#/properties/annotations", + "type": "object", + "required": [ + "config", + "deployment", + "pod", + "service", + "serviceAccount", + "certSecret", + "ingress" + ], + "properties": { + "config": { + "$id": "#/properties/annotations/properties/config", + "type": "object", + "default": {} + }, + "deployment": { + "$id": "#/properties/annotations/properties/deployment", + "type": "object", + "default": {} + }, + "pod": { + "$id": "#/properties/annotations/properties/pod", + "type": "object", + "default": {} + }, + "service": { + "$id": "#/properties/annotations/properties/service", + "type": "object", + "default": {} + }, + "serviceAccount": { + "$id": "#/properties/annotations/properties/serviceAccount", + "type": "object", + "default": {} + }, + "certSecret": { + "$id": "#/properties/annotations/properties/certSecret", + "type": "object", + "default": {} + } + } + }, + "service": { + "$id": "#/properties/service", + "type": "object", + "required": [ + "type" + ], + "properties": { + "type": { + "$id": "#properties/service/type", + "type": "string", + "default": "LoadBalancer" + }, + "spec": { + "$id": "#/properties/service/spec", + "type": "object", + "default": {} + } + } + }, + "ingress": { + "enabled": { + "$id": "#/properties/ingress/enabled", + "type": "boolean", + "default": false + }, + "suppressAutomaticWildcards": { + "$id": "#/properties/ingress/suppressAutomaticWildcards", + "type": "boolean", + "default": false + }, + "spec": { + "$id": "#/properties/ingress/spec", + "type": "object", + "default": {} + } + }, + "serviceAccount": { + "$id": "#/properties/serviceAccount", + "type": "object", + "required": [], + "properties": { + "name": { + "$id": "#properties/service/name", + "type": "string", + "default": "" + }, + "create": { + "$id": "#properties/service/create", + "type": "boolean", + "default": true + } + } + }, + "rbac": { + "$id": "#/properties/rbac", + "type": "object", + "required": [], + "properties": { + "create": { + "$id": "#properties/rbac/create", + "type": "boolean", + "default": true + } + } + }, + "extraArgs": { + "$id": "#/properties/extraArgs", + "type": "array", + "default": [] + }, + "extraEnv": { + "$id": "#/properties/extraEnv", + "type": "array", + "default": [] + }, + "extraVolumes": { + "$id": "#/properties/extraVolumes", + "type": "array", + "default": [] + }, + "extraVolumeMounts": { + "$id": "#/properties/extraVolumeMounts", + "type": "array", + "default": [] + }, + "imagePullPolicy": { + "$id": "#/properties/imagePullPolicy", + "type": "string", + "enum": [ + "Never", + "IfNotPresent", + "Always" + ], + "default": "IfNotPresent" + }, + "initContainers": { + "$id": "#/properties/initContainers", + "type": "array", + "default": [] + }, + "postStart": { + "$id": "#/properties/postStart", + "type": "object", + "required": [ + "command" + ], + "properties": { + "command": { + "$id": "#properties/postStart/command", + "type": "array", + "default": [] + } + } + }, + "kubeClusterName": { + "$id": "#/properties/kubeClusterName", + "type": "string", + "default": "" + }, + "resources": { + "$id": "#/properties/resources", + "type": "object", + "default": {} + }, + "securityContext": { + "$id": "#/properties/securityContext", + "type": "object", + "default": {} + }, + "tolerations": { + "$id": "#/properties/tolerations", + "type": "array", + "default": [] + }, + "priorityClassName": { + "$id": "#/properties/priorityClassName", + "type": "string", + "default": "" + }, + "probeTimeoutSeconds": { + "$id": "#/properties/probeTimeoutSeconds", + "type": "integer", + "default": 1 + }, + "terminationGracePeriodSeconds": { + "$id": "#/properties/terminationGracePeriodSeconds", + "type": "integer", + "default": 60 + } + } +} diff --git a/helm/teleport-cluster/values.yaml b/helm/teleport-cluster/values.yaml new file mode 100644 index 0000000..54283ec --- /dev/null +++ b/helm/teleport-cluster/values.yaml @@ -0,0 +1,638 @@ +################################################## +# Values that must always be provided by the user. +################################################## + +# `clusterName` controls the name used to refer to the Teleport cluster, along with +# the externally-facing public address to use to access it. In most setups this must +# be a fully-qualified domain name (e.g. `teleport.example.com`) as this value is +# used as the cluster's public address by default. +# +# Note: When using a fully qualified domain name as your `clusterName`, you will also +# need to configure the DNS provider for this domain to point to the external +# load balancer address of your Teleport cluster. +# +# Warning: The clusterName cannot be changed during a Teleport cluster's lifespan. +# If you need to change it, you must redeploy a completely new cluster. +clusterName: "" + +# Name for this kubernetes cluster to be used by teleport users. +kubeClusterName: "" + +################################################## +# Values that you may need to change. +################################################## + +# Version of teleport image, if different from chart version in Chart.yaml. +# DANGER: `teleportVersionOverride` MUST NOT be used to control the Teleport version. +# This chart is designed to run a specific teleport version (see Chart.yaml). +# You will face compatibility issues trying to run a different Teleport version with it. +# +# If you want to run Teleport version X, you should use `helm --version X` instead. +teleportVersionOverride: "" + +# The `teleport-cluster` charts deploys two sets of pods: auth and proxy. +# `auth` contains values specific for the auth pods. You can use it to +# set specific values for auth pods, taking precedence over chart-scoped values. +# For example, to override the [`postStart`](#postStart) value only for auth pods: +# +# auth: +# postStart: ["curl", "http://hook"] +# imagePullPolicy: Always +auth: + # auth.teleportConfig contains YAML teleport configuration for auth pods + # The configuration will be merged with the chart-generated configuration + # and will take precedence in case of conflict. + # + # See the Teleport Configuration Reference for the list of supported fields: + # https://goteleport.com/docs/reference/config/ + # + # teleportConfig: + # teleport: + # cache: + # enabled: false + # auth_service: + # client_idle_timeout: 2h + # client_idle_timeout_message: "Connection closed after 2hours without activity" + teleportConfig: {} + +# proxy contains values specific for the proxy pods +# You can override chart-scoped values, for example +# proxy: +# postStart: ["curl", "http://hook"] +# imagePullPolicy: Always +proxy: + # proxy.teleportConfig contains YAML teleport configuration for proxy pods + # The configuration will be merged with the chart-generated configuration + # and will take precedence in case of conflict + # + # See the Teleport Configuration Reference for the list of supported fields: + # https://goteleport.com/docs/reference/config/ + # + # teleportConfig: + # teleport: + # cache: + # enabled: false + # proxy_service: + # https_keypairs: + # - key_file: /my-custom-mount/key.pem + # cert_file: /my-custom-mount/cert.pem + teleportConfig: {} + +authentication: + # Default authentication type. Possible values are 'local' and 'github' for OSS, plus 'oidc' and 'saml' for Enterprise. + type: local + + # Sets the authenticator connector for SSO or the default connector for "local" authentication. + # See SSO for Enterprise (https://goteleport.com/docs/enterprise/sso/). + # See Passwordless for local + # (http://goteleport.com/docs/access-controls/guides/passwordless/#optional-enable-passwordless-by-default). + # Defaults to "local". + connectorName: "" + + # Enable/disable local authentication by setting `authentication.local_auth` in `teleport.yaml`. + # Disabling local auth is required for FedRAMP / FIPS; see https://gravitational.com/teleport/docs/enterprise/ssh-kubernetes-fedramp/. + localAuth: true + + # Controls the locking mode: in case of network split should Teleport guarantee availability or integrity ? + # Possible values are "best_effort" and "strict". When not defined, Teleport defaults to "best_effort". + # See https://goteleport.com/docs/access-controls/guides/locking/#next-steps-locking-modes. + lockingMode: "" + + # Second factor requirements for users of the Teleport cluster. + # Controls the `auth_config.authentication.second_factor` field in `teleport.yaml`. + # Possible values are 'off', 'on', 'otp', 'optional' and 'webauthn'. + # + # WARNING: + # If you set `publicAddr` for users to access the cluster under a domain different + # to clusterName you must manually set the webauthn Relying + # Party Identifier (RP ID) - https://www.w3.org/TR/webauthn-2/#relying-party-identifier + # If you don't, RP ID will default to `clusterName` and users will fail + # to register second factors. + # + # You can do this by setting the value + # `auth.teleportConfig.auth_service.authentication.webauthn.rp_id`. + # + # RP ID must be both a valid domain, and part of the full domain users are connecting to. + # For example, if users are accessing the cluster with the domain + # "teleport.example.com", RP ID can be "teleport.example.com" or "example.com". + # + # Changing the RP ID will invalidate all already registered webauthn second factors. + secondFactor: "on" + + # (Optional) When using webauthn this allows to restrict which vendor and key models can be used. + # webauthn: + # attestationAllowedCas: + # - /path/to/allowed_ca.pem + # - | + # -----BEGIN CERTIFICATE----- + # ... + # -----END CERTIFICATE----- + # attestationDeniedCas: + # - /path/to/denied_ca.pem + # - | + # -----BEGIN CERTIFICATE----- + # ... + # -----END CERTIFICATE----- + +# Deprecated way to set the authentication type, `authentication.type` should be preferred. +# authenticationType: local + +# Deprecated way to set the authentication second factor, `authentication.secondFactor` should be preferred. +# authenticationSecondFactor: +# secondFactor: "otp" + +# Teleport supports TLS routing. In this mode, all client connections are wrapped in TLS and multiplexed on one Teleport proxy port. +# Default mode will not utilize TLS routing and operate in backwards-compatibility mode. +# +# To use an ingress, set proxyListenerMode=multiplex, ingress.enabled=true and service.type=ClusterIP +# +# Possible values are 'separate' and 'multiplex' +proxyListenerMode: "separate" + +# Optional setting for configuring session recording. +# See `session_recording` under https://goteleport.com/docs/setup/reference/config/#teleportyaml +sessionRecording: "" + +# By default, Teleport will multiplex Postgres and MongoDB database connections on the same port as the proxy's web listener (443) +# Setting either of these values to true will separate the listeners out onto a separate port (5432 for Postgres, 27017 for MongoDB) +# This is useful when terminating TLS at a load balancer in front of Teleport (such as when using AWS ACM) +# These settings will not apply if proxyListenerMode is set to "multiplex". +separatePostgresListener: false +separateMongoListener: false + +# Do not set any of these values unless you explicitly need to. Teleport always uses the cluster name by default. +# +# WARNING: +# If you set `publicAddr` for users to access the cluster under a domain different +# to clusterName, you must manually set the webauthn Relying +# Party Identifier (RP ID) - https://www.w3.org/TR/webauthn-2/#relying-party-identifier +# If you don't, RP ID will default to `clusterName` and users will fail +# to register second factors. +# +# You can do this by setting the value +# `auth.teleportConfig.auth_service.authentication.webauthn.rp_id`. +# +# RP ID must be both a valid domain, and part of the full domain users are connecting to. +# For example, if users are accessing the cluster with the domain +# "teleport.example.com", RP ID can be "teleport.example.com" or "example.com". +# +# Changing the RP ID will invalidate all already registered webauthn second factors. +# +# Public cluster addresses, including port (e.g. teleport.example.com:443) +# Defaults to `clusterName` on port 443. +publicAddr: [] +# Public cluster kube addresses, including port. Defaults to `publicAddr` on port 3026. +# Only used when `proxyListenerMode` is not 'multiplex'. +kubePublicAddr: [] +# Public cluster mongo listener addresses, including port. Defaults to `publicAddr` on port 27017. +# Only used when `proxyListenerMode` is not 'multiplex' and `separateMongoListener` is true. +mongoPublicAddr: [] +# Public cluster MySQL addresses, including port. Defaults to `publicAddr` on port 3036. +# Only used when `proxyListenerMode` is not 'multiplex'. +mysqlPublicAddr: [] +# Public cluster postgres listener addresses, including port. Defaults to `publicAddr` on port 5432. +# Only used when `proxyListenerMode` is not 'multiplex' and `separatePostgresListener` is true. +postgresPublicAddr: [] +# Public cluster SSH addresses, including port. Defaults to `publicAddr` on port 3023. +# Only used when `proxyListenerMode` is not 'multiplex'. +sshPublicAddr: [] +# Public cluster tunnel SSH addresses, including port. Defaults to `publicAddr` on port 3024. +# Only used when `proxyListenerMode` is not 'multiplex'. +tunnelPublicAddr: [] + +# ACME is a protocol for getting Web X.509 certificates +# Note: ACME can only be used for single-instance clusters. It is not suitable for use in HA configurations. +# For HA configurations, see either the "highAvailability.certManager" or "tls" values. +# Setting acme to 'true' enables the ACME protocol and will attempt to get a free TLS certificate from Let's Encrypt. +# Setting acme to 'false' (the default) will cause Teleport to generate and use self-signed certificates for its web UI. +# This section is mutually exclusive with the "tls" value below. +acme: false +# acmeEmail is the email address to provide during certificate registration (this is a Let's Encrypt requirement) +acmeEmail: "" +# acmeURI is the ACME server to use for getting certificates. The default is to use Let's Encrypt's production server. +acmeURI: "" + +# Set enterprise to true to use enterprise image +# You will need to download your Enterprise license from the Teleport dashboard and create a secret to use this: +# kubectl -n ${TELEPORT_NAMESPACE?} create secret generic license --from-file=/path/to/downloaded/license.pem +enterprise: false + +# CRDs are installed by default when the operator is enabled. This manual override allows to disable CRD installation +# when deploying multiple releases in the same cluster. +# installCRDs: + +# Configuration of the optional Teleport operator +operator: + # Set enabled to true to add the Kubernetes Teleport Operator + enabled: false + # Kubernetes Teleport Operator image + image: public.ecr.aws/gravitational/teleport-operator + # Resources to request for the operator container + # https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + resources: {} + # requests: + # cpu: "0.5" + # memory: "1Gi" + # limits: + # memory: "1Gi" + +# If true, create & use Pod Security Policy resources +# https://kubernetes.io/docs/concepts/policy/pod-security-policy/ +# WARNING: the PSP won't be deployed for Kubernetes 1.23 and higher. +# Please read https://goteleport.com/docs/deploy-a-cluster/helm-deployments/migration-kubernetes-1-25-psp/ +podSecurityPolicy: + enabled: true + +# Labels is a map of key-value pairs about this cluster +labels: {} + +# Mode to deploy the chart in. The default is "standalone". Options: +# - "standalone": will deploy a Teleport container running auth and proxy services with a PersistentVolumeClaim for storage. +# - "aws": will deploy Teleport using DynamoDB for backend/audit log storage and S3 for session recordings. (1) +# - "gcp": will deploy Teleport using Firestore for backend/audit log storage and Google Cloud storage for session recordings. (2) +# - "azure": will deploy Teleport using Azure Database for PostgreSQL for backend/audit and Azure Blob Storage for session recordings. (3) +# - "scratch": will deploy Teleport containers but will not provide default configuration file. You must pass your own configuration. (4) +# (1) To use "aws" mode, you must also configure the "aws" section below. +# (2) To use "gcp" mode, you must also configure the "gcp" section below. +# (3) To use "azure" mode, you must also configure the "azure" section below. +# (4) When set to "scratch", you must write the teleport configuration in auth.teleportConfig and proxy.teleportConfig. +# `scratch` usage is strongly discouraged, this is a last resort option and +# everything should be doable with `standalone` mode + overrides through +# `auth.teleportConfig` and `proxy.teleportConfig`. +chartMode: standalone + +# validateConfigOnDeploy enables a Kubernetes job before install and upgrade that will verify +# if the teleport.yaml configuration is valid and will block the deployment if it is not +validateConfigOnDeploy: true + +# Whether the chart should create a Teleport ProvisionToken for the proxies to join the Teleport cluster. +# Disabling this flag will cause the proxies not to be able to join the auth pods. In this case, the +# Helm chart user is responsible for configuring working join_params on the proxy. +createProxyToken: true + +# podMonitor controls the PodMonitor CR (from monitoring.coreos.com/v1) +# This CRD is managed by the prometheus-operator and allows workload to +# get monitored. To use this value, you need to run a `prometheus-operator` +# in the cluster for this value to take effect. +# See https://prometheus-operator.dev/docs/prologue/introduction/ +podMonitor: + # Whether the chart should deploy a PodMonitor. + # Disabled by default as it requires the PodMonitor CRD to be installed. + enabled: false + # additionalLabels to put on the PodMonitor. + # This is used to be selected by a specific prometheus instance. + # Defaults to {prometheus: default} which seems to be the common default prometheus selector + additionalLabels: + prometheus: default + # interval is the interval between two metrics scrapes. Defaults to 30s + interval: 30s + +###################################################################### +# Persistence settings (only used in "standalone" and "scratch" modes) +# NOTE: Changes in Kubernetes 1.23+ mean that persistent volumes will not automatically be provisioned in AWS EKS clusters +# without additional configuration. See https://docs.aws.amazon.com/eks/latest/userguide/ebs-csi.html for more details. +# This driver addon must be configured to use persistent volumes in EKS clusters after Kubernetes 1.23. +###################################################################### +persistence: + # Enable persistence using a PersistentVolumeClaim + enabled: true + # Leave blank to automatically create a PersistentVolumeClaim for Teleport storage. + # If you would like to use a pre-existing PersistentVolumeClaim, put its name here. + existingClaimName: "" + # Size of persistent volume to request when created by Teleport. + # Ignored if existingClaimName is provided. + volumeSize: 10Gi + +################################################## +# AWS-specific settings (only used in "aws" mode) +################################################## +aws: + # The AWS region where the DynamoDB tables are located. + region: "" + # The DynamoDB table name to use for backend storage. Teleport will attempt to create this table automatically if it does not exist. + # The container will need an appropriately-provisioned IAM role with permissions to create DynamoDB tables. + backendTable: "" + # The DynamoDB table name to use for audit log storage. Teleport will attempt to create this table automatically if it does not exist. + # The container will need an appropriately-provisioned IAM role with permissions to create DynamoDB tables. + # This MUST NOT be the same table name as used for 'backendTable' as the schemas are different. + auditLogTable: "" + # Whether to mirror audit log entries to stdout in JSON format (useful for external log collectors) + auditLogMirrorOnStdout: false + # The S3 bucket name to use for recorded session storage. Teleport will attempt to create this bucket automatically if it does not exist. + # The container will need an appropriately-provisioned IAM role with permissions to create S3 buckets. + sessionRecordingBucket: "" + # Whether or not to turn on DynamoDB backups + backups: false + + # Whether Teleport should configure DynamoDB's autoscaling. + # Requires additional statements in the IAM Teleport Policy to be allowed to configure the autoscaling. + # See https://goteleport.com/docs/setup/reference/backends/#dynamodb-autoscaling + dynamoAutoScaling: false + + # DynamoDB autoscaling settings. Required if `dynamoAutoScaling` is `true`. + # See https://goteleport.com/docs/setup/reference/backends/#dynamodb-autoscaling + readMinCapacity: null # Integer + readMaxCapacity: null # Integer + readTargetValue: null # Float + writeMinCapacity: null # Integer + writeMaxCapacity: null # Integer + writeTargetValue: null # Float + +################################################## +# GCP-specific settings (only used in "gcp" mode) +################################################## +gcp: + # The project name being used for the GCP account where Teleport is running. + # See https://support.google.com/googleapi/answer/7014113?hl=en + projectId: "" + # The Firestore collection to use for backend storage. Teleport will attempt to create this collection automatically if it does not exist. + # Either of the following must be true: + # - The container will need an appropriately-provisioned IAM role/service account with permissions to create Firestore collections + # - The service account credentials provided via 'credentialSecretName' will need permissions to create Firestore collections. + backendTable: "" + # The Firestore collection to use for audit log storage. Teleport will attempt to create this collection automatically if it does not exist. + # Either of the following must be true: + # - The container will need an appropriately-provisioned IAM role/service account with permissions to create Firestore collections + # - The service account credentials provided via 'credentialSecretName' will need permissions to create Firestore collections. + # This MUST NOT be the same collection name as used for 'backendTable' as the schemas are different. + auditLogTable: "" + # Whether to mirror audit log entries to stdout in JSON format (useful for external log collectors) + auditLogMirrorOnStdout: false + # The Google storage bucket name to use for recorded session storage. This bucket must already exist in the Google account being used. + sessionRecordingBucket: "" + # The name of the Kubernetes secret used to store the Google credentials. + # You will need to create this secret manually. It must contain a JSON file from Google with the credentials that Teleport will use. + # You can override this to a blank value if the worker node running Teleport already has a service account which grants access. + credentialSecretName: teleport-gcp-credentials + +##################################################### +# Azure-specific settings (only used in "azure" mode) +##################################################### +azure: + # The fully qualified hostname of the Postgres database cluster hosted in Azure. + # It should follow the format ".postgres.database.azure.com". + databaseHost: "" + # The Postgres user Teleport must use to connect to the backend and audit + # databases. + databaseUser: "" + # The Postgres database to use for backend storage. + backendDatabase: "teleport_backend" + # The Postgres database to use for audit log storage. + # This MUST NOT be the same database as used for 'backendDatabase'. + auditLogDatabase: "teleport_audit" + # Whether to mirror audit log entries to stdout in JSON format (useful for external log collectors) + auditLogMirrorOnStdout: false + # The fully qualified domain name of the Azure Blob Storage account to use for + # recorded session storage. This account must already exist. + # It should follow the format ".blob.core.windows.net" + sessionRecordingStorageAccount: "" + # Azure client ID is used by the Kubernetes Service Account to know which + # Application it should impersonate. This can be unset only if the clientID is + # passed through other means (e.g. environment variable) + clientID: "" + # Controls the `pool_max_conns` setting passed to PostgreSQL. This is the + # max amount of connections Teleport can open to the database. This can affect + # performance on large clusters and depends on various factors like the + # database size, the number of CPU cores available for Teleport, GOMAXPROCS + # and the database latency. + # This only applies to the core backend connections, not the audit log ones. + # 0 means the parameter is not set and the client's default is used (recommended) + databasePoolMaxConnections: 0 + +# `highAvailability` contains settings controlling how Teleport pods are +# replicated and scheduled. This allows Teleport to run in a highly-available +# fashion: Teleport should sustain the crash/loss of a machine without interrupting +# the service. +# +# For auth pods: +# When using "standalone" or "scratch" mode, you must use highly-available storage +# (etcd, DynamoDB or Firestore) for multiple replicas to be supported. +# Manually configuring NFS-based storage or ReadWriteMany volume claims +# is NOT supported and will result in errors. Using Teleport's built-in +# ACME client (as opposed to using cert-manager or passing certs through a secret) +# is not supported with multiple replicas. +# For proxy pods: +# Proxy pods need to be provided a certificate to be replicated (either via +# `tls.existingSecretName` or via `highAvailability.certManager`). +# If proxy pods are replicable, they will default to 2 replicas, +# even if `highAvailability.replicaCount` is 1. To force a single proxy replica, +# set `proxy.highAvailability.replicaCount: 1`. +highAvailability: + # Controls the amount of pod replicas. The `highAvailability` comment describes + # the replication requirements. + # + # WARNING: You **must** meet the replication criteria, + # else the deployment will result in errors and inconsistent data. + replicaCount: 1 + # Setting 'requireAntiAffinity' to true will use 'requiredDuringSchedulingIgnoredDuringExecution' to require that multiple Teleport pods must not be scheduled on the + # same physical host. This will result in Teleport pods failing to be scheduled in very small clusters or during node downtime, so should be used with caution. + # Setting 'requireAntiAffinity' to false (the default) uses 'preferredDuringSchedulingIgnoredDuringExecution' to make this a soft requirement. + # This setting only has any effect when replicaCount is greater than 1. + requireAntiAffinity: false + # If enabled will create a Pod Disruption Budget + # https://kubernetes.io/docs/concepts/workloads/pods/disruptions/ + podDisruptionBudget: + enabled: false + minAvailable: 1 + # Settings for cert-manager (can be used for provisioning TLS certs in HA mode) + # These settings are mutually exclusive with the "tls" value below. + certManager: + # If set to true, a common name matching the cluster name will be set in the certificate signing request. This is mandatory for some CAs. + addCommonName: false + # If set to true, use cert-manager to get certificates for Teleport to use for TLS termination + enabled: false + # Name of the Issuer/ClusterIssuer to use for certs + # NOTE: You will always need to create this yourself when certManager.enabled is true. + issuerName: "" + # Kind of Issuer that cert-manager should look for. + # This defaults to 'Issuer' to keep everything contained within the teleport namespace. + issuerKind: Issuer + # Group of Issuer that cert-manager should look for. + # This defaults to 'cert-manager.io' which is the default Issuer group. + issuerGroup: cert-manager.io + # Injects delay when performing pod rollouts to mitigate the loss of all agent tunnels at the same time + # See https://github.com/gravitational/teleport/issues/13129 + minReadySeconds: 15 + +# Settings for mounting your own TLS keypair to secure Teleport's web UI. +# These settings are mutually exclusive with the "highAvailability.certManager" and "acme" values above. +tls: + # Name of an existing secret to use which contains a TLS keypair. Will automatically set the https_keypairs section in teleport.yaml. + # Create the secret in the same namespace as Teleport using `kubectl create secret tls my-tls-secret --cert=/path/to/cert/file --key=/path/to/key/file` + # See https://kubernetes.io/docs/concepts/configuration/secret/#tls-secrets for more information. + existingSecretName: "" + # (optional) Name of an existing secret to use which contains a CA or trust bundle in x509 PEM format. + # Useful for building trust when using intermediate certificate authorities. + # This will automatically set the SSL_CERT_FILE environment variable to trust the CA. + # Create the secret with `kubectl create secret generic --from-file=ca.pem=/path/to/root-ca.pem + # The filename inside the secret is important - it _must_ be ca.pem + existingCASecretName: "" + +################################################## +# Values that you shouldn't need to change. +################################################## + +# Container image for the cluster. +# Since version 13, hardened distroless images are used by default. +# You can use the deprecated debian-based images by setting the value to +# `public.ecr.aws/gravitational/teleport`. Those images will be +# removed with teleport 14. +image: public.ecr.aws/gravitational/teleport-distroless +# Enterprise version of the image +# Since version 13, hardened distroless images are used by default. +# You can use the deprecated debian-based images by setting the value to +# `public.ecr.aws/gravitational/teleport-ent`. Those images will be +# removed with teleport 14. +enterpriseImage: public.ecr.aws/gravitational/teleport-ent-distroless +# Optional array of imagePullSecrets, to use when pulling from a private registry +imagePullSecrets: [] +# Teleport logging configuration +log: + # Log level for the Teleport process. + # Available log levels are: DEBUG, INFO, WARNING, ERROR. + # The default is INFO, which is recommended in production. + # DEBUG is useful during first-time setup or to see more detailed logs for debugging. + level: INFO + # Log output + # Use a file path to log to disk: e.g. '/var/lib/teleport/teleport.log' + # Other supported values: 'stdout', 'stderr' and 'syslog' + output: stderr + # Log format configuration + # Possible output values are 'json' and 'text' (default). + format: text + # Possible extra_fields values include: timestamp, component, caller, and level. + # All extra fields are included by default. + extraFields: ["timestamp", "level", "component", "caller"] + +################################## +# Extra Kubernetes configuration # +################################## + +# nodeSelector to apply for pod assignment +# https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#nodeselector +nodeSelector: {} + +# Affinity for pod assignment +# https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity +# NOTE: If affinity is set here, highAvailability.requireAntiAffinity cannot also be used - you can only set one or the other. +affinity: {} + +# Kubernetes annotations to apply +# https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ +annotations: + # Annotations for the ConfigMap + config: {} + # Annotations for the Deployment + deployment: {} + # Annotations for each Pod in the Deployment + pod: {} + # Annotations for the Service object + service: {} + # Annotations for the ServiceAccount object + serviceAccount: {} + # Annotations for the certificate secret generated by cert-manager v1.5+ when + # highAvailability.certManager.enabled is true + certSecret: {} + # Annotations for the Ingress object + ingress: {} + +# Kubernetes service account to create/use. +serviceAccount: + # Specifies whether a ServiceAccount should be created + create: true + # The name of the ServiceAccount to use. + # If not set and serviceAccount.create is true, the name is generated using the release name. + # If create is false, the name will be used to reference an existing service account. + name: "" + # To set annotations on the service account, use the annotations.serviceAccount value. + +# Set to true (default) to create Kubernetes ClusterRole and ClusterRoleBinding. +rbac: + # Specifies whether a ClusterRole and ClusterRoleBinding should be created. + # Set to false if your cluster level resources are managed separately. + create: true + +# Options for the Teleport proxy service +# This setting only applies to the proxy service. The teleport auth service is internal-only and always uses a ClusterIP. +# You can override the proxy's backend service to any service type (other than "LoadBalancer") here if really needed. +# To use an Ingress, set service.type=ClusterIP and ingress.enabled=true +service: + type: LoadBalancer + # Additional entries here will be added to the service spec. + spec: {} + # loadBalancerIP: "1.2.3.4" + +# Options for ingress +# If you set ingress.enabled to true, service.type MUST also be set to something other than "LoadBalancer" to prevent +# additional unnecessary load balancers from being created. Ingress controllers should provision their own load balancer. +# Using an Ingress also requires that you use the `tsh` client to connect to Kubernetes clusters and databases behind Teleport. +# See https://goteleport.com/docs/architecture/tls-routing/#working-with-layer-7-load-balancers-or-reverse-proxies-preview for details. +ingress: + enabled: false + # Setting suppressAutomaticWildcards to true will not automatically add *. as a hostname served + # by the Ingress. This may be desirable if you don't use Teleport Application Access. + suppressAutomaticWildcards: false + # Additional entries here will be added to the ingress spec. + spec: {} + # ingressClassName: nginx + +# Extra arguments to pass to 'teleport start' for the main Teleport pod +extraArgs: [] + +# Extra environment to be configured on the Teleport pod +extraEnv: [] + +# Extra volumes to mount into the Teleport pods +# https://kubernetes.io/docs/concepts/storage/volumes/ +extraVolumes: [] +# - name: myvolume +# secret: +# secretName: testSecret + +# Extra volume mounts corresponding to the volumes mounted above +extraVolumeMounts: [] +# - name: myvolume +# mountPath: /path/on/host + +# Allow the imagePullPolicy to be overridden +imagePullPolicy: IfNotPresent + +# A list of initContainers to run before each Teleport pod starts +# https://kubernetes.io/docs/concepts/workloads/pods/init-containers/ +initContainers: [] +# - name: "teleport-init" +# image: "alpine" +# args: ["echo test"] + +# If set, will run the command as a postStart handler +# https://kubernetes.io/docs/tasks/configure-pod-container/attach-handler-lifecycle-event/ +postStart: + command: [] + +# Resources to request for the teleport container +# https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ +resources: {} +# requests: +# cpu: "1" +# memory: "2Gi" + +# Security context to add to the container +securityContext: {} + # runAsUser: 99 + +# Priority class name to add to the deployment +priorityClassName: "" + +# Tolerations for pod assignment +# https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ +tolerations: [] + +# Timeouts for the readiness and liveness probes +# https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/ +probeTimeoutSeconds: 1 + +# Kubernetes termination grace period +# https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#hook-handler-execution +# +# This should be greater than 30 seconds as pods are waiting 30 seconds in a preStop hook. +terminationGracePeriodSeconds: 60 diff --git a/helm/vault/.helmignore b/helm/vault/.helmignore new file mode 100644 index 0000000..4007e24 --- /dev/null +++ b/helm/vault/.helmignore @@ -0,0 +1,28 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.terraform/ +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*~ +# Various IDEs +.project +.idea/ +*.tmproj + +# CI and test +.circleci/ +.github/ +.gitlab-ci.yml +test/ diff --git a/helm/vault/CHANGELOG.md b/helm/vault/CHANGELOG.md new file mode 100644 index 0000000..f3c466f --- /dev/null +++ b/helm/vault/CHANGELOG.md @@ -0,0 +1,484 @@ +## Unreleased + +## 0.25.0 (June 26, 2023) + +Changes: +* Latest Kubernetes version tested is now 1.27 +* server: Headless service ignores `server.service.publishNotReadyAddresses` setting and always sets it as `true` [GH-902](https://github.com/hashicorp/vault-helm/pull/902) +* `vault` updated to 1.14.0 [GH-916](https://github.com/hashicorp/vault-helm/pull/916) +* `vault-csi-provider` updated to 1.4.0 [GH-916](https://github.com/hashicorp/vault-helm/pull/916) + +Improvements: +* CSI: Make `nodeSelector` and `affinity` configurable for CSI daemonset's pods [GH-862](https://github.com/hashicorp/vault-helm/pull/862) +* injector: Add `ephemeralLimit` and `ephemeralRequest` as options for configuring Agent's ephemeral storage resources [GH-798](https://github.com/hashicorp/vault-helm/pull/798) +* Minimum kubernetes version for chart reverted to 1.20.0 to allow installation on clusters older than the oldest tested version [GH-916](https://github.com/hashicorp/vault-helm/pull/916) + +Bugs: +* server: Set the default for `prometheusRules.rules` to an empty list [GH-886](https://github.com/hashicorp/vault-helm/pull/886) + +## 0.24.1 (April 17, 2023) + +Bugs: +* csi: Add RBAC required by v1.3.0 to create secret for HMAC key used to generate secret versions [GH-872](https://github.com/hashicorp/vault-helm/pull/872) + +## 0.24.0 (April 6, 2023) + +Changes: +* Earliest Kubernetes version tested is now 1.22 +* `vault` updated to 1.13.1 [GH-863](https://github.com/hashicorp/vault-helm/pull/863) +* `vault-k8s` updated to 1.2.1 [GH-868](https://github.com/hashicorp/vault-helm/pull/868) +* `vault-csi-provider` updated to 1.3.0 [GH-749](https://github.com/hashicorp/vault-helm/pull/749) + +Features: +* server: New `extraPorts` option for adding ports to the Vault server statefulset [GH-841](https://github.com/hashicorp/vault-helm/pull/841) +* server: Add configurable Port Number in readinessProbe and livenessProbe for the server-statefulset [GH-831](https://github.com/hashicorp/vault-helm/pull/831) +* injector: Make livenessProbe and readinessProbe configurable and add configurable startupProbe [GH-852](https://github.com/hashicorp/vault-helm/pull/852) +* csi: Add an Agent sidecar to Vault CSI Provider pods to provide lease caching and renewals [GH-749](https://github.com/hashicorp/vault-helm/pull/749) + +## 0.23.0 (November 28th, 2022) + +Changes: +* `vault` updated to 1.12.1 [GH-814](https://github.com/hashicorp/vault-helm/pull/814) +* `vault-k8s` updated to 1.1.0 [GH-814](https://github.com/hashicorp/vault-helm/pull/814) +* `vault-csi-provider` updated to 1.2.1 [GH-814](https://github.com/hashicorp/vault-helm/pull/814) + +Features: +* server: Add `extraLabels` for Vault server serviceAccount [GH-806](https://github.com/hashicorp/vault-helm/pull/806) +* server: Add `server.service.active.enabled` and `server.service.standby.enabled` options to selectively disable additional services [GH-811](https://github.com/hashicorp/vault-helm/pull/811) +* server: Add `server.serviceAccount.serviceDiscovery.enabled` option to selectively disable a Vault service discovery role and role binding [GH-811](https://github.com/hashicorp/vault-helm/pull/811) +* server: Add `server.service.instanceSelector.enabled` option to allow selecting pods outside the helm chart deployment [GH-813](https://github.com/hashicorp/vault-helm/pull/813) + +Bugs: +* server: Quote `.server.ha.clusterAddr` value [GH-810](https://github.com/hashicorp/vault-helm/pull/810) + +## 0.22.1 (October 26th, 2022) + +Changes: +* `vault` updated to 1.12.0 [GH-803](https://github.com/hashicorp/vault-helm/pull/803) +* `vault-k8s` updated to 1.0.1 [GH-803](https://github.com/hashicorp/vault-helm/pull/803) + +## 0.22.0 (September 8th, 2022) + +Features: +* Add PrometheusOperator support for collecting Vault server metrics. [GH-772](https://github.com/hashicorp/vault-helm/pull/772) + +Changes: +* `vault-k8s` to 1.0.0 [GH-784](https://github.com/hashicorp/vault-helm/pull/784) +* Test against Kubernetes 1.25 [GH-784](https://github.com/hashicorp/vault-helm/pull/784) +* `vault` updated to 1.11.3 [GH-785](https://github.com/hashicorp/vault-helm/pull/785) + +## 0.21.0 (August 10th, 2022) + +CHANGES: +* `vault-k8s` updated to 0.17.0. [GH-771](https://github.com/hashicorp/vault-helm/pull/771) +* `vault-csi-provider` updated to 1.2.0 [GH-771](https://github.com/hashicorp/vault-helm/pull/771) +* `vault` updated to 1.11.2 [GH-771](https://github.com/hashicorp/vault-helm/pull/771) +* Start testing against Kubernetes 1.24. [GH-744](https://github.com/hashicorp/vault-helm/pull/744) +* Deprecated `injector.externalVaultAddr`. Added `global.externalVaultAddr`, which applies to both the Injector and the CSI Provider. [GH-745](https://github.com/hashicorp/vault-helm/pull/745) +* CSI Provider pods now set the `VAULT_ADDR` environment variable to either the internal Vault service or the configured external address. [GH-745](https://github.com/hashicorp/vault-helm/pull/745) + +Features: +* server: Add `server.statefulSet.securityContext` to override pod and container `securityContext`. [GH-767](https://github.com/hashicorp/vault-helm/pull/767) +* csi: Add `csi.daemonSet.securityContext` to override pod and container `securityContext`. [GH-767](https://github.com/hashicorp/vault-helm/pull/767) +* injector: Add `injector.securityContext` to override pod and container `securityContext`. [GH-750](https://github.com/hashicorp/vault-helm/pull/750) and [GH-767](https://github.com/hashicorp/vault-helm/pull/767) +* Add `server.service.activeNodePort` and `server.service.standbyNodePort` to specify the `nodePort` for active and standby services. [GH-610](https://github.com/hashicorp/vault-helm/pull/610) +* Support for setting annotations on the injector's serviceAccount [GH-753](https://github.com/hashicorp/vault-helm/pull/753) + +## 0.20.1 (May 25th, 2022) +CHANGES: +* `vault-k8s` updated to 0.16.1 [GH-739](https://github.com/hashicorp/vault-helm/pull/739) + +Improvements: +* Mutating webhook will no longer target the agent injector pod [GH-736](https://github.com/hashicorp/vault-helm/pull/736) + +Bugs: +* `vault` service account is now created even if the server is set to disabled, as per before 0.20.0 [GH-737](https://github.com/hashicorp/vault-helm/pull/737) + +## 0.20.0 (May 16th, 2022) + +CHANGES: +* `global.enabled` now works as documented, that is, setting `global.enabled` to false will disable everything, with individual components able to be turned on individually [GH-703](https://github.com/hashicorp/vault-helm/pull/703) +* Default value of `-` used for injector and server to indicate that they follow `global.enabled`. [GH-703](https://github.com/hashicorp/vault-helm/pull/703) +* Vault default image to 1.10.3 +* CSI provider default image to 1.1.0 +* Vault K8s default image to 0.16.0 +* Earliest Kubernetes version tested is now 1.16 +* Helm 3.6+ now required + +Features: +* Support topologySpreadConstraints in server and injector. [GH-652](https://github.com/hashicorp/vault-helm/pull/652) + +Improvements: +* CSI: Set `extraLabels` for daemonset, pods, and service account [GH-690](https://github.com/hashicorp/vault-helm/pull/690) +* Add namespace to injector-leader-elector role, rolebinding and secret [GH-683](https://github.com/hashicorp/vault-helm/pull/683) +* Support policy/v1 PodDisruptionBudget in Kubernetes 1.21+ for server and injector [GH-710](https://github.com/hashicorp/vault-helm/pull/710) +* Make the Cluster Address (CLUSTER_ADDR) configurable [GH-629](https://github.com/hashicorp/vault-helm/pull/709) +* server: Make `publishNotReadyAddresses` configurable for services [GH-694](https://github.com/hashicorp/vault-helm/pull/694) +* server: Allow config to be defined as a YAML object in the values file [GH-684](https://github.com/hashicorp/vault-helm/pull/684) +* Maintain default MutatingWebhookConfiguration values from `v1beta1` [GH-692](https://github.com/hashicorp/vault-helm/pull/692) + +## 0.19.0 (January 20th, 2022) + +CHANGES: +* Vault image default 1.9.2 +* Vault K8s image default 0.14.2 + +Features: +* Added configurable podDisruptionBudget for injector [GH-653](https://github.com/hashicorp/vault-helm/pull/653) +* Make terminationGracePeriodSeconds configurable for server [GH-659](https://github.com/hashicorp/vault-helm/pull/659) +* Added configurable update strategy for injector [GH-661](https://github.com/hashicorp/vault-helm/pull/661) +* csi: ability to set priorityClassName for CSI daemonset pods [GH-670](https://github.com/hashicorp/vault-helm/pull/670) + +Improvements: +* Set the namespace on the OpenShift Route [GH-679](https://github.com/hashicorp/vault-helm/pull/679) +* Add volumes and env vars to helm hook test pod [GH-673](https://github.com/hashicorp/vault-helm/pull/673) +* Make TLS configurable for OpenShift routes [GH-686](https://github.com/hashicorp/vault-helm/pull/686) + +## 0.18.0 (November 17th, 2021) + +CHANGES: +* Removed support for deploying a leader-elector container with the [vault-k8s injector](https://github.com/hashicorp/vault-k8s) injector since vault-k8s now uses an internal mechanism to determine leadership [GH-649](https://github.com/hashicorp/vault-helm/pull/649) +* Vault image default 1.9.0 +* Vault K8s image default 0.14.1 + +Improvements: +* Added templateConfig.staticSecretRenderInterval chart option for the injector [GH-621](https://github.com/hashicorp/vault-helm/pull/621) + +## 0.17.1 (October 25th, 2021) + +Improvements: + * Add option for Ingress PathType [GH-634](https://github.com/hashicorp/vault-helm/pull/634) + +## 0.17.0 (October 21st, 2021) + +KNOWN ISSUES: +* The chart will fail to deploy on Kubernetes 1.19+ with `server.ingress.enabled=true` because no `pathType` is set + +CHANGES: +* Vault image default 1.8.4 +* Vault K8s image default 0.14.0 + +Improvements: +* Support Ingress stable networking API [GH-590](https://github.com/hashicorp/vault-helm/pull/590) +* Support setting the `externalTrafficPolicy` for `LoadBalancer` and `NodePort` service types [GH-626](https://github.com/hashicorp/vault-helm/pull/626) +* Support setting ingressClassName on server Ingress [GH-630](https://github.com/hashicorp/vault-helm/pull/630) + +Bugs: +* Ensure `kubeletRootDir` volume path and mounts are the same when `csi.daemonSet.kubeletRootDir` is overridden [GH-628](https://github.com/hashicorp/vault-helm/pull/628) + +## 0.16.1 (September 29th, 2021) + +CHANGES: +* Vault image default 1.8.3 +* Vault K8s image default 0.13.1 + +## 0.16.0 (September 16th, 2021) + +CHANGES: +* Support for deploying a leader-elector container with the [vault-k8s injector](https://github.com/hashicorp/vault-k8s) injector will be removed in version 0.18.0 of this chart since vault-k8s now uses an internal mechanism to determine leadership. To enable the deployment of the leader-elector container for use with vault-k8s 0.12.0 and earlier, set `useContainer=true`. + +Improvements: + * Make CSI provider `hostPaths` configurable via `csi.daemonSet.providersDir` and `csi.daemonSet.kubeletRootDir` [GH-603](https://github.com/hashicorp/vault-helm/pull/603) + * Support vault-k8s internal leader election [GH-568](https://github.com/hashicorp/vault-helm/pull/568) [GH-607](https://github.com/hashicorp/vault-helm/pull/607) + +## 0.15.0 (August 23rd, 2021) + +Improvements: +* Add imagePullSecrets on server test [GH-572](https://github.com/hashicorp/vault-helm/pull/572) +* Add injector.webhookAnnotations chart option [GH-584](https://github.com/hashicorp/vault-helm/pull/584) + +## 0.14.0 (July 28th, 2021) + +Features: +* Added templateConfig.exitOnRetryFailure chart option for the injector [GH-560](https://github.com/hashicorp/vault-helm/pull/560) + +Improvements: +* Support configuring pod tolerations, pod affinity, and node selectors as YAML [GH-565](https://github.com/hashicorp/vault-helm/pull/565) +* Set the default vault image to come from the hashicorp organization [GH-567](https://github.com/hashicorp/vault-helm/pull/567) +* Add support for running the acceptance tests against a local `kind` cluster [GH-567](https://github.com/hashicorp/vault-helm/pull/567) +* Add `server.ingress.activeService` to configure if the ingress should use the active service [GH-570](https://github.com/hashicorp/vault-helm/pull/570) +* Add `server.route.activeService` to configure if the route should use the active service [GH-570](https://github.com/hashicorp/vault-helm/pull/570) +* Support configuring `global.imagePullSecrets` from a string array [GH-576](https://github.com/hashicorp/vault-helm/pull/576) + + +## 0.13.0 (June 17th, 2021) + +Improvements: +* Added a helm test for vault server [GH-531](https://github.com/hashicorp/vault-helm/pull/531) +* Added server.enterpriseLicense option [GH-547](https://github.com/hashicorp/vault-helm/pull/547) +* Added OpenShift overrides [GH-549](https://github.com/hashicorp/vault-helm/pull/549) + +Bugs: +* Fix ui.serviceNodePort schema [GH-537](https://github.com/hashicorp/vault-helm/pull/537) +* Fix server.ha.disruptionBudget.maxUnavailable schema [GH-535](https://github.com/hashicorp/vault-helm/pull/535) +* Added webhook-certs volume mount to sidecar injector [GH-545](https://github.com/hashicorp/vault-helm/pull/545) + +## 0.12.0 (May 25th, 2021) + +Features: +* Pass additional arguments to `vault-csi-provider` using `csi.extraArgs` [GH-526](https://github.com/hashicorp/vault-helm/pull/526) + +Improvements: +* Set chart kubeVersion and added chart-verifier tests [GH-510](https://github.com/hashicorp/vault-helm/pull/510) +* Added values json schema [GH-513](https://github.com/hashicorp/vault-helm/pull/513) +* Ability to set tolerations for CSI daemonset pods [GH-521](https://github.com/hashicorp/vault-helm/pull/521) +* UI target port is now configurable [GH-437](https://github.com/hashicorp/vault-helm/pull/437) + +Bugs: +* CSI: `global.imagePullSecrets` are now also used for CSI daemonset [GH-519](https://github.com/hashicorp/vault-helm/pull/519) + +## 0.11.0 (April 14th, 2021) + +Features: +* Added `server.enabled` to explicitly skip installing a Vault server [GH-486](https://github.com/hashicorp/vault-helm/pull/486) +* Injector now supports enabling host network [GH-471](https://github.com/hashicorp/vault-helm/pull/471) +* Injector port is now configurable [GH-489](https://github.com/hashicorp/vault-helm/pull/489) +* Injector Vault Agent resource defaults are now configurable [GH-493](https://github.com/hashicorp/vault-helm/pull/493) +* Extra paths can now be added to the Vault ingress service [GH-460](https://github.com/hashicorp/vault-helm/pull/460) +* Log level and format can now be set directly using `server.logFormat` and `server.logLevel` [GH-488](https://github.com/hashicorp/vault-helm/pull/488) + +Improvements: +* Added `https` name to injector service port [GH-495](https://github.com/hashicorp/vault-helm/pull/495) + +Bugs: +* CSI: Fix ClusterRole name and DaemonSet's service account to properly match deployment name [GH-486](https://github.com/hashicorp/vault-helm/pull/486) + +## 0.10.0 (March 25th, 2021) + +Features: +* Add support for [Vault CSI provider](https://github.com/hashicorp/vault-csi-provider) [GH-461](https://github.com/hashicorp/vault-helm/pull/461) + +Improvements: +* `objectSelector` can now be set on the mutating admission webhook [GH-456](https://github.com/hashicorp/vault-helm/pull/456) + +## 0.9.1 (February 2nd, 2021) + +Bugs: +* Injector: fix labels for default anti-affinity rule [GH-441](https://github.com/hashicorp/vault-helm/pull/441), [GH-442](https://github.com/hashicorp/vault-helm/pull/442) +* Set VAULT_DEV_LISTEN_ADDRESS in dev mode [GH-446](https://github.com/hashicorp/vault-helm/pull/446) + +## 0.9.0 (January 5th, 2021) + +Features: +* Injector now supports configurable number of replicas [GH-436](https://github.com/hashicorp/vault-helm/pull/436) +* Injector now supports auto TLS for multiple replicas using leader elections [GH-436](https://github.com/hashicorp/vault-helm/pull/436) + +Improvements: +* Dev mode now supports `server.extraArgs` [GH-421](https://github.com/hashicorp/vault-helm/pull/421) +* Dev mode root token is now configurable with `server.dev.devRootToken` [GH-415](https://github.com/hashicorp/vault-helm/pull/415) +* ClusterRoleBinding updated to `v1` [GH-395](https://github.com/hashicorp/vault-helm/pull/395) +* MutatingWebhook updated to `v1` [GH-408](https://github.com/hashicorp/vault-helm/pull/408) +* Injector service now supports `injector.service.annotations` [425](https://github.com/hashicorp/vault-helm/pull/425) +* Injector now supports `injector.extraLabels` [428](https://github.com/hashicorp/vault-helm/pull/428) +* Added `allowPrivilegeEscalation: false` to Vault and Injector containers [429](https://github.com/hashicorp/vault-helm/pull/429) +* Network Policy now supports `server.networkPolicy.egress` [389](https://github.com/hashicorp/vault-helm/pull/389) + +## 0.8.0 (October 20th, 2020) + +Improvements: +* Make server NetworkPolicy independent of OpenShift [GH-381](https://github.com/hashicorp/vault-helm/pull/381) +* Added configurables for all probe values [GH-387](https://github.com/hashicorp/vault-helm/pull/387) +* MountPath for audit and data storage is now configurable [GH-393](https://github.com/hashicorp/vault-helm/pull/393) +* Annotations can now be added to the Injector pods [GH-394](https://github.com/hashicorp/vault-helm/pull/394) +* The injector can now be configured with a failurePolicy [GH-400](https://github.com/hashicorp/vault-helm/pull/400) +* Added additional environment variables for rendering within Vault config [GH-398](https://github.com/hashicorp/vault-helm/pull/398) +* Service account for Vault K8s auth is automatically created when `injector.externalVaultAddr` is set [GH-392](https://github.com/hashicorp/vault-helm/pull/392) + +Bugs: +* Fixed install output using Helm V2 command [GH-378](https://github.com/hashicorp/vault-helm/pull/378) + +## 0.7.0 (August 24th, 2020) + +Features: +* Added `volumes` and `volumeMounts` for mounting _any_ type of volume [GH-314](https://github.com/hashicorp/vault-helm/pull/314). +* Added configurable to enable prometheus telemetery exporter for Vault Agent Injector [GH-372](https://github.com/hashicorp/vault-helm/pull/372) + +Improvements: +* Added `defaultMode` configurable to `extraVolumes`[GH-321](https://github.com/hashicorp/vault-helm/pull/321) +* Option to install and use PodSecurityPolicy's for vault server and injector [GH-177](https://github.com/hashicorp/vault-helm/pull/177) +* `VAULT_API_ADDR` is now configurable [GH-290](https://github.com/hashicorp/vault-helm/pull/290) +* Removed deprecated tolerate unready endpoint annotations [GH-363](https://github.com/hashicorp/vault-helm/pull/363) +* Add an option to set annotations on the StatefulSet [GH-199](https://github.com/hashicorp/vault-helm/pull/199) +* Make the vault server serviceAccount name a configuration option [GH-367](https://github.com/hashicorp/vault-helm/pull/367) +* Removed annotation striction from `dev` mode [GH-371](https://github.com/hashicorp/vault-helm/pull/371) +* Add an option to set annotations on PVCs [GH-364](https://github.com/hashicorp/vault-helm/pull/364) +* Added service configurables for UI [GH-285](https://github.com/hashicorp/vault-helm/pull/285) + +Bugs: +* Fix python dependency in test image [GH-337](https://github.com/hashicorp/vault-helm/pull/337) +* Fix caBundle not being quoted causing validation issues with Helm 3 [GH-352](https://github.com/hashicorp/vault-helm/pull/352) +* Fix injector network policy being rendered when injector is not enabled [GH-358](https://github.com/hashicorp/vault-helm/pull/358) + +## 0.6.0 (June 3rd, 2020) + +Features: +* Added `extraInitContainers` to define init containers for the Vault cluster [GH-258](https://github.com/hashicorp/vault-helm/pull/258) +* Added `postStart` lifecycle hook allowing users to configure commands to run on the Vault pods after they're ready [GH-315](https://github.com/hashicorp/vault-helm/pull/315) +* Beta: Added OpenShift support [GH-319](https://github.com/hashicorp/vault-helm/pull/319) + +Improvements: +* Server configs can now be defined in YAML. Multi-line string configs are still compatible [GH-213](https://github.com/hashicorp/vault-helm/pull/213) +* Removed IPC_LOCK privileges since swap is disabled on containers [[GH-198](https://github.com/hashicorp/vault-helm/pull/198)] +* Use port names that map to vault.scheme [[GH-223](https://github.com/hashicorp/vault-helm/pull/223)] +* Allow both yaml and multi-line string annotations [[GH-272](https://github.com/hashicorp/vault-helm/pull/272)] +* Added configurable to set the Raft node name to hostname [[GH-269](https://github.com/hashicorp/vault-helm/pull/269)] +* Support setting priorityClassName on pods [[GH-282](https://github.com/hashicorp/vault-helm/pull/282)] +* Added support for ingress apiVersion `networking.k8s.io/v1beta1` [[GH-310](https://github.com/hashicorp/vault-helm/pull/310)] +* Added configurable to change service type for the HA active service [GH-317](https://github.com/hashicorp/vault-helm/pull/317) + +Bugs: +* Fixed default ingress path [[GH-224](https://github.com/hashicorp/vault-helm/pull/224)] +* Fixed annotations for HA standby/active services [[GH-268](https://github.com/hashicorp/vault-helm/pull/268)] +* Updated some value defaults to match their use in templates [[GH-309](https://github.com/hashicorp/vault-helm/pull/309)] +* Use active service on ingress when ha [[GH-270](https://github.com/hashicorp/vault-helm/pull/270)] +* Fixed bug where pull secrets weren't being used for injector image [GH-298](https://github.com/hashicorp/vault-helm/pull/298) + +## 0.5.0 (April 9th, 2020) + +Features: + +* Added Raft support for HA mode [[GH-228](https://github.com/hashicorp/vault-helm/pull/229)] +* Now supports Vault Enterprise [[GH-250](https://github.com/hashicorp/vault-helm/pull/250)] +* Added K8s Service Registration for HA modes [[GH-250](https://github.com/hashicorp/vault-helm/pull/250)] + +* Option to set `AGENT_INJECT_VAULT_AUTH_PATH` for the injector [[GH-185](https://github.com/hashicorp/vault-helm/pull/185)] +* Added environment variables for logging and revocation on Vault Agent Injector [[GH-219](https://github.com/hashicorp/vault-helm/pull/219)] +* Option to set environment variables for the injector deployment [[GH-232](https://github.com/hashicorp/vault-helm/pull/232)] +* Added affinity, tolerations, and nodeSelector options for the injector deployment [[GH-234](https://github.com/hashicorp/vault-helm/pull/234)] +* Made all annotations multi-line strings [[GH-227](https://github.com/hashicorp/vault-helm/pull/227)] + +## 0.4.0 (February 21st, 2020) + +Improvements: + +* Allow process namespace sharing between Vault and sidecar containers [[GH-174](https://github.com/hashicorp/vault-helm/pull/174)] +* Added configurable to change updateStrategy [[GH-172](https://github.com/hashicorp/vault-helm/pull/172)] +* Added sleep in the preStop lifecycle step [[GH-188](https://github.com/hashicorp/vault-helm/pull/188)] +* Updated chart and tests to Helm 3 [[GH-195](https://github.com/hashicorp/vault-helm/pull/195)] +* Adds Values.injector.externalVaultAddr to use the injector with an external vault [[GH-207](https://github.com/hashicorp/vault-helm/pull/207)] + +Bugs: + +* Fix bug where Vault lifecycle was appended after extra containers. [[GH-179](https://github.com/hashicorp/vault-helm/pull/179)] + +## 0.3.3 (January 14th, 2020) + +Security: + +* Added `server.extraArgs` to allow loading of additional Vault configurations containing sensitive settings [GH-175](https://github.com/hashicorp/vault-helm/issues/175) + +Bugs: + +* Fixed injection bug where wrong environment variables were being used for manually mounted TLS files + +## 0.3.2 (January 8th, 2020) + +Bugs: + +* Fixed injection bug where TLS Skip Verify was true by default [VK8S-35] + +## 0.3.1 (January 2nd, 2020) + +Bugs: + +* Fixed injection bug causing kube-system pods to be rejected [VK8S-14] + +## 0.3.0 (December 19th, 2019) + +Features: + +* Extra containers can now be added to the Vault pods +* Added configurability of pod probes +* Added Vault Agent Injector + +Improvements: + +* Moved `global.image` to `server.image` +* Changed UI service template to route pods that aren't ready via `publishNotReadyAddresses: true` +* Added better HTTP/HTTPS scheme support to http probes +* Added configurable node port for Vault service +* `server.authDelegator` is now enabled by default + +Bugs: + +* Fixed upgrade bug by removing chart label which contained the version +* Fixed typo on `serviceAccount` (was `serviceaccount`) +* Fixed readiness/liveliness HTTP probe default to accept standbys + +## 0.2.1 (November 12th, 2019) + +Bugs: + +* Removed `readOnlyRootFilesystem` causing issues when validating deployments + +## 0.2.0 (October 29th, 2019) + +Features: + +* Added load balancer support +* Added ingress support +* Added configurable for service types (ClusterIP, NodePort, LoadBalancer, etc) +* Removed root requirements, now runs as Vault user + +Improvements: + +* Added namespace value to all rendered objects +* Made ports configurable in services +* Added the ability to add custom annotations to services +* Added docker image for running bats test in CircleCI +* Removed restrictions around `dev` mode such as annotations +* `readOnlyRootFilesystem` is now configurable +* Image Pull Policy is now configurable + +Bugs: + +* Fixed selector bugs related to Helm label updates (services, affinities, and pod disruption) +* Fixed bug where audit storage was not being mounted in HA mode +* Fixed bug where Vault pod wasn't receiving SIGTERM signals + + +## 0.1.2 (August 22nd, 2019) + +Features: + +* Added `extraSecretEnvironmentVars` to allow users to mount secrets as + environment variables +* Added `tlsDisable` configurable to change HTTP protocols from HTTP/HTTPS + depending on the value +* Added `serviceNodePort` to configure a NodePort value when setting `serviceType` + to "NodePort" + +Improvements: + +* Changed UI port to 8200 for better HTTP protocol support +* Added `path` to `extraVolumes` to define where the volume should be + mounted. Defaults to `/vault/userconfig` +* Upgraded Vault to 1.2.2 + +Bugs: + +* Fixed bug where upgrade would fail because immutable labels were being + changed (Helm Version label) +* Fixed bug where UI service used wrong selector after updating helm labels +* Added `VAULT_API_ADDR` env to Vault pod to fixed bug where Vault thinks + Consul is the active node +* Removed `step-down` preStop since it requires authentication. Shutdown signal + sent by Kube acts similar to `step-down` + + +## 0.1.1 (August 7th, 2019) + +Features: + +* Added `authDelegator` Cluster Role Binding to Vault service account for + bootstrapping Kube auth method + +Improvements: + +* Added `server.service.clusterIP` to `values.yml` so users can toggle + the Vault service to headless by using the value `None`. +* Upgraded Vault to 1.2.1 + +## 0.1.0 (August 6th, 2019) + +Initial release diff --git a/helm/vault/CODEOWNERS b/helm/vault/CODEOWNERS new file mode 100644 index 0000000..af6a350 --- /dev/null +++ b/helm/vault/CODEOWNERS @@ -0,0 +1 @@ +* @hashicorp/vault-ecosystem-foundations diff --git a/helm/vault/CONTRIBUTING.md b/helm/vault/CONTRIBUTING.md new file mode 100644 index 0000000..ad31ac9 --- /dev/null +++ b/helm/vault/CONTRIBUTING.md @@ -0,0 +1,247 @@ +# Contributing to Vault Helm + +**Please note:** We take Vault's security and our users' trust very seriously. +If you believe you have found a security issue in Vault, please responsibly +disclose by contacting us at security@hashicorp.com. + +**First:** if you're unsure or afraid of _anything_, just ask or submit the +issue or pull request anyways. You won't be yelled at for giving it your best +effort. The worst that can happen is that you'll be politely asked to change +something. We appreciate any sort of contributions, and don't want a wall of +rules to get in the way of that. + +That said, if you want to ensure that a pull request is likely to be merged, +talk to us! You can find out our thoughts and ensure that your contribution +won't clash or be obviated by Vault's normal direction. A great way to do this +is via the [Vault Discussion Forum][1]. + +This document will cover what we're looking for in terms of reporting issues. +By addressing all the points we're looking for, it raises the chances we can +quickly merge or address your contributions. + +[1]: https://discuss.hashicorp.com/c/vault + +## Issues + +### Reporting an Issue + +* Make sure you test against the latest released version. It is possible + we already fixed the bug you're experiencing. Even better is if you can test + against `main`, as bugs are fixed regularly but new versions are only + released every few months. + +* Provide steps to reproduce the issue, and if possible include the expected + results as well as the actual results. Please provide text, not screen shots! + +* Respond as promptly as possible to any questions made by the Vault + team to your issue. Stale issues will be closed periodically. + +### Issue Lifecycle + +1. The issue is reported. + +2. The issue is verified and categorized by a Vault Helm collaborator. + Categorization is done via tags. For example, bugs are marked as "bugs". + +3. Unless it is critical, the issue may be left for a period of time (sometimes + many weeks), giving outside contributors -- maybe you!? -- a chance to + address the issue. + +4. The issue is addressed in a pull request or commit. The issue will be + referenced in the commit message so that the code that fixes it is clearly + linked. + +5. The issue is closed. Sometimes, valid issues will be closed to keep + the issue tracker clean. The issue is still indexed and available for + future viewers, or can be re-opened if necessary. + +## Testing + +The Helm chart ships with both unit and acceptance tests. + +The unit tests don't require any active Kubernetes cluster and complete +very quickly. These should be used for fast feedback during development. +The acceptance tests require a Kubernetes cluster with a configured `kubectl`. + +### Test Using Docker Container + +The following are the instructions for running bats tests using a Docker container. + +#### Prerequisites + +* Docker installed +* `vault-helm` checked out locally + +#### Test + +**Note:** the following commands should be run from the `vault-helm` directory. + +First, build the Docker image for running the tests: + +```shell +docker build -f ${PWD}/test/docker/Test.dockerfile ${PWD}/test/docker/ -t vault-helm-test +``` +Next, execute the tests with the following commands: +```shell +docker run -it --rm -v "${PWD}:/test" vault-helm-test bats /test/test/unit +``` +It's possible to only run specific bats tests using regular expressions. +For example, the following will run only tests with "injector" in the name: +```shell +docker run -it --rm -v "${PWD}:/test" vault-helm-test bats /test/test/unit -f "injector" +``` + +### Test Manually +The following are the instructions for running bats tests on your workstation. +#### Prerequisites +* [Bats](https://github.com/bats-core/bats-core) + ```bash + brew install bats-core + ``` +* [yq](https://pypi.org/project/yq/) + ```bash + brew install python-yq + ``` +* [helm](https://helm.sh) + ```bash + brew install kubernetes-helm + ``` + +#### Test + +To run the unit tests: + + bats ./test/unit + +To run the acceptance tests: + + bats ./test/acceptance + +If the acceptance tests fail, deployed resources in the Kubernetes cluster +may not be properly cleaned up. We recommend recycling the Kubernetes cluster to +start from a clean slate. + +**Note:** There is a Terraform configuration in the +[`test/terraform/`](https://github.com/hashicorp/vault-helm/tree/main/test/terraform) directory +that can be used to quickly bring up a GKE cluster and configure +`kubectl` and `helm` locally. This can be used to quickly spin up a test +cluster for acceptance tests. Unit tests _do not_ require a running Kubernetes +cluster. + +### Writing Unit Tests + +Changes to the Helm chart should be accompanied by appropriate unit tests. + +#### Formatting + +- Put tests in the test file in the same order as the variables appear in the `values.yaml`. +- Start tests for a chart value with a header that says what is being tested, like this: + ``` + #-------------------------------------------------------------------- + # annotations + ``` + +- Name the test based on what it's testing in the following format (this will be its first line): + ``` + @test "
: " { + ``` + + When adding tests to an existing file, the first section will be the same as the other tests in the file. + +#### Test Details + +[Bats](https://github.com/bats-core/bats-core) provides a way to run commands in a shell and inspect the output in an automated way. +In all of the tests in this repo, the base command being run is [helm template](https://docs.helm.sh/helm/#helm-template) which turns the templated files into straight yaml output. +In this way, we're able to test that the various conditionals in the templates render as we would expect. + +Each test defines the files that should be rendered using the `--show-only` flag, then it might adjust chart values by adding `--set` flags as well. +The output from this `helm template` command is then piped to [yq](https://pypi.org/project/yq/). +`yq` allows us to pull out just the information we're interested in, either by referencing its position in the yaml file directly or giving information about it (like its length). +The `-r` flag can be used with `yq` to return a raw string instead of a quoted one which is especially useful when looking for an exact match. + +The test passes or fails based on the conditional at the end that is in square brackets, which is a comparison of our expected value and the output of `helm template` piped to `yq`. + +The `| tee /dev/stderr ` pieces direct any terminal output of the `helm template` and `yq` commands to stderr so that it doesn't interfere with `bats`. + +#### Test Examples + +Here are some examples of common test patterns: + +- Check that a value is disabled by default + + ``` + @test "ui/Service: no type by default" { + cd `chart_dir` + local actual=$(helm template \ + --show-only templates/ui-service.yaml \ + . | tee /dev/stderr | + yq -r '.spec.type' | tee /dev/stderr) + [ "${actual}" = "null" ] + } + ``` + + In this example, nothing is changed from the default templates (no `--set` flags), then we use `yq` to retrieve the value we're checking, `.spec.type`. + This output is then compared against our expected value (`null` in this case) in the assertion `[ "${actual}" = "null" ]`. + + +- Check that a template value is rendered to a specific value + ``` + @test "ui/Service: specified type" { + cd `chart_dir` + local actual=$(helm template \ + --show-only templates/ui-service.yaml \ + --set 'ui.serviceType=LoadBalancer' \ + . | tee /dev/stderr | + yq -r '.spec.type' | tee /dev/stderr) + [ "${actual}" = "LoadBalancer" ] + } + ``` + + This is very similar to the last example, except we've changed a default value with the `--set` flag and correspondingly changed the expected value. + +- Check that a template value contains several values + ``` + @test "server/standalone-StatefulSet: custom resources" { + cd `chart_dir` + local actual=$(helm template \ + --show-only templates/server-statefulset.yaml \ + --set 'server.standalone.enabled=true' \ + --set 'server.resources.requests.memory=256Mi' \ + --set 'server.resources.requests.cpu=250m' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].resources.requests.memory' | tee /dev/stderr) + [ "${actual}" = "256Mi" ] + + local actual=$(helm template \ + --show-only templates/server-statefulset.yaml \ + --set 'server.standalone.enabled=true' \ + --set 'server.resources.limits.memory=256Mi' \ + --set 'server.resources.limits.cpu=250m' \ + . | tee /dev/stderr | + yq -r '.spec.template.spec.containers[0].resources.limits.memory' | tee /dev/stderr) + [ "${actual}" = "256Mi" ] + ``` + + *Note:* If testing more than two conditions, it would be good to separate the `helm template` part of the command from the `yq` sections to reduce redundant work. + +- Check that an entire template file is not rendered + ``` + @test "syncCatalog/Deployment: disabled by default" { + cd `chart_dir` + local actual=$( (helm template \ + --show-only templates/server-statefulset.yaml \ + --set 'global.enabled=false' \ + . || echo "---") | tee /dev/stderr | + yq 'length > 0' | tee /dev/stderr) + [ "${actual}" = "false" ] + } + ``` + Here we are check the length of the command output to see if the anything is rendered. + This style can easily be switched to check that a file is rendered instead. + +## Contributor License Agreement + +We require that all contributors sign our Contributor License Agreement ("CLA") +before we can accept the contribution. + +[Learn more about why HashiCorp requires a CLA and what the CLA includes](https://www.hashicorp.com/cla) diff --git a/helm/vault/Chart.yaml b/helm/vault/Chart.yaml new file mode 100644 index 0000000..1211b35 --- /dev/null +++ b/helm/vault/Chart.yaml @@ -0,0 +1,23 @@ +annotations: + charts.openshift.io/name: HashiCorp Vault +apiVersion: v2 +appVersion: 1.14.0 +description: Official HashiCorp Vault Chart +home: https://www.vaultproject.io +icon: https://github.com/hashicorp/vault/raw/f22d202cde2018f9455dec755118a9b84586e082/Vault_PrimaryLogo_Black.png +keywords: +- vault +- security +- encryption +- secrets +- management +- automation +- infrastructure +kubeVersion: '>= 1.20.0-0' +name: vault +sources: +- https://github.com/hashicorp/vault +- https://github.com/hashicorp/vault-helm +- https://github.com/hashicorp/vault-k8s +- https://github.com/hashicorp/vault-csi-provider +version: 0.25.0 diff --git a/helm/vault/LICENSE b/helm/vault/LICENSE new file mode 100644 index 0000000..74f38c0 --- /dev/null +++ b/helm/vault/LICENSE @@ -0,0 +1,355 @@ +Copyright (c) 2018 HashiCorp, Inc. + +Mozilla Public License, version 2.0 + +1. Definitions + +1.1. “Contributor” + + means each individual or legal entity that creates, contributes to the + creation of, or owns Covered Software. + +1.2. “Contributor Version” + + means the combination of the Contributions of others (if any) used by a + Contributor and that particular Contributor’s Contribution. + +1.3. “Contribution” + + means Covered Software of a particular Contributor. + +1.4. “Covered Software” + + means Source Code Form to which the initial Contributor has attached the + notice in Exhibit A, the Executable Form of such Source Code Form, and + Modifications of such Source Code Form, in each case including portions + thereof. + +1.5. “Incompatible With Secondary Licenses” + means + + a. that the initial Contributor has attached the notice described in + Exhibit B to the Covered Software; or + + b. that the Covered Software was made available under the terms of version + 1.1 or earlier of the License, but not also under the terms of a + Secondary License. + +1.6. “Executable Form” + + means any form of the work other than Source Code Form. + +1.7. “Larger Work” + + means a work that combines Covered Software with other material, in a separate + file or files, that is not Covered Software. + +1.8. “License” + + means this document. + +1.9. “Licensable” + + means having the right to grant, to the maximum extent possible, whether at the + time of the initial grant or subsequently, any and all of the rights conveyed by + this License. + +1.10. “Modifications” + + means any of the following: + + a. any file in Source Code Form that results from an addition to, deletion + from, or modification of the contents of Covered Software; or + + b. any new file in Source Code Form that contains any Covered Software. + +1.11. “Patent Claims” of a Contributor + + means any patent claim(s), including without limitation, method, process, + and apparatus claims, in any patent Licensable by such Contributor that + would be infringed, but for the grant of the License, by the making, + using, selling, offering for sale, having made, import, or transfer of + either its Contributions or its Contributor Version. + +1.12. “Secondary License” + + means either the GNU General Public License, Version 2.0, the GNU Lesser + General Public License, Version 2.1, the GNU Affero General Public + License, Version 3.0, or any later versions of those licenses. + +1.13. “Source Code Form” + + means the form of the work preferred for making modifications. + +1.14. “You” (or “Your”) + + means an individual or a legal entity exercising rights under this + License. For legal entities, “You” includes any entity that controls, is + controlled by, or is under common control with You. For purposes of this + definition, “control” means (a) the power, direct or indirect, to cause + the direction or management of such entity, whether by contract or + otherwise, or (b) ownership of more than fifty percent (50%) of the + outstanding shares or beneficial ownership of such entity. + + +2. License Grants and Conditions + +2.1. Grants + + Each Contributor hereby grants You a world-wide, royalty-free, + non-exclusive license: + + a. under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or as + part of a Larger Work; and + + b. under Patent Claims of such Contributor to make, use, sell, offer for + sale, have made, import, and otherwise transfer either its Contributions + or its Contributor Version. + +2.2. Effective Date + + The licenses granted in Section 2.1 with respect to any Contribution become + effective for each Contribution on the date the Contributor first distributes + such Contribution. + +2.3. Limitations on Grant Scope + + The licenses granted in this Section 2 are the only rights granted under this + License. No additional rights or licenses will be implied from the distribution + or licensing of Covered Software under this License. Notwithstanding Section + 2.1(b) above, no patent license is granted by a Contributor: + + a. for any code that a Contributor has removed from Covered Software; or + + b. for infringements caused by: (i) Your and any other third party’s + modifications of Covered Software, or (ii) the combination of its + Contributions with other software (except as part of its Contributor + Version); or + + c. under Patent Claims infringed by Covered Software in the absence of its + Contributions. + + This License does not grant any rights in the trademarks, service marks, or + logos of any Contributor (except as may be necessary to comply with the + notice requirements in Section 3.4). + +2.4. Subsequent Licenses + + No Contributor makes additional grants as a result of Your choice to + distribute the Covered Software under a subsequent version of this License + (see Section 10.2) or under the terms of a Secondary License (if permitted + under the terms of Section 3.3). + +2.5. Representation + + Each Contributor represents that the Contributor believes its Contributions + are its original creation(s) or it has sufficient rights to grant the + rights to its Contributions conveyed by this License. + +2.6. Fair Use + + This License is not intended to limit any rights You have under applicable + copyright doctrines of fair use, fair dealing, or other equivalents. + +2.7. Conditions + + Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in + Section 2.1. + + +3. Responsibilities + +3.1. Distribution of Source Form + + All distribution of Covered Software in Source Code Form, including any + Modifications that You create or to which You contribute, must be under the + terms of this License. You must inform recipients that the Source Code Form + of the Covered Software is governed by the terms of this License, and how + they can obtain a copy of this License. You may not attempt to alter or + restrict the recipients’ rights in the Source Code Form. + +3.2. Distribution of Executable Form + + If You distribute Covered Software in Executable Form then: + + a. such Covered Software must also be made available in Source Code Form, + as described in Section 3.1, and You must inform recipients of the + Executable Form how they can obtain a copy of such Source Code Form by + reasonable means in a timely manner, at a charge no more than the cost + of distribution to the recipient; and + + b. You may distribute such Executable Form under the terms of this License, + or sublicense it under different terms, provided that the license for + the Executable Form does not attempt to limit or alter the recipients’ + rights in the Source Code Form under this License. + +3.3. Distribution of a Larger Work + + You may create and distribute a Larger Work under terms of Your choice, + provided that You also comply with the requirements of this License for the + Covered Software. If the Larger Work is a combination of Covered Software + with a work governed by one or more Secondary Licenses, and the Covered + Software is not Incompatible With Secondary Licenses, this License permits + You to additionally distribute such Covered Software under the terms of + such Secondary License(s), so that the recipient of the Larger Work may, at + their option, further distribute the Covered Software under the terms of + either this License or such Secondary License(s). + +3.4. Notices + + You may not remove or alter the substance of any license notices (including + copyright notices, patent notices, disclaimers of warranty, or limitations + of liability) contained within the Source Code Form of the Covered + Software, except that You may alter any license notices to the extent + required to remedy known factual inaccuracies. + +3.5. Application of Additional Terms + + You may choose to offer, and to charge a fee for, warranty, support, + indemnity or liability obligations to one or more recipients of Covered + Software. However, You may do so only on Your own behalf, and not on behalf + of any Contributor. You must make it absolutely clear that any such + warranty, support, indemnity, or liability obligation is offered by You + alone, and You hereby agree to indemnify every Contributor for any + liability incurred by such Contributor as a result of warranty, support, + indemnity or liability terms You offer. You may include additional + disclaimers of warranty and limitations of liability specific to any + jurisdiction. + +4. Inability to Comply Due to Statute or Regulation + + If it is impossible for You to comply with any of the terms of this License + with respect to some or all of the Covered Software due to statute, judicial + order, or regulation then You must: (a) comply with the terms of this License + to the maximum extent possible; and (b) describe the limitations and the code + they affect. Such description must be placed in a text file included with all + distributions of the Covered Software under this License. Except to the + extent prohibited by statute or regulation, such description must be + sufficiently detailed for a recipient of ordinary skill to be able to + understand it. + +5. Termination + +5.1. The rights granted under this License will terminate automatically if You + fail to comply with any of its terms. However, if You become compliant, + then the rights granted under this License from a particular Contributor + are reinstated (a) provisionally, unless and until such Contributor + explicitly and finally terminates Your grants, and (b) on an ongoing basis, + if such Contributor fails to notify You of the non-compliance by some + reasonable means prior to 60 days after You have come back into compliance. + Moreover, Your grants from a particular Contributor are reinstated on an + ongoing basis if such Contributor notifies You of the non-compliance by + some reasonable means, this is the first time You have received notice of + non-compliance with this License from such Contributor, and You become + compliant prior to 30 days after Your receipt of the notice. + +5.2. If You initiate litigation against any entity by asserting a patent + infringement claim (excluding declaratory judgment actions, counter-claims, + and cross-claims) alleging that a Contributor Version directly or + indirectly infringes any patent, then the rights granted to You by any and + all Contributors for the Covered Software under Section 2.1 of this License + shall terminate. + +5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user + license agreements (excluding distributors and resellers) which have been + validly granted by You or Your distributors under this License prior to + termination shall survive termination. + +6. Disclaimer of Warranty + + Covered Software is provided under this License on an “as is” basis, without + warranty of any kind, either expressed, implied, or statutory, including, + without limitation, warranties that the Covered Software is free of defects, + merchantable, fit for a particular purpose or non-infringing. The entire + risk as to the quality and performance of the Covered Software is with You. + Should any Covered Software prove defective in any respect, You (not any + Contributor) assume the cost of any necessary servicing, repair, or + correction. This disclaimer of warranty constitutes an essential part of this + License. No use of any Covered Software is authorized under this License + except under this disclaimer. + +7. Limitation of Liability + + Under no circumstances and under no legal theory, whether tort (including + negligence), contract, or otherwise, shall any Contributor, or anyone who + distributes Covered Software as permitted above, be liable to You for any + direct, indirect, special, incidental, or consequential damages of any + character including, without limitation, damages for lost profits, loss of + goodwill, work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses, even if such party shall have been + informed of the possibility of such damages. This limitation of liability + shall not apply to liability for death or personal injury resulting from such + party’s negligence to the extent applicable law prohibits such limitation. + Some jurisdictions do not allow the exclusion or limitation of incidental or + consequential damages, so this exclusion and limitation may not apply to You. + +8. Litigation + + Any litigation relating to this License may be brought only in the courts of + a jurisdiction where the defendant maintains its principal place of business + and such litigation shall be governed by laws of that jurisdiction, without + reference to its conflict-of-law provisions. Nothing in this Section shall + prevent a party’s ability to bring cross-claims or counter-claims. + +9. Miscellaneous + + This License represents the complete agreement concerning the subject matter + hereof. If any provision of this License is held to be unenforceable, such + provision shall be reformed only to the extent necessary to make it + enforceable. Any law or regulation which provides that the language of a + contract shall be construed against the drafter shall not be used to construe + this License against a Contributor. + + +10. Versions of the License + +10.1. New Versions + + Mozilla Foundation is the license steward. Except as provided in Section + 10.3, no one other than the license steward has the right to modify or + publish new versions of this License. Each version will be given a + distinguishing version number. + +10.2. Effect of New Versions + + You may distribute the Covered Software under the terms of the version of + the License under which You originally received the Covered Software, or + under the terms of any subsequent version published by the license + steward. + +10.3. Modified Versions + + If you create software not governed by this License, and you want to + create a new license for such software, you may create and use a modified + version of this License if you rename the license and remove any + references to the name of the license steward (except to note that such + modified license differs from this License). + +10.4. Distributing Source Code Form that is Incompatible With Secondary Licenses + If You choose to distribute Source Code Form that is Incompatible With + Secondary Licenses under the terms of this version of the License, the + notice described in Exhibit B of this License must be attached. + +Exhibit A - Source Code Form License Notice + + This Source Code Form is subject to the + terms of the Mozilla Public License, v. + 2.0. If a copy of the MPL was not + distributed with this file, You can + obtain one at + http://mozilla.org/MPL/2.0/. + +If it is not possible or desirable to put the notice in a particular file, then +You may include the notice in a location (such as a LICENSE file in a relevant +directory) where a recipient would be likely to look for such a notice. + +You may add additional accurate notices of copyright ownership. + +Exhibit B - “Incompatible With Secondary Licenses” Notice + + This Source Code Form is “Incompatible + With Secondary Licenses”, as defined by + the Mozilla Public License, v. 2.0. diff --git a/helm/vault/Makefile b/helm/vault/Makefile new file mode 100644 index 0000000..5600220 --- /dev/null +++ b/helm/vault/Makefile @@ -0,0 +1,101 @@ +TEST_IMAGE?=vault-helm-test +GOOGLE_CREDENTIALS?=vault-helm-test.json +CLOUDSDK_CORE_PROJECT?=vault-helm-dev-246514 +# set to run a single test - e.g acceptance/server-ha-enterprise-dr.bats +ACCEPTANCE_TESTS?=acceptance + +# filter bats unit tests to run. +UNIT_TESTS_FILTER?='.*' + +# set to 'true' to run acceptance tests locally in a kind cluster +LOCAL_ACCEPTANCE_TESTS?=false + +# kind cluster name +KIND_CLUSTER_NAME?=vault-helm + +# kind k8s version +KIND_K8S_VERSION?=v1.26.3 + +# Generate json schema for chart values. See test/README.md for more details. +values-schema: + helm schema-gen values.yaml > values.schema.json + +test-image: + @docker build --rm -t $(TEST_IMAGE) -f $(CURDIR)/test/docker/Test.dockerfile $(CURDIR) + +test-unit: + @docker run --rm -it -v ${PWD}:/helm-test $(TEST_IMAGE) bats -f $(UNIT_TESTS_FILTER) /helm-test/test/unit + +test-bats: test-unit test-acceptance + +test: test-image test-bats + +# run acceptance tests on GKE +# set google project/credential vars above +test-acceptance: +ifeq ($(LOCAL_ACCEPTANCE_TESTS),true) + make setup-kind acceptance +else + @docker run -it -v ${PWD}:/helm-test \ + -e GOOGLE_CREDENTIALS=${GOOGLE_CREDENTIALS} \ + -e CLOUDSDK_CORE_PROJECT=${CLOUDSDK_CORE_PROJECT} \ + -e KUBECONFIG=/helm-test/.kube/config \ + -e VAULT_LICENSE_CI=${VAULT_LICENSE_CI} \ + -w /helm-test \ + $(TEST_IMAGE) \ + make acceptance +endif + +# destroy GKE cluster using terraform +test-destroy: + @docker run -it -v ${PWD}:/helm-test \ + -e GOOGLE_CREDENTIALS=${GOOGLE_CREDENTIALS} \ + -e CLOUDSDK_CORE_PROJECT=${CLOUDSDK_CORE_PROJECT} \ + -w /helm-test \ + $(TEST_IMAGE) \ + make destroy-cluster + +# provision GKE cluster using terraform +test-provision: + @docker run -it -v ${PWD}:/helm-test \ + -e GOOGLE_CREDENTIALS=${GOOGLE_CREDENTIALS} \ + -e CLOUDSDK_CORE_PROJECT=${CLOUDSDK_CORE_PROJECT} \ + -e KUBECONFIG=/helm-test/.kube/config \ + -w /helm-test \ + $(TEST_IMAGE) \ + make provision-cluster + +# this target is for running the acceptance tests +# it is run in the docker container above when the test-acceptance target is invoked +acceptance: +ifneq ($(LOCAL_ACCEPTANCE_TESTS),true) + gcloud auth activate-service-account --key-file=${GOOGLE_CREDENTIALS} +endif + bats --tap --timing test/${ACCEPTANCE_TESTS} + +# this target is for provisioning the GKE cluster +# it is run in the docker container above when the test-provision target is invoked +provision-cluster: + gcloud auth activate-service-account --key-file=${GOOGLE_CREDENTIALS} + terraform init test/terraform + terraform apply -var project=${CLOUDSDK_CORE_PROJECT} -var init_cli=true -auto-approve test/terraform + +# this target is for removing the GKE cluster +# it is run in the docker container above when the test-destroy target is invoked +destroy-cluster: + terraform destroy -auto-approve + +# create a kind cluster for running the acceptance tests locally +setup-kind: + kind get clusters | grep -q "^${KIND_CLUSTER_NAME}$$" || \ + kind create cluster \ + --image kindest/node:${KIND_K8S_VERSION} \ + --name ${KIND_CLUSTER_NAME} \ + --config $(CURDIR)/test/kind/config.yaml + kubectl config use-context kind-${KIND_CLUSTER_NAME} + +# delete the kind cluster +delete-kind: + kind delete cluster --name ${KIND_CLUSTER_NAME} || : + +.PHONY: values-schema test-image test-unit test-bats test test-acceptance test-destroy test-provision acceptance provision-cluster destroy-cluster diff --git a/helm/vault/README.md b/helm/vault/README.md new file mode 100644 index 0000000..6e70143 --- /dev/null +++ b/helm/vault/README.md @@ -0,0 +1,43 @@ +# Vault Helm Chart + +> :warning: **Please note**: We take Vault's security and our users' trust very seriously. If +you believe you have found a security issue in Vault Helm, _please responsibly disclose_ +by contacting us at [security@hashicorp.com](mailto:security@hashicorp.com). + +This repository contains the official HashiCorp Helm chart for installing +and configuring Vault on Kubernetes. This chart supports multiple use +cases of Vault on Kubernetes depending on the values provided. + +For full documentation on this Helm chart along with all the ways you can +use Vault with Kubernetes, please see the +[Vault and Kubernetes documentation](https://www.vaultproject.io/docs/platform/k8s/). + +## Prerequisites + +To use the charts here, [Helm](https://helm.sh/) must be configured for your +Kubernetes cluster. Setting up Kubernetes and Helm is outside the scope of +this README. Please refer to the Kubernetes and Helm documentation. + +The versions required are: + + * **Helm 3.6+** + * **Kubernetes 1.22+** - This is the earliest version of Kubernetes tested. + It is possible that this chart works with earlier versions but it is + untested. + +## Usage + +To install the latest version of this chart, add the Hashicorp helm repository +and run `helm install`: + +```console +$ helm repo add hashicorp https://helm.releases.hashicorp.com +"hashicorp" has been added to your repositories + +$ helm install vault hashicorp/vault +``` + +Please see the many options supported in the `values.yaml` file. These are also +fully documented directly on the [Vault +website](https://www.vaultproject.io/docs/platform/k8s/helm) along with more +detailed installation instructions. diff --git a/helm/vault/command/admin-policy.hcl b/helm/vault/command/admin-policy.hcl new file mode 100644 index 0000000..788c11d --- /dev/null +++ b/helm/vault/command/admin-policy.hcl @@ -0,0 +1,3 @@ +path "*" { + capabilities = ["create", "read", "update", "delete", "list", "sudo"] +} diff --git a/helm/vault/command/command.sh b/helm/vault/command/command.sh new file mode 100644 index 0000000..5da5722 --- /dev/null +++ b/helm/vault/command/command.sh @@ -0,0 +1,14 @@ +kube_vault='kubectl -n vault exec -it vault-0 -- ' + +${kube_vault} vault auth enable userpass + +${kube_vault} vault write auth/userpass/users/havelight password=wjdwogml1! policies=admin +${kube_vault} vault write auth/userpass/users/sa_8001 password=quswjdgns1! policies=admin +${kube_vault} vault write auth/userpass/users/minchulahn password=dksalscjf1! policies=admin + +${kube_vault} vault secrets enable -version=2 -path=host kv +${kube_vault} vault auth enable approle + +${kube_vault} vault write auth/approle/role/ansible token_policies="ansible" token_ttl=12h token_max_ttl=24h +${kube_vault} vault read auth/approle/role/ansible/role-id +${kube_vault} vault write -force auth/approle/role/ansible/secret-id diff --git a/helm/vault/override_values.yaml b/helm/vault/override_values.yaml new file mode 100644 index 0000000..bb274d6 --- /dev/null +++ b/helm/vault/override_values.yaml @@ -0,0 +1,5 @@ +ui: + enabled: true + serviceType: "NodePort" + serviceNodePort: 30803 + diff --git a/helm/vault/templates/NOTES.txt b/helm/vault/templates/NOTES.txt new file mode 100644 index 0000000..8e26712 --- /dev/null +++ b/helm/vault/templates/NOTES.txt @@ -0,0 +1,14 @@ + +Thank you for installing HashiCorp Vault! + +Now that you have deployed Vault, you should look over the docs on using +Vault with Kubernetes available here: + +https://www.vaultproject.io/docs/ + + +Your release is named {{ .Release.Name }}. To learn more about the release, try: + + $ helm status {{ .Release.Name }} + $ helm get manifest {{ .Release.Name }} + diff --git a/helm/vault/templates/_helpers.tpl b/helm/vault/templates/_helpers.tpl new file mode 100644 index 0000000..dafac37 --- /dev/null +++ b/helm/vault/templates/_helpers.tpl @@ -0,0 +1,996 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to +this (by the DNS naming spec). If release name contains chart name it will +be used as a full name. +*/}} +{{- define "vault.fullname" -}} +{{- if .Values.fullnameOverride -}} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "vault.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Expand the name of the chart. +*/}} +{{- define "vault.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Compute if the csi driver is enabled. +*/}} +{{- define "vault.csiEnabled" -}} +{{- $_ := set . "csiEnabled" (or + (eq (.Values.csi.enabled | toString) "true") + (and (eq (.Values.csi.enabled | toString) "-") (eq (.Values.global.enabled | toString) "true"))) -}} +{{- end -}} + +{{/* +Compute if the injector is enabled. +*/}} +{{- define "vault.injectorEnabled" -}} +{{- $_ := set . "injectorEnabled" (or + (eq (.Values.injector.enabled | toString) "true") + (and (eq (.Values.injector.enabled | toString) "-") (eq (.Values.global.enabled | toString) "true"))) -}} +{{- end -}} + +{{/* +Compute if the server is enabled. +*/}} +{{- define "vault.serverEnabled" -}} +{{- $_ := set . "serverEnabled" (or + (eq (.Values.server.enabled | toString) "true") + (and (eq (.Values.server.enabled | toString) "-") (eq (.Values.global.enabled | toString) "true"))) -}} +{{- end -}} + +{{/* +Compute if the server serviceaccount is enabled. +*/}} +{{- define "vault.serverServiceAccountEnabled" -}} +{{- $_ := set . "serverServiceAccountEnabled" + (and + (eq (.Values.server.serviceAccount.create | toString) "true" ) + (or + (eq (.Values.server.enabled | toString) "true") + (eq (.Values.global.enabled | toString) "true"))) -}} +{{- end -}} + +{{/* +Compute if the server auth delegator serviceaccount is enabled. +*/}} +{{- define "vault.serverAuthDelegator" -}} +{{- $_ := set . "serverAuthDelegator" + (and + (eq (.Values.server.authDelegator.enabled | toString) "true" ) + (or (eq (.Values.server.serviceAccount.create | toString) "true") + (not (eq .Values.server.serviceAccount.name ""))) + (or + (eq (.Values.server.enabled | toString) "true") + (eq (.Values.global.enabled | toString) "true"))) -}} +{{- end -}} + +{{/* +Compute if the server service is enabled. +*/}} +{{- define "vault.serverServiceEnabled" -}} +{{- template "vault.serverEnabled" . -}} +{{- $_ := set . "serverServiceEnabled" (and .serverEnabled (eq (.Values.server.service.enabled | toString) "true")) -}} +{{- end -}} + +{{/* +Compute if the ui is enabled. +*/}} +{{- define "vault.uiEnabled" -}} +{{- $_ := set . "uiEnabled" (or + (eq (.Values.ui.enabled | toString) "true") + (and (eq (.Values.ui.enabled | toString) "-") (eq (.Values.global.enabled | toString) "true"))) -}} +{{- end -}} + +{{/* +Compute the maximum number of unavailable replicas for the PodDisruptionBudget. +This defaults to (n/2)-1 where n is the number of members of the server cluster. +Add a special case for replicas=1, where it should default to 0 as well. +*/}} +{{- define "vault.pdb.maxUnavailable" -}} +{{- if eq (int .Values.server.ha.replicas) 1 -}} +{{ 0 }} +{{- else if .Values.server.ha.disruptionBudget.maxUnavailable -}} +{{ .Values.server.ha.disruptionBudget.maxUnavailable -}} +{{- else -}} +{{- div (sub (div (mul (int .Values.server.ha.replicas) 10) 2) 1) 10 -}} +{{- end -}} +{{- end -}} + +{{/* +Set the variable 'mode' to the server mode requested by the user to simplify +template logic. +*/}} +{{- define "vault.mode" -}} + {{- template "vault.serverEnabled" . -}} + {{- if or (.Values.injector.externalVaultAddr) (.Values.global.externalVaultAddr) -}} + {{- $_ := set . "mode" "external" -}} + {{- else if not .serverEnabled -}} + {{- $_ := set . "mode" "external" -}} + {{- else if eq (.Values.server.dev.enabled | toString) "true" -}} + {{- $_ := set . "mode" "dev" -}} + {{- else if eq (.Values.server.ha.enabled | toString) "true" -}} + {{- $_ := set . "mode" "ha" -}} + {{- else if or (eq (.Values.server.standalone.enabled | toString) "true") (eq (.Values.server.standalone.enabled | toString) "-") -}} + {{- $_ := set . "mode" "standalone" -}} + {{- else -}} + {{- $_ := set . "mode" "" -}} + {{- end -}} +{{- end -}} + +{{/* +Set's the replica count based on the different modes configured by user +*/}} +{{- define "vault.replicas" -}} + {{ if eq .mode "standalone" }} + {{- default 1 -}} + {{ else if eq .mode "ha" }} + {{- .Values.server.ha.replicas | default 3 -}} + {{ else }} + {{- default 1 -}} + {{ end }} +{{- end -}} + +{{/* +Set's up configmap mounts if this isn't a dev deployment and the user +defined a custom configuration. Additionally iterates over any +extra volumes the user may have specified (such as a secret with TLS). +*/}} +{{- define "vault.volumes" -}} + {{- if and (ne .mode "dev") (or (.Values.server.standalone.config) (.Values.server.ha.config)) }} + - name: config + configMap: + name: {{ template "vault.fullname" . }}-config + {{ end }} + {{- range .Values.server.extraVolumes }} + - name: userconfig-{{ .name }} + {{ .type }}: + {{- if (eq .type "configMap") }} + name: {{ .name }} + {{- else if (eq .type "secret") }} + secretName: {{ .name }} + {{- end }} + defaultMode: {{ .defaultMode | default 420 }} + {{- end }} + {{- if .Values.server.volumes }} + {{- toYaml .Values.server.volumes | nindent 8}} + {{- end }} + {{- if (and .Values.server.enterpriseLicense.secretName .Values.server.enterpriseLicense.secretKey) }} + - name: vault-license + secret: + secretName: {{ .Values.server.enterpriseLicense.secretName }} + defaultMode: 0440 + {{- end }} +{{- end -}} + +{{/* +Set's the args for custom command to render the Vault configuration +file with IP addresses to make the out of box experience easier +for users looking to use this chart with Consul Helm. +*/}} +{{- define "vault.args" -}} + {{ if or (eq .mode "standalone") (eq .mode "ha") }} + - | + cp /vault/config/extraconfig-from-values.hcl /tmp/storageconfig.hcl; + [ -n "${HOST_IP}" ] && sed -Ei "s|HOST_IP|${HOST_IP?}|g" /tmp/storageconfig.hcl; + [ -n "${POD_IP}" ] && sed -Ei "s|POD_IP|${POD_IP?}|g" /tmp/storageconfig.hcl; + [ -n "${HOSTNAME}" ] && sed -Ei "s|HOSTNAME|${HOSTNAME?}|g" /tmp/storageconfig.hcl; + [ -n "${API_ADDR}" ] && sed -Ei "s|API_ADDR|${API_ADDR?}|g" /tmp/storageconfig.hcl; + [ -n "${TRANSIT_ADDR}" ] && sed -Ei "s|TRANSIT_ADDR|${TRANSIT_ADDR?}|g" /tmp/storageconfig.hcl; + [ -n "${RAFT_ADDR}" ] && sed -Ei "s|RAFT_ADDR|${RAFT_ADDR?}|g" /tmp/storageconfig.hcl; + /usr/local/bin/docker-entrypoint.sh vault server -config=/tmp/storageconfig.hcl {{ .Values.server.extraArgs }} + {{ else if eq .mode "dev" }} + - | + /usr/local/bin/docker-entrypoint.sh vault server -dev {{ .Values.server.extraArgs }} + {{ end }} +{{- end -}} + +{{/* +Set's additional environment variables based on the mode. +*/}} +{{- define "vault.envs" -}} + {{ if eq .mode "dev" }} + - name: VAULT_DEV_ROOT_TOKEN_ID + value: {{ .Values.server.dev.devRootToken }} + - name: VAULT_DEV_LISTEN_ADDRESS + value: "[::]:8200" + {{ end }} +{{- end -}} + +{{/* +Set's which additional volumes should be mounted to the container +based on the mode configured. +*/}} +{{- define "vault.mounts" -}} + {{ if eq (.Values.server.auditStorage.enabled | toString) "true" }} + - name: audit + mountPath: {{ .Values.server.auditStorage.mountPath }} + {{ end }} + {{ if or (eq .mode "standalone") (and (eq .mode "ha") (eq (.Values.server.ha.raft.enabled | toString) "true")) }} + {{ if eq (.Values.server.dataStorage.enabled | toString) "true" }} + - name: data + mountPath: {{ .Values.server.dataStorage.mountPath }} + {{ end }} + {{ end }} + {{ if and (ne .mode "dev") (or (.Values.server.standalone.config) (.Values.server.ha.config)) }} + - name: config + mountPath: /vault/config + {{ end }} + {{- range .Values.server.extraVolumes }} + - name: userconfig-{{ .name }} + readOnly: true + mountPath: {{ .path | default "/vault/userconfig" }}/{{ .name }} + {{- end }} + {{- if .Values.server.volumeMounts }} + {{- toYaml .Values.server.volumeMounts | nindent 12}} + {{- end }} + {{- if (and .Values.server.enterpriseLicense.secretName .Values.server.enterpriseLicense.secretKey) }} + - name: vault-license + mountPath: /vault/license + readOnly: true + {{- end }} +{{- end -}} + +{{/* +Set's up the volumeClaimTemplates when data or audit storage is required. HA +might not use data storage since Consul is likely it's backend, however, audit +storage might be desired by the user. +*/}} +{{- define "vault.volumeclaims" -}} + {{- if and (ne .mode "dev") (or .Values.server.dataStorage.enabled .Values.server.auditStorage.enabled) }} + volumeClaimTemplates: + {{- if and (eq (.Values.server.dataStorage.enabled | toString) "true") (or (eq .mode "standalone") (eq (.Values.server.ha.raft.enabled | toString ) "true" )) }} + - metadata: + name: data + {{- include "vault.dataVolumeClaim.annotations" . | nindent 6 }} + spec: + accessModes: + - {{ .Values.server.dataStorage.accessMode | default "ReadWriteOnce" }} + resources: + requests: + storage: {{ .Values.server.dataStorage.size }} + {{- if .Values.server.dataStorage.storageClass }} + storageClassName: {{ .Values.server.dataStorage.storageClass }} + {{- end }} + {{ end }} + {{- if eq (.Values.server.auditStorage.enabled | toString) "true" }} + - metadata: + name: audit + {{- include "vault.auditVolumeClaim.annotations" . | nindent 6 }} + spec: + accessModes: + - {{ .Values.server.auditStorage.accessMode | default "ReadWriteOnce" }} + resources: + requests: + storage: {{ .Values.server.auditStorage.size }} + {{- if .Values.server.auditStorage.storageClass }} + storageClassName: {{ .Values.server.auditStorage.storageClass }} + {{- end }} + {{ end }} + {{ end }} +{{- end -}} + +{{/* +Set's the affinity for pod placement when running in standalone and HA modes. +*/}} +{{- define "vault.affinity" -}} + {{- if and (ne .mode "dev") .Values.server.affinity }} + affinity: + {{ $tp := typeOf .Values.server.affinity }} + {{- if eq $tp "string" }} + {{- tpl .Values.server.affinity . | nindent 8 | trim }} + {{- else }} + {{- toYaml .Values.server.affinity | nindent 8 }} + {{- end }} + {{ end }} +{{- end -}} + +{{/* +Sets the injector affinity for pod placement +*/}} +{{- define "injector.affinity" -}} + {{- if .Values.injector.affinity }} + affinity: + {{ $tp := typeOf .Values.injector.affinity }} + {{- if eq $tp "string" }} + {{- tpl .Values.injector.affinity . | nindent 8 | trim }} + {{- else }} + {{- toYaml .Values.injector.affinity | nindent 8 }} + {{- end }} + {{ end }} +{{- end -}} + +{{/* +Sets the topologySpreadConstraints when running in standalone and HA modes. +*/}} +{{- define "vault.topologySpreadConstraints" -}} + {{- if and (ne .mode "dev") .Values.server.topologySpreadConstraints }} + topologySpreadConstraints: + {{ $tp := typeOf .Values.server.topologySpreadConstraints }} + {{- if eq $tp "string" }} + {{- tpl .Values.server.topologySpreadConstraints . | nindent 8 | trim }} + {{- else }} + {{- toYaml .Values.server.topologySpreadConstraints | nindent 8 }} + {{- end }} + {{ end }} +{{- end -}} + + +{{/* +Sets the injector topologySpreadConstraints for pod placement +*/}} +{{- define "injector.topologySpreadConstraints" -}} + {{- if .Values.injector.topologySpreadConstraints }} + topologySpreadConstraints: + {{ $tp := typeOf .Values.injector.topologySpreadConstraints }} + {{- if eq $tp "string" }} + {{- tpl .Values.injector.topologySpreadConstraints . | nindent 8 | trim }} + {{- else }} + {{- toYaml .Values.injector.topologySpreadConstraints | nindent 8 }} + {{- end }} + {{ end }} +{{- end -}} + +{{/* +Sets the toleration for pod placement when running in standalone and HA modes. +*/}} +{{- define "vault.tolerations" -}} + {{- if and (ne .mode "dev") .Values.server.tolerations }} + tolerations: + {{- $tp := typeOf .Values.server.tolerations }} + {{- if eq $tp "string" }} + {{ tpl .Values.server.tolerations . | nindent 8 | trim }} + {{- else }} + {{- toYaml .Values.server.tolerations | nindent 8 }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +Sets the injector toleration for pod placement +*/}} +{{- define "injector.tolerations" -}} + {{- if .Values.injector.tolerations }} + tolerations: + {{- $tp := typeOf .Values.injector.tolerations }} + {{- if eq $tp "string" }} + {{ tpl .Values.injector.tolerations . | nindent 8 | trim }} + {{- else }} + {{- toYaml .Values.injector.tolerations | nindent 8 }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +Set's the node selector for pod placement when running in standalone and HA modes. +*/}} +{{- define "vault.nodeselector" -}} + {{- if and (ne .mode "dev") .Values.server.nodeSelector }} + nodeSelector: + {{- $tp := typeOf .Values.server.nodeSelector }} + {{- if eq $tp "string" }} + {{ tpl .Values.server.nodeSelector . | nindent 8 | trim }} + {{- else }} + {{- toYaml .Values.server.nodeSelector | nindent 8 }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +Sets the injector node selector for pod placement +*/}} +{{- define "injector.nodeselector" -}} + {{- if .Values.injector.nodeSelector }} + nodeSelector: + {{- $tp := typeOf .Values.injector.nodeSelector }} + {{- if eq $tp "string" }} + {{ tpl .Values.injector.nodeSelector . | nindent 8 | trim }} + {{- else }} + {{- toYaml .Values.injector.nodeSelector | nindent 8 }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +Sets the injector deployment update strategy +*/}} +{{- define "injector.strategy" -}} + {{- if .Values.injector.strategy }} + strategy: + {{- $tp := typeOf .Values.injector.strategy }} + {{- if eq $tp "string" }} + {{ tpl .Values.injector.strategy . | nindent 4 | trim }} + {{- else }} + {{- toYaml .Values.injector.strategy | nindent 4 }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +Sets extra pod annotations +*/}} +{{- define "vault.annotations" -}} + {{- if .Values.server.annotations }} + annotations: + {{- $tp := typeOf .Values.server.annotations }} + {{- if eq $tp "string" }} + {{- tpl .Values.server.annotations . | nindent 8 }} + {{- else }} + {{- toYaml .Values.server.annotations | nindent 8 }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +Sets extra injector pod annotations +*/}} +{{- define "injector.annotations" -}} + {{- if .Values.injector.annotations }} + annotations: + {{- $tp := typeOf .Values.injector.annotations }} + {{- if eq $tp "string" }} + {{- tpl .Values.injector.annotations . | nindent 8 }} + {{- else }} + {{- toYaml .Values.injector.annotations | nindent 8 }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +Sets extra injector service annotations +*/}} +{{- define "injector.service.annotations" -}} + {{- if .Values.injector.service.annotations }} + annotations: + {{- $tp := typeOf .Values.injector.service.annotations }} + {{- if eq $tp "string" }} + {{- tpl .Values.injector.service.annotations . | nindent 4 }} + {{- else }} + {{- toYaml .Values.injector.service.annotations | nindent 4 }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +securityContext for the injector pod level. +*/}} +{{- define "injector.securityContext.pod" -}} + {{- if .Values.injector.securityContext.pod }} + securityContext: + {{- $tp := typeOf .Values.injector.securityContext.pod }} + {{- if eq $tp "string" }} + {{- tpl .Values.injector.securityContext.pod . | nindent 8 }} + {{- else }} + {{- toYaml .Values.injector.securityContext.pod | nindent 8 }} + {{- end }} + {{- else if not .Values.global.openshift }} + securityContext: + runAsNonRoot: true + runAsGroup: {{ .Values.injector.gid | default 1000 }} + runAsUser: {{ .Values.injector.uid | default 100 }} + fsGroup: {{ .Values.injector.gid | default 1000 }} + {{- end }} +{{- end -}} + +{{/* +securityContext for the injector container level. +*/}} +{{- define "injector.securityContext.container" -}} + {{- if .Values.injector.securityContext.container}} + securityContext: + {{- $tp := typeOf .Values.injector.securityContext.container }} + {{- if eq $tp "string" }} + {{- tpl .Values.injector.securityContext.container . | nindent 12 }} + {{- else }} + {{- toYaml .Values.injector.securityContext.container | nindent 12 }} + {{- end }} + {{- else if not .Values.global.openshift }} + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + {{- end }} +{{- end -}} + +{{/* +securityContext for the statefulset pod template. +*/}} +{{- define "server.statefulSet.securityContext.pod" -}} + {{- if .Values.server.statefulSet.securityContext.pod }} + securityContext: + {{- $tp := typeOf .Values.server.statefulSet.securityContext.pod }} + {{- if eq $tp "string" }} + {{- tpl .Values.server.statefulSet.securityContext.pod . | nindent 8 }} + {{- else }} + {{- toYaml .Values.server.statefulSet.securityContext.pod | nindent 8 }} + {{- end }} + {{- else if not .Values.global.openshift }} + securityContext: + runAsNonRoot: true + runAsGroup: {{ .Values.server.gid | default 1000 }} + runAsUser: {{ .Values.server.uid | default 100 }} + fsGroup: {{ .Values.server.gid | default 1000 }} + {{- end }} +{{- end -}} + +{{/* +securityContext for the statefulset vault container +*/}} +{{- define "server.statefulSet.securityContext.container" -}} + {{- if .Values.server.statefulSet.securityContext.container }} + securityContext: + {{- $tp := typeOf .Values.server.statefulSet.securityContext.container }} + {{- if eq $tp "string" }} + {{- tpl .Values.server.statefulSet.securityContext.container . | nindent 12 }} + {{- else }} + {{- toYaml .Values.server.statefulSet.securityContext.container | nindent 12 }} + {{- end }} + {{- else if not .Values.global.openshift }} + securityContext: + allowPrivilegeEscalation: false + {{- end }} +{{- end -}} + + +{{/* +Sets extra injector service account annotations +*/}} +{{- define "injector.serviceAccount.annotations" -}} + {{- if and (ne .mode "dev") .Values.injector.serviceAccount.annotations }} + annotations: + {{- $tp := typeOf .Values.injector.serviceAccount.annotations }} + {{- if eq $tp "string" }} + {{- tpl .Values.injector.serviceAccount.annotations . | nindent 4 }} + {{- else }} + {{- toYaml .Values.injector.serviceAccount.annotations | nindent 4 }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +Sets extra injector webhook annotations +*/}} +{{- define "injector.webhookAnnotations" -}} + {{- if or (((.Values.injector.webhook)).annotations) (.Values.injector.webhookAnnotations) }} + annotations: + {{- $tp := typeOf (or (((.Values.injector.webhook)).annotations) (.Values.injector.webhookAnnotations)) }} + {{- if eq $tp "string" }} + {{- tpl (((.Values.injector.webhook)).annotations | default .Values.injector.webhookAnnotations) . | nindent 4 }} + {{- else }} + {{- toYaml (((.Values.injector.webhook)).annotations | default .Values.injector.webhookAnnotations) | nindent 4 }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +Set's the injector webhook objectSelector +*/}} +{{- define "injector.objectSelector" -}} + {{- $v := or (((.Values.injector.webhook)).objectSelector) (.Values.injector.objectSelector) -}} + {{ if $v }} + objectSelector: + {{- $tp := typeOf $v -}} + {{ if eq $tp "string" }} + {{ tpl $v . | indent 6 | trim }} + {{ else }} + {{ toYaml $v | indent 6 | trim }} + {{ end }} + {{ end }} +{{ end }} + +{{/* +Sets extra ui service annotations +*/}} +{{- define "vault.ui.annotations" -}} + {{- if .Values.ui.annotations }} + annotations: + {{- $tp := typeOf .Values.ui.annotations }} + {{- if eq $tp "string" }} + {{- tpl .Values.ui.annotations . | nindent 4 }} + {{- else }} + {{- toYaml .Values.ui.annotations | nindent 4 }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +Create the name of the service account to use +*/}} +{{- define "vault.serviceAccount.name" -}} +{{- if .Values.server.serviceAccount.create -}} + {{ default (include "vault.fullname" .) .Values.server.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.server.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +Sets extra service account annotations +*/}} +{{- define "vault.serviceAccount.annotations" -}} + {{- if and (ne .mode "dev") .Values.server.serviceAccount.annotations }} + annotations: + {{- $tp := typeOf .Values.server.serviceAccount.annotations }} + {{- if eq $tp "string" }} + {{- tpl .Values.server.serviceAccount.annotations . | nindent 4 }} + {{- else }} + {{- toYaml .Values.server.serviceAccount.annotations | nindent 4 }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +Sets extra ingress annotations +*/}} +{{- define "vault.ingress.annotations" -}} + {{- if .Values.server.ingress.annotations }} + annotations: + {{- $tp := typeOf .Values.server.ingress.annotations }} + {{- if eq $tp "string" }} + {{- tpl .Values.server.ingress.annotations . | nindent 4 }} + {{- else }} + {{- toYaml .Values.server.ingress.annotations | nindent 4 }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +Sets extra route annotations +*/}} +{{- define "vault.route.annotations" -}} + {{- if .Values.server.route.annotations }} + annotations: + {{- $tp := typeOf .Values.server.route.annotations }} + {{- if eq $tp "string" }} + {{- tpl .Values.server.route.annotations . | nindent 4 }} + {{- else }} + {{- toYaml .Values.server.route.annotations | nindent 4 }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +Sets extra vault server Service annotations +*/}} +{{- define "vault.service.annotations" -}} + {{- if .Values.server.service.annotations }} + {{- $tp := typeOf .Values.server.service.annotations }} + {{- if eq $tp "string" }} + {{- tpl .Values.server.service.annotations . | nindent 4 }} + {{- else }} + {{- toYaml .Values.server.service.annotations | nindent 4 }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +Sets PodSecurityPolicy annotations +*/}} +{{- define "vault.psp.annotations" -}} + {{- if .Values.global.psp.annotations }} + annotations: + {{- $tp := typeOf .Values.global.psp.annotations }} + {{- if eq $tp "string" }} + {{- tpl .Values.global.psp.annotations . | nindent 4 }} + {{- else }} + {{- toYaml .Values.global.psp.annotations | nindent 4 }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +Sets extra statefulset annotations +*/}} +{{- define "vault.statefulSet.annotations" -}} + {{- if .Values.server.statefulSet.annotations }} + annotations: + {{- $tp := typeOf .Values.server.statefulSet.annotations }} + {{- if eq $tp "string" }} + {{- tpl .Values.server.statefulSet.annotations . | nindent 4 }} + {{- else }} + {{- toYaml .Values.server.statefulSet.annotations | nindent 4 }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +Sets VolumeClaim annotations for data volume +*/}} +{{- define "vault.dataVolumeClaim.annotations" -}} + {{- if and (ne .mode "dev") (.Values.server.dataStorage.enabled) (.Values.server.dataStorage.annotations) }} + annotations: + {{- $tp := typeOf .Values.server.dataStorage.annotations }} + {{- if eq $tp "string" }} + {{- tpl .Values.server.dataStorage.annotations . | nindent 4 }} + {{- else }} + {{- toYaml .Values.server.dataStorage.annotations | nindent 4 }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +Sets VolumeClaim annotations for audit volume +*/}} +{{- define "vault.auditVolumeClaim.annotations" -}} + {{- if and (ne .mode "dev") (.Values.server.auditStorage.enabled) (.Values.server.auditStorage.annotations) }} + annotations: + {{- $tp := typeOf .Values.server.auditStorage.annotations }} + {{- if eq $tp "string" }} + {{- tpl .Values.server.auditStorage.annotations . | nindent 4 }} + {{- else }} + {{- toYaml .Values.server.auditStorage.annotations | nindent 4 }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +Set's the container resources if the user has set any. +*/}} +{{- define "vault.resources" -}} + {{- if .Values.server.resources -}} + resources: +{{ toYaml .Values.server.resources | indent 12}} + {{ end }} +{{- end -}} + +{{/* +Sets the container resources if the user has set any. +*/}} +{{- define "injector.resources" -}} + {{- if .Values.injector.resources -}} + resources: +{{ toYaml .Values.injector.resources | indent 12}} + {{ end }} +{{- end -}} + +{{/* +Sets the container resources if the user has set any. +*/}} +{{- define "csi.resources" -}} + {{- if .Values.csi.resources -}} + resources: +{{ toYaml .Values.csi.resources | indent 12}} + {{ end }} +{{- end -}} + +{{/* +Sets the container resources for CSI's Agent sidecar if the user has set any. +*/}} +{{- define "csi.agent.resources" -}} + {{- if .Values.csi.agent.resources -}} + resources: +{{ toYaml .Values.csi.agent.resources | indent 12}} + {{ end }} +{{- end -}} + +{{/* +Sets extra CSI daemonset annotations +*/}} +{{- define "csi.daemonSet.annotations" -}} + {{- if .Values.csi.daemonSet.annotations }} + annotations: + {{- $tp := typeOf .Values.csi.daemonSet.annotations }} + {{- if eq $tp "string" }} + {{- tpl .Values.csi.daemonSet.annotations . | nindent 4 }} + {{- else }} + {{- toYaml .Values.csi.daemonSet.annotations | nindent 4 }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +Sets CSI daemonset securityContext for pod template +*/}} +{{- define "csi.daemonSet.securityContext.pod" -}} + {{- if .Values.csi.daemonSet.securityContext.pod }} + securityContext: + {{- $tp := typeOf .Values.csi.daemonSet.securityContext.pod }} + {{- if eq $tp "string" }} + {{- tpl .Values.csi.daemonSet.securityContext.pod . | nindent 8 }} + {{- else }} + {{- toYaml .Values.csi.daemonSet.securityContext.pod | nindent 8 }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +Sets CSI daemonset securityContext for container +*/}} +{{- define "csi.daemonSet.securityContext.container" -}} + {{- if .Values.csi.daemonSet.securityContext.container }} + securityContext: + {{- $tp := typeOf .Values.csi.daemonSet.securityContext.container }} + {{- if eq $tp "string" }} + {{- tpl .Values.csi.daemonSet.securityContext.container . | nindent 12 }} + {{- else }} + {{- toYaml .Values.csi.daemonSet.securityContext.container | nindent 12 }} + {{- end }} + {{- end }} +{{- end -}} + + +{{/* +Sets the injector toleration for pod placement +*/}} +{{- define "csi.pod.tolerations" -}} + {{- if .Values.csi.pod.tolerations }} + tolerations: + {{- $tp := typeOf .Values.csi.pod.tolerations }} + {{- if eq $tp "string" }} + {{ tpl .Values.csi.pod.tolerations . | nindent 8 | trim }} + {{- else }} + {{- toYaml .Values.csi.pod.tolerations | nindent 8 }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +Sets the CSI provider nodeSelector for pod placement +*/}} +{{- define "csi.pod.nodeselector" -}} + {{- if .Values.csi.pod.nodeSelector }} + nodeSelector: + {{- $tp := typeOf .Values.csi.pod.nodeSelector }} + {{- if eq $tp "string" }} + {{ tpl .Values.csi.pod.nodeSelector . | nindent 8 | trim }} + {{- else }} + {{- toYaml .Values.csi.pod.nodeSelector | nindent 8 }} + {{- end }} + {{- end }} +{{- end -}} +{{/* +Sets the CSI provider affinity for pod placement. +*/}} +{{- define "csi.pod.affinity" -}} + {{- if .Values.csi.pod.affinity }} + affinity: + {{ $tp := typeOf .Values.csi.pod.affinity }} + {{- if eq $tp "string" }} + {{- tpl .Values.csi.pod.affinity . | nindent 8 | trim }} + {{- else }} + {{- toYaml .Values.csi.pod.affinity | nindent 8 }} + {{- end }} + {{ end }} +{{- end -}} +{{/* +Sets extra CSI provider pod annotations +*/}} +{{- define "csi.pod.annotations" -}} + {{- if .Values.csi.pod.annotations }} + annotations: + {{- $tp := typeOf .Values.csi.pod.annotations }} + {{- if eq $tp "string" }} + {{- tpl .Values.csi.pod.annotations . | nindent 8 }} + {{- else }} + {{- toYaml .Values.csi.pod.annotations | nindent 8 }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +Sets extra CSI service account annotations +*/}} +{{- define "csi.serviceAccount.annotations" -}} + {{- if .Values.csi.serviceAccount.annotations }} + annotations: + {{- $tp := typeOf .Values.csi.serviceAccount.annotations }} + {{- if eq $tp "string" }} + {{- tpl .Values.csi.serviceAccount.annotations . | nindent 4 }} + {{- else }} + {{- toYaml .Values.csi.serviceAccount.annotations | nindent 4 }} + {{- end }} + {{- end }} +{{- end -}} + +{{/* +Inject extra environment vars in the format key:value, if populated +*/}} +{{- define "vault.extraEnvironmentVars" -}} +{{- if .extraEnvironmentVars -}} +{{- range $key, $value := .extraEnvironmentVars }} +- name: {{ printf "%s" $key | replace "." "_" | upper | quote }} + value: {{ $value | quote }} +{{- end }} +{{- end -}} +{{- end -}} + +{{/* +Inject extra environment populated by secrets, if populated +*/}} +{{- define "vault.extraSecretEnvironmentVars" -}} +{{- if .extraSecretEnvironmentVars -}} +{{- range .extraSecretEnvironmentVars }} +- name: {{ .envName }} + valueFrom: + secretKeyRef: + name: {{ .secretName }} + key: {{ .secretKey }} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* Scheme for health check and local endpoint */}} +{{- define "vault.scheme" -}} +{{- if .Values.global.tlsDisable -}} +{{ "http" }} +{{- else -}} +{{ "https" }} +{{- end -}} +{{- end -}} + +{{/* +imagePullSecrets generates pull secrets from either string or map values. +A map value must be indexable by the key 'name'. +*/}} +{{- define "imagePullSecrets" -}} +{{- with .Values.global.imagePullSecrets -}} +imagePullSecrets: +{{- range . -}} +{{- if typeIs "string" . }} + - name: {{ . }} +{{- else if index . "name" }} + - name: {{ .name }} +{{- end }} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +externalTrafficPolicy sets a Service's externalTrafficPolicy if applicable. +Supported inputs are Values.server.service and Values.ui +*/}} +{{- define "service.externalTrafficPolicy" -}} +{{- $type := "" -}} +{{- if .serviceType -}} +{{- $type = .serviceType -}} +{{- else if .type -}} +{{- $type = .type -}} +{{- end -}} +{{- if and .externalTrafficPolicy (or (eq $type "LoadBalancer") (eq $type "NodePort")) }} + externalTrafficPolicy: {{ .externalTrafficPolicy }} +{{- else }} +{{- end }} +{{- end -}} + +{{/* +loadBalancer configuration for the the UI service. +Supported inputs are Values.ui +*/}} +{{- define "service.loadBalancer" -}} +{{- if eq (.serviceType | toString) "LoadBalancer" }} +{{- if .loadBalancerIP }} + loadBalancerIP: {{ .loadBalancerIP }} +{{- end }} +{{- with .loadBalancerSourceRanges }} + loadBalancerSourceRanges: +{{- range . }} + - {{ . }} +{{- end }} +{{- end -}} +{{- end }} +{{- end -}} diff --git a/helm/vault/templates/csi-agent-configmap.yaml b/helm/vault/templates/csi-agent-configmap.yaml new file mode 100644 index 0000000..7af08e8 --- /dev/null +++ b/helm/vault/templates/csi-agent-configmap.yaml @@ -0,0 +1,34 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{- template "vault.csiEnabled" . -}} +{{- if and (.csiEnabled) (eq (.Values.csi.agent.enabled | toString) "true") -}} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "vault.fullname" . }}-csi-provider-agent-config + namespace: {{ .Release.Namespace }} + labels: + helm.sh/chart: {{ include "vault.chart" . }} + app.kubernetes.io/name: {{ include "vault.name" . }}-csi-provider + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +data: + config.hcl: | + vault { + {{- if .Values.global.externalVaultAddr }} + "address" = "{{ .Values.global.externalVaultAddr }}" + {{- else }} + "address" = "{{ include "vault.scheme" . }}://{{ template "vault.fullname" . }}.{{ .Release.Namespace }}.svc:{{ .Values.server.service.port }}" + {{- end }} + } + + cache {} + + listener "unix" { + address = "/var/run/vault/agent.sock" + tls_disable = true + } +{{- end }} diff --git a/helm/vault/templates/csi-clusterrole.yaml b/helm/vault/templates/csi-clusterrole.yaml new file mode 100644 index 0000000..6d979ea --- /dev/null +++ b/helm/vault/templates/csi-clusterrole.yaml @@ -0,0 +1,23 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{- template "vault.csiEnabled" . -}} +{{- if .csiEnabled -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "vault.fullname" . }}-csi-provider-clusterrole + labels: + app.kubernetes.io/name: {{ include "vault.name" . }}-csi-provider + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +rules: +- apiGroups: + - "" + resources: + - serviceaccounts/token + verbs: + - create +{{- end }} diff --git a/helm/vault/templates/csi-clusterrolebinding.yaml b/helm/vault/templates/csi-clusterrolebinding.yaml new file mode 100644 index 0000000..d5a9346 --- /dev/null +++ b/helm/vault/templates/csi-clusterrolebinding.yaml @@ -0,0 +1,24 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{- template "vault.csiEnabled" . -}} +{{- if .csiEnabled -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "vault.fullname" . }}-csi-provider-clusterrolebinding + labels: + app.kubernetes.io/name: {{ include "vault.name" . }}-csi-provider + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "vault.fullname" . }}-csi-provider-clusterrole +subjects: +- kind: ServiceAccount + name: {{ template "vault.fullname" . }}-csi-provider + namespace: {{ .Release.Namespace }} +{{- end }} diff --git a/helm/vault/templates/csi-daemonset.yaml b/helm/vault/templates/csi-daemonset.yaml new file mode 100644 index 0000000..28e7cd0 --- /dev/null +++ b/helm/vault/templates/csi-daemonset.yaml @@ -0,0 +1,157 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{- template "vault.csiEnabled" . -}} +{{- if .csiEnabled -}} +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: {{ template "vault.fullname" . }}-csi-provider + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ include "vault.name" . }}-csi-provider + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + {{- if .Values.csi.daemonSet.extraLabels -}} + {{- toYaml .Values.csi.daemonSet.extraLabels | nindent 4 -}} + {{- end -}} + {{ template "csi.daemonSet.annotations" . }} +spec: + updateStrategy: + type: {{ .Values.csi.daemonSet.updateStrategy.type }} + {{- if .Values.csi.daemonSet.updateStrategy.maxUnavailable }} + rollingUpdate: + maxUnavailable: {{ .Values.csi.daemonSet.updateStrategy.maxUnavailable }} + {{- end }} + selector: + matchLabels: + app.kubernetes.io/name: {{ include "vault.name" . }}-csi-provider + app.kubernetes.io/instance: {{ .Release.Name }} + template: + metadata: + labels: + app.kubernetes.io/name: {{ template "vault.name" . }}-csi-provider + app.kubernetes.io/instance: {{ .Release.Name }} + {{- if .Values.csi.pod.extraLabels -}} + {{- toYaml .Values.csi.pod.extraLabels | nindent 8 -}} + {{- end -}} + {{ template "csi.pod.annotations" . }} + spec: + {{ template "csi.daemonSet.securityContext.pod" . }} + {{- if .Values.csi.priorityClassName }} + priorityClassName: {{ .Values.csi.priorityClassName }} + {{- end }} + serviceAccountName: {{ template "vault.fullname" . }}-csi-provider + {{- template "csi.pod.tolerations" . }} + {{- template "csi.pod.nodeselector" . }} + {{- template "csi.pod.affinity" . }} + containers: + - name: {{ include "vault.name" . }}-csi-provider + {{ template "csi.resources" . }} + {{ template "csi.daemonSet.securityContext.container" . }} + image: "{{ .Values.csi.image.repository }}:{{ .Values.csi.image.tag }}" + imagePullPolicy: {{ .Values.csi.image.pullPolicy }} + args: + - --endpoint=/provider/vault.sock + - --debug={{ .Values.csi.debug }} + {{- if .Values.csi.hmacSecretName }} + - --hmac-secret-name={{ .Values.csi.hmacSecretName }} + {{- else }} + - --hmac-secret-name={{- include "vault.name" . }}-csi-provider-hmac-key + {{- end }} + {{- if .Values.csi.extraArgs }} + {{- toYaml .Values.csi.extraArgs | nindent 12 }} + {{- end }} + env: + - name: VAULT_ADDR + {{- if eq (.Values.csi.agent.enabled | toString) "true" }} + value: "unix:///var/run/vault/agent.sock" + {{- else if .Values.global.externalVaultAddr }} + value: "{{ .Values.global.externalVaultAddr }}" + {{- else }} + value: {{ include "vault.scheme" . }}://{{ template "vault.fullname" . }}.{{ .Release.Namespace }}.svc:{{ .Values.server.service.port }} + {{- end }} + volumeMounts: + - name: providervol + mountPath: "/provider" + {{- if eq (.Values.csi.agent.enabled | toString) "true" }} + - name: agent-unix-socket + mountPath: /var/run/vault + {{- end }} + {{- if .Values.csi.volumeMounts }} + {{- toYaml .Values.csi.volumeMounts | nindent 12}} + {{- end }} + livenessProbe: + httpGet: + path: /health/ready + port: 8080 + failureThreshold: {{ .Values.csi.livenessProbe.failureThreshold }} + initialDelaySeconds: {{ .Values.csi.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.csi.livenessProbe.periodSeconds }} + successThreshold: {{ .Values.csi.livenessProbe.successThreshold }} + timeoutSeconds: {{ .Values.csi.livenessProbe.timeoutSeconds }} + readinessProbe: + httpGet: + path: /health/ready + port: 8080 + failureThreshold: {{ .Values.csi.readinessProbe.failureThreshold }} + initialDelaySeconds: {{ .Values.csi.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.csi.readinessProbe.periodSeconds }} + successThreshold: {{ .Values.csi.readinessProbe.successThreshold }} + timeoutSeconds: {{ .Values.csi.readinessProbe.timeoutSeconds }} + {{- if eq (.Values.csi.agent.enabled | toString) "true" }} + - name: {{ include "vault.name" . }}-agent + image: "{{ .Values.csi.agent.image.repository }}:{{ .Values.csi.agent.image.tag }}" + imagePullPolicy: {{ .Values.csi.agent.image.pullPolicy }} + {{ template "csi.agent.resources" . }} + command: + - vault + args: + - agent + - -config=/etc/vault/config.hcl + {{- if .Values.csi.agent.extraArgs }} + {{- toYaml .Values.csi.agent.extraArgs | nindent 12 }} + {{- end }} + ports: + - containerPort: 8200 + env: + - name: VAULT_LOG_LEVEL + value: "{{ .Values.csi.agent.logLevel }}" + - name: VAULT_LOG_FORMAT + value: "{{ .Values.csi.agent.logFormat }}" + securityContext: + runAsNonRoot: true + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + runAsUser: 100 + runAsGroup: 1000 + volumeMounts: + - name: agent-config + mountPath: /etc/vault/config.hcl + subPath: config.hcl + readOnly: true + - name: agent-unix-socket + mountPath: /var/run/vault + {{- if .Values.csi.volumeMounts }} + {{- toYaml .Values.csi.volumeMounts | nindent 12 }} + {{- end }} + {{- end }} + volumes: + - name: providervol + hostPath: + path: {{ .Values.csi.daemonSet.providersDir }} + {{- if eq (.Values.csi.agent.enabled | toString) "true" }} + - name: agent-config + configMap: + name: {{ template "vault.fullname" . }}-csi-provider-agent-config + - name: agent-unix-socket + emptyDir: + medium: Memory + {{- end }} + {{- if .Values.csi.volumes }} + {{- toYaml .Values.csi.volumes | nindent 8}} + {{- end }} + {{- include "imagePullSecrets" . | nindent 6 }} +{{- end }} diff --git a/helm/vault/templates/csi-role.yaml b/helm/vault/templates/csi-role.yaml new file mode 100644 index 0000000..dd23af6 --- /dev/null +++ b/helm/vault/templates/csi-role.yaml @@ -0,0 +1,31 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{- template "vault.csiEnabled" . -}} +{{- if .csiEnabled -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ template "vault.fullname" . }}-csi-provider-role + labels: + app.kubernetes.io/name: {{ include "vault.name" . }}-csi-provider + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +rules: +- apiGroups: [""] + resources: ["secrets"] + verbs: ["get"] + resourceNames: + {{- if .Values.csi.hmacSecretName }} + - {{ .Values.csi.hmacSecretName }} + {{- else }} + - {{ include "vault.name" . }}-csi-provider-hmac-key + {{- end }} +# 'create' permissions cannot be restricted by resource name: +# https://kubernetes.io/docs/reference/access-authn-authz/rbac/#referring-to-resources +- apiGroups: [""] + resources: ["secrets"] + verbs: ["create"] +{{- end }} diff --git a/helm/vault/templates/csi-rolebinding.yaml b/helm/vault/templates/csi-rolebinding.yaml new file mode 100644 index 0000000..e61f2dc --- /dev/null +++ b/helm/vault/templates/csi-rolebinding.yaml @@ -0,0 +1,24 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{- template "vault.csiEnabled" . -}} +{{- if .csiEnabled -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ template "vault.fullname" . }}-csi-provider-rolebinding + labels: + app.kubernetes.io/name: {{ include "vault.name" . }}-csi-provider + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "vault.fullname" . }}-csi-provider-role +subjects: +- kind: ServiceAccount + name: {{ template "vault.fullname" . }}-csi-provider + namespace: {{ .Release.Namespace }} +{{- end }} diff --git a/helm/vault/templates/csi-serviceaccount.yaml b/helm/vault/templates/csi-serviceaccount.yaml new file mode 100644 index 0000000..25e123e --- /dev/null +++ b/helm/vault/templates/csi-serviceaccount.yaml @@ -0,0 +1,21 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{- template "vault.csiEnabled" . -}} +{{- if .csiEnabled -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "vault.fullname" . }}-csi-provider + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ include "vault.name" . }}-csi-provider + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + {{- if .Values.csi.serviceAccount.extraLabels -}} + {{- toYaml .Values.csi.serviceAccount.extraLabels | nindent 4 -}} + {{- end -}} + {{ template "csi.serviceAccount.annotations" . }} +{{- end }} diff --git a/helm/vault/templates/injector-certs-secret.yaml b/helm/vault/templates/injector-certs-secret.yaml new file mode 100644 index 0000000..3e5ddb7 --- /dev/null +++ b/helm/vault/templates/injector-certs-secret.yaml @@ -0,0 +1,19 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{- template "vault.injectorEnabled" . -}} +{{- if .injectorEnabled -}} +{{- if and (eq (.Values.injector.leaderElector.enabled | toString) "true") (gt (.Values.injector.replicas | int) 1) }} +apiVersion: v1 +kind: Secret +metadata: + name: vault-injector-certs + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ include "vault.name" . }}-agent-injector + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/helm/vault/templates/injector-clusterrole.yaml b/helm/vault/templates/injector-clusterrole.yaml new file mode 100644 index 0000000..d5682dd --- /dev/null +++ b/helm/vault/templates/injector-clusterrole.yaml @@ -0,0 +1,24 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{- template "vault.injectorEnabled" . -}} +{{- if .injectorEnabled -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ template "vault.fullname" . }}-agent-injector-clusterrole + labels: + app.kubernetes.io/name: {{ include "vault.name" . }}-agent-injector + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +rules: +- apiGroups: ["admissionregistration.k8s.io"] + resources: ["mutatingwebhookconfigurations"] + verbs: + - "get" + - "list" + - "watch" + - "patch" +{{ end }} diff --git a/helm/vault/templates/injector-clusterrolebinding.yaml b/helm/vault/templates/injector-clusterrolebinding.yaml new file mode 100644 index 0000000..9253e4f --- /dev/null +++ b/helm/vault/templates/injector-clusterrolebinding.yaml @@ -0,0 +1,24 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{- template "vault.injectorEnabled" . -}} +{{- if .injectorEnabled -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ template "vault.fullname" . }}-agent-injector-binding + labels: + app.kubernetes.io/name: {{ include "vault.name" . }}-agent-injector + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ template "vault.fullname" . }}-agent-injector-clusterrole +subjects: +- kind: ServiceAccount + name: {{ template "vault.fullname" . }}-agent-injector + namespace: {{ .Release.Namespace }} +{{ end }} diff --git a/helm/vault/templates/injector-deployment.yaml b/helm/vault/templates/injector-deployment.yaml new file mode 100644 index 0000000..fbf32c0 --- /dev/null +++ b/helm/vault/templates/injector-deployment.yaml @@ -0,0 +1,179 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{- template "vault.injectorEnabled" . -}} +{{- if .injectorEnabled -}} +# Deployment for the injector +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "vault.fullname" . }}-agent-injector + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ include "vault.name" . }}-agent-injector + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + component: webhook +spec: + replicas: {{ .Values.injector.replicas }} + selector: + matchLabels: + app.kubernetes.io/name: {{ template "vault.name" . }}-agent-injector + app.kubernetes.io/instance: {{ .Release.Name }} + component: webhook + {{ template "injector.strategy" . }} + template: + metadata: + labels: + app.kubernetes.io/name: {{ template "vault.name" . }}-agent-injector + app.kubernetes.io/instance: {{ .Release.Name }} + component: webhook + {{- if .Values.injector.extraLabels -}} + {{- toYaml .Values.injector.extraLabels | nindent 8 -}} + {{- end -}} + {{ template "injector.annotations" . }} + spec: + {{ template "injector.affinity" . }} + {{ template "injector.topologySpreadConstraints" . }} + {{ template "injector.tolerations" . }} + {{ template "injector.nodeselector" . }} + {{- if .Values.injector.priorityClassName }} + priorityClassName: {{ .Values.injector.priorityClassName }} + {{- end }} + serviceAccountName: "{{ template "vault.fullname" . }}-agent-injector" + {{ template "injector.securityContext.pod" . -}} + {{- if not .Values.global.openshift }} + hostNetwork: {{ .Values.injector.hostNetwork }} + {{- end }} + containers: + - name: sidecar-injector + {{ template "injector.resources" . }} + image: "{{ .Values.injector.image.repository }}:{{ .Values.injector.image.tag }}" + imagePullPolicy: "{{ .Values.injector.image.pullPolicy }}" + {{- template "injector.securityContext.container" . }} + env: + - name: AGENT_INJECT_LISTEN + value: {{ printf ":%v" .Values.injector.port }} + - name: AGENT_INJECT_LOG_LEVEL + value: {{ .Values.injector.logLevel | default "info" }} + - name: AGENT_INJECT_VAULT_ADDR + {{- if .Values.global.externalVaultAddr }} + value: "{{ .Values.global.externalVaultAddr }}" + {{- else if .Values.injector.externalVaultAddr }} + value: "{{ .Values.injector.externalVaultAddr }}" + {{- else }} + value: {{ include "vault.scheme" . }}://{{ template "vault.fullname" . }}.{{ .Release.Namespace }}.svc:{{ .Values.server.service.port }} + {{- end }} + - name: AGENT_INJECT_VAULT_AUTH_PATH + value: {{ .Values.injector.authPath }} + - name: AGENT_INJECT_VAULT_IMAGE + value: "{{ .Values.injector.agentImage.repository }}:{{ .Values.injector.agentImage.tag }}" + {{- if .Values.injector.certs.secretName }} + - name: AGENT_INJECT_TLS_CERT_FILE + value: "/etc/webhook/certs/{{ .Values.injector.certs.certName }}" + - name: AGENT_INJECT_TLS_KEY_FILE + value: "/etc/webhook/certs/{{ .Values.injector.certs.keyName }}" + {{- else }} + - name: AGENT_INJECT_TLS_AUTO + value: {{ template "vault.fullname" . }}-agent-injector-cfg + - name: AGENT_INJECT_TLS_AUTO_HOSTS + value: {{ template "vault.fullname" . }}-agent-injector-svc,{{ template "vault.fullname" . }}-agent-injector-svc.{{ .Release.Namespace }},{{ template "vault.fullname" . }}-agent-injector-svc.{{ .Release.Namespace }}.svc + {{- end }} + - name: AGENT_INJECT_LOG_FORMAT + value: {{ .Values.injector.logFormat | default "standard" }} + - name: AGENT_INJECT_REVOKE_ON_SHUTDOWN + value: "{{ .Values.injector.revokeOnShutdown | default false }}" + {{- if .Values.global.openshift }} + - name: AGENT_INJECT_SET_SECURITY_CONTEXT + value: "false" + {{- end }} + {{- if .Values.injector.metrics.enabled }} + - name: AGENT_INJECT_TELEMETRY_PATH + value: "/metrics" + {{- end }} + {{- if and (eq (.Values.injector.leaderElector.enabled | toString) "true") (gt (.Values.injector.replicas | int) 1) }} + - name: AGENT_INJECT_USE_LEADER_ELECTOR + value: "true" + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + {{- end }} + - name: AGENT_INJECT_CPU_REQUEST + value: "{{ .Values.injector.agentDefaults.cpuRequest }}" + - name: AGENT_INJECT_CPU_LIMIT + value: "{{ .Values.injector.agentDefaults.cpuLimit }}" + - name: AGENT_INJECT_MEM_REQUEST + value: "{{ .Values.injector.agentDefaults.memRequest }}" + - name: AGENT_INJECT_MEM_LIMIT + value: "{{ .Values.injector.agentDefaults.memLimit }}" + {{- if .Values.injector.agentDefaults.ephemeralRequest }} + - name: AGENT_INJECT_EPHEMERAL_REQUEST + value: "{{ .Values.injector.agentDefaults.ephemeralRequest }}" + {{- end }} + {{- if .Values.injector.agentDefaults.ephemeralLimit }} + - name: AGENT_INJECT_EPHEMERAL_LIMIT + value: "{{ .Values.injector.agentDefaults.ephemeralLimit }}" + {{- end }} + - name: AGENT_INJECT_DEFAULT_TEMPLATE + value: "{{ .Values.injector.agentDefaults.template }}" + - name: AGENT_INJECT_TEMPLATE_CONFIG_EXIT_ON_RETRY_FAILURE + value: "{{ .Values.injector.agentDefaults.templateConfig.exitOnRetryFailure }}" + {{- if .Values.injector.agentDefaults.templateConfig.staticSecretRenderInterval }} + - name: AGENT_INJECT_TEMPLATE_STATIC_SECRET_RENDER_INTERVAL + value: "{{ .Values.injector.agentDefaults.templateConfig.staticSecretRenderInterval }}" + {{- end }} + {{- include "vault.extraEnvironmentVars" .Values.injector | nindent 12 }} + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + args: + - agent-inject + - 2>&1 + livenessProbe: + httpGet: + path: /health/ready + port: {{ .Values.injector.port }} + scheme: HTTPS + failureThreshold: {{ .Values.injector.livenessProbe.failureThreshold }} + initialDelaySeconds: {{ .Values.injector.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.injector.livenessProbe.periodSeconds }} + successThreshold: {{ .Values.injector.livenessProbe.successThreshold }} + timeoutSeconds: {{ .Values.injector.livenessProbe.timeoutSeconds }} + readinessProbe: + httpGet: + path: /health/ready + port: {{ .Values.injector.port }} + scheme: HTTPS + failureThreshold: {{ .Values.injector.readinessProbe.failureThreshold }} + initialDelaySeconds: {{ .Values.injector.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.injector.readinessProbe.periodSeconds }} + successThreshold: {{ .Values.injector.readinessProbe.successThreshold }} + timeoutSeconds: {{ .Values.injector.readinessProbe.timeoutSeconds }} + startupProbe: + httpGet: + path: /health/ready + port: {{ .Values.injector.port }} + scheme: HTTPS + failureThreshold: {{ .Values.injector.startupProbe.failureThreshold }} + initialDelaySeconds: {{ .Values.injector.startupProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.injector.startupProbe.periodSeconds }} + successThreshold: {{ .Values.injector.startupProbe.successThreshold }} + timeoutSeconds: {{ .Values.injector.startupProbe.timeoutSeconds }} +{{- if .Values.injector.certs.secretName }} + volumeMounts: + - name: webhook-certs + mountPath: /etc/webhook/certs + readOnly: true +{{- end }} +{{- if .Values.injector.certs.secretName }} + volumes: + - name: webhook-certs + secret: + secretName: "{{ .Values.injector.certs.secretName }}" +{{- end }} + {{- include "imagePullSecrets" . | nindent 6 }} +{{ end }} diff --git a/helm/vault/templates/injector-disruptionbudget.yaml b/helm/vault/templates/injector-disruptionbudget.yaml new file mode 100644 index 0000000..6ae714b --- /dev/null +++ b/helm/vault/templates/injector-disruptionbudget.yaml @@ -0,0 +1,25 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{- if .Values.injector.podDisruptionBudget }} +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: {{ template "vault.fullname" . }}-agent-injector + namespace: {{ .Release.Namespace }} + labels: + helm.sh/chart: {{ include "vault.chart" . }} + app.kubernetes.io/name: {{ include "vault.name" . }}-agent-injector + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + component: webhook +spec: + selector: + matchLabels: + app.kubernetes.io/name: {{ template "vault.name" . }}-agent-injector + app.kubernetes.io/instance: {{ .Release.Name }} + component: webhook + {{- toYaml .Values.injector.podDisruptionBudget | nindent 2 }} +{{- end -}} diff --git a/helm/vault/templates/injector-mutating-webhook.yaml b/helm/vault/templates/injector-mutating-webhook.yaml new file mode 100644 index 0000000..d03cd13 --- /dev/null +++ b/helm/vault/templates/injector-mutating-webhook.yaml @@ -0,0 +1,44 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{- template "vault.injectorEnabled" . -}} +{{- if .injectorEnabled -}} +{{- if .Capabilities.APIVersions.Has "admissionregistration.k8s.io/v1" }} +apiVersion: admissionregistration.k8s.io/v1 +{{- else }} +apiVersion: admissionregistration.k8s.io/v1beta1 +{{- end }} +kind: MutatingWebhookConfiguration +metadata: + name: {{ template "vault.fullname" . }}-agent-injector-cfg + labels: + app.kubernetes.io/name: {{ include "vault.name" . }}-agent-injector + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + {{- template "injector.webhookAnnotations" . }} +webhooks: + - name: vault.hashicorp.com + failurePolicy: {{ ((.Values.injector.webhook)).failurePolicy | default .Values.injector.failurePolicy }} + matchPolicy: {{ ((.Values.injector.webhook)).matchPolicy | default "Exact" }} + sideEffects: None + timeoutSeconds: {{ ((.Values.injector.webhook)).timeoutSeconds | default "30" }} + admissionReviewVersions: ["v1", "v1beta1"] + clientConfig: + service: + name: {{ template "vault.fullname" . }}-agent-injector-svc + namespace: {{ .Release.Namespace }} + path: "/mutate" + caBundle: {{ .Values.injector.certs.caBundle | quote }} + rules: + - operations: ["CREATE", "UPDATE"] + apiGroups: [""] + apiVersions: ["v1"] + resources: ["pods"] +{{- if or (.Values.injector.namespaceSelector) (((.Values.injector.webhook)).namespaceSelector) }} + namespaceSelector: +{{ toYaml (((.Values.injector.webhook)).namespaceSelector | default .Values.injector.namespaceSelector) | indent 6}} +{{ end }} +{{- template "injector.objectSelector" . -}} +{{ end }} diff --git a/helm/vault/templates/injector-network-policy.yaml b/helm/vault/templates/injector-network-policy.yaml new file mode 100644 index 0000000..4c3b087 --- /dev/null +++ b/helm/vault/templates/injector-network-policy.yaml @@ -0,0 +1,29 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{- template "vault.injectorEnabled" . -}} +{{- if .injectorEnabled -}} +{{- if eq (.Values.global.openshift | toString) "true" }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ template "vault.fullname" . }}-agent-injector + labels: + app.kubernetes.io/name: {{ template "vault.name" . }}-agent-injector + app.kubernetes.io/instance: {{ .Release.Name }} +spec: + podSelector: + matchLabels: + app.kubernetes.io/name: {{ template "vault.name" . }}-agent-injector + app.kubernetes.io/instance: {{ .Release.Name }} + component: webhook + ingress: + - from: + - namespaceSelector: {} + ports: + - port: 8080 + protocol: TCP +{{ end }} +{{ end }} diff --git a/helm/vault/templates/injector-psp-role.yaml b/helm/vault/templates/injector-psp-role.yaml new file mode 100644 index 0000000..65d8e9b --- /dev/null +++ b/helm/vault/templates/injector-psp-role.yaml @@ -0,0 +1,25 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{- template "vault.injectorEnabled" . -}} +{{- if .injectorEnabled -}} +{{- if eq (.Values.global.psp.enable | toString) "true" }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ template "vault.fullname" . }}-agent-injector-psp + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ include "vault.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +rules: +- apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ template "vault.fullname" . }}-agent-injector +{{- end }} +{{- end }} diff --git a/helm/vault/templates/injector-psp-rolebinding.yaml b/helm/vault/templates/injector-psp-rolebinding.yaml new file mode 100644 index 0000000..48a3a26 --- /dev/null +++ b/helm/vault/templates/injector-psp-rolebinding.yaml @@ -0,0 +1,26 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{- template "vault.injectorEnabled" . -}} +{{- if .injectorEnabled -}} +{{- if eq (.Values.global.psp.enable | toString) "true" }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ template "vault.fullname" . }}-agent-injector-psp + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ include "vault.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +roleRef: + kind: Role + name: {{ template "vault.fullname" . }}-agent-injector-psp + apiGroup: rbac.authorization.k8s.io +subjects: + - kind: ServiceAccount + name: {{ template "vault.fullname" . }}-agent-injector +{{- end }} +{{- end }} \ No newline at end of file diff --git a/helm/vault/templates/injector-psp.yaml b/helm/vault/templates/injector-psp.yaml new file mode 100644 index 0000000..0eca9a8 --- /dev/null +++ b/helm/vault/templates/injector-psp.yaml @@ -0,0 +1,51 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{- template "vault.injectorEnabled" . -}} +{{- if .injectorEnabled -}} +{{- if eq (.Values.global.psp.enable | toString) "true" }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "vault.fullname" . }}-agent-injector + labels: + app.kubernetes.io/name: {{ include "vault.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- template "vault.psp.annotations" . }} +spec: + privileged: false + # Required to prevent escalations to root. + allowPrivilegeEscalation: false + volumes: + - configMap + - emptyDir + - projected + - secret + - downwardAPI + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + # Require the container to run without root privileges. + rule: MustRunAsNonRoot + seLinux: + # This policy assumes the nodes are using AppArmor rather than SELinux. + rule: RunAsAny + supplementalGroups: + rule: MustRunAs + ranges: + # Forbid adding the root group. + - min: 1 + max: 65535 + fsGroup: + rule: MustRunAs + ranges: + # Forbid adding the root group. + - min: 1 + max: 65535 + readOnlyRootFilesystem: false +{{- end }} +{{- end }} \ No newline at end of file diff --git a/helm/vault/templates/injector-role.yaml b/helm/vault/templates/injector-role.yaml new file mode 100644 index 0000000..df7b0ed --- /dev/null +++ b/helm/vault/templates/injector-role.yaml @@ -0,0 +1,34 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{- template "vault.injectorEnabled" . -}} +{{- if .injectorEnabled -}} +{{- if and (eq (.Values.injector.leaderElector.enabled | toString) "true") (gt (.Values.injector.replicas | int) 1) }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ template "vault.fullname" . }}-agent-injector-leader-elector-role + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ include "vault.name" . }}-agent-injector + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +rules: + - apiGroups: [""] + resources: ["secrets", "configmaps"] + verbs: + - "create" + - "get" + - "watch" + - "list" + - "update" + - apiGroups: [""] + resources: ["pods"] + verbs: + - "get" + - "patch" + - "delete" +{{- end }} +{{- end }} \ No newline at end of file diff --git a/helm/vault/templates/injector-rolebinding.yaml b/helm/vault/templates/injector-rolebinding.yaml new file mode 100644 index 0000000..0848e43 --- /dev/null +++ b/helm/vault/templates/injector-rolebinding.yaml @@ -0,0 +1,27 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{- template "vault.injectorEnabled" . -}} +{{- if .injectorEnabled -}} +{{- if and (eq (.Values.injector.leaderElector.enabled | toString) "true") (gt (.Values.injector.replicas | int) 1) }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ template "vault.fullname" . }}-agent-injector-leader-elector-binding + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ include "vault.name" . }}-agent-injector + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "vault.fullname" . }}-agent-injector-leader-elector-role +subjects: + - kind: ServiceAccount + name: {{ template "vault.fullname" . }}-agent-injector + namespace: {{ .Release.Namespace }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/helm/vault/templates/injector-service.yaml b/helm/vault/templates/injector-service.yaml new file mode 100644 index 0000000..5b20692 --- /dev/null +++ b/helm/vault/templates/injector-service.yaml @@ -0,0 +1,27 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{- template "vault.injectorEnabled" . -}} +{{- if .injectorEnabled -}} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "vault.fullname" . }}-agent-injector-svc + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ include "vault.name" . }}-agent-injector + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + {{ template "injector.service.annotations" . }} +spec: + ports: + - name: https + port: 443 + targetPort: {{ .Values.injector.port }} + selector: + app.kubernetes.io/name: {{ include "vault.name" . }}-agent-injector + app.kubernetes.io/instance: {{ .Release.Name }} + component: webhook +{{- end }} diff --git a/helm/vault/templates/injector-serviceaccount.yaml b/helm/vault/templates/injector-serviceaccount.yaml new file mode 100644 index 0000000..9b5c2f6 --- /dev/null +++ b/helm/vault/templates/injector-serviceaccount.yaml @@ -0,0 +1,18 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{- template "vault.injectorEnabled" . -}} +{{- if .injectorEnabled -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "vault.fullname" . }}-agent-injector + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ include "vault.name" . }}-agent-injector + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + {{ template "injector.serviceAccount.annotations" . }} +{{ end }} diff --git a/helm/vault/templates/prometheus-prometheusrules.yaml b/helm/vault/templates/prometheus-prometheusrules.yaml new file mode 100644 index 0000000..7e58a0e --- /dev/null +++ b/helm/vault/templates/prometheus-prometheusrules.yaml @@ -0,0 +1,31 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{ if and (.Values.serverTelemetry.prometheusRules.rules) + (or (.Values.global.serverTelemetry.prometheusOperator) (.Values.serverTelemetry.prometheusRules.enabled) ) +}} +--- +apiVersion: monitoring.coreos.com/v1 +kind: PrometheusRule +metadata: + name: {{ template "vault.fullname" . }} + labels: + helm.sh/chart: {{ include "vault.chart" . }} + app.kubernetes.io/name: {{ include "vault.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + {{- /* update the selectors docs in values.yaml whenever the defaults below change. */ -}} + {{- $selectors := .Values.serverTelemetry.prometheusRules.selectors }} + {{- if $selectors }} + {{- toYaml $selectors | nindent 4 }} + {{- else }} + release: prometheus + {{- end }} +spec: + groups: + - name: {{ include "vault.fullname" . }} + rules: + {{- toYaml .Values.serverTelemetry.prometheusRules.rules | nindent 6 }} +{{- end }} diff --git a/helm/vault/templates/prometheus-servicemonitor.yaml b/helm/vault/templates/prometheus-servicemonitor.yaml new file mode 100644 index 0000000..60f2729 --- /dev/null +++ b/helm/vault/templates/prometheus-servicemonitor.yaml @@ -0,0 +1,49 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{ template "vault.mode" . }} +{{ if or (.Values.global.serverTelemetry.prometheusOperator) (.Values.serverTelemetry.serviceMonitor.enabled) }} +--- +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "vault.fullname" . }} + labels: + helm.sh/chart: {{ include "vault.chart" . }} + app.kubernetes.io/name: {{ include "vault.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + {{- /* update the selectors docs in values.yaml whenever the defaults below change. */ -}} + {{- $selectors := .Values.serverTelemetry.serviceMonitor.selectors }} + {{- if $selectors }} + {{- toYaml $selectors | nindent 4 }} + {{- else }} + release: prometheus + {{- end }} +spec: + selector: + matchLabels: + app.kubernetes.io/name: {{ template "vault.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + {{- if eq .mode "ha" }} + vault-active: "true" + {{- else }} + vault-internal: "true" + {{- end }} + endpoints: + - port: {{ include "vault.scheme" . }} + interval: {{ .Values.serverTelemetry.serviceMonitor.interval }} + scrapeTimeout: {{ .Values.serverTelemetry.serviceMonitor.scrapeTimeout }} + scheme: {{ include "vault.scheme" . | lower }} + path: /v1/sys/metrics + params: + format: + - prometheus + tlsConfig: + insecureSkipVerify: true + namespaceSelector: + matchNames: + - {{ .Release.Namespace }} +{{ end }} diff --git a/helm/vault/templates/server-clusterrolebinding.yaml b/helm/vault/templates/server-clusterrolebinding.yaml new file mode 100644 index 0000000..b694129 --- /dev/null +++ b/helm/vault/templates/server-clusterrolebinding.yaml @@ -0,0 +1,29 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{ template "vault.serverAuthDelegator" . }} +{{- if .serverAuthDelegator -}} +{{- if .Capabilities.APIVersions.Has "rbac.authorization.k8s.io/v1" -}} +apiVersion: rbac.authorization.k8s.io/v1 +{{- else }} +apiVersion: rbac.authorization.k8s.io/v1beta1 +{{- end }} +kind: ClusterRoleBinding +metadata: + name: {{ template "vault.fullname" . }}-server-binding + labels: + helm.sh/chart: {{ include "vault.chart" . }} + app.kubernetes.io/name: {{ include "vault.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: system:auth-delegator +subjects: +- kind: ServiceAccount + name: {{ template "vault.serviceAccount.name" . }} + namespace: {{ .Release.Namespace }} +{{ end }} \ No newline at end of file diff --git a/helm/vault/templates/server-config-configmap.yaml b/helm/vault/templates/server-config-configmap.yaml new file mode 100644 index 0000000..5d29e98 --- /dev/null +++ b/helm/vault/templates/server-config-configmap.yaml @@ -0,0 +1,45 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{ template "vault.mode" . }} +{{- if ne .mode "external" }} +{{- if .serverEnabled -}} +{{- if ne .mode "dev" -}} +{{ if or (.Values.server.standalone.config) (.Values.server.ha.config) -}} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "vault.fullname" . }}-config + namespace: {{ .Release.Namespace }} + labels: + helm.sh/chart: {{ include "vault.chart" . }} + app.kubernetes.io/name: {{ include "vault.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +data: + extraconfig-from-values.hcl: |- + {{- if or (eq .mode "ha") (eq .mode "standalone") }} + {{- $type := typeOf (index .Values.server .mode).config }} + {{- if eq $type "string" }} + disable_mlock = true + {{- if eq .mode "standalone" }} + {{ tpl .Values.server.standalone.config . | nindent 4 | trim }} + {{- else if and (eq .mode "ha") (eq (.Values.server.ha.raft.enabled | toString) "false") }} + {{ tpl .Values.server.ha.config . | nindent 4 | trim }} + {{- else if and (eq .mode "ha") (eq (.Values.server.ha.raft.enabled | toString) "true") }} + {{ tpl .Values.server.ha.raft.config . | nindent 4 | trim }} + {{ end }} + {{- else }} + {{- if and (eq .mode "ha") (eq (.Values.server.ha.raft.enabled | toString) "true") }} +{{ merge (dict "disable_mlock" true) (index .Values.server .mode).raft.config | toPrettyJson | indent 4 }} + {{- else }} +{{ merge (dict "disable_mlock" true) (index .Values.server .mode).config | toPrettyJson | indent 4 }} + {{- end }} + {{- end }} + {{- end }} +{{- end }} +{{- end }} +{{- end }} +{{- end }} diff --git a/helm/vault/templates/server-discovery-role.yaml b/helm/vault/templates/server-discovery-role.yaml new file mode 100644 index 0000000..adae42a --- /dev/null +++ b/helm/vault/templates/server-discovery-role.yaml @@ -0,0 +1,26 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{ template "vault.mode" . }} +{{- if .serverEnabled -}} +{{- if eq .mode "ha" }} +{{- if eq (.Values.server.serviceAccount.serviceDiscovery.enabled | toString) "true" }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + namespace: {{ .Release.Namespace }} + name: {{ template "vault.fullname" . }}-discovery-role + labels: + helm.sh/chart: {{ include "vault.chart" . }} + app.kubernetes.io/name: {{ include "vault.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +rules: +- apiGroups: [""] + resources: ["pods"] + verbs: ["get", "watch", "list", "update", "patch"] +{{ end }} +{{ end }} +{{ end }} diff --git a/helm/vault/templates/server-discovery-rolebinding.yaml b/helm/vault/templates/server-discovery-rolebinding.yaml new file mode 100644 index 0000000..853ee87 --- /dev/null +++ b/helm/vault/templates/server-discovery-rolebinding.yaml @@ -0,0 +1,34 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{ template "vault.mode" . }} +{{- if .serverEnabled -}} +{{- if eq .mode "ha" }} +{{- if eq (.Values.server.serviceAccount.serviceDiscovery.enabled | toString) "true" }} +{{- if .Capabilities.APIVersions.Has "rbac.authorization.k8s.io/v1" -}} +apiVersion: rbac.authorization.k8s.io/v1 +{{- else }} +apiVersion: rbac.authorization.k8s.io/v1beta1 +{{- end }} +kind: RoleBinding +metadata: + name: {{ template "vault.fullname" . }}-discovery-rolebinding + namespace: {{ .Release.Namespace }} + labels: + helm.sh/chart: {{ include "vault.chart" . }} + app.kubernetes.io/name: {{ include "vault.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: {{ template "vault.fullname" . }}-discovery-role +subjects: +- kind: ServiceAccount + name: {{ template "vault.serviceAccount.name" . }} + namespace: {{ .Release.Namespace }} +{{ end }} +{{ end }} +{{ end }} diff --git a/helm/vault/templates/server-disruptionbudget.yaml b/helm/vault/templates/server-disruptionbudget.yaml new file mode 100644 index 0000000..3ff1109 --- /dev/null +++ b/helm/vault/templates/server-disruptionbudget.yaml @@ -0,0 +1,31 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{ template "vault.mode" . }} +{{- if ne .mode "external" -}} +{{- if .serverEnabled -}} +{{- if and (eq .mode "ha") (eq (.Values.server.ha.disruptionBudget.enabled | toString) "true") -}} +# PodDisruptionBudget to prevent degrading the server cluster through +# voluntary cluster changes. +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + name: {{ template "vault.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + helm.sh/chart: {{ include "vault.chart" . }} + app.kubernetes.io/name: {{ include "vault.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +spec: + maxUnavailable: {{ template "vault.pdb.maxUnavailable" . }} + selector: + matchLabels: + app.kubernetes.io/name: {{ include "vault.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + component: server +{{- end -}} +{{- end -}} +{{- end -}} diff --git a/helm/vault/templates/server-ha-active-service.yaml b/helm/vault/templates/server-ha-active-service.yaml new file mode 100644 index 0000000..58d540f --- /dev/null +++ b/helm/vault/templates/server-ha-active-service.yaml @@ -0,0 +1,55 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{ template "vault.mode" . }} +{{- if ne .mode "external" }} +{{- template "vault.serverServiceEnabled" . -}} +{{- if .serverServiceEnabled -}} +{{- if eq .mode "ha" }} +{{- if eq (.Values.server.service.active.enabled | toString) "true" }} +# Service for active Vault pod +apiVersion: v1 +kind: Service +metadata: + name: {{ template "vault.fullname" . }}-active + namespace: {{ .Release.Namespace }} + labels: + helm.sh/chart: {{ include "vault.chart" . }} + app.kubernetes.io/name: {{ include "vault.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + vault-active: "true" + annotations: +{{ template "vault.service.annotations" .}} +spec: + {{- if .Values.server.service.type}} + type: {{ .Values.server.service.type }} + {{- end}} + {{- if .Values.server.service.clusterIP }} + clusterIP: {{ .Values.server.service.clusterIP }} + {{- end }} + {{- include "service.externalTrafficPolicy" .Values.server.service }} + publishNotReadyAddresses: {{ .Values.server.service.publishNotReadyAddresses }} + ports: + - name: {{ include "vault.scheme" . }} + port: {{ .Values.server.service.port }} + targetPort: {{ .Values.server.service.targetPort }} + {{- if and (.Values.server.service.activeNodePort) (eq (.Values.server.service.type | toString) "NodePort") }} + nodePort: {{ .Values.server.service.activeNodePort }} + {{- end }} + - name: https-internal + port: 8201 + targetPort: 8201 + selector: + app.kubernetes.io/name: {{ include "vault.name" . }} + {{- if eq (.Values.server.service.instanceSelector.enabled | toString) "true" }} + app.kubernetes.io/instance: {{ .Release.Name }} + {{- end }} + component: server + vault-active: "true" +{{- end }} +{{- end }} +{{- end }} +{{- end }} diff --git a/helm/vault/templates/server-ha-standby-service.yaml b/helm/vault/templates/server-ha-standby-service.yaml new file mode 100644 index 0000000..b9f6435 --- /dev/null +++ b/helm/vault/templates/server-ha-standby-service.yaml @@ -0,0 +1,54 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{ template "vault.mode" . }} +{{- if ne .mode "external" }} +{{- template "vault.serverServiceEnabled" . -}} +{{- if .serverServiceEnabled -}} +{{- if eq .mode "ha" }} +{{- if eq (.Values.server.service.standby.enabled | toString) "true" }} +# Service for standby Vault pod +apiVersion: v1 +kind: Service +metadata: + name: {{ template "vault.fullname" . }}-standby + namespace: {{ .Release.Namespace }} + labels: + helm.sh/chart: {{ include "vault.chart" . }} + app.kubernetes.io/name: {{ include "vault.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + annotations: +{{ template "vault.service.annotations" .}} +spec: + {{- if .Values.server.service.type}} + type: {{ .Values.server.service.type }} + {{- end}} + {{- if .Values.server.service.clusterIP }} + clusterIP: {{ .Values.server.service.clusterIP }} + {{- end }} + {{- include "service.externalTrafficPolicy" .Values.server.service }} + publishNotReadyAddresses: {{ .Values.server.service.publishNotReadyAddresses }} + ports: + - name: {{ include "vault.scheme" . }} + port: {{ .Values.server.service.port }} + targetPort: {{ .Values.server.service.targetPort }} + {{- if and (.Values.server.service.standbyNodePort) (eq (.Values.server.service.type | toString) "NodePort") }} + nodePort: {{ .Values.server.service.standbyNodePort }} + {{- end }} + - name: https-internal + port: 8201 + targetPort: 8201 + selector: + app.kubernetes.io/name: {{ include "vault.name" . }} + {{- if eq (.Values.server.service.instanceSelector.enabled | toString) "true" }} + app.kubernetes.io/instance: {{ .Release.Name }} + {{- end }} + component: server + vault-active: "false" +{{- end }} +{{- end }} +{{- end }} +{{- end }} diff --git a/helm/vault/templates/server-headless-service.yaml b/helm/vault/templates/server-headless-service.yaml new file mode 100644 index 0000000..42e1aa0 --- /dev/null +++ b/helm/vault/templates/server-headless-service.yaml @@ -0,0 +1,39 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{ template "vault.mode" . }} +{{- if ne .mode "external" }} +{{- template "vault.serverServiceEnabled" . -}} +{{- if .serverServiceEnabled -}} +# Service for Vault cluster +apiVersion: v1 +kind: Service +metadata: + name: {{ template "vault.fullname" . }}-internal + namespace: {{ .Release.Namespace }} + labels: + helm.sh/chart: {{ include "vault.chart" . }} + app.kubernetes.io/name: {{ include "vault.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + vault-internal: "true" + annotations: +{{ template "vault.service.annotations" .}} +spec: + clusterIP: None + publishNotReadyAddresses: true + ports: + - name: "{{ include "vault.scheme" . }}" + port: {{ .Values.server.service.port }} + targetPort: {{ .Values.server.service.targetPort }} + - name: https-internal + port: 8201 + targetPort: 8201 + selector: + app.kubernetes.io/name: {{ include "vault.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + component: server +{{- end }} +{{- end }} diff --git a/helm/vault/templates/server-ingress.yaml b/helm/vault/templates/server-ingress.yaml new file mode 100644 index 0000000..3aba668 --- /dev/null +++ b/helm/vault/templates/server-ingress.yaml @@ -0,0 +1,69 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{- if not .Values.global.openshift }} +{{ template "vault.mode" . }} +{{- if ne .mode "external" }} +{{- if .Values.server.ingress.enabled -}} +{{- $extraPaths := .Values.server.ingress.extraPaths -}} +{{- $serviceName := include "vault.fullname" . -}} +{{- template "vault.serverServiceEnabled" . -}} +{{- if .serverServiceEnabled -}} +{{- if and (eq .mode "ha" ) (eq (.Values.server.ingress.activeService | toString) "true") }} +{{- $serviceName = printf "%s-%s" $serviceName "active" -}} +{{- end }} +{{- $servicePort := .Values.server.service.port -}} +{{- $pathType := .Values.server.ingress.pathType -}} +{{- $kubeVersion := .Capabilities.KubeVersion.Version }} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ template "vault.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + helm.sh/chart: {{ include "vault.chart" . }} + app.kubernetes.io/name: {{ include "vault.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + {{- with .Values.server.ingress.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- template "vault.ingress.annotations" . }} +spec: +{{- if .Values.server.ingress.tls }} + tls: + {{- range .Values.server.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ . | quote }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} +{{- end }} +{{- if .Values.server.ingress.ingressClassName }} + ingressClassName: {{ .Values.server.ingress.ingressClassName }} +{{- end }} + rules: + {{- range .Values.server.ingress.hosts }} + - host: {{ .host | quote }} + http: + paths: +{{ if $extraPaths }} +{{ toYaml $extraPaths | indent 10 }} +{{- end }} + {{- range (.paths | default (list "/")) }} + - path: {{ . }} + pathType: {{ $pathType }} + backend: + service: + name: {{ $serviceName }} + port: + number: {{ $servicePort }} + {{- end }} + {{- end }} +{{- end }} +{{- end }} +{{- end }} +{{- end }} diff --git a/helm/vault/templates/server-network-policy.yaml b/helm/vault/templates/server-network-policy.yaml new file mode 100644 index 0000000..62d4ae1 --- /dev/null +++ b/helm/vault/templates/server-network-policy.yaml @@ -0,0 +1,31 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{- if eq (.Values.server.networkPolicy.enabled | toString) "true" }} +apiVersion: networking.k8s.io/v1 +kind: NetworkPolicy +metadata: + name: {{ template "vault.fullname" . }} + labels: + app.kubernetes.io/name: {{ template "vault.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} +spec: + podSelector: + matchLabels: + app.kubernetes.io/name: {{ template "vault.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + ingress: + - from: + - namespaceSelector: {} + ports: + - port: 8200 + protocol: TCP + - port: 8201 + protocol: TCP + {{- if .Values.server.networkPolicy.egress }} + egress: + {{- toYaml .Values.server.networkPolicy.egress | nindent 4 }} + {{ end }} +{{ end }} diff --git a/helm/vault/templates/server-psp-role.yaml b/helm/vault/templates/server-psp-role.yaml new file mode 100644 index 0000000..0c8c983 --- /dev/null +++ b/helm/vault/templates/server-psp-role.yaml @@ -0,0 +1,25 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{ template "vault.mode" . }} +{{- if .serverEnabled -}} +{{- if and (ne .mode "") (eq (.Values.global.psp.enable | toString) "true") }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ template "vault.fullname" . }}-psp + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ include "vault.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +rules: +- apiGroups: ['policy'] + resources: ['podsecuritypolicies'] + verbs: ['use'] + resourceNames: + - {{ template "vault.fullname" . }} +{{- end }} +{{- end }} diff --git a/helm/vault/templates/server-psp-rolebinding.yaml b/helm/vault/templates/server-psp-rolebinding.yaml new file mode 100644 index 0000000..9b975d5 --- /dev/null +++ b/helm/vault/templates/server-psp-rolebinding.yaml @@ -0,0 +1,26 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{ template "vault.mode" . }} +{{- if .serverEnabled -}} +{{- if and (ne .mode "") (eq (.Values.global.psp.enable | toString) "true") }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ template "vault.fullname" . }}-psp + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ include "vault.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +roleRef: + kind: Role + name: {{ template "vault.fullname" . }}-psp + apiGroup: rbac.authorization.k8s.io +subjects: + - kind: ServiceAccount + name: {{ template "vault.fullname" . }} +{{- end }} +{{- end }} diff --git a/helm/vault/templates/server-psp.yaml b/helm/vault/templates/server-psp.yaml new file mode 100644 index 0000000..567e662 --- /dev/null +++ b/helm/vault/templates/server-psp.yaml @@ -0,0 +1,54 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{ template "vault.mode" . }} +{{- if .serverEnabled -}} +{{- if and (ne .mode "") (eq (.Values.global.psp.enable | toString) "true") }} +apiVersion: policy/v1beta1 +kind: PodSecurityPolicy +metadata: + name: {{ template "vault.fullname" . }} + labels: + app.kubernetes.io/name: {{ include "vault.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- template "vault.psp.annotations" . }} +spec: + privileged: false + # Required to prevent escalations to root. + allowPrivilegeEscalation: false + volumes: + - configMap + - emptyDir + - projected + - secret + - downwardAPI + {{- if eq (.Values.server.dataStorage.enabled | toString) "true" }} + - persistentVolumeClaim + {{- end }} + hostNetwork: false + hostIPC: false + hostPID: false + runAsUser: + # Require the container to run without root privileges. + rule: MustRunAsNonRoot + seLinux: + # This policy assumes the nodes are using AppArmor rather than SELinux. + rule: RunAsAny + supplementalGroups: + rule: MustRunAs + ranges: + # Forbid adding the root group. + - min: 1 + max: 65535 + fsGroup: + rule: MustRunAs + ranges: + # Forbid adding the root group. + - min: 1 + max: 65535 + readOnlyRootFilesystem: false +{{- end }} +{{- end }} diff --git a/helm/vault/templates/server-route.yaml b/helm/vault/templates/server-route.yaml new file mode 100644 index 0000000..3f35aef --- /dev/null +++ b/helm/vault/templates/server-route.yaml @@ -0,0 +1,39 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{- if .Values.global.openshift }} +{{- if ne .mode "external" }} +{{- if .Values.server.route.enabled -}} +{{- $serviceName := include "vault.fullname" . -}} +{{- if and (eq .mode "ha" ) (eq (.Values.server.route.activeService | toString) "true") }} +{{- $serviceName = printf "%s-%s" $serviceName "active" -}} +{{- end }} +kind: Route +apiVersion: route.openshift.io/v1 +metadata: + name: {{ template "vault.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + helm.sh/chart: {{ include "vault.chart" . }} + app.kubernetes.io/name: {{ include "vault.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + {{- with .Values.server.route.labels }} + {{- toYaml . | nindent 4 }} + {{- end }} + {{- template "vault.route.annotations" . }} +spec: + host: {{ .Values.server.route.host }} + to: + kind: Service + name: {{ $serviceName }} + weight: 100 + port: + targetPort: 8200 + tls: + {{- toYaml .Values.server.route.tls | nindent 4 }} +{{- end }} +{{- end }} +{{- end }} diff --git a/helm/vault/templates/server-service.yaml b/helm/vault/templates/server-service.yaml new file mode 100644 index 0000000..8e34c88 --- /dev/null +++ b/helm/vault/templates/server-service.yaml @@ -0,0 +1,51 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{ template "vault.mode" . }} +{{- if ne .mode "external" }} +{{- template "vault.serverServiceEnabled" . -}} +{{- if .serverServiceEnabled -}} +# Service for Vault cluster +apiVersion: v1 +kind: Service +metadata: + name: {{ template "vault.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + helm.sh/chart: {{ include "vault.chart" . }} + app.kubernetes.io/name: {{ include "vault.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + annotations: +{{ template "vault.service.annotations" .}} +spec: + {{- if .Values.server.service.type}} + type: {{ .Values.server.service.type }} + {{- end}} + {{- if .Values.server.service.clusterIP }} + clusterIP: {{ .Values.server.service.clusterIP }} + {{- end }} + {{- include "service.externalTrafficPolicy" .Values.server.service }} + # We want the servers to become available even if they're not ready + # since this DNS is also used for join operations. + publishNotReadyAddresses: {{ .Values.server.service.publishNotReadyAddresses }} + ports: + - name: {{ include "vault.scheme" . }} + port: {{ .Values.server.service.port }} + targetPort: {{ .Values.server.service.targetPort }} + {{- if and (.Values.server.service.nodePort) (eq (.Values.server.service.type | toString) "NodePort") }} + nodePort: {{ .Values.server.service.nodePort }} + {{- end }} + - name: https-internal + port: 8201 + targetPort: 8201 + selector: + app.kubernetes.io/name: {{ include "vault.name" . }} + {{- if eq (.Values.server.service.instanceSelector.enabled | toString) "true" }} + app.kubernetes.io/instance: {{ .Release.Name }} + {{- end }} + component: server +{{- end }} +{{- end }} diff --git a/helm/vault/templates/server-serviceaccount.yaml b/helm/vault/templates/server-serviceaccount.yaml new file mode 100644 index 0000000..e154f8d --- /dev/null +++ b/helm/vault/templates/server-serviceaccount.yaml @@ -0,0 +1,22 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{ template "vault.serverServiceAccountEnabled" . }} +{{- if .serverServiceAccountEnabled -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ template "vault.serviceAccount.name" . }} + namespace: {{ .Release.Namespace }} + labels: + helm.sh/chart: {{ include "vault.chart" . }} + app.kubernetes.io/name: {{ include "vault.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + {{- if .Values.server.serviceAccount.extraLabels -}} + {{- toYaml .Values.server.serviceAccount.extraLabels | nindent 4 -}} + {{- end -}} + {{ template "vault.serviceAccount.annotations" . }} +{{ end }} diff --git a/helm/vault/templates/server-statefulset.yaml b/helm/vault/templates/server-statefulset.yaml new file mode 100644 index 0000000..7ab7de8 --- /dev/null +++ b/helm/vault/templates/server-statefulset.yaml @@ -0,0 +1,217 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{ template "vault.mode" . }} +{{- if ne .mode "external" }} +{{- if ne .mode "" }} +{{- if .serverEnabled -}} +# StatefulSet to run the actual vault server cluster. +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ template "vault.fullname" . }} + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ include "vault.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + {{- template "vault.statefulSet.annotations" . }} +spec: + serviceName: {{ template "vault.fullname" . }}-internal + podManagementPolicy: Parallel + replicas: {{ template "vault.replicas" . }} + updateStrategy: + type: {{ .Values.server.updateStrategyType }} + selector: + matchLabels: + app.kubernetes.io/name: {{ template "vault.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + component: server + template: + metadata: + labels: + helm.sh/chart: {{ template "vault.chart" . }} + app.kubernetes.io/name: {{ template "vault.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + component: server + {{- if .Values.server.extraLabels -}} + {{- toYaml .Values.server.extraLabels | nindent 8 -}} + {{- end -}} + {{ template "vault.annotations" . }} + spec: + {{ template "vault.affinity" . }} + {{ template "vault.topologySpreadConstraints" . }} + {{ template "vault.tolerations" . }} + {{ template "vault.nodeselector" . }} + {{- if .Values.server.priorityClassName }} + priorityClassName: {{ .Values.server.priorityClassName }} + {{- end }} + terminationGracePeriodSeconds: {{ .Values.server.terminationGracePeriodSeconds }} + serviceAccountName: {{ template "vault.serviceAccount.name" . }} + {{ if .Values.server.shareProcessNamespace }} + shareProcessNamespace: true + {{ end }} + {{- template "server.statefulSet.securityContext.pod" . }} + {{- if not .Values.global.openshift }} + hostNetwork: {{ .Values.server.hostNetwork }} + {{- end }} + volumes: + {{ template "vault.volumes" . }} + - name: home + emptyDir: {} + {{- if .Values.server.extraInitContainers }} + initContainers: + {{ toYaml .Values.server.extraInitContainers | nindent 8}} + {{- end }} + containers: + - name: vault + {{ template "vault.resources" . }} + image: {{ .Values.server.image.repository }}:{{ .Values.server.image.tag | default "latest" }} + imagePullPolicy: {{ .Values.server.image.pullPolicy }} + command: + - "/bin/sh" + - "-ec" + args: {{ template "vault.args" . }} + {{- template "server.statefulSet.securityContext.container" . }} + env: + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + - name: POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: VAULT_K8S_POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: VAULT_K8S_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: VAULT_ADDR + value: "{{ include "vault.scheme" . }}://127.0.0.1:8200" + - name: VAULT_API_ADDR + {{- if .Values.server.ha.apiAddr }} + value: {{ .Values.server.ha.apiAddr }} + {{- else }} + value: "{{ include "vault.scheme" . }}://$(POD_IP):8200" + {{- end }} + - name: SKIP_CHOWN + value: "true" + - name: SKIP_SETCAP + value: "true" + - name: HOSTNAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: VAULT_CLUSTER_ADDR + {{- if .Values.server.ha.clusterAddr }} + value: {{ .Values.server.ha.clusterAddr | quote }} + {{- else }} + value: "https://$(HOSTNAME).{{ template "vault.fullname" . }}-internal:8201" + {{- end }} + {{- if and (eq (.Values.server.ha.raft.enabled | toString) "true") (eq (.Values.server.ha.raft.setNodeId | toString) "true") }} + - name: VAULT_RAFT_NODE_ID + valueFrom: + fieldRef: + fieldPath: metadata.name + {{- end }} + - name: HOME + value: "/home/vault" + {{- if .Values.server.logLevel }} + - name: VAULT_LOG_LEVEL + value: "{{ .Values.server.logLevel }}" + {{- end }} + {{- if .Values.server.logFormat }} + - name: VAULT_LOG_FORMAT + value: "{{ .Values.server.logFormat }}" + {{- end }} + {{- if (and .Values.server.enterpriseLicense.secretName .Values.server.enterpriseLicense.secretKey) }} + - name: VAULT_LICENSE_PATH + value: /vault/license/{{ .Values.server.enterpriseLicense.secretKey }} + {{- end }} + {{ template "vault.envs" . }} + {{- include "vault.extraEnvironmentVars" .Values.server | nindent 12 }} + {{- include "vault.extraSecretEnvironmentVars" .Values.server | nindent 12 }} + volumeMounts: + {{ template "vault.mounts" . }} + - name: home + mountPath: /home/vault + ports: + - containerPort: 8200 + name: {{ include "vault.scheme" . }} + - containerPort: 8201 + name: https-internal + - containerPort: 8202 + name: {{ include "vault.scheme" . }}-rep + {{- if .Values.server.extraPorts -}} + {{ toYaml .Values.server.extraPorts | nindent 12}} + {{- end }} + {{- if .Values.server.readinessProbe.enabled }} + readinessProbe: + {{- if .Values.server.readinessProbe.path }} + httpGet: + path: {{ .Values.server.readinessProbe.path | quote }} + port: {{ .Values.server.readinessProbe.port }} + scheme: {{ include "vault.scheme" . | upper }} + {{- else }} + # Check status; unsealed vault servers return 0 + # The exit code reflects the seal status: + # 0 - unsealed + # 1 - error + # 2 - sealed + exec: + command: ["/bin/sh", "-ec", "vault status -tls-skip-verify"] + {{- end }} + failureThreshold: {{ .Values.server.readinessProbe.failureThreshold }} + initialDelaySeconds: {{ .Values.server.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.server.readinessProbe.periodSeconds }} + successThreshold: {{ .Values.server.readinessProbe.successThreshold }} + timeoutSeconds: {{ .Values.server.readinessProbe.timeoutSeconds }} + {{- end }} + {{- if .Values.server.livenessProbe.enabled }} + livenessProbe: + httpGet: + path: {{ .Values.server.livenessProbe.path | quote }} + port: {{ .Values.server.livenessProbe.port }} + scheme: {{ include "vault.scheme" . | upper }} + failureThreshold: {{ .Values.server.livenessProbe.failureThreshold }} + initialDelaySeconds: {{ .Values.server.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.server.livenessProbe.periodSeconds }} + successThreshold: {{ .Values.server.livenessProbe.successThreshold }} + timeoutSeconds: {{ .Values.server.livenessProbe.timeoutSeconds }} + {{- end }} + lifecycle: + # Vault container doesn't receive SIGTERM from Kubernetes + # and after the grace period ends, Kube sends SIGKILL. This + # causes issues with graceful shutdowns such as deregistering itself + # from Consul (zombie services). + preStop: + exec: + command: [ + "/bin/sh", "-c", + # Adding a sleep here to give the pod eviction a + # chance to propagate, so requests will not be made + # to this pod while it's terminating + "sleep {{ .Values.server.preStopSleepSeconds }} && kill -SIGTERM $(pidof vault)", + ] + {{- if .Values.server.postStart }} + postStart: + exec: + command: + {{- range (.Values.server.postStart) }} + - {{ . | quote }} + {{- end }} + {{- end }} + {{- if .Values.server.extraContainers }} + {{ toYaml .Values.server.extraContainers | nindent 8}} + {{- end }} + {{- include "imagePullSecrets" . | nindent 6 }} + {{ template "vault.volumeclaims" . }} +{{ end }} +{{ end }} +{{ end }} diff --git a/helm/vault/templates/tests/server-test.yaml b/helm/vault/templates/tests/server-test.yaml new file mode 100644 index 0000000..59b1501 --- /dev/null +++ b/helm/vault/templates/tests/server-test.yaml @@ -0,0 +1,56 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{ template "vault.mode" . }} +{{- if ne .mode "external" }} +{{- if .serverEnabled -}} +apiVersion: v1 +kind: Pod +metadata: + name: "{{ .Release.Name }}-server-test" + namespace: {{ .Release.Namespace }} + annotations: + "helm.sh/hook": test +spec: + {{- include "imagePullSecrets" . | nindent 2 }} + containers: + - name: {{ .Release.Name }}-server-test + image: {{ .Values.server.image.repository }}:{{ .Values.server.image.tag | default "latest" }} + imagePullPolicy: {{ .Values.server.image.pullPolicy }} + env: + - name: VAULT_ADDR + value: {{ include "vault.scheme" . }}://{{ template "vault.fullname" . }}.{{ .Release.Namespace }}.svc:{{ .Values.server.service.port }} + {{- include "vault.extraEnvironmentVars" .Values.server | nindent 8 }} + command: + - /bin/sh + - -c + - | + echo "Checking for sealed info in 'vault status' output" + ATTEMPTS=10 + n=0 + until [ "$n" -ge $ATTEMPTS ] + do + echo "Attempt" $n... + vault status -format yaml | grep -E '^sealed: (true|false)' && break + n=$((n+1)) + sleep 5 + done + if [ $n -ge $ATTEMPTS ]; then + echo "timed out looking for sealed info in 'vault status' output" + exit 1 + fi + + exit 0 + volumeMounts: + {{- if .Values.server.volumeMounts }} + {{- toYaml .Values.server.volumeMounts | nindent 8}} + {{- end }} + volumes: + {{- if .Values.server.volumes }} + {{- toYaml .Values.server.volumes | nindent 4}} + {{- end }} + restartPolicy: Never +{{- end }} +{{- end }} diff --git a/helm/vault/templates/ui-service.yaml b/helm/vault/templates/ui-service.yaml new file mode 100644 index 0000000..4b2e8f7 --- /dev/null +++ b/helm/vault/templates/ui-service.yaml @@ -0,0 +1,42 @@ +{{/* +Copyright (c) HashiCorp, Inc. +SPDX-License-Identifier: MPL-2.0 +*/}} + +{{ template "vault.mode" . }} +{{- if ne .mode "external" }} +{{- template "vault.uiEnabled" . -}} +{{- if .uiEnabled -}} + +apiVersion: v1 +kind: Service +metadata: + name: {{ template "vault.fullname" . }}-ui + namespace: {{ .Release.Namespace }} + labels: + helm.sh/chart: {{ include "vault.chart" . }} + app.kubernetes.io/name: {{ include "vault.name" . }}-ui + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + {{- template "vault.ui.annotations" . }} +spec: + selector: + app.kubernetes.io/name: {{ include "vault.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + component: server + {{- if and (.Values.ui.activeVaultPodOnly) (eq .mode "ha") }} + vault-active: "true" + {{- end }} + publishNotReadyAddresses: {{ .Values.ui.publishNotReadyAddresses }} + ports: + - name: {{ include "vault.scheme" . }} + port: {{ .Values.ui.externalPort }} + targetPort: {{ .Values.ui.targetPort }} + {{- if .Values.ui.serviceNodePort }} + nodePort: {{ .Values.ui.serviceNodePort }} + {{- end }} + type: {{ .Values.ui.serviceType }} + {{- include "service.externalTrafficPolicy" .Values.ui }} + {{- include "service.loadBalancer" .Values.ui }} +{{- end -}} +{{- end }} diff --git a/helm/vault/values.openshift.yaml b/helm/vault/values.openshift.yaml new file mode 100644 index 0000000..6e575e4 --- /dev/null +++ b/helm/vault/values.openshift.yaml @@ -0,0 +1,21 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +# These overrides are appropriate defaults for deploying this chart on OpenShift + +global: + openshift: true + +injector: + image: + repository: "registry.connect.redhat.com/hashicorp/vault-k8s" + tag: "1.2.1-ubi" + + agentImage: + repository: "registry.connect.redhat.com/hashicorp/vault" + tag: "1.14.0-ubi" + +server: + image: + repository: "registry.connect.redhat.com/hashicorp/vault" + tag: "1.14.0-ubi" diff --git a/helm/vault/values.schema.json b/helm/vault/values.schema.json new file mode 100644 index 0000000..ecb97de --- /dev/null +++ b/helm/vault/values.schema.json @@ -0,0 +1,1144 @@ +{ + "$schema": "http://json-schema.org/schema#", + "type": "object", + "properties": { + "csi": { + "type": "object", + "properties": { + "agent": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "extraArgs": { + "type": "array" + }, + "image": { + "type": "object", + "properties": { + "pullPolicy": { + "type": "string" + }, + "repository": { + "type": "string" + }, + "tag": { + "type": "string" + } + } + }, + "logFormat": { + "type": "string" + }, + "logLevel": { + "type": "string" + }, + "resources": { + "type": "object" + } + } + }, + "daemonSet": { + "type": "object", + "properties": { + "annotations": { + "type": [ + "object", + "string" + ] + }, + "extraLabels": { + "type": "object" + }, + "kubeletRootDir": { + "type": "string" + }, + "providersDir": { + "type": "string" + }, + "securityContext": { + "type": "object", + "properties": { + "container": { + "type": [ + "object", + "string" + ] + }, + "pod": { + "type": [ + "object", + "string" + ] + } + } + }, + "updateStrategy": { + "type": "object", + "properties": { + "maxUnavailable": { + "type": "string" + }, + "type": { + "type": "string" + } + } + } + } + }, + "debug": { + "type": "boolean" + }, + "enabled": { + "type": [ + "boolean", + "string" + ] + }, + "extraArgs": { + "type": "array" + }, + "image": { + "type": "object", + "properties": { + "pullPolicy": { + "type": "string" + }, + "repository": { + "type": "string" + }, + "tag": { + "type": "string" + } + } + }, + "livenessProbe": { + "type": "object", + "properties": { + "failureThreshold": { + "type": "integer" + }, + "initialDelaySeconds": { + "type": "integer" + }, + "periodSeconds": { + "type": "integer" + }, + "successThreshold": { + "type": "integer" + }, + "timeoutSeconds": { + "type": "integer" + } + } + }, + "pod": { + "type": "object", + "properties": { + "affinity": { + "type": [ + "null", + "object", + "string" + ] + }, + "annotations": { + "type": [ + "object", + "string" + ] + }, + "extraLabels": { + "type": "object" + }, + "nodeSelector": { + "type": [ + "null", + "object", + "string" + ] + }, + "tolerations": { + "type": [ + "null", + "array", + "string" + ] + } + } + }, + "priorityClassName": { + "type": "string" + }, + "readinessProbe": { + "type": "object", + "properties": { + "failureThreshold": { + "type": "integer" + }, + "initialDelaySeconds": { + "type": "integer" + }, + "periodSeconds": { + "type": "integer" + }, + "successThreshold": { + "type": "integer" + }, + "timeoutSeconds": { + "type": "integer" + } + } + }, + "resources": { + "type": "object" + }, + "serviceAccount": { + "type": "object", + "properties": { + "annotations": { + "type": [ + "object", + "string" + ] + }, + "extraLabels": { + "type": "object" + } + } + }, + "volumeMounts": { + "type": [ + "null", + "array" + ] + }, + "volumes": { + "type": [ + "null", + "array" + ] + } + } + }, + "global": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "externalVaultAddr": { + "type": "string" + }, + "imagePullSecrets": { + "type": "array" + }, + "openshift": { + "type": "boolean" + }, + "psp": { + "type": "object", + "properties": { + "annotations": { + "type": [ + "object", + "string" + ] + }, + "enable": { + "type": "boolean" + } + } + }, + "tlsDisable": { + "type": "boolean" + } + } + }, + "injector": { + "type": "object", + "properties": { + "affinity": { + "type": [ + "object", + "string" + ] + }, + "agentDefaults": { + "type": "object", + "properties": { + "cpuLimit": { + "type": "string" + }, + "cpuRequest": { + "type": "string" + }, + "memLimit": { + "type": "string" + }, + "memRequest": { + "type": "string" + }, + "ephemeralLimit": { + "type": "string" + }, + "ephemeralRequest": { + "type": "string" + }, + "template": { + "type": "string" + }, + "templateConfig": { + "type": "object", + "properties": { + "exitOnRetryFailure": { + "type": "boolean" + }, + "staticSecretRenderInterval": { + "type": "string" + } + } + } + } + }, + "agentImage": { + "type": "object", + "properties": { + "repository": { + "type": "string" + }, + "tag": { + "type": "string" + } + } + }, + "annotations": { + "type": [ + "object", + "string" + ] + }, + "authPath": { + "type": "string" + }, + "certs": { + "type": "object", + "properties": { + "caBundle": { + "type": "string" + }, + "certName": { + "type": "string" + }, + "keyName": { + "type": "string" + }, + "secretName": { + "type": [ + "null", + "string" + ] + } + } + }, + "enabled": { + "type": [ + "boolean", + "string" + ] + }, + "externalVaultAddr": { + "type": "string" + }, + "extraEnvironmentVars": { + "type": "object" + }, + "extraLabels": { + "type": "object" + }, + "failurePolicy": { + "type": "string" + }, + "hostNetwork": { + "type": "boolean" + }, + "image": { + "type": "object", + "properties": { + "pullPolicy": { + "type": "string" + }, + "repository": { + "type": "string" + }, + "tag": { + "type": "string" + } + } + }, + "leaderElector": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + } + } + }, + "logFormat": { + "type": "string" + }, + "logLevel": { + "type": "string" + }, + "metrics": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + } + } + }, + "namespaceSelector": { + "type": "object" + }, + "nodeSelector": { + "type": [ + "null", + "object", + "string" + ] + }, + "objectSelector": { + "type": [ + "object", + "string" + ] + }, + "podDisruptionBudget": { + "type": "object" + }, + "port": { + "type": "integer" + }, + "priorityClassName": { + "type": "string" + }, + "replicas": { + "type": "integer" + }, + "resources": { + "type": "object" + }, + "revokeOnShutdown": { + "type": "boolean" + }, + "securityContext": { + "type": "object", + "properties": { + "container": { + "type": [ + "object", + "string" + ] + }, + "pod": { + "type": [ + "object", + "string" + ] + } + } + }, + "service": { + "type": "object", + "properties": { + "annotations": { + "type": [ + "object", + "string" + ] + } + } + }, + "serviceAccount": { + "type": "object", + "properties": { + "annotations": { + "type": [ + "object", + "string" + ] + } + } + }, + "strategy": { + "type": [ + "object", + "string" + ] + }, + "tolerations": { + "type": [ + "null", + "array", + "string" + ] + }, + "topologySpreadConstraints": { + "type": [ + "null", + "array", + "string" + ] + }, + "webhook": { + "type": "object", + "properties": { + "annotations": { + "type": [ + "object", + "string" + ] + }, + "failurePolicy": { + "type": "string" + }, + "matchPolicy": { + "type": "string" + }, + "namespaceSelector": { + "type": "object" + }, + "objectSelector": { + "type": [ + "object", + "string" + ] + }, + "timeoutSeconds": { + "type": "integer" + } + } + }, + "webhookAnnotations": { + "type": [ + "object", + "string" + ] + } + } + }, + "server": { + "type": "object", + "properties": { + "affinity": { + "type": [ + "object", + "string" + ] + }, + "annotations": { + "type": [ + "object", + "string" + ] + }, + "auditStorage": { + "type": "object", + "properties": { + "accessMode": { + "type": "string" + }, + "annotations": { + "type": [ + "object", + "string" + ] + }, + "enabled": { + "type": [ + "boolean", + "string" + ] + }, + "mountPath": { + "type": "string" + }, + "size": { + "type": "string" + }, + "storageClass": { + "type": [ + "null", + "string" + ] + } + } + }, + "authDelegator": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + } + } + }, + "dataStorage": { + "type": "object", + "properties": { + "accessMode": { + "type": "string" + }, + "annotations": { + "type": [ + "object", + "string" + ] + }, + "enabled": { + "type": [ + "boolean", + "string" + ] + }, + "mountPath": { + "type": "string" + }, + "size": { + "type": "string" + }, + "storageClass": { + "type": [ + "null", + "string" + ] + } + } + }, + "dev": { + "type": "object", + "properties": { + "devRootToken": { + "type": "string" + }, + "enabled": { + "type": "boolean" + } + } + }, + "enabled": { + "type": [ + "boolean", + "string" + ] + }, + "enterpriseLicense": { + "type": "object", + "properties": { + "secretKey": { + "type": "string" + }, + "secretName": { + "type": "string" + } + } + }, + "extraArgs": { + "type": "string" + }, + "extraPorts": { + "type": [ + "null", + "array" + ] + }, + "extraContainers": { + "type": [ + "null", + "array" + ] + }, + "extraEnvironmentVars": { + "type": "object" + }, + "extraInitContainers": { + "type": [ + "null", + "array" + ] + }, + "extraLabels": { + "type": "object" + }, + "extraSecretEnvironmentVars": { + "type": "array" + }, + "extraVolumes": { + "type": "array" + }, + "ha": { + "type": "object", + "properties": { + "apiAddr": { + "type": [ + "null", + "string" + ] + }, + "clusterAddr": { + "type": [ + "null", + "string" + ] + }, + "config": { + "type": [ + "string", + "object" + ] + }, + "disruptionBudget": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "maxUnavailable": { + "type": [ + "null", + "integer" + ] + } + } + }, + "enabled": { + "type": "boolean" + }, + "raft": { + "type": "object", + "properties": { + "config": { + "type": [ + "string", + "object" + ] + }, + "enabled": { + "type": "boolean" + }, + "setNodeId": { + "type": "boolean" + } + } + }, + "replicas": { + "type": "integer" + } + } + }, + "image": { + "type": "object", + "properties": { + "pullPolicy": { + "type": "string" + }, + "repository": { + "type": "string" + }, + "tag": { + "type": "string" + } + } + }, + "ingress": { + "type": "object", + "properties": { + "activeService": { + "type": "boolean" + }, + "annotations": { + "type": [ + "object", + "string" + ] + }, + "enabled": { + "type": "boolean" + }, + "extraPaths": { + "type": "array" + }, + "hosts": { + "type": "array", + "items": { + "type": "object", + "properties": { + "host": { + "type": "string" + }, + "paths": { + "type": "array" + } + } + } + }, + "ingressClassName": { + "type": "string" + }, + "labels": { + "type": "object" + }, + "pathType": { + "type": "string" + }, + "tls": { + "type": "array" + } + } + }, + "livenessProbe": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "failureThreshold": { + "type": "integer" + }, + "initialDelaySeconds": { + "type": "integer" + }, + "path": { + "type": "string" + }, + "periodSeconds": { + "type": "integer" + }, + "successThreshold": { + "type": "integer" + }, + "timeoutSeconds": { + "type": "integer" + } + } + }, + "logFormat": { + "type": "string" + }, + "logLevel": { + "type": "string" + }, + "networkPolicy": { + "type": "object", + "properties": { + "egress": { + "type": "array" + }, + "enabled": { + "type": "boolean" + } + } + }, + "nodeSelector": { + "type": [ + "null", + "object", + "string" + ] + }, + "postStart": { + "type": "array" + }, + "preStopSleepSeconds": { + "type": "integer" + }, + "priorityClassName": { + "type": "string" + }, + "readinessProbe": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "failureThreshold": { + "type": "integer" + }, + "initialDelaySeconds": { + "type": "integer" + }, + "periodSeconds": { + "type": "integer" + }, + "successThreshold": { + "type": "integer" + }, + "timeoutSeconds": { + "type": "integer" + } + } + }, + "resources": { + "type": "object" + }, + "route": { + "type": "object", + "properties": { + "activeService": { + "type": "boolean" + }, + "annotations": { + "type": [ + "object", + "string" + ] + }, + "enabled": { + "type": "boolean" + }, + "host": { + "type": "string" + }, + "labels": { + "type": "object" + }, + "tls": { + "type": "object" + } + } + }, + "service": { + "type": "object", + "properties": { + "active": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + } + } + }, + "annotations": { + "type": [ + "object", + "string" + ] + }, + "enabled": { + "type": "boolean" + }, + "externalTrafficPolicy": { + "type": "string" + }, + "instanceSelector": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + } + } + }, + "port": { + "type": "integer" + }, + "publishNotReadyAddresses": { + "type": "boolean" + }, + "standby": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + } + } + }, + "targetPort": { + "type": "integer" + }, + "nodePort": { + "type": "integer" + }, + "activeNodePort": { + "type": "integer" + }, + "standbyNodePort": { + "type": "integer" + } + } + }, + "serviceAccount": { + "type": "object", + "properties": { + "annotations": { + "type": [ + "object", + "string" + ] + }, + "create": { + "type": "boolean" + }, + "extraLabels": { + "type": "object" + }, + "name": { + "type": "string" + }, + "serviceDiscovery": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + } + } + } + } + }, + "shareProcessNamespace": { + "type": "boolean" + }, + "standalone": { + "type": "object", + "properties": { + "config": { + "type": [ + "string", + "object" + ] + }, + "enabled": { + "type": [ + "string", + "boolean" + ] + } + } + }, + "statefulSet": { + "type": "object", + "properties": { + "annotations": { + "type": [ + "object", + "string" + ] + }, + "securityContext": { + "type": "object", + "properties": { + "container": { + "type": [ + "object", + "string" + ] + }, + "pod": { + "type": [ + "object", + "string" + ] + } + } + } + } + }, + "terminationGracePeriodSeconds": { + "type": "integer" + }, + "tolerations": { + "type": [ + "null", + "array", + "string" + ] + }, + "topologySpreadConstraints": { + "type": [ + "null", + "array", + "string" + ] + }, + "updateStrategyType": { + "type": "string" + }, + "volumeMounts": { + "type": [ + "null", + "array" + ] + }, + "volumes": { + "type": [ + "null", + "array" + ] + }, + "hostNetwork": { + "type": "boolean" + } + } + }, + "serverTelemetry": { + "type": "object", + "properties": { + "prometheusRules": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "rules": { + "type": "array" + }, + "selectors": { + "type": "object" + } + } + } + } + }, + "ui": { + "type": "object", + "properties": { + "activeVaultPodOnly": { + "type": "boolean" + }, + "annotations": { + "type": [ + "object", + "string" + ] + }, + "enabled": { + "type": [ + "boolean", + "string" + ] + }, + "externalPort": { + "type": "integer" + }, + "externalTrafficPolicy": { + "type": "string" + }, + "publishNotReadyAddresses": { + "type": "boolean" + }, + "serviceNodePort": { + "type": [ + "null", + "integer" + ] + }, + "serviceType": { + "type": "string" + }, + "targetPort": { + "type": "integer" + } + } + } + } +} diff --git a/helm/vault/values.yaml b/helm/vault/values.yaml new file mode 100644 index 0000000..58eb8a2 --- /dev/null +++ b/helm/vault/values.yaml @@ -0,0 +1,1230 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +# Available parameters and their default values for the Vault chart. + +global: + # enabled is the master enabled switch. Setting this to true or false + # will enable or disable all the components within this chart by default. + enabled: true + + # Image pull secret to use for registry authentication. + # Alternatively, the value may be specified as an array of strings. + imagePullSecrets: [] + # imagePullSecrets: + # - name: image-pull-secret + + # TLS for end-to-end encrypted transport + tlsDisable: true + + # External vault server address for the injector and CSI provider to use. + # Setting this will disable deployment of a vault server. + externalVaultAddr: "" + + # If deploying to OpenShift + openshift: false + + # Create PodSecurityPolicy for pods + psp: + enable: false + # Annotation for PodSecurityPolicy. + # This is a multi-line templated string map, and can also be set as YAML. + annotations: | + seccomp.security.alpha.kubernetes.io/allowedProfileNames: docker/default,runtime/default + apparmor.security.beta.kubernetes.io/allowedProfileNames: runtime/default + seccomp.security.alpha.kubernetes.io/defaultProfileName: runtime/default + apparmor.security.beta.kubernetes.io/defaultProfileName: runtime/default + + serverTelemetry: + # Enable integration with the Prometheus Operator + # See the top level serverTelemetry section below before enabling this feature. + prometheusOperator: false + +injector: + # True if you want to enable vault agent injection. + # @default: global.enabled + enabled: "-" + + replicas: 1 + + # Configures the port the injector should listen on + port: 8080 + + # If multiple replicas are specified, by default a leader will be determined + # so that only one injector attempts to create TLS certificates. + leaderElector: + enabled: true + + # If true, will enable a node exporter metrics endpoint at /metrics. + metrics: + enabled: false + + # Deprecated: Please use global.externalVaultAddr instead. + externalVaultAddr: "" + + # image sets the repo and tag of the vault-k8s image to use for the injector. + image: + repository: "hashicorp/vault-k8s" + tag: "1.2.1" + pullPolicy: IfNotPresent + + # agentImage sets the repo and tag of the Vault image to use for the Vault Agent + # containers. This should be set to the official Vault image. Vault 1.3.1+ is + # required. + agentImage: + repository: "hashicorp/vault" + tag: "1.14.0" + + # The default values for the injected Vault Agent containers. + agentDefaults: + # For more information on configuring resources, see the K8s documentation: + # https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + cpuLimit: "500m" + cpuRequest: "250m" + memLimit: "128Mi" + memRequest: "64Mi" + # ephemeralLimit: "128Mi" + # ephemeralRequest: "64Mi" + + # Default template type for secrets when no custom template is specified. + # Possible values include: "json" and "map". + template: "map" + + # Default values within Agent's template_config stanza. + templateConfig: + exitOnRetryFailure: true + staticSecretRenderInterval: "" + + # Used to define custom livenessProbe settings + livenessProbe: + # When a probe fails, Kubernetes will try failureThreshold times before giving up + failureThreshold: 2 + # Number of seconds after the container has started before probe initiates + initialDelaySeconds: 5 + # How often (in seconds) to perform the probe + periodSeconds: 2 + # Minimum consecutive successes for the probe to be considered successful after having failed + successThreshold: 1 + # Number of seconds after which the probe times out. + timeoutSeconds: 5 + # Used to define custom readinessProbe settings + readinessProbe: + # When a probe fails, Kubernetes will try failureThreshold times before giving up + failureThreshold: 2 + # Number of seconds after the container has started before probe initiates + initialDelaySeconds: 5 + # How often (in seconds) to perform the probe + periodSeconds: 2 + # Minimum consecutive successes for the probe to be considered successful after having failed + successThreshold: 1 + # Number of seconds after which the probe times out. + timeoutSeconds: 5 + # Used to define custom startupProbe settings + startupProbe: + # When a probe fails, Kubernetes will try failureThreshold times before giving up + failureThreshold: 12 + # Number of seconds after the container has started before probe initiates + initialDelaySeconds: 5 + # How often (in seconds) to perform the probe + periodSeconds: 5 + # Minimum consecutive successes for the probe to be considered successful after having failed + successThreshold: 1 + # Number of seconds after which the probe times out. + timeoutSeconds: 5 + + # Mount Path of the Vault Kubernetes Auth Method. + authPath: "auth/kubernetes" + + # Configures the log verbosity of the injector. + # Supported log levels include: trace, debug, info, warn, error + logLevel: "info" + + # Configures the log format of the injector. Supported log formats: "standard", "json". + logFormat: "standard" + + # Configures all Vault Agent sidecars to revoke their token when shutting down + revokeOnShutdown: false + + webhook: + # Configures failurePolicy of the webhook. The "unspecified" default behaviour depends on the + # API Version of the WebHook. + # To block pod creation while the webhook is unavailable, set the policy to `Fail` below. + # See https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#failure-policy + # + failurePolicy: Ignore + + # matchPolicy specifies the approach to accepting changes based on the rules of + # the MutatingWebhookConfiguration. + # See https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#matching-requests-matchpolicy + # for more details. + # + matchPolicy: Exact + + # timeoutSeconds is the amount of seconds before the webhook request will be ignored + # or fails. + # If it is ignored or fails depends on the failurePolicy + # See https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#timeouts + # for more details. + # + timeoutSeconds: 30 + + # namespaceSelector is the selector for restricting the webhook to only + # specific namespaces. + # See https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#matching-requests-namespaceselector + # for more details. + # Example: + # namespaceSelector: + # matchLabels: + # sidecar-injector: enabled + namespaceSelector: {} + + # objectSelector is the selector for restricting the webhook to only + # specific labels. + # See https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#matching-requests-objectselector + # for more details. + # Example: + # objectSelector: + # matchLabels: + # vault-sidecar-injector: enabled + objectSelector: | + matchExpressions: + - key: app.kubernetes.io/name + operator: NotIn + values: + - {{ template "vault.name" . }}-agent-injector + + # Extra annotations to attach to the webhook + annotations: {} + + # Deprecated: please use 'webhook.failurePolicy' instead + # Configures failurePolicy of the webhook. The "unspecified" default behaviour depends on the + # API Version of the WebHook. + # To block pod creation while webhook is unavailable, set the policy to `Fail` below. + # See https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#failure-policy + # + failurePolicy: Ignore + + # Deprecated: please use 'webhook.namespaceSelector' instead + # namespaceSelector is the selector for restricting the webhook to only + # specific namespaces. + # See https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#matching-requests-namespaceselector + # for more details. + # Example: + # namespaceSelector: + # matchLabels: + # sidecar-injector: enabled + namespaceSelector: {} + + # Deprecated: please use 'webhook.objectSelector' instead + # objectSelector is the selector for restricting the webhook to only + # specific labels. + # See https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#matching-requests-objectselector + # for more details. + # Example: + # objectSelector: + # matchLabels: + # vault-sidecar-injector: enabled + objectSelector: {} + + # Deprecated: please use 'webhook.annotations' instead + # Extra annotations to attach to the webhook + webhookAnnotations: {} + + certs: + # secretName is the name of the secret that has the TLS certificate and + # private key to serve the injector webhook. If this is null, then the + # injector will default to its automatic management mode that will assign + # a service account to the injector to generate its own certificates. + secretName: null + + # caBundle is a base64-encoded PEM-encoded certificate bundle for the CA + # that signed the TLS certificate that the webhook serves. This must be set + # if secretName is non-null unless an external service like cert-manager is + # keeping the caBundle updated. + caBundle: "" + + # certName and keyName are the names of the files within the secret for + # the TLS cert and private key, respectively. These have reasonable + # defaults but can be customized if necessary. + certName: tls.crt + keyName: tls.key + + # Security context for the pod template and the injector container + # The default pod securityContext is: + # runAsNonRoot: true + # runAsGroup: {{ .Values.injector.gid | default 1000 }} + # runAsUser: {{ .Values.injector.uid | default 100 }} + # fsGroup: {{ .Values.injector.gid | default 1000 }} + # and for container is + # allowPrivilegeEscalation: false + # capabilities: + # drop: + # - ALL + securityContext: + pod: {} + container: {} + + resources: {} + # resources: + # requests: + # memory: 256Mi + # cpu: 250m + # limits: + # memory: 256Mi + # cpu: 250m + + # extraEnvironmentVars is a list of extra environment variables to set in the + # injector deployment. + extraEnvironmentVars: {} + # KUBERNETES_SERVICE_HOST: kubernetes.default.svc + + # Affinity Settings for injector pods + # This can either be a multi-line string or YAML matching the PodSpec's affinity field. + # Commenting out or setting as empty the affinity variable, will allow + # deployment of multiple replicas to single node services such as Minikube. + affinity: | + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/name: {{ template "vault.name" . }}-agent-injector + app.kubernetes.io/instance: "{{ .Release.Name }}" + component: webhook + topologyKey: kubernetes.io/hostname + + # Topology settings for injector pods + # ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ + # This should be either a multi-line string or YAML matching the topologySpreadConstraints array + # in a PodSpec. + topologySpreadConstraints: [] + + # Toleration Settings for injector pods + # This should be either a multi-line string or YAML matching the Toleration array + # in a PodSpec. + tolerations: [] + + # nodeSelector labels for server pod assignment, formatted as a multi-line string or YAML map. + # ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector + # Example: + # nodeSelector: + # beta.kubernetes.io/arch: amd64 + nodeSelector: {} + + # Priority class for injector pods + priorityClassName: "" + + # Extra annotations to attach to the injector pods + # This can either be YAML or a YAML-formatted multi-line templated string map + # of the annotations to apply to the injector pods + annotations: {} + + # Extra labels to attach to the agent-injector + # This should be a YAML map of the labels to apply to the injector + extraLabels: {} + + # Should the injector pods run on the host network (useful when using + # an alternate CNI in EKS) + hostNetwork: false + + # Injector service specific config + service: + # Extra annotations to attach to the injector service + annotations: {} + + # Injector serviceAccount specific config + serviceAccount: + # Extra annotations to attach to the injector serviceAccount + annotations: {} + + # A disruption budget limits the number of pods of a replicated application + # that are down simultaneously from voluntary disruptions + podDisruptionBudget: {} + # podDisruptionBudget: + # maxUnavailable: 1 + + # strategy for updating the deployment. This can be a multi-line string or a + # YAML map. + strategy: {} + # strategy: | + # rollingUpdate: + # maxSurge: 25% + # maxUnavailable: 25% + # type: RollingUpdate + +server: + # If true, or "-" with global.enabled true, Vault server will be installed. + # See vault.mode in _helpers.tpl for implementation details. + enabled: "-" + + # [Enterprise Only] This value refers to a Kubernetes secret that you have + # created that contains your enterprise license. If you are not using an + # enterprise image or if you plan to introduce the license key via another + # route, then leave secretName blank ("") or set it to null. + # Requires Vault Enterprise 1.8 or later. + enterpriseLicense: + # The name of the Kubernetes secret that holds the enterprise license. The + # secret must be in the same namespace that Vault is installed into. + secretName: "" + # The key within the Kubernetes secret that holds the enterprise license. + secretKey: "license" + + # Resource requests, limits, etc. for the server cluster placement. This + # should map directly to the value of the resources field for a PodSpec. + # By default no direct resource request is made. + + image: + repository: "hashicorp/vault" + tag: "1.14.0" + # Overrides the default Image Pull Policy + pullPolicy: IfNotPresent + + # Configure the Update Strategy Type for the StatefulSet + # See https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#update-strategies + updateStrategyType: "OnDelete" + + # Configure the logging verbosity for the Vault server. + # Supported log levels include: trace, debug, info, warn, error + logLevel: "" + + # Configure the logging format for the Vault server. + # Supported log formats include: standard, json + logFormat: "" + + resources: {} + # resources: + # requests: + # memory: 256Mi + # cpu: 250m + # limits: + # memory: 256Mi + # cpu: 250m + + # Ingress allows ingress services to be created to allow external access + # from Kubernetes to access Vault pods. + # If deployment is on OpenShift, the following block is ignored. + # In order to expose the service, use the route section below + ingress: + enabled: false + labels: {} + # traffic: external + annotations: {} + # | + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: "true" + # or + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: "true" + + # Optionally use ingressClassName instead of deprecated annotation. + # See: https://kubernetes.io/docs/concepts/services-networking/ingress/#deprecated-annotation + ingressClassName: "" + + # As of Kubernetes 1.19, all Ingress Paths must have a pathType configured. The default value below should be sufficient in most cases. + # See: https://kubernetes.io/docs/concepts/services-networking/ingress/#path-types for other possible values. + pathType: Prefix + + # When HA mode is enabled and K8s service registration is being used, + # configure the ingress to point to the Vault active service. + activeService: true + hosts: + - host: chart-example.local + paths: [] + ## Extra paths to prepend to the host configuration. This is useful when working with annotation based services. + extraPaths: [] + # - path: /* + # backend: + # service: + # name: ssl-redirect + # port: + # number: use-annotation + tls: [] + # - secretName: chart-example-tls + # hosts: + # - chart-example.local + + # OpenShift only - create a route to expose the service + # By default the created route will be of type passthrough + route: + enabled: false + + # When HA mode is enabled and K8s service registration is being used, + # configure the route to point to the Vault active service. + activeService: true + + labels: {} + annotations: {} + host: chart-example.local + # tls will be passed directly to the route's TLS config, which + # can be used to configure other termination methods that terminate + # TLS at the router + tls: + termination: passthrough + + # authDelegator enables a cluster role binding to be attached to the service + # account. This cluster role binding can be used to setup Kubernetes auth + # method. https://www.vaultproject.io/docs/auth/kubernetes.html + authDelegator: + enabled: true + + # extraInitContainers is a list of init containers. Specified as a YAML list. + # This is useful if you need to run a script to provision TLS certificates or + # write out configuration files in a dynamic way. + extraInitContainers: null + # # This example installs a plugin pulled from github into the /usr/local/libexec/vault/oauthapp folder, + # # which is defined in the volumes value. + # - name: oauthapp + # image: "alpine" + # command: [sh, -c] + # args: + # - cd /tmp && + # wget https://github.com/puppetlabs/vault-plugin-secrets-oauthapp/releases/download/v1.2.0/vault-plugin-secrets-oauthapp-v1.2.0-linux-amd64.tar.xz -O oauthapp.xz && + # tar -xf oauthapp.xz && + # mv vault-plugin-secrets-oauthapp-v1.2.0-linux-amd64 /usr/local/libexec/vault/oauthapp && + # chmod +x /usr/local/libexec/vault/oauthapp + # volumeMounts: + # - name: plugins + # mountPath: /usr/local/libexec/vault + + # extraContainers is a list of sidecar containers. Specified as a YAML list. + extraContainers: null + + # shareProcessNamespace enables process namespace sharing between Vault and the extraContainers + # This is useful if Vault must be signaled, e.g. to send a SIGHUP for a log rotation + shareProcessNamespace: false + + # extraArgs is a string containing additional Vault server arguments. + extraArgs: "" + + # extraPorts is a list of extra ports. Specified as a YAML list. + # This is useful if you need to add additional ports to the statefulset in dynamic way. + extraPorts: null + # - containerPort: 8300 + # name: http-monitoring + + # Used to define custom readinessProbe settings + readinessProbe: + enabled: true + # If you need to use a http path instead of the default exec + # path: /v1/sys/health?standbyok=true + + # Port number on which readinessProbe will be checked. + port: 8200 + # When a probe fails, Kubernetes will try failureThreshold times before giving up + failureThreshold: 2 + # Number of seconds after the container has started before probe initiates + initialDelaySeconds: 5 + # How often (in seconds) to perform the probe + periodSeconds: 5 + # Minimum consecutive successes for the probe to be considered successful after having failed + successThreshold: 1 + # Number of seconds after which the probe times out. + timeoutSeconds: 3 + # Used to enable a livenessProbe for the pods + livenessProbe: + enabled: false + path: "/v1/sys/health?standbyok=true" + # Port number on which livenessProbe will be checked. + port: 8200 + # When a probe fails, Kubernetes will try failureThreshold times before giving up + failureThreshold: 2 + # Number of seconds after the container has started before probe initiates + initialDelaySeconds: 60 + # How often (in seconds) to perform the probe + periodSeconds: 5 + # Minimum consecutive successes for the probe to be considered successful after having failed + successThreshold: 1 + # Number of seconds after which the probe times out. + timeoutSeconds: 3 + + # Optional duration in seconds the pod needs to terminate gracefully. + # See: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/ + terminationGracePeriodSeconds: 10 + + # Used to set the sleep time during the preStop step + preStopSleepSeconds: 5 + + # Used to define commands to run after the pod is ready. + # This can be used to automate processes such as initialization + # or boostrapping auth methods. + postStart: [] + # - /bin/sh + # - -c + # - /vault/userconfig/myscript/run.sh + + # extraEnvironmentVars is a list of extra environment variables to set with the stateful set. These could be + # used to include variables required for auto-unseal. + extraEnvironmentVars: {} + # GOOGLE_REGION: global + # GOOGLE_PROJECT: myproject + # GOOGLE_APPLICATION_CREDENTIALS: /vault/userconfig/myproject/myproject-creds.json + + # extraSecretEnvironmentVars is a list of extra environment variables to set with the stateful set. + # These variables take value from existing Secret objects. + extraSecretEnvironmentVars: [] + # - envName: AWS_SECRET_ACCESS_KEY + # secretName: vault + # secretKey: AWS_SECRET_ACCESS_KEY + + # Deprecated: please use 'volumes' instead. + # extraVolumes is a list of extra volumes to mount. These will be exposed + # to Vault in the path `/vault/userconfig//`. The value below is + # an array of objects, examples are shown below. + extraVolumes: [] + # - type: secret (or "configMap") + # name: my-secret + # path: null # default is `/vault/userconfig` + + # volumes is a list of volumes made available to all containers. These are rendered + # via toYaml rather than pre-processed like the extraVolumes value. + # The purpose is to make it easy to share volumes between containers. + volumes: null + # - name: plugins + # emptyDir: {} + + # volumeMounts is a list of volumeMounts for the main server container. These are rendered + # via toYaml rather than pre-processed like the extraVolumes value. + # The purpose is to make it easy to share volumes between containers. + volumeMounts: null + # - mountPath: /usr/local/libexec/vault + # name: plugins + # readOnly: true + + # Affinity Settings + # Commenting out or setting as empty the affinity variable, will allow + # deployment to single node services such as Minikube + # This should be either a multi-line string or YAML matching the PodSpec's affinity field. + affinity: | + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/name: {{ template "vault.name" . }} + app.kubernetes.io/instance: "{{ .Release.Name }}" + component: server + topologyKey: kubernetes.io/hostname + + # Topology settings for server pods + # ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/ + # This should be either a multi-line string or YAML matching the topologySpreadConstraints array + # in a PodSpec. + topologySpreadConstraints: [] + + # Toleration Settings for server pods + # This should be either a multi-line string or YAML matching the Toleration array + # in a PodSpec. + tolerations: [] + + # nodeSelector labels for server pod assignment, formatted as a multi-line string or YAML map. + # ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector + # Example: + # nodeSelector: + # beta.kubernetes.io/arch: amd64 + nodeSelector: {} + + # Enables network policy for server pods + networkPolicy: + enabled: false + egress: [] + # egress: + # - to: + # - ipBlock: + # cidr: 10.0.0.0/24 + # ports: + # - protocol: TCP + # port: 443 + + # Priority class for server pods + priorityClassName: "" + + # Extra labels to attach to the server pods + # This should be a YAML map of the labels to apply to the server pods + extraLabels: {} + + # Extra annotations to attach to the server pods + # This can either be YAML or a YAML-formatted multi-line templated string map + # of the annotations to apply to the server pods + annotations: {} + + # Enables a headless service to be used by the Vault Statefulset + service: + enabled: true + # Enable or disable the vault-active service, which selects Vault pods that + # have labelled themselves as the cluster leader with `vault-active: "true"` + active: + enabled: true + # Enable or disable the vault-standby service, which selects Vault pods that + # have labelled themselves as a cluster follower with `vault-active: "false"` + standby: + enabled: true + # If enabled, the service selectors will include `app.kubernetes.io/instance: {{ .Release.Name }}` + # When disabled, services may select Vault pods not deployed from the chart. + # Does not affect the headless vault-internal service with `ClusterIP: None` + instanceSelector: + enabled: true + # clusterIP controls whether a Cluster IP address is attached to the + # Vault service within Kubernetes. By default, the Vault service will + # be given a Cluster IP address, set to None to disable. When disabled + # Kubernetes will create a "headless" service. Headless services can be + # used to communicate with pods directly through DNS instead of a round-robin + # load balancer. + # clusterIP: None + + # Configures the service type for the main Vault service. Can be ClusterIP + # or NodePort. + #type: ClusterIP + + # Do not wait for pods to be ready before including them in the services' + # targets. Does not apply to the headless service, which is used for + # cluster-internal communication. + publishNotReadyAddresses: true + + # The externalTrafficPolicy can be set to either Cluster or Local + # and is only valid for LoadBalancer and NodePort service types. + # The default value is Cluster. + # ref: https://kubernetes.io/docs/concepts/services-networking/service/#external-traffic-policy + externalTrafficPolicy: Cluster + + # If type is set to "NodePort", a specific nodePort value can be configured, + # will be random if left blank. + #nodePort: 30000 + + # When HA mode is enabled + # If type is set to "NodePort", a specific nodePort value can be configured, + # will be random if left blank. + #activeNodePort: 30001 + + # When HA mode is enabled + # If type is set to "NodePort", a specific nodePort value can be configured, + # will be random if left blank. + #standbyNodePort: 30002 + + # Port on which Vault server is listening + port: 8200 + # Target port to which the service should be mapped to + targetPort: 8200 + # Extra annotations for the service definition. This can either be YAML or a + # YAML-formatted multi-line templated string map of the annotations to apply + # to the service. + annotations: {} + + # This configures the Vault Statefulset to create a PVC for data + # storage when using the file or raft backend storage engines. + # See https://www.vaultproject.io/docs/configuration/storage/index.html to know more + dataStorage: + enabled: true + # Size of the PVC created + size: 10Gi + # Location where the PVC will be mounted. + mountPath: "/vault/data" + # Name of the storage class to use. If null it will use the + # configured default Storage Class. + storageClass: null + # Access Mode of the storage device being used for the PVC + accessMode: ReadWriteOnce + # Annotations to apply to the PVC + annotations: {} + + # This configures the Vault Statefulset to create a PVC for audit + # logs. Once Vault is deployed, initialized, and unsealed, Vault must + # be configured to use this for audit logs. This will be mounted to + # /vault/audit + # See https://www.vaultproject.io/docs/audit/index.html to know more + auditStorage: + enabled: false + # Size of the PVC created + size: 10Gi + # Location where the PVC will be mounted. + mountPath: "/vault/audit" + # Name of the storage class to use. If null it will use the + # configured default Storage Class. + storageClass: null + # Access Mode of the storage device being used for the PVC + accessMode: ReadWriteOnce + # Annotations to apply to the PVC + annotations: {} + + # Run Vault in "dev" mode. This requires no further setup, no state management, + # and no initialization. This is useful for experimenting with Vault without + # needing to unseal, store keys, et. al. All data is lost on restart - do not + # use dev mode for anything other than experimenting. + # See https://www.vaultproject.io/docs/concepts/dev-server.html to know more + dev: + enabled: false + + # Set VAULT_DEV_ROOT_TOKEN_ID value + devRootToken: "root" + + # Run Vault in "standalone" mode. This is the default mode that will deploy if + # no arguments are given to helm. This requires a PVC for data storage to use + # the "file" backend. This mode is not highly available and should not be scaled + # past a single replica. + standalone: + enabled: "-" + + # config is a raw string of default configuration when using a Stateful + # deployment. Default is to use a PersistentVolumeClaim mounted at /vault/data + # and store data there. This is only used when using a Replica count of 1, and + # using a stateful set. This should be HCL. + + # Note: Configuration files are stored in ConfigMaps so sensitive data + # such as passwords should be either mounted through extraSecretEnvironmentVars + # or through a Kube secret. For more information see: + # https://www.vaultproject.io/docs/platform/k8s/helm/run#protecting-sensitive-vault-configurations + config: | + ui = true + + listener "tcp" { + tls_disable = 1 + address = "[::]:8200" + cluster_address = "[::]:8201" + # Enable unauthenticated metrics access (necessary for Prometheus Operator) + #telemetry { + # unauthenticated_metrics_access = "true" + #} + } + storage "file" { + path = "/vault/data" + } + + # Example configuration for using auto-unseal, using Google Cloud KMS. The + # GKMS keys must already exist, and the cluster must have a service account + # that is authorized to access GCP KMS. + #seal "gcpckms" { + # project = "vault-helm-dev" + # region = "global" + # key_ring = "vault-helm-unseal-kr" + # crypto_key = "vault-helm-unseal-key" + #} + + # Example configuration for enabling Prometheus metrics in your config. + #telemetry { + # prometheus_retention_time = "30s" + # disable_hostname = true + #} + + # Run Vault in "HA" mode. There are no storage requirements unless the audit log + # persistence is required. In HA mode Vault will configure itself to use Consul + # for its storage backend. The default configuration provided will work the Consul + # Helm project by default. It is possible to manually configure Vault to use a + # different HA backend. + ha: + enabled: false + replicas: 3 + + # Set the api_addr configuration for Vault HA + # See https://www.vaultproject.io/docs/configuration#api_addr + # If set to null, this will be set to the Pod IP Address + apiAddr: null + + # Set the cluster_addr confuguration for Vault HA + # See https://www.vaultproject.io/docs/configuration#cluster_addr + # If set to null, this will be set to https://$(HOSTNAME).{{ template "vault.fullname" . }}-internal:8201 + clusterAddr: null + + # Enables Vault's integrated Raft storage. Unlike the typical HA modes where + # Vault's persistence is external (such as Consul), enabling Raft mode will create + # persistent volumes for Vault to store data according to the configuration under server.dataStorage. + # The Vault cluster will coordinate leader elections and failovers internally. + raft: + + # Enables Raft integrated storage + enabled: false + # Set the Node Raft ID to the name of the pod + setNodeId: false + + # Note: Configuration files are stored in ConfigMaps so sensitive data + # such as passwords should be either mounted through extraSecretEnvironmentVars + # or through a Kube secret. For more information see: + # https://www.vaultproject.io/docs/platform/k8s/helm/run#protecting-sensitive-vault-configurations + config: | + ui = true + + listener "tcp" { + tls_disable = 1 + address = "[::]:8200" + cluster_address = "[::]:8201" + # Enable unauthenticated metrics access (necessary for Prometheus Operator) + #telemetry { + # unauthenticated_metrics_access = "true" + #} + } + + storage "raft" { + path = "/vault/data" + } + + service_registration "kubernetes" {} + + # config is a raw string of default configuration when using a Stateful + # deployment. Default is to use a Consul for its HA storage backend. + # This should be HCL. + + # Note: Configuration files are stored in ConfigMaps so sensitive data + # such as passwords should be either mounted through extraSecretEnvironmentVars + # or through a Kube secret. For more information see: + # https://www.vaultproject.io/docs/platform/k8s/helm/run#protecting-sensitive-vault-configurations + config: | + ui = true + + listener "tcp" { + tls_disable = 1 + address = "[::]:8200" + cluster_address = "[::]:8201" + } + storage "consul" { + path = "vault" + address = "HOST_IP:8500" + } + + service_registration "kubernetes" {} + + # Example configuration for using auto-unseal, using Google Cloud KMS. The + # GKMS keys must already exist, and the cluster must have a service account + # that is authorized to access GCP KMS. + #seal "gcpckms" { + # project = "vault-helm-dev-246514" + # region = "global" + # key_ring = "vault-helm-unseal-kr" + # crypto_key = "vault-helm-unseal-key" + #} + + # Example configuration for enabling Prometheus metrics. + # If you are using Prometheus Operator you can enable a ServiceMonitor resource below. + # You may wish to enable unauthenticated metrics in the listener block above. + #telemetry { + # prometheus_retention_time = "30s" + # disable_hostname = true + #} + + # A disruption budget limits the number of pods of a replicated application + # that are down simultaneously from voluntary disruptions + disruptionBudget: + enabled: true + + # maxUnavailable will default to (n/2)-1 where n is the number of + # replicas. If you'd like a custom value, you can specify an override here. + maxUnavailable: null + + # Definition of the serviceAccount used to run Vault. + # These options are also used when using an external Vault server to validate + # Kubernetes tokens. + serviceAccount: + # Specifies whether a service account should be created + create: true + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "" + # Extra annotations for the serviceAccount definition. This can either be + # YAML or a YAML-formatted multi-line templated string map of the + # annotations to apply to the serviceAccount. + annotations: {} + # Extra labels to attach to the serviceAccount + # This should be a YAML map of the labels to apply to the serviceAccount + extraLabels: {} + # Enable or disable a service account role binding with the permissions required for + # Vault's Kubernetes service_registration config option. + # See https://developer.hashicorp.com/vault/docs/configuration/service-registration/kubernetes + serviceDiscovery: + enabled: true + + # Settings for the statefulSet used to run Vault. + statefulSet: + # Extra annotations for the statefulSet. This can either be YAML or a + # YAML-formatted multi-line templated string map of the annotations to apply + # to the statefulSet. + annotations: {} + + # Set the pod and container security contexts. + # If not set, these will default to, and for *not* OpenShift: + # pod: + # runAsNonRoot: true + # runAsGroup: {{ .Values.server.gid | default 1000 }} + # runAsUser: {{ .Values.server.uid | default 100 }} + # fsGroup: {{ .Values.server.gid | default 1000 }} + # container: + # allowPrivilegeEscalation: false + # + # If not set, these will default to, and for OpenShift: + # pod: {} + # container: {} + securityContext: + pod: {} + container: {} + + # Should the server pods run on the host network + hostNetwork: false + +# Vault UI +ui: + # True if you want to create a Service entry for the Vault UI. + # + # serviceType can be used to control the type of service created. For + # example, setting this to "LoadBalancer" will create an external load + # balancer (for supported K8S installations) to access the UI. + enabled: false + publishNotReadyAddresses: true + # The service should only contain selectors for active Vault pod + activeVaultPodOnly: false + serviceType: "ClusterIP" + serviceNodePort: null + externalPort: 8200 + targetPort: 8200 + + # The externalTrafficPolicy can be set to either Cluster or Local + # and is only valid for LoadBalancer and NodePort service types. + # The default value is Cluster. + # ref: https://kubernetes.io/docs/concepts/services-networking/service/#external-traffic-policy + externalTrafficPolicy: Cluster + + #loadBalancerSourceRanges: + # - 10.0.0.0/16 + # - 1.78.23.3/32 + + # loadBalancerIP: + + # Extra annotations to attach to the ui service + # This can either be YAML or a YAML-formatted multi-line templated string map + # of the annotations to apply to the ui service + annotations: {} + +# secrets-store-csi-driver-provider-vault +csi: + # True if you want to install a secrets-store-csi-driver-provider-vault daemonset. + # + # Requires installing the secrets-store-csi-driver separately, see: + # https://github.com/kubernetes-sigs/secrets-store-csi-driver#install-the-secrets-store-csi-driver + # + # With the driver and provider installed, you can mount Vault secrets into volumes + # similar to the Vault Agent injector, and you can also sync those secrets into + # Kubernetes secrets. + enabled: false + + image: + repository: "hashicorp/vault-csi-provider" + tag: "1.4.0" + pullPolicy: IfNotPresent + + # volumes is a list of volumes made available to all containers. These are rendered + # via toYaml rather than pre-processed like the extraVolumes value. + # The purpose is to make it easy to share volumes between containers. + volumes: null + # - name: tls + # secret: + # secretName: vault-tls + + # volumeMounts is a list of volumeMounts for the main server container. These are rendered + # via toYaml rather than pre-processed like the extraVolumes value. + # The purpose is to make it easy to share volumes between containers. + volumeMounts: null + # - name: tls + # mountPath: "/vault/tls" + # readOnly: true + + resources: {} + # resources: + # requests: + # cpu: 50m + # memory: 128Mi + # limits: + # cpu: 50m + # memory: 128Mi + + # Override the default secret name for the CSI Provider's HMAC key used for + # generating secret versions. + hmacSecretName: "" + + # Settings for the daemonSet used to run the provider. + daemonSet: + updateStrategy: + type: RollingUpdate + maxUnavailable: "" + # Extra annotations for the daemonSet. This can either be YAML or a + # YAML-formatted multi-line templated string map of the annotations to apply + # to the daemonSet. + annotations: {} + # Provider host path (must match the CSI provider's path) + providersDir: "/etc/kubernetes/secrets-store-csi-providers" + # Kubelet host path + kubeletRootDir: "/var/lib/kubelet" + # Extra labels to attach to the vault-csi-provider daemonSet + # This should be a YAML map of the labels to apply to the csi provider daemonSet + extraLabels: {} + # security context for the pod template and container in the csi provider daemonSet + securityContext: + pod: {} + container: {} + + pod: + # Extra annotations for the provider pods. This can either be YAML or a + # YAML-formatted multi-line templated string map of the annotations to apply + # to the pod. + annotations: {} + + # Toleration Settings for provider pods + # This should be either a multi-line string or YAML matching the Toleration array + # in a PodSpec. + tolerations: [] + + # nodeSelector labels for csi pod assignment, formatted as a multi-line string or YAML map. + # ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector + # Example: + # nodeSelector: + # beta.kubernetes.io/arch: amd64 + nodeSelector: {} + + # Affinity Settings + # This should be either a multi-line string or YAML matching the PodSpec's affinity field. + affinity: {} + + # Extra labels to attach to the vault-csi-provider pod + # This should be a YAML map of the labels to apply to the csi provider pod + extraLabels: {} + + agent: + enabled: true + extraArgs: [] + + image: + repository: "hashicorp/vault" + tag: "1.14.0" + pullPolicy: IfNotPresent + + logFormat: standard + logLevel: info + + resources: {} + # resources: + # requests: + # memory: 256Mi + # cpu: 250m + # limits: + # memory: 256Mi + # cpu: 250m + + # Priority class for csi pods + priorityClassName: "" + + serviceAccount: + # Extra annotations for the serviceAccount definition. This can either be + # YAML or a YAML-formatted multi-line templated string map of the + # annotations to apply to the serviceAccount. + annotations: {} + + # Extra labels to attach to the vault-csi-provider serviceAccount + # This should be a YAML map of the labels to apply to the csi provider serviceAccount + extraLabels: {} + + # Used to configure readinessProbe for the pods. + readinessProbe: + # When a probe fails, Kubernetes will try failureThreshold times before giving up + failureThreshold: 2 + # Number of seconds after the container has started before probe initiates + initialDelaySeconds: 5 + # How often (in seconds) to perform the probe + periodSeconds: 5 + # Minimum consecutive successes for the probe to be considered successful after having failed + successThreshold: 1 + # Number of seconds after which the probe times out. + timeoutSeconds: 3 + # Used to configure livenessProbe for the pods. + livenessProbe: + # When a probe fails, Kubernetes will try failureThreshold times before giving up + failureThreshold: 2 + # Number of seconds after the container has started before probe initiates + initialDelaySeconds: 5 + # How often (in seconds) to perform the probe + periodSeconds: 5 + # Minimum consecutive successes for the probe to be considered successful after having failed + successThreshold: 1 + # Number of seconds after which the probe times out. + timeoutSeconds: 3 + + # Enables debug logging. + debug: false + + # Pass arbitrary additional arguments to vault-csi-provider. + # See https://www.vaultproject.io/docs/platform/k8s/csi/configurations#command-line-arguments + # for the available command line flags. + extraArgs: [] + +# Vault is able to collect and publish various runtime metrics. +# Enabling this feature requires setting adding `telemetry{}` stanza to +# the Vault configuration. There are a few examples included in the `config` sections above. +# +# For more information see: +# https://www.vaultproject.io/docs/configuration/telemetry +# https://www.vaultproject.io/docs/internals/telemetry +serverTelemetry: + # Enable support for the Prometheus Operator. Currently, this chart does not support + # authenticating to Vault's metrics endpoint, so the following `telemetry{}` must be included + # in the `listener "tcp"{}` stanza + # telemetry { + # unauthenticated_metrics_access = "true" + # } + # + # See the `standalone.config` for a more complete example of this. + # + # In addition, a top level `telemetry{}` stanza must also be included in the Vault configuration: + # + # example: + # telemetry { + # prometheus_retention_time = "30s" + # disable_hostname = true + # } + # + # Configuration for monitoring the Vault server. + serviceMonitor: + # The Prometheus operator *must* be installed before enabling this feature, + # if not the chart will fail to install due to missing CustomResourceDefinitions + # provided by the operator. + # + # Instructions on how to install the Helm chart can be found here: + # https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack + # More information can be found here: + # https://github.com/prometheus-operator/prometheus-operator + # https://github.com/prometheus-operator/kube-prometheus + + # Enable deployment of the Vault Server ServiceMonitor CustomResource. + enabled: false + + # Selector labels to add to the ServiceMonitor. + # When empty, defaults to: + # release: prometheus + selectors: {} + + # Interval at which Prometheus scrapes metrics + interval: 30s + + # Timeout for Prometheus scrapes + scrapeTimeout: 10s + + prometheusRules: + # The Prometheus operator *must* be installed before enabling this feature, + # if not the chart will fail to install due to missing CustomResourceDefinitions + # provided by the operator. + + # Deploy the PrometheusRule custom resource for AlertManager based alerts. + # Requires that AlertManager is properly deployed. + enabled: false + + # Selector labels to add to the PrometheusRules. + # When empty, defaults to: + # release: prometheus + selectors: {} + + # Some example rules. + rules: [] + # - alert: vault-HighResponseTime + # annotations: + # message: The response time of Vault is over 500ms on average over the last 5 minutes. + # expr: vault_core_handle_request{quantile="0.5", namespace="mynamespace"} > 500 + # for: 5m + # labels: + # severity: warning + # - alert: vault-HighResponseTime + # annotations: + # message: The response time of Vault is over 1s on average over the last 5 minutes. + # expr: vault_core_handle_request{quantile="0.5", namespace="mynamespace"} > 1000 + # for: 5m + # labels: + # severity: critical diff --git a/scripts/README.md b/scripts/README.md new file mode 100644 index 0000000..82916c1 --- /dev/null +++ b/scripts/README.md @@ -0,0 +1 @@ +# Scripts \ No newline at end of file diff --git a/yaml/README.md b/yaml/README.md new file mode 100644 index 0000000..e6a7a21 --- /dev/null +++ b/yaml/README.md @@ -0,0 +1 @@ +# YAML \ No newline at end of file